1use std::{
2 env, fs,
3 process::{Command, Stdio},
4};
5
6use crate::PackageManager;
7use anyhow::Error;
8
9pub struct Pkgx {}
10
11impl Pkgx {
12 pub fn new() -> Self {
13 Self {}
14 }
15
16 pub fn write_command(&self, name: &str) -> Result<(), Error> {
17 let org = name.split("/").next().unwrap();
18 let package = name.split("/").last().unwrap();
19
20 let mut command = "#!/bin/sh\n".to_string();
21 command.push_str(&format!("exec pkgx +{} -- {} \"$@\"", org, package));
22 fs::write(
23 format!("{}/.local/bin/{}", env::var("HOME")?, package),
24 command,
25 )?;
26
27 let mut child = Command::new("sh")
28 .arg("-c")
29 .arg(format!("chmod +x ~/.local/bin/{}", package))
30 .stdin(Stdio::inherit())
31 .stdout(Stdio::inherit())
32 .stderr(Stdio::inherit())
33 .spawn()?;
34 child.wait()?;
35 Ok(())
36 }
37
38 pub fn setup_path(&self, rc_file: &str) -> Result<(), Error> {
39 let mut child = Command::new("sh")
40 .arg("-c")
41 .arg(format!(
42 "type pkgx > /dev/null || echo \'PATH=$HOME/.local/bin:$PATH\' >> ~/{}",
43 rc_file
44 ))
45 .stdin(Stdio::inherit())
46 .stdout(Stdio::inherit())
47 .stderr(Stdio::inherit())
48 .spawn()?;
49 child.wait()?;
50 Ok(())
51 }
52}
53
54impl PackageManager for Pkgx {
55 fn install(&self, name: &str) -> Result<(), Error> {
56 self.setup()?;
57 if name.split("/").count() == 2 {
58 return self.write_command(name);
59 }
60
61 let mut child = Command::new("sh")
62 .arg("-c")
63 .arg(format!(
64 "[ ! -f ~/.local/bin/{} ] && pkgx install {}",
65 name, name
66 ))
67 .stdin(Stdio::inherit())
68 .stdout(Stdio::inherit())
69 .stderr(Stdio::inherit())
70 .spawn()?;
71 child.wait()?;
72 Ok(())
73 }
74
75 fn uninstall(&self, name: &str) -> Result<(), Error> {
76 let mut child = Command::new("sh")
77 .arg("-c")
78 .arg(format!("rm ~/.local/bin/{}", name))
79 .stdin(Stdio::inherit())
80 .stdout(Stdio::inherit())
81 .stderr(Stdio::inherit())
82 .spawn()?;
83 child.wait()?;
84 Ok(())
85 }
86
87 fn setup(&self) -> Result<(), Error> {
88 self.setup_path(".bashrc")?;
89 self.setup_path(".zshrc")?;
90 let mut child = Command::new("sh")
91 .arg("-c")
92 .arg("type pkgx > /dev/null || curl -fsS https://pkgx.sh | sh")
93 .stdin(Stdio::inherit())
94 .stdout(Stdio::inherit())
95 .stderr(Stdio::inherit())
96 .spawn()?;
97 child.wait()?;
98 Ok(())
99 }
100}