1use crate::{ext, CommandExt};
2use std::{ffi::OsStr, path::PathBuf, process::Command};
3
4ext!(def; Git);
5
6impl Git {
7 fn new(sub: impl AsRef<OsStr>) -> Self {
8 let mut git = Self(Command::new("git"));
9 git.arg(sub);
10 git
11 }
12
13 pub fn lfs() -> Self {
14 Self::new("lfs")
15 }
16
17 pub fn config(global: bool) -> Self {
18 let mut git = Self::new("config");
19 git.option(global.then_some("--global"));
20 git
21 }
22
23 pub fn clone(repo: impl AsRef<str>) -> GitCloneContext {
24 GitCloneContext {
25 repo: repo.as_ref().into(),
26 dir: None,
27 branch: None,
28 single_branch: false,
29 depth: usize::MAX,
30 }
31 }
32
33 pub fn pull() -> Self {
34 Self::new("pull")
35 }
36
37 pub fn submodule_update(init: bool) -> Self {
38 let mut git = Self::new("submodule");
39 git.arg("update").option(init.then_some("--init"));
40 git
41 }
42}
43
44pub struct GitCloneContext {
45 repo: String,
46 dir: Option<PathBuf>,
47 branch: Option<String>,
48 single_branch: bool,
49 depth: usize,
50}
51
52impl GitCloneContext {
53 #[inline]
54 pub fn dir(mut self, path: PathBuf) -> Self {
55 self.dir = Some(path);
56 self
57 }
58
59 #[inline]
60 pub fn branch(mut self, branch: impl AsRef<str>) -> Self {
61 self.branch = Some(branch.as_ref().into());
62 self
63 }
64
65 #[inline]
66 pub fn single_branch(mut self) -> Self {
67 self.single_branch = true;
68 self
69 }
70
71 #[inline]
72 pub fn depth(mut self, depth: usize) -> Self {
73 self.depth = depth;
74 self
75 }
76
77 pub fn done(self) -> Git {
78 let mut git = Git::new("clone");
79 git.arg(self.repo);
80 if let Some(dir) = self.dir {
81 git.arg(dir);
82 }
83 if let Some(branch) = self.branch {
84 git.args(["--branch", &branch]);
85 }
86 if self.single_branch {
87 git.arg("--single-branch");
88 }
89 if self.depth != usize::MAX {
90 git.arg(format!("--depth={}", self.depth));
91 }
92 git
93 }
94}