async-git 0.0.0-squat-name

Pure-rust async implementation of git built on tokio
Documentation
use std::env;
use std::path::PathBuf;

use futures::future::TryFutureExt;
use tokio::fs::{self};

use crate::errors::Result;
use crate::config::Config;

#[derive(Debug, StructOpt)]
pub struct InitOptions {
    /// Specify the directory from which templates will be used.
    #[structopt(long = "template")]
    template: Option<PathBuf>,

    /// Create a bare repository.
    #[structopt(long = "bare")]
    bare: bool,

    /// The directory where the git repository should be initialized.
    ///
    /// If you don't provide this value, the current working directory will be used.
    /// If the directory you provided doesn't exist, it will be created.
    directory: Option<PathBuf>,
}

pub async fn init_cmd(options: InitOptions) -> Result<()> {
    let mut target_directory = match options.directory {
        Some(dir) => dir,
        None => env::current_dir()?,
    };

    if !options.bare {
        target_directory.push(".git");
    }

    fs::create_dir_all(&target_directory).await?;

    // make contents of the git directory
    try_join!(
        fs::create_dir(target_directory.join("branches")),
        fs::create_dir(target_directory.join("objects")),
        fs::create_dir(target_directory.join("refs")).and_then(|_| async {
            try_join!(
                fs::create_dir(target_directory.join("refs").join("tags")),
                fs::create_dir(target_directory.join("refs").join("heads"))
            )
        }),
        crate::util::init_file(
            target_directory.join("description"),
            "Unnamed repository; edit this file 'description' to name the repository.\n"
        ),
        crate::util::init_file(target_directory.join("HEAD"), "ref: refs/heads/master\n"),
        Config::default()
            .to_string()
            .and_then(|config| crate::util::init_file(target_directory.join("config"), config)),
    )?;

    Ok(())
}