1use std::process::Command;
5
6use anyhow::{Result, anyhow};
7use colored::Colorize;
8
9use crate::pkg::{resolve, types};
10
11pub fn run(
23 package_name: &str,
24 location: Option<String>,
25 yes: bool
26) -> Result<()> {
27 println!(
28 "{} Resolving package '{}' for cloning...",
29 "::".bold().blue(),
30 package_name.cyan().bold()
31 );
32
33 let resolved_source =
34 resolve::resolve_source(package_name, None, false, yes)?;
35
36 let pkg: types::Package = crate::pkg::lua::parser::parse_lua_package(
37 resolved_source.path.to_str().ok_or_else(|| {
38 let p = resolved_source.path.display();
39 anyhow!("Path contains invalid UTF-8 characters: {p}")
40 })?,
41 None,
42 None,
43 false
44 )?;
45
46 if pkg.git.is_empty() {
47 return Err(anyhow!(
48 "Package '{}' does not have a git repository defined in its \
49 metadata.",
50 pkg.name
51 ));
52 }
53
54 let git_url = &pkg.git;
55 let target_location = location.unwrap_or(pkg.name);
56
57 println!(
58 "{} Cloning {} into {}...",
59 "::".bold().blue(),
60 git_url.cyan(),
61 if target_location == "." {
62 "current directory".bold()
63 } else {
64 target_location.bold()
65 }
66 );
67
68 let mut git_cmd = Command::new("git");
69 git_cmd.arg("clone").arg(git_url).arg(&target_location);
70
71 let status = git_cmd
72 .status()
73 .map_err(|e| anyhow!("Failed to execute git clone: {e}"))?;
74
75 if status.success() {
76 println!("\n{}", "Successfully cloned repository.".green());
77 } else {
78 let code = status
79 .code()
80 .map_or_else(|| "unknown".to_string(), |c| c.to_string());
81 return Err(anyhow!("git clone failed with exit code {code}"));
82 }
83
84 Ok(())
85}