Skip to main content

changepacks_cli/commands/
init.rs

1use changepacks_core::Config;
2use tokio::fs::{create_dir_all, write};
3
4use anyhow::Result;
5use changepacks_utils::get_changepacks_dir;
6use clap::Args;
7
8#[derive(Args, Debug)]
9#[command(about = "Initialize a new changepacks project")]
10pub struct InitArgs {
11    /// If true, do not make any filesystem changes.
12    #[arg(short, long, default_value = "false")]
13    dry_run: bool,
14}
15
16/// Initialize a new changepacks project
17///
18/// # Errors
19/// Returns error if creating the .changepacks directory or config file fails.
20pub async fn handle_init(args: &InitArgs) -> Result<()> {
21    // create .changepacks directory
22    let current_dir = std::env::current_dir()?;
23    let changepacks_dir = get_changepacks_dir(&current_dir)?;
24    if !args.dry_run {
25        create_dir_all(&changepacks_dir).await?;
26    }
27    // create config.json file
28    let config_file = changepacks_dir.join("config.json");
29    if config_file.exists() {
30        Err(anyhow::anyhow!("changepacks project already initialized"))
31    } else {
32        if !args.dry_run {
33            write(
34                config_file,
35                serde_json::to_string_pretty(&Config::default())?,
36            )
37            .await?;
38        }
39
40        println!(
41            "changepacks project initialized in {}",
42            changepacks_dir.display()
43        );
44
45        Ok(())
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52    use clap::Parser;
53
54    #[derive(Parser)]
55    struct TestCli {
56        #[command(flatten)]
57        init: InitArgs,
58    }
59
60    #[test]
61    fn test_init_args_default() {
62        let cli = TestCli::parse_from(["test"]);
63        assert!(!cli.init.dry_run);
64    }
65
66    #[test]
67    fn test_init_args_with_dry_run() {
68        let cli = TestCli::parse_from(["test", "--dry-run"]);
69        assert!(cli.init.dry_run);
70    }
71
72    #[test]
73    fn test_init_args_with_short_dry_run() {
74        let cli = TestCli::parse_from(["test", "-d"]);
75        assert!(cli.init.dry_run);
76    }
77}