summaryrefslogtreecommitdiff
path: root/src/package_manager/deb.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/package_manager/deb.rs')
-rw-r--r--src/package_manager/deb.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/package_manager/deb.rs b/src/package_manager/deb.rs
new file mode 100644
index 0000000..bba86e6
--- /dev/null
+++ b/src/package_manager/deb.rs
@@ -0,0 +1,48 @@
+use std::process::Command;
+
+use datatype::{Error, Package, UpdateResultCode};
+use package_manager::package_manager::{InstallOutcome, parse_package};
+
+
+/// Returns a list of installed DEB packages with
+/// `dpkg-query -f='${Package} ${Version}\n -W`.
+pub fn installed_packages() -> Result<Vec<Package>, Error> {
+ Command::new("dpkg-query").arg("-f='${Package} ${Version}\n'").arg("-W")
+ .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(|pkg| pkg.is_ok())
+ .collect::<Result<Vec<Package>, _>>()
+ })
+}
+
+/// Installs a new DEB package.
+pub fn install_package(path: &str) -> Result<InstallOutcome, InstallOutcome> {
+ let output = try!(Command::new("dpkg").arg("-E").arg("-i").arg(path)
+ .output()
+ .map_err(|e| (UpdateResultCode::GENERAL_ERROR, format!("{:?}", e))));
+
+ 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) => {
+ if (&stdout).contains("already installed") {
+ Ok((UpdateResultCode::ALREADY_PROCESSED, stdout))
+ } else {
+ Ok((UpdateResultCode::OK, stdout))
+ }
+ }
+ _ => {
+ let out = format!("stdout: {}\nstderr: {}", stdout, stderr);
+ Err((UpdateResultCode::INSTALL_FAILED, out))
+ }
+ }
+}