Skip to content

Commit

Permalink
rewite: Simplify public api (#27)
Browse files Browse the repository at this point in the history
* chore: temp

* temp: [skip ci]

* chore: compilation success

* chore: clippy fixes

* feat: Closes #24

* feat: version v0.5.0

* rebased main

* chore: test fixes
  • Loading branch information
dilawar authored Apr 5, 2024
1 parent 6b9ca80 commit 823aeb2
Show file tree
Hide file tree
Showing 19 changed files with 1,083 additions and 1,420 deletions.
16 changes: 5 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
[package]
name = "mpm"
version = "0.4.0"
version = "0.5.0"
edition = "2021"
license = "AGPL-3.0"

[dependencies]
anyhow = "1.0.81"
clap = { version = "4.5", features = ["derive"] }
colored = "2.1"
elevate = "0.6.1"
sudo = "0.6"
xmltree = "0.10"
os_info = "3.8.2"
strum = { version = "0.26", features = ["derive"] }
tabled = "0.15"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
serde = { version = "1.0.197", features = ["derive"], optional = true }
serde_json = {version = "1.0.115", optional = true }

[features]
default = ["cli"]
cli = ["verify", "json"]
verify = []
serde = ["dep:serde"]
json = ["serde", "dep:serde_json"]
ambassador = "0.3.6"
serde_json = "1.0.115"
serde = "1.0.197"

[dev-dependencies]
tracing-test = "0.2.4"
143 changes: 143 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
use std::str::FromStr;

use clap::{Parser, Subcommand};

use crate::common::{Package, PackageManager};

#[derive(Parser)]
#[command(
author,
version,
about = "A generic package manager.",
long_about = "A generic package manager for interfacing with multiple distro and platform specific package managers."
)]

/// Cli for PackageManager.
///
/// It is public because other tools can use this interface to pass the command
/// line args.
pub struct Cli {
#[command(subcommand)]
command: MpmCommands,

/// Optionally specify a package manager that you want to use. If not given,
/// mpm will search for default package manager on this system.
#[arg(long, short)]
manager: Option<crate::common::AvailablePackageManager>,

/// Set output to be in json format.
#[arg(long, default_value_t = false)]
json: bool,
}

#[derive(Subcommand)]
pub enum MpmCommands {
#[command(about = "List supported package managers and display their availability")]
Managers,

#[command(about = "Search for a given sub-string and list matching packages")]
Search { string: String },

#[command(about = "List all packages that are installed")]
List,

#[command(
about = "Install the given package(s)",
long_about = "Install the given package(s).\nIf a specific version of the package is desired, it can be specified using the format <package_name>@<version>.\nNote: version information is optional."
)]
Install {
#[clap(required = true)]
packages: Vec<String>,
},

#[command(
about = "Uninstall the given package(s)",
long_about = "Uninstall the given package(s).\nIf a specific version of the package is desired, it can be specified using the format <package_name>@<version>.\nNote: version information is optional."
)]
Uninstall {
#[clap(required = true)]
packages: Vec<String>,
},

#[command(
about = "Add the provided third-party repo location to the package manager",
long_about = "Provide a repo in the form of a URL or package manager specific repo format to add it to the list of repositories of the package manager"
)]
Repo { repo: String },

#[command(
about = "Updates the cached package repository data",
long_about = "Sync the cached package repository data.\nNote: this behavior might not be consistent among package managers; when sync is not supported, the package manager might simply update itself."
)]
Sync,

#[command(about = "Update/upgrade the given package(s) or (--)all of them")]
#[group(required = true)]
Update {
packages: Vec<String>,
#[arg(long, short)]
all: bool,
},
}
/// Function that handles the parsed CLI arguments in one place
pub fn execute(args: Cli) -> anyhow::Result<()> {
let mpm = if let Some(manager) = args.manager {
crate::MetaPackageManager::try_new(manager)?
} else {
crate::MetaPackageManager::new_default()?
};

match args.command {
MpmCommands::Managers => crate::print::print_managers(),
MpmCommands::Search { string } => {
let pkgs = mpm.search(&string);
print_pkgs(&pkgs, args.json)?;
}
MpmCommands::List => {
let pkgs = mpm.list_installed();
print_pkgs(&pkgs, args.json)?;
}
MpmCommands::Install { packages } => {
for pkg in packages {
let s = mpm.install(Package::from_str(&pkg)?);
anyhow::ensure!(s.success(), "Failed to install {pkg}");
}
}
MpmCommands::Uninstall { packages } => {
for pkg in packages {
let s = mpm.uninstall(Package::from_str(&pkg)?);
anyhow::ensure!(s.success(), "Failed to uninstall pacakge {pkg}");
}
}

MpmCommands::Update { packages, all } => {
if all {
mpm.update_all();
} else {
for pkg in packages {
let s = mpm.update(Package::from_str(&pkg)?);
anyhow::ensure!(s.success(), "Failed to update pacakge {pkg}");
}
}
}
MpmCommands::Repo { repo } => {
mpm.add_repo(&repo)?;
}
MpmCommands::Sync => {
let s = mpm.sync();
anyhow::ensure!(s.success(), "Failed to sync repositories");
}
};

Ok(())
}

/// Print packages
fn print_pkgs(pkgs: &[Package], json: bool) -> anyhow::Result<()> {
if json {
println!("{}", serde_json::to_string_pretty(pkgs)?);
} else {
println!("{}", tabled::Table::new(pkgs));
}
Ok(())
}
Loading

0 comments on commit 823aeb2

Please sign in to comment.