git_prole/
app.rs

1use calm_io::stdout;
2use camino::Utf8PathBuf;
3use clap::CommandFactory;
4use miette::miette;
5use miette::IntoDiagnostic;
6
7use crate::add::WorktreePlan;
8use crate::app_git::AppGit;
9use crate::cli;
10use crate::cli::ConfigCommand;
11use crate::cli::ConfigInitArgs;
12use crate::config::Config;
13use crate::convert::ConvertPlan;
14use crate::convert::ConvertPlanOpts;
15use crate::fs;
16use crate::git::Git;
17
18pub struct App {
19    config: Config,
20}
21
22impl App {
23    pub fn new(config: Config) -> Self {
24        Self { config }
25    }
26
27    pub fn git(&self) -> miette::Result<AppGit<'_, Utf8PathBuf>> {
28        Ok(Git::from_current_dir()?.with_config(&self.config))
29    }
30
31    pub fn run(self) -> miette::Result<()> {
32        match &self.config.cli.command {
33            cli::Command::Completions { shell } => {
34                let mut clap_command = cli::Cli::command();
35                clap_complete::generate(
36                    *shell,
37                    &mut clap_command,
38                    "git-prole",
39                    &mut std::io::stdout(),
40                );
41            }
42            #[cfg(feature = "clap_mangen")]
43            cli::Command::Manpages { out_dir } => {
44                use miette::Context;
45                let clap_command = cli::Cli::command();
46                clap_mangen::generate_to(clap_command, out_dir)
47                    .into_diagnostic()
48                    .wrap_err("Failed to generate man pages")?;
49            }
50            cli::Command::Convert(args) => ConvertPlan::new(
51                self.git()?,
52                ConvertPlanOpts {
53                    default_branch: args.default_branch.clone(),
54                    destination: args.destination.clone(),
55                },
56            )?
57            .execute()?,
58            cli::Command::Clone(args) => crate::clone::clone(self.git()?, args.to_owned())?,
59            cli::Command::Add(args) => WorktreePlan::new(self.git()?, args)?.execute()?,
60            cli::Command::Config(ConfigCommand::Init(args)) => self.config_init(args.to_owned())?,
61        }
62
63        Ok(())
64    }
65
66    fn config_init(&self, args: ConfigInitArgs) -> miette::Result<()> {
67        let path = match &args.output {
68            Some(path) => {
69                if path == "-" {
70                    stdout!("{}", Config::DEFAULT).into_diagnostic()?;
71                    return Ok(());
72                } else {
73                    path
74                }
75            }
76            None => &self.config.path,
77        };
78
79        if path.exists() {
80            return Err(miette!("Default configuration file already exists: {path}"));
81        }
82
83        tracing::info!(
84            %path,
85            "Writing default configuration file"
86        );
87
88        if let Some(parent) = path.parent() {
89            fs::create_dir_all(parent)?;
90        }
91
92        fs::write(path, Config::DEFAULT)?;
93
94        Ok(())
95    }
96}