Rename SpecificPackageManager trait PackageManager, add some unit tests
This commit is contained in:
parent
1245db813b
commit
d2ef322761
|
@ -1,21 +1,52 @@
|
||||||
use crate::utils::cmd::Cmd;
|
use crate::utils::cmd::{Cmd, CmdOutput};
|
||||||
|
|
||||||
use super::{PackageError, PackageList, SpecificPackageManager};
|
use super::{PackageError, PackageList, PackageManager};
|
||||||
|
|
||||||
pub fn apt() -> Cmd {
|
/// This structure is mostly used as an indirection for testing purposes.
|
||||||
Cmd::new("apt").env("DEBIAN_FRONTEND", "noninteractive")
|
/// But you can use it to build your own apt commands.
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
|
||||||
|
pub struct AptCmd(pub Cmd);
|
||||||
|
|
||||||
|
impl AptCmd {
|
||||||
|
pub fn new() -> AptCmd {
|
||||||
|
AptCmd(
|
||||||
|
Cmd::new("apt").env("DEBIAN_FRONTEND", "noninteractive")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update() -> AptCmd {
|
||||||
|
let mut cmd = Self::new();
|
||||||
|
cmd.0 = cmd.0.arg("update");
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn install(list: PackageList) -> AptCmd {
|
||||||
|
let mut cmd = Self::new();
|
||||||
|
cmd.0 = cmd.0.arg("install").args(list.list());
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(list: PackageList) -> AptCmd {
|
||||||
|
let mut cmd = Self::new();
|
||||||
|
cmd.0 = cmd.0.arg("remove").args(list.list());
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(self) -> Result<CmdOutput, std::io::Error> {
|
||||||
|
self.0.run()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DebianPackageManager;
|
pub struct AptManager;
|
||||||
|
|
||||||
impl SpecificPackageManager for DebianPackageManager {
|
impl PackageManager for AptManager {
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
"apt"
|
"apt"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&self) -> Result<(), PackageError> {
|
fn update(&self) -> Result<(), PackageError> {
|
||||||
let res = apt().arg("update").run()?;
|
let res = AptCmd::update().run()?;
|
||||||
|
|
||||||
if ! res.success {
|
if ! res.success {
|
||||||
return Err(PackageError::CmdFail(res));
|
return Err(PackageError::CmdFail(res));
|
||||||
|
@ -24,7 +55,7 @@ impl SpecificPackageManager for DebianPackageManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn install(&self, list: PackageList) -> Result<(), PackageError> {
|
fn install(&self, list: PackageList) -> Result<(), PackageError> {
|
||||||
let res = apt().arg("install").args(list.list()).run()?;
|
let res = AptCmd::install(list).run()?;
|
||||||
|
|
||||||
if ! res.success {
|
if ! res.success {
|
||||||
return Err(PackageError::CmdFail(res));
|
return Err(PackageError::CmdFail(res));
|
||||||
|
@ -33,7 +64,7 @@ impl SpecificPackageManager for DebianPackageManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove(&self, list: PackageList) -> Result<(), PackageError> {
|
fn remove(&self, list: PackageList) -> Result<(), PackageError> {
|
||||||
let res = apt().arg("remove").args(list.list()).run()?;
|
let res = AptCmd::remove(list).run()?;
|
||||||
|
|
||||||
if ! res.success {
|
if ! res.success {
|
||||||
return Err(PackageError::CmdFail(res));
|
return Err(PackageError::CmdFail(res));
|
||||||
|
@ -41,3 +72,100 @@ impl SpecificPackageManager for DebianPackageManager {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use super::super::IntoPackageList;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn update_cmd() {
|
||||||
|
let cmd = AptCmd::update();
|
||||||
|
let mut env: HashMap<String, String> = HashMap::new();
|
||||||
|
env.insert("DEBIAN_FRONTEND".to_string(), "noninteractive".to_string());
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cmd.0,
|
||||||
|
Cmd {
|
||||||
|
program: "apt".to_string(),
|
||||||
|
args: vec!("update".to_string()),
|
||||||
|
stdin: None,
|
||||||
|
chdir: None,
|
||||||
|
env,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn install_cmd() {
|
||||||
|
let cmd = AptCmd::install(vec!("sl").into_package_list());
|
||||||
|
let mut env: HashMap<String, String> = HashMap::new();
|
||||||
|
env.insert("DEBIAN_FRONTEND".to_string(), "noninteractive".to_string());
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cmd.0,
|
||||||
|
Cmd {
|
||||||
|
program: "apt".to_string(),
|
||||||
|
args: vec!("install", "sl").iter().map(|x| x.to_string()).collect(),
|
||||||
|
stdin: None,
|
||||||
|
chdir: None,
|
||||||
|
env,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn install_cmd_multi() {
|
||||||
|
let cmd = AptCmd::install(vec!("sl", "hello").into_package_list());
|
||||||
|
let mut env: HashMap<String, String> = HashMap::new();
|
||||||
|
env.insert("DEBIAN_FRONTEND".to_string(), "noninteractive".to_string());
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cmd.0,
|
||||||
|
Cmd {
|
||||||
|
program: "apt".to_string(),
|
||||||
|
args: vec!("install", "sl", "hello").iter().map(|x| x.to_string()).collect(),
|
||||||
|
stdin: None,
|
||||||
|
chdir: None,
|
||||||
|
env,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn remove_cmd() {
|
||||||
|
let cmd = AptCmd::remove(vec!("sl").into_package_list());
|
||||||
|
let mut env: HashMap<String, String> = HashMap::new();
|
||||||
|
env.insert("DEBIAN_FRONTEND".to_string(), "noninteractive".to_string());
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cmd.0,
|
||||||
|
Cmd {
|
||||||
|
program: "apt".to_string(),
|
||||||
|
args: vec!("remove", "sl").iter().map(|x| x.to_string()).collect(),
|
||||||
|
stdin: None,
|
||||||
|
chdir: None,
|
||||||
|
env,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn remove_cmd_multi() {
|
||||||
|
let cmd = AptCmd::remove(vec!("sl", "hello").into_package_list());
|
||||||
|
let mut env: HashMap<String, String> = HashMap::new();
|
||||||
|
env.insert("DEBIAN_FRONTEND".to_string(), "noninteractive".to_string());
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cmd.0,
|
||||||
|
Cmd {
|
||||||
|
program: "apt".to_string(),
|
||||||
|
args: vec!("remove", "sl", "hello").iter().map(|x| x.to_string()).collect(),
|
||||||
|
stdin: None,
|
||||||
|
chdir: None,
|
||||||
|
env,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use super::{PackageArgs, IntoPackageList, PackageList, PackageState, PackageModule, PackageStatus, PackageError, SpecificPackageManager};
|
use super::{PackageArgs, IntoPackageList, PackageList, PackageState, PackageModule, PackageStatus, PackageError, PackageManager};
|
||||||
use super::apt::DebianPackageManager;
|
use super::{apt::AptManager, pacman::PacmanManager};
|
||||||
use super::pacman::ArchlinuxPackageManager;
|
|
||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
|
|
||||||
use crate::Module;
|
use crate::Module;
|
||||||
|
@ -50,7 +49,7 @@ impl<Packages, Manager> PackageArgsBuilder<Packages, NoState, Manager> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Packages, State> PackageArgsBuilder<Packages, State, NoManager> {
|
impl<Packages, State> PackageArgsBuilder<Packages, State, NoManager> {
|
||||||
pub fn with(self, manager: impl SpecificPackageManager + 'static) -> PackageArgsBuilder<Packages, State, Box<dyn SpecificPackageManager>> {
|
pub fn with(self, manager: impl PackageManager + 'static) -> PackageArgsBuilder<Packages, State, Box<dyn PackageManager>> {
|
||||||
let Self { name, state, .. } = self;
|
let Self { name, state, .. } = self;
|
||||||
|
|
||||||
PackageArgsBuilder {
|
PackageArgsBuilder {
|
||||||
|
@ -60,21 +59,21 @@ impl<Packages, State> PackageArgsBuilder<Packages, State, NoManager> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_apt(self) -> PackageArgsBuilder<Packages, State, Box<dyn SpecificPackageManager>> {
|
pub fn with_apt(self) -> PackageArgsBuilder<Packages, State, Box<dyn PackageManager>> {
|
||||||
let Self { name, state, .. } = self;
|
let Self { name, state, .. } = self;
|
||||||
PackageArgsBuilder {
|
PackageArgsBuilder {
|
||||||
name,
|
name,
|
||||||
state,
|
state,
|
||||||
manager: Box::new(DebianPackageManager),
|
manager: Box::new(AptManager),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_pacman(self) -> PackageArgsBuilder<Packages, State, Box<dyn SpecificPackageManager>> {
|
pub fn with_pacman(self) -> PackageArgsBuilder<Packages, State, Box<dyn PackageManager>> {
|
||||||
let Self { name, state, .. } = self;
|
let Self { name, state, .. } = self;
|
||||||
PackageArgsBuilder {
|
PackageArgsBuilder {
|
||||||
name,
|
name,
|
||||||
state,
|
state,
|
||||||
manager: Box::new(ArchlinuxPackageManager),
|
manager: Box::new(PacmanManager),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,14 +81,14 @@ impl<Packages, State> PackageArgsBuilder<Packages, State, NoManager> {
|
||||||
|
|
||||||
// We can only RUN the args when a package manager has been set. Alternatively,
|
// We can only RUN the args when a package manager has been set. Alternatively,
|
||||||
// when called inside a playbook, the package manager can be populated automatically from facts.
|
// when called inside a playbook, the package manager can be populated automatically from facts.
|
||||||
impl PackageArgsBuilder<PackageList, PackageState, Box<dyn SpecificPackageManager>> {
|
impl PackageArgsBuilder<PackageList, PackageState, Box<dyn PackageManager>> {
|
||||||
pub fn run(self) -> Result<PackageStatus, PackageError> {
|
pub fn run(self) -> Result<PackageStatus, PackageError> {
|
||||||
self.build().run()
|
self.build().run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PackageArgsBuilder<PackageList, PackageState, Box<dyn SpecificPackageManager>> {
|
impl PackageArgsBuilder<PackageList, PackageState, Box<dyn PackageManager>> {
|
||||||
pub fn build(self) -> PackageModule<Box<dyn SpecificPackageManager>> {
|
pub fn build(self) -> PackageModule<Box<dyn PackageManager>> {
|
||||||
let Self { name, state, manager, .. } = self;
|
let Self { name, state, manager, .. } = self;
|
||||||
|
|
||||||
PackageModule {
|
PackageModule {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
pub struct PackageList {
|
pub struct PackageList {
|
||||||
pub list: Vec<String>,
|
pub list: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,35 +10,35 @@ pub mod list;
|
||||||
pub use list::{PackageList, IntoPackageList};
|
pub use list::{PackageList, IntoPackageList};
|
||||||
|
|
||||||
pub mod pacman;
|
pub mod pacman;
|
||||||
use pacman::ArchlinuxPackageManager;
|
use pacman::PacmanManager;
|
||||||
pub mod apt;
|
pub mod apt;
|
||||||
use apt::DebianPackageManager;
|
use apt::AptManager;
|
||||||
|
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
pub use builder::{PackageArgsBuilder, NoManager};
|
pub use builder::{PackageArgsBuilder, NoManager};
|
||||||
|
|
||||||
pub type PackageStatus = ();
|
pub type PackageStatus = ();
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
|
||||||
pub struct PackageArgs {
|
pub struct PackageArgs {
|
||||||
name: PackageList,
|
name: PackageList,
|
||||||
state: PackageState,
|
state: PackageState,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
|
||||||
pub enum PackageState {
|
pub enum PackageState {
|
||||||
Present,
|
Present,
|
||||||
Absent,
|
Absent,
|
||||||
Latest,
|
Latest,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct PackageModule<Manager> {
|
pub struct PackageModule<Manager> {
|
||||||
manager: Manager,
|
manager: Manager,
|
||||||
args: PackageArgs,
|
args: PackageArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Module<PackageArgs, (), PackageError> for PackageModule<Box<dyn SpecificPackageManager>> {
|
impl Module<PackageArgs, (), PackageError> for PackageModule<Box<dyn PackageManager>> {
|
||||||
fn serialize_args(&self) -> serde_json::Value {
|
fn serialize_args(&self) -> serde_json::Value {
|
||||||
serde_json::to_value(&self.args).unwrap()
|
serde_json::to_value(&self.args).unwrap()
|
||||||
}
|
}
|
||||||
|
@ -62,13 +62,13 @@ impl Module<PackageArgs, (), PackageError> for PackageModule<Box<dyn SpecificPac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleSetup<PackageModule<Box<dyn SpecificPackageManager>>, PackageArgs, (), PackageError> for PackageModule<NoManager> {
|
impl ModuleSetup<PackageModule<Box<dyn PackageManager>>, PackageArgs, (), PackageError> for PackageModule<NoManager> {
|
||||||
fn with_facts(self, facts: &Facts) -> PackageModule<Box<dyn SpecificPackageManager>> {
|
fn with_facts(self, facts: &Facts) -> PackageModule<Box<dyn PackageManager>> {
|
||||||
let Self { args, .. } = self;
|
let Self { args, .. } = self;
|
||||||
|
|
||||||
let manager: Box<dyn SpecificPackageManager> = match facts.os.family() {
|
let manager: Box<dyn PackageManager> = match facts.os.family() {
|
||||||
OsFamily::Debian => Box::new(DebianPackageManager),
|
OsFamily::Debian => Box::new(AptManager),
|
||||||
OsFamily::Archlinux => Box::new(ArchlinuxPackageManager),
|
OsFamily::Archlinux => Box::new(PacmanManager),
|
||||||
};
|
};
|
||||||
|
|
||||||
PackageModule {
|
PackageModule {
|
||||||
|
@ -97,9 +97,82 @@ impl From<std::io::Error> for PackageError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SpecificPackageManager: std::fmt::Debug {
|
pub trait PackageManager: std::fmt::Debug {
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
fn update(&self) -> Result<(), PackageError>;
|
fn update(&self) -> Result<(), PackageError>;
|
||||||
fn install(&self, list: PackageList) -> Result<(), PackageError>;
|
fn install(&self, list: PackageList) -> Result<(), PackageError>;
|
||||||
fn remove(&self, list: PackageList) -> Result<(), PackageError>;
|
fn remove(&self, list: PackageList) -> Result<(), PackageError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ensure_present() {
|
||||||
|
let pkg = PackageModule::new()
|
||||||
|
.name("hello")
|
||||||
|
.state(PackageState::Present)
|
||||||
|
.with_apt()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
pkg.serialize_args(),
|
||||||
|
serde_json::json!({
|
||||||
|
"name": vec!("hello"),
|
||||||
|
"state": PackageState::Present,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ensure_present_multi() {
|
||||||
|
let pkg = PackageModule::new()
|
||||||
|
.name(&[ "hello", "sl" ])
|
||||||
|
.state(PackageState::Present)
|
||||||
|
.with_apt()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
pkg.serialize_args(),
|
||||||
|
serde_json::json!({
|
||||||
|
"name": vec!("hello", "sl"),
|
||||||
|
"state": PackageState::Present,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ensure_absent() {
|
||||||
|
let pkg = PackageModule::new()
|
||||||
|
.name("hello")
|
||||||
|
.state(PackageState::Absent)
|
||||||
|
.with_apt()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
pkg.serialize_args(),
|
||||||
|
serde_json::json!({
|
||||||
|
"name": vec!("hello"),
|
||||||
|
"state": PackageState::Absent,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ensure_absent_multi() {
|
||||||
|
let pkg = PackageModule::new()
|
||||||
|
.name(&[ "hello", "sl" ])
|
||||||
|
.state(PackageState::Absent)
|
||||||
|
.with_apt()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
pkg.serialize_args(),
|
||||||
|
serde_json::json!({
|
||||||
|
"name": vec!("hello", "sl"),
|
||||||
|
"state": PackageState::Absent,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,17 +1,53 @@
|
||||||
use crate::utils::cmd::Cmd;
|
use crate::utils::cmd::{Cmd, CmdOutput};
|
||||||
|
|
||||||
|
use super::{PackageError, PackageList, PackageManager};
|
||||||
|
|
||||||
|
/// This structure is mostly used as an indirection for testing purposes.
|
||||||
|
/// But you can use it to build your own pacman commands.
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
|
||||||
|
pub struct PacmanCmd(pub Cmd);
|
||||||
|
|
||||||
|
impl PacmanCmd {
|
||||||
|
pub fn new() -> PacmanCmd {
|
||||||
|
PacmanCmd(
|
||||||
|
Cmd::new("pacman").arg("--noconfirm").arg("--needed")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update() -> PacmanCmd {
|
||||||
|
let mut cmd = Self::new();
|
||||||
|
cmd.0 = cmd.0.arg("-Sy");
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn install(list: PackageList) -> PacmanCmd {
|
||||||
|
let mut cmd = Self::new();
|
||||||
|
cmd.0 = cmd.0.arg("-S").args(list.list());
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(list: PackageList) -> PacmanCmd {
|
||||||
|
let mut cmd = Self::new();
|
||||||
|
cmd.0 = cmd.0.arg("-R").args(list.list());
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(self) -> Result<CmdOutput, std::io::Error> {
|
||||||
|
self.0.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use super::{PackageError, PackageList, SpecificPackageManager};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ArchlinuxPackageManager;
|
pub struct PacmanManager;
|
||||||
|
|
||||||
impl SpecificPackageManager for ArchlinuxPackageManager {
|
impl PackageManager for PacmanManager {
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
"pacman"
|
"pacman"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&self) -> Result<(), PackageError> {
|
fn update(&self) -> Result<(), PackageError> {
|
||||||
let res = Cmd::new("pacman").arg("-Sy").run()?;
|
let res = PacmanCmd::update().run()?;
|
||||||
|
|
||||||
if ! res.success {
|
if ! res.success {
|
||||||
return Err(PackageError::CmdFail(res));
|
return Err(PackageError::CmdFail(res));
|
||||||
|
@ -21,7 +57,7 @@ impl SpecificPackageManager for ArchlinuxPackageManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn install(&self, list: PackageList) -> Result<(), PackageError> {
|
fn install(&self, list: PackageList) -> Result<(), PackageError> {
|
||||||
let res = Cmd::new("pacman").arg("-S").args(list.list()).run()?;
|
let res = PacmanCmd::install(list).run()?;
|
||||||
|
|
||||||
if ! res.success {
|
if ! res.success {
|
||||||
return Err(PackageError::CmdFail(res));
|
return Err(PackageError::CmdFail(res));
|
||||||
|
@ -31,7 +67,7 @@ impl SpecificPackageManager for ArchlinuxPackageManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove(&self, list: PackageList) -> Result<(), PackageError> {
|
fn remove(&self, list: PackageList) -> Result<(), PackageError> {
|
||||||
let res = Cmd::new("pacman").arg("-R").args(list.list()).run()?;
|
let res = PacmanCmd::remove(list).run()?;
|
||||||
|
|
||||||
if ! res.success {
|
if ! res.success {
|
||||||
return Err(PackageError::CmdFail(res));
|
return Err(PackageError::CmdFail(res));
|
||||||
|
@ -40,3 +76,100 @@ impl SpecificPackageManager for ArchlinuxPackageManager {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use super::super::IntoPackageList;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn update_cmd() {
|
||||||
|
let cmd = PacmanCmd::update();
|
||||||
|
let mut args: Vec<&str> = vec!("--noconfirm", "--needed");
|
||||||
|
args.push("-Sy");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cmd.0,
|
||||||
|
Cmd {
|
||||||
|
program: "pacman".to_string(),
|
||||||
|
args: args.iter().map(|x| x.to_string()).collect(),
|
||||||
|
stdin: None,
|
||||||
|
chdir: None,
|
||||||
|
env: HashMap::new(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn install_cmd() {
|
||||||
|
let cmd = PacmanCmd::install(vec!("sl").into_package_list());
|
||||||
|
let mut args: Vec<&str> = vec!("--noconfirm", "--needed");
|
||||||
|
args.extend(& [ "-S", "sl" ]);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cmd.0,
|
||||||
|
Cmd {
|
||||||
|
program: "pacman".to_string(),
|
||||||
|
args: args.iter().map(|x| x.to_string()).collect(),
|
||||||
|
stdin: None,
|
||||||
|
chdir: None,
|
||||||
|
env: HashMap::new(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn install_cmd_multi() {
|
||||||
|
let cmd = PacmanCmd::install(vec!("sl", "hello").into_package_list());
|
||||||
|
let mut args: Vec<&str> = vec!("--noconfirm", "--needed");
|
||||||
|
args.extend(& [ "-S", "sl", "hello" ]);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cmd.0,
|
||||||
|
Cmd {
|
||||||
|
program: "pacman".to_string(),
|
||||||
|
args: args.iter().map(|x| x.to_string()).collect(),
|
||||||
|
stdin: None,
|
||||||
|
chdir: None,
|
||||||
|
env: HashMap::new(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn remove_cmd() {
|
||||||
|
let cmd = PacmanCmd::remove(vec!("sl").into_package_list());
|
||||||
|
let mut args: Vec<&str> = vec!("--noconfirm", "--needed");
|
||||||
|
args.extend(& [ "-R", "sl" ]);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cmd.0,
|
||||||
|
Cmd {
|
||||||
|
program: "pacman".to_string(),
|
||||||
|
args: args.iter().map(|x| x.to_string()).collect(),
|
||||||
|
stdin: None,
|
||||||
|
chdir: None,
|
||||||
|
env: HashMap::new(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn remove_cmd_multi() {
|
||||||
|
let cmd = PacmanCmd::remove(vec!("sl", "hello").into_package_list());
|
||||||
|
let mut args: Vec<&str> = vec!("--noconfirm", "--needed");
|
||||||
|
args.extend(& [ "-R", "sl", "hello" ]);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cmd.0,
|
||||||
|
Cmd {
|
||||||
|
program: "pacman".to_string(),
|
||||||
|
args: args.iter().map(|x| x.to_string()).collect(),
|
||||||
|
stdin: None,
|
||||||
|
chdir: None,
|
||||||
|
env: HashMap::new(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@ use duct::cmd as duct_cmd;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
|
||||||
pub struct Cmd {
|
pub struct Cmd {
|
||||||
program: String,
|
pub program: String,
|
||||||
args: Vec<String>,
|
pub args: Vec<String>,
|
||||||
stdin: Option<String>,
|
pub stdin: Option<String>,
|
||||||
chdir: Option<PathBuf>,
|
pub chdir: Option<PathBuf>,
|
||||||
env: HashMap<String, String>,
|
pub env: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cmd {
|
impl Cmd {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user