summaryrefslogtreecommitdiffstats
path: root/src/repo.rs
blob: f82ee97d4f933e1ab1e9813067cbb91f79e3dbee (plain)
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
97
98
99
100
101
use clap::Subcommand;
use forgejo_api::CreateRepoOption;
use url::Url;

#[derive(Subcommand, Clone, Debug)]
pub enum RepoCommand {
    Create {
        host: String,
        repo: String,

        // flags
        #[clap(long, short)]
        description: Option<String>,
        #[clap(long, short)]
        private: bool,
        /// Sets the new repo to be the `origin` remote of the current local repo.
        #[clap(long, short)]
        set_upstream: Option<String>,
        /// Pushes the current branch to the default branch on the new repo.
        /// Implies `--set-upstream=origin` (setting upstream manual overrides this)
        #[clap(long, short)]
        push: bool,
    },
    Info,
    Browse,
}

impl RepoCommand {
    pub async fn run(self, keys: &crate::KeyInfo) -> eyre::Result<()> {
        match self {
            RepoCommand::Create {
                host,
                repo,

                description,
                private,
                set_upstream,
                push,
            } => {
                let host = Url::parse(&host)?;
                let login = keys.get_login(&host)?;
                let api = login.api_for(&host)?;
                let repo_spec = CreateRepoOption {
                    auto_init: false,
                    default_branch: "main".into(),
                    description,
                    gitignores: String::new(),
                    issue_labels: String::new(),
                    license: String::new(),
                    name: repo.clone(),
                    private,
                    readme: String::new(),
                    template: false,
                    trust_model: forgejo_api::TrustModel::Default,
                };
                let new_repo = api.create_repo(repo_spec).await?;
                eprintln!(
                    "created new repo at {}",
                    host.join(&format!("{}/{}", login.username(), repo))?
                );

                let upstream = set_upstream.as_deref().unwrap_or("origin");

                let repo = git2::Repository::open(".")?;
                let mut remote = if set_upstream.is_some() || push {
                    repo.remote(upstream, new_repo.clone_url.as_str())?
                } else {
                    repo.find_remote(upstream)?
                };

                if push {
                    remote.push::<&str>(&[], None)?;
                }
            }
            RepoCommand::Info => {
                let (host, repo) = keys.get_current()?;
                let api = host.api()?;
                let repo = api.get_repo(repo.owner(), repo.name()).await?;
                match repo {
                    Some(repo) => {
                        dbg!(repo);
                    }
                    None => eprintln!("repo not found"),
                }
            }
            RepoCommand::Browse => {
                let (host, repo) = keys.get_current()?;
                let mut url = host.url().clone();
                let new_path = format!(
                    "{}/{}/{}",
                    url.path().strip_suffix("/").unwrap_or(url.path()),
                    repo.owner(),
                    repo.name(),
                );
                url.set_path(&new_path);
                open::that(url.as_str())?;
            }
        };
        Ok(())
    }
}