tinymist_package/pack/
gitcl.rs1use ecow::EcoString;
2
3use super::*;
4
5#[derive(Clone)]
7pub struct GitClPack<P> {
8 pub namespace: EcoString,
10 pub url: P,
12}
13
14impl<P: AsRef<str>> GitClPack<P> {
15 pub fn new(namespace: EcoString, url: P) -> Self {
17 Self { namespace, url }
18 }
19}
20
21impl<P: AsRef<str>> fmt::Debug for GitClPack<P> {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 write!(f, "GitClPack({})", self.url.as_ref())
24 }
25}
26
27impl<P: AsRef<str>> PackFs for GitClPack<P> {
28 fn read_all(
29 &mut self,
30 f: &mut (dyn FnMut(&str, PackFile) -> PackageResult<()> + Send + Sync),
31 ) -> PackageResult<()> {
32 let temp_dir = std::env::temp_dir();
33 let temp_dir = temp_dir.join("tinymist/package-gitcl");
34
35 tinymist_std::fs::paths::temp_dir_in(temp_dir, |temp_dir| {
36 let package_path = temp_dir.join("package");
37 clone(self.url.as_ref(), &package_path)?;
38
39 Ok(DirPack::new(package_path).read_all(f))
40 })
41 .map_err(other)?
42 }
43}
44
45impl<P: AsRef<str>> Pack for GitClPack<P> {}
46impl<P: AsRef<str>> PackExt for GitClPack<P> {}
47
48fn clone(url: &str, dst: &Path) -> io::Result<()> {
49 let mut cmd = gitcl();
50 cmd.arg("clone").arg(url).arg(dst);
51 let status = cmd.status()?;
52 if !status.success() {
53 return Err(io::Error::other(format!("git clone failed: {status}")));
54 }
55 Ok(())
56}
57
58fn gitcl() -> std::process::Command {
59 std::process::Command::new("git")
60}