// This file is part of GAnarchy - decentralized development hub
// Copyright (C) 2021 Soni L.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
//! This module provides some abstractions over git.
//!
//! Having this module allows easily(-ish) replacing the git backend, for
//! example from calling the git CLI directly to using a git library.
use std::collections::BTreeSet;
use std::error;
use std::ffi::{OsStr, OsString};
use std::fmt;
use std::fs;
use std::io;
use std::path::Path;
use std::path::PathBuf;
//use std::process;
use std::process::{Command, Output};
use impl_trait::impl_trait;
use crate::util::NamePurpose;
use crate::marker::Initializer;
#[cfg(test)]
mod tests;
mod sealed {
pub trait Sealed {
fn is_repo_path_valid(filename: &str, sha256: bool) -> bool;
}
}
/// A repository kind.
pub trait RepoKind: sealed::Sealed {
}
/// A permanent repository used to cache remote objects.
pub struct CacheRepo {
_non_exhaustive: (),
}
impl sealed::Sealed for CacheRepo {
fn is_repo_path_valid(filename: &str, sha256: bool) -> bool {
if sha256 {
NamePurpose::CacheRepo64.is_fit(filename)
} else {
NamePurpose::CacheRepo.is_fit(filename)
}
}
}
impl RepoKind for CacheRepo {
}
/// A temporary repository used to fetch remote objects.
pub struct FetchRepo {
pending_branches: BTreeSet,
}
impl sealed::Sealed for FetchRepo {
fn is_repo_path_valid(filename: &str, sha256: bool) -> bool {
if sha256 {
NamePurpose::WorkRepo64.is_fit(filename)
} else {
NamePurpose::WorkRepo.is_fit(filename)
}
}
}
impl RepoKind for FetchRepo {
}
/// A local git repository.
pub struct Git {
path: PathBuf,
sha256: bool,
inner: T,
}
/// Error returned by operations on a git repo.
#[derive(Debug)]
pub struct GitError {
inner: GitErrorInner,
command: Vec,
}
#[derive(Debug)]
enum GitErrorInner {
IoError(io::Error),
Output(Output),
}
/// Helper for tracking args to a Command.
struct Args {
inner: Command,
args: Vec,
}
impl_trait! {
impl Args {
/// Creates a new Args for the given command.
pub fn new_cmd>(cmd: S) -> Self {
let cmd = cmd.as_ref();
Self {
inner: Command::new(cmd),
args: vec![cmd.into()],
}
}
/// Adds a single arg to the Command.
pub fn arg>(&mut self, arg: S) -> &mut Self {
let arg = arg.as_ref();
self.inner.arg(arg);
self.args.push(arg.into());
self
}
// /// Adds multiple args to the Command.
// pub fn args(&mut self, args: I) -> &mut Self
// where I: IntoIterator- , S: AsRef {
// for arg in args {
// self.arg(arg);
// }
// self
// }
// impl trait Into> {
// fn into(self) -> Result