gh_cli_rs/commands/
repo.rs

1use crate::command::{BaseCommand, CommandBuilder, GhCommand};
2use crate::error::Result;
3use crate::executor::GhExecutor;
4use std::sync::Arc;
5
6/// Repository commands namespace
7#[derive(Clone)]
8pub struct RepoCommands {
9    executor: Arc<GhExecutor>,
10}
11
12impl RepoCommands {
13    pub(crate) fn new(executor: Arc<GhExecutor>) -> Self {
14        Self { executor }
15    }
16
17    /// Clone a repository
18    /// # Example
19    /// ```no_run
20    /// # use gh_cli_rs::GhClient;
21    /// let client = GhClient::new();
22    /// client.repo().clone("cli/cli").execute();
23    /// ```
24    pub fn clone(&self, repo: &str) -> RepoCloneCommand {
25        RepoCloneCommand::new(self.executor.clone(), repo)
26    }
27
28    /// Create a new repository
29    pub fn create(&self, name: &str) -> RepoCreateCommand {
30        RepoCreateCommand::new(self.executor.clone(), name)
31    }
32
33    /// Fork a repository
34    pub fn fork(&self, repo: &str) -> RepoForkCommand {
35        RepoForkCommand::new(self.executor.clone(), repo)
36    }
37
38    /// List repositories
39    pub fn list(&self) -> RepoListCommand {
40        RepoListCommand::new(self.executor.clone())
41    }
42
43    /// View repository details
44    pub fn view(&self, repo: Option<&str>) -> RepoViewCommand {
45        RepoViewCommand::new(self.executor.clone(), repo)
46    }
47}
48
49/// Command for cloning a repository
50pub struct RepoCloneCommand {
51    executor: Arc<GhExecutor>,
52    cmd: BaseCommand,
53}
54
55impl RepoCloneCommand {
56    fn new(executor: Arc<GhExecutor>, repo: &str) -> Self {
57        Self {
58            executor,
59            cmd: BaseCommand::with_subcommands(&["repo", "clone"]).arg(repo),
60        }
61    }
62
63    /// Execute the clone command
64    pub fn execute(&self) -> Result<String> {
65        GhCommand::execute(self, self.executor.as_ref())
66    }
67}
68
69impl GhCommand for RepoCloneCommand {
70    fn build_args(&self) -> Vec<String> {
71        self.cmd.build_args()
72    }
73}
74
75/// Command for creating a repository
76pub struct RepoCreateCommand {
77    executor: Arc<GhExecutor>,
78    cmd: BaseCommand,
79}
80
81impl RepoCreateCommand {
82    fn new(executor: Arc<GhExecutor>, name: &str) -> Self {
83        Self {
84            executor,
85            cmd: BaseCommand::with_subcommands(&["repo", "create"]).arg(name),
86        }
87    }
88
89    /// Set repository visibility to public
90    pub fn public(mut self) -> Self {
91        self.cmd = self.cmd.flag("--public");
92        self
93    }
94
95    /// Set repository visibility to private
96    pub fn private(mut self) -> Self {
97        self.cmd = self.cmd.flag("--private");
98        self
99    }
100
101    /// Add a description
102    pub fn description(mut self, desc: &str) -> Self {
103        self.cmd = self.cmd.option("--description", desc);
104        self
105    }
106
107    /// Add a homepage URL
108    pub fn homepage(mut self, url: &str) -> Self {
109        self.cmd = self.cmd.option("--homepage", url);
110        self
111    }
112
113    /// Initialize with a README
114    pub fn with_readme(mut self) -> Self {
115        self.cmd = self.cmd.flag("--add-readme");
116        self
117    }
118
119    /// Execute the create command
120    pub fn execute(&self) -> Result<String> {
121        GhCommand::execute(self, self.executor.as_ref())
122    }
123}
124
125impl GhCommand for RepoCreateCommand {
126    fn build_args(&self) -> Vec<String> {
127        self.cmd.build_args()
128    }
129}
130
131/// Command for forking a repository
132pub struct RepoForkCommand {
133    executor: Arc<GhExecutor>,
134    cmd: BaseCommand,
135}
136
137impl RepoForkCommand {
138    fn new(executor: Arc<GhExecutor>, repo: &str) -> Self {
139        Self {
140            executor,
141            cmd: BaseCommand::with_subcommands(&["repo", "fork"]).arg(repo),
142        }
143    }
144
145    /// Clone the fork after creating it
146    pub fn clone(mut self) -> Self {
147        self.cmd = self.cmd.flag("--clone");
148        self
149    }
150
151    /// Execute the fork command
152    pub fn execute(&self) -> Result<String> {
153        GhCommand::execute(self, self.executor.as_ref())
154    }
155}
156
157impl GhCommand for RepoForkCommand {
158    fn build_args(&self) -> Vec<String> {
159        self.cmd.build_args()
160    }
161}
162
163/// Command for listing repositories
164pub struct RepoListCommand {
165    executor: Arc<GhExecutor>,
166    cmd: BaseCommand,
167}
168
169impl RepoListCommand {
170    fn new(executor: Arc<GhExecutor>) -> Self {
171        Self {
172            executor,
173            cmd: BaseCommand::with_subcommands(&["repo", "list"]),
174        }
175    }
176
177    /// List repositories for a specific owner
178    pub fn owner(mut self, owner: &str) -> Self {
179        self.cmd = self.cmd.arg(owner);
180        self
181    }
182
183    /// Limit the number of results
184    pub fn limit(mut self, limit: u32) -> Self {
185        self.cmd = self.cmd.option("--limit", &limit.to_string());
186        self
187    }
188
189    /// Execute and get raw output
190    pub fn execute(&self) -> Result<String> {
191        GhCommand::execute(self, self.executor.as_ref())
192    }
193}
194
195impl GhCommand for RepoListCommand {
196    fn build_args(&self) -> Vec<String> {
197        self.cmd.build_args()
198    }
199}
200
201/// Command for viewing repository details
202pub struct RepoViewCommand {
203    executor: Arc<GhExecutor>,
204    cmd: BaseCommand,
205}
206
207impl RepoViewCommand {
208    fn new(executor: Arc<GhExecutor>, repo: Option<&str>) -> Self {
209        let mut cmd = BaseCommand::with_subcommands(&["repo", "view"]);
210        if let Some(repo) = repo {
211            cmd = cmd.arg(repo);
212        }
213        Self { executor, cmd }
214    }
215
216    /// Open in web browser
217    pub fn web(mut self) -> Self {
218        self.cmd = self.cmd.flag("--web");
219        self
220    }
221
222    /// Execute and get raw output
223    pub fn execute(&self) -> Result<String> {
224        GhCommand::execute(self, self.executor.as_ref())
225    }
226}
227
228impl GhCommand for RepoViewCommand {
229    fn build_args(&self) -> Vec<String> {
230        self.cmd.build_args()
231    }
232}