summaryrefslogtreecommitdiff
path: root/src/packages/portage.rs
blob: dac0c2fd2dc347ca40c0b3ac77509953887d28f5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use std::process::{Command, Stdio};

use crate::error::Error;

use super::{Package, PackageList, PackageManager};

pub struct Portage;

impl PackageManager for Portage {
    fn get_installed(&self) -> crate::error::Result<PackageList> {
        let eix_pkgs = Command::new("eix")
            .args(["--world", "-c*"])
            .output()
            .unwrap();

        let eix_pkgs_out = String::from_utf8(eix_pkgs.stdout).unwrap();

        let mut pkgs: Vec<Package> = Vec::new();
        let portage_pkgs: Vec<&str> = eix_pkgs_out.split('\n').collect();
        for pkg in portage_pkgs {
            if pkg.is_empty() {
                continue;
            };
            let split = pkg.split_once('@');
            let info = if let Some(sp) = split {
                sp.0
            } else {
                return Err(Error::UnknownOutput);
            };

            let (id, version) = if let Some(res) = info.split_once('(') {
                (res.0.split_at(4).1.trim().to_string(), res.1.to_string())
            } else {
                return Err(Error::UnknownOutput);
            };

            pkgs.push(Package {
                id,
                version,
                explicit: true,
            });
        }

        Ok(PackageList {
            packages: pkgs,
            manager: super::Manager::Portage,
        })
    }

    fn install(&self, pkgs: Vec<super::Package>) -> crate::error::Result<()> {
        let mut args = vec!["emerge".to_string()];

        for pkg in pkgs {
            args.push(pkg.id);
        }
        Command::new("doas")
            .stdout(Stdio::inherit())
            .args(args)
            .spawn()?
            .wait_with_output()?;
        Ok(())
    }
}