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
17pub async fn handle_init(args: &InitArgs) -> Result<()> {
18    // create .changepacks directory
19    let current_dir = std::env::current_dir()?;
20    let changepacks_dir = get_changepacks_dir(&current_dir)?;
21    if !args.dry_run {
22        create_dir_all(&changepacks_dir).await?;
23    }
24    // create config.json file
25    let config_file = changepacks_dir.join("config.json");
26    if config_file.exists() {
27        Err(anyhow::anyhow!("changepacks project already initialized"))
28    } else {
29        if !args.dry_run {
30            write(
31                config_file,
32                serde_json::to_string_pretty(&Config::default())?,
33            )
34            .await?;
35        }
36
37        println!(
38            "changepacks project initialized in {}",
39            changepacks_dir.display()
40        );
41
42        Ok(())
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49    use clap::Parser;
50
51    #[derive(Parser)]
52    struct TestCli {
53        #[command(flatten)]
54        init: InitArgs,
55    }
56
57    #[test]
58    fn test_init_args_default() {
59        let cli = TestCli::parse_from(["test"]);
60        assert!(!cli.init.dry_run);
61    }
62
63    #[test]
64    fn test_init_args_with_dry_run() {
65        let cli = TestCli::parse_from(["test", "--dry-run"]);
66        assert!(cli.init.dry_run);
67    }
68
69    #[test]
70    fn test_init_args_with_short_dry_run() {
71        let cli = TestCli::parse_from(["test", "-d"]);
72        assert!(cli.init.dry_run);
73    }
74}