gittwo 0.0.2

A command-line like wrapper around git2.
Documentation
use crate::GitRepository;
use git2::Error;
use std::path::Path;

pub struct AddConfig {
    spec: Vec<String>,
    flags: AddFlagsInternals,
}

impl AddConfig {
    pub fn new(spec: Vec<String>) -> Self {
        AddConfig {
            spec,
            flags: AddFlagsInternals::default(),
        }
    }

    pub fn get_specs(&self) -> &Vec<String> {
        &self.spec
    }

    pub fn add_flag(&mut self, flag: AddFlags) -> &Self {
        match flag {
            AddFlags::Update(update) => self.flags.update = update,
            AddFlags::DryRun(dry) => self.flags.dry_run = dry,
        }
        self
    }
}

#[derive(Default, Clone, Copy)]
pub(crate) struct AddFlagsInternals {
    update: bool,
    dry_run: bool,
}

pub enum AddFlags {
    Update(bool),
    DryRun(bool),
}

impl GitRepository {
    pub fn git_add(&self, config: AddConfig) -> Result<(), Error> {
        unsafe {
            git2::opts::set_verify_owner_validation(self.skip_owner_validation)?;
        };

        if let Some(repository) = &self.repository {
            let mut index = repository.index()?;

            let dry = config.flags.dry_run;
            let callback = &mut |path: &Path, _matched_spec: &[u8]| -> i32 {
                let status = repository.status_file(path).unwrap();

                let ret = if status.contains(git2::Status::WT_MODIFIED)
                    || status.contains(git2::Status::WT_NEW)
                    || status.contains(git2::Status::WT_DELETED)
                {
                    println!("add '{}'", path.display());
                    0
                } else {
                    1
                };

                if dry { 1 } else { ret }
            };

            let callback = if config.flags.update {
                Some(callback as &mut git2::IndexMatchedPath)
            } else {
                None
            };

            if config.flags.update {
                index.update_all(config.spec.iter(), callback)?;
            } else {
                index.add_all(config.spec.iter(), git2::IndexAddOption::DEFAULT, callback)?;
            }
            index.write()?;

            return Ok(());
        }

        Err(Error::from_str(
            "Repository not found or created, try opening a valid repository or cloning one",
        ))
    }
}