summaryrefslogtreecommitdiff
path: root/src/package_manager/rpm.rs
blob: f2c8f2a9c73d47edf76b229f584940cc276d8608 (plain)
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
use std::process::Command;

use datatype::{Error, Package, UpdateResultCode};
use package_manager::package_manager::{InstallOutcome, parse_package};


/// Returns a list of installed RPM packages with
/// `rpm -qa --queryformat ${NAME} ${VERSION}\n`.
pub fn installed_packages() -> Result<Vec<Package>, Error> {
    Command::new("rpm").arg("-qa").arg("--queryformat").arg("%{NAME} %{VERSION}\n")
        .output()
        .map_err(|e| Error::Package(format!("Error fetching packages: {}", e)))
        .and_then(|c| {
            String::from_utf8(c.stdout)
                .map_err(|e| Error::Parse(format!("Error parsing package: {}", e)))
                .map(|s| s.lines().map(String::from).collect::<Vec<String>>())
        })
        .and_then(|lines| {
            lines.iter()
                 .map(|line| parse_package(line))
                 .filter(|item| item.is_ok())
                 .collect::<Result<Vec<Package>, _>>()
        })
}

/// Installs a new RPM package with `rpm -Uvh --force <package-path>`.
pub fn install_package(path: &str) -> Result<InstallOutcome, InstallOutcome> {
    let output = try!(Command::new("rpm").arg("-Uvh").arg("--force").arg(path)
        .output()
        .map_err(|err| (UpdateResultCode::GENERAL_ERROR, format!("{:?}", err))));

    let stdout = String::from_utf8_lossy(&output.stdout).into_owned();
    let stderr = String::from_utf8_lossy(&output.stderr).into_owned();

    match output.status.code() {
        Some(0) => {
            let _ = Command::new("sync").status()
                .map_err(|err| error!("couldn't run 'sync': {}", err));
            Ok((UpdateResultCode::OK, stdout))
        }

        _ => {
            let out = format!("stdout: {}\nstderr: {}", stdout, stderr);
            if (&stderr).contains("already installed") {
                Ok((UpdateResultCode::ALREADY_PROCESSED, out))
            } else {
                Err((UpdateResultCode::INSTALL_FAILED, out))
            }
        }
    }
}