1use std::path::Path;
2use std::path::PathBuf;
3
4use rootcause::prelude::ResultExt as _;
5
6pub fn run(dev_tools_dir: &Path, tool: &str, packages: &[&str]) -> rootcause::Result<PathBuf> {
13 let dev_tools_repo_dir = dev_tools_dir.join(tool);
14
15 std::fs::create_dir_all(&dev_tools_repo_dir)
16 .context("error creating pip tool directory")
17 .attach_with(|| format!("path={}", dev_tools_repo_dir.display()))?;
18
19 ytil_cmd::silent_cmd("python3")
20 .args(["-m", "venv", &dev_tools_repo_dir.join(".venv").to_string_lossy()])
21 .status()
22 .context("failed to spawn python3 venv")?
23 .exit_ok()
24 .context("python3 venv creation failed")
25 .attach_with(|| format!("tool={tool}"))
26 .attach_with(|| format!("venv_dir={}", dev_tools_repo_dir.join(".venv").display()))?;
27
28 ytil_cmd::silent_cmd("sh")
29 .args([
30 "-c",
31 &format!(
32 r"
33 source {}/.venv/bin/activate && \
34 pip install pip {packages} --upgrade
35 ",
36 dev_tools_repo_dir.display(),
37 packages = packages.join(" "),
38 ),
39 ])
40 .status()
41 .context("failed to spawn pip install")?
42 .exit_ok()
43 .context("pip install failed")
44 .attach_with(|| format!("tool={tool}"))
45 .attach_with(|| format!("packages={packages:?}"))?;
46
47 Ok(dev_tools_repo_dir.join(".venv").join("bin"))
48}