git_prole/
app.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use calm_io::stdout;
use camino::Utf8PathBuf;
use clap::CommandFactory;
use miette::miette;
use miette::IntoDiagnostic;

use crate::add::WorktreePlan;
use crate::app_git::AppGit;
use crate::cli;
use crate::cli::ConfigCommand;
use crate::cli::ConfigInitArgs;
use crate::config::Config;
use crate::convert::ConvertPlan;
use crate::convert::ConvertPlanOpts;
use crate::fs;
use crate::git::Git;

pub struct App {
    config: Config,
}

impl App {
    pub fn new(config: Config) -> Self {
        Self { config }
    }

    pub fn git(&self) -> miette::Result<AppGit<'_, Utf8PathBuf>> {
        Ok(Git::from_current_dir()?.with_config(&self.config))
    }

    pub fn run(self) -> miette::Result<()> {
        match &self.config.cli.command {
            cli::Command::Completions { shell } => {
                let mut clap_command = cli::Cli::command();
                clap_complete::generate(
                    *shell,
                    &mut clap_command,
                    "git-prole",
                    &mut std::io::stdout(),
                );
            }
            #[cfg(feature = "clap_mangen")]
            cli::Command::Manpages { out_dir } => {
                use miette::Context;
                let clap_command = cli::Cli::command();
                clap_mangen::generate_to(clap_command, out_dir)
                    .into_diagnostic()
                    .wrap_err("Failed to generate man pages")?;
            }
            cli::Command::Convert(args) => ConvertPlan::new(
                self.git()?,
                ConvertPlanOpts {
                    default_branch: args.default_branch.clone(),
                    destination: args.destination.clone(),
                },
            )?
            .execute()?,
            cli::Command::Clone(args) => crate::clone::clone(self.git()?, args.to_owned())?,
            cli::Command::Add(args) => WorktreePlan::new(self.git()?, args)?.execute()?,
            cli::Command::Config(ConfigCommand::Init(args)) => self.config_init(args.to_owned())?,
        }

        Ok(())
    }

    fn config_init(&self, args: ConfigInitArgs) -> miette::Result<()> {
        let path = match &args.output {
            Some(path) => {
                if path == "-" {
                    stdout!("{}", Config::DEFAULT).into_diagnostic()?;
                    return Ok(());
                } else {
                    path
                }
            }
            None => &self.config.path,
        };

        if path.exists() {
            return Err(miette!("Default configuration file already exists: {path}"));
        }

        tracing::info!(
            %path,
            "Writing default configuration file"
        );

        if let Some(parent) = path.parent() {
            fs::create_dir_all(parent)?;
        }

        fs::write(path, Config::DEFAULT)?;

        Ok(())
    }
}