Merge branch 'main' into 'main'

Change argument parsing to clap v3 derives

See merge request crystal/programs/amethyst!18
i18n
michal 2 years ago
commit 51aee8e721

@ -51,7 +51,7 @@ codegen-units = 1
[dependencies]
mimalloc = { version = "0.1.27", default-features = false }
clap = { version = "2.34.0", default-features = false, features = ["suggestions"] }
clap = { version = "3.1.9", features = [ "derive", "wrap_help"] }
regex = { version = "1.5.4", default-features = false, features = ["std", "unicode-perl"] }
runas = "0.2.1"
rusqlite = { version = "0.26.3", default-features = false }

@ -0,0 +1,85 @@
use clap::{Parser, Subcommand};
#[derive(Debug, Clone, Parser)]
#[clap(name="Amethyst", version=env!("CARGO_PKG_VERSION"), about=env!("CARGO_PKG_DESCRIPTION"))]
pub struct Args {
#[clap(subcommand)]
pub subcommand: Option<Operation>,
/// Sets the level of verbosity
#[clap(long, short, parse(from_occurrences))]
pub verbose: usize,
/// Complete operation without prompting user
#[clap(long = "noconfirm")]
pub no_confirm: bool,
}
#[derive(Debug, Clone, Subcommand)]
pub enum Operation {
/// Installs a package from either the AUR or the PacMan-defined repositories
#[clap(name="install", aliases=&["i", "-S"])]
Install(InstallArgs),
/// Removes a previously installed package
#[clap(name="remove", aliases=&["rm", "-R", "-Rs"])]
Remove(RemoveArgs),
/// Searches for the relevant packages in both the AUR and repos
#[clap(name="search", aliases=&["sea", "-Ss"])]
Search(SearchArgs),
/// Queries installed packages
#[clap(name="query", aliases=&["ls", "-Q"])]
Query(QueryArgs),
/// Upgrades locally installed packages to their latest versions
#[clap(name="upgrade", aliases=&["upg", "-Syu"])]
Upgrade,
}
impl Default for Operation {
fn default() -> Self {
Self::Upgrade
}
}
#[derive(Default, Debug, Clone, Parser)]
pub struct InstallArgs {
/// The name of the package(s) to install
#[clap(required = true)]
pub packages: Vec<String>,
}
#[derive(Default, Debug, Clone, Parser)]
pub struct RemoveArgs {
/// The name of the package(s) to remove
#[clap(required = true)]
pub packages: Vec<String>,
}
#[derive(Default, Debug, Clone, Parser)]
pub struct SearchArgs {
/// Searches for the relevant packages in both the AUR and repos
#[clap(long, short)]
pub aur: bool,
/// Searches only local repos for the package
#[clap(long, short)]
pub repo: bool,
/// The string the package must match in the search
#[clap(required = true)]
pub search: Vec<String>,
}
#[derive(Default, Debug, Clone, Parser)]
pub struct QueryArgs {
/// Lists AUR/foreign packages
#[clap(long, short)]
pub aur: bool,
/// Lists repo/native packages
#[clap(long, short)]
pub repo: bool,
}

@ -1,23 +1,9 @@
use crate::internal::rpc::Package;
use crate::Options;
mod add;
mod initialise;
mod query;
mod remove;
pub fn add(a: Package, options: Options) {
add::add(a, options);
}
pub fn remove(a: &str, options: Options) {
remove::remove(a, options);
}
pub fn init(options: Options) {
initialise::init(options);
}
pub fn query(options: Options) -> Vec<Package> {
query::query(options)
}
pub use add::*;
pub use initialise::*;
pub use query::*;
pub use remove::*;

@ -1,5 +1,3 @@
use crate::Options;
mod clean;
mod initialise;
pub mod rpc;
@ -7,33 +5,10 @@ mod sort;
mod strings;
pub mod structs;
pub fn sort(a: &[String], options: Options) -> structs::Sorted {
sort::sort(a, options)
}
pub fn clean(a: &[String], options: Options) -> Vec<String> {
clean::clean(a, options)
}
pub fn init(options: Options) {
initialise::init(options);
}
pub fn info(a: String) {
strings::info(a);
}
pub fn crash(a: String, b: i32) {
strings::crash(a, b);
}
pub fn log(a: String) {
strings::log(a);
}
pub fn prompt(a: String, b: bool) -> bool {
strings::prompt(a, b)
}
pub use clean::*;
pub use initialise::*;
pub use sort::*;
pub use strings::*;
#[macro_export]
macro_rules! uwu {

@ -1,13 +1,16 @@
use std::process::{exit, Command};
use std::{env, io, process};
use clap::Parser;
use std::process;
use std::process::Command;
use clap::{App, AppSettings, Arg, ArgMatches, ArgSettings, Shell, SubCommand};
use crate::args::{InstallArgs, Operation, QueryArgs, RemoveArgs, SearchArgs};
use args::Args;
use crate::internal::{crash, info, init, log, sort, structs::Options};
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
mod args;
mod database;
mod internal;
mod operations;
@ -21,118 +24,10 @@ fn main() {
crash("Running amethyst as root is disallowed as it can lead to system breakage. Instead, amethyst will prompt you when it needs superuser permissions".to_string(), 1);
}
fn build_app() -> App<'static, 'static> {
let app = App::new("Amethyst")
.version(env!("CARGO_PKG_VERSION"))
.about(env!("CARGO_PKG_DESCRIPTION"))
.arg(
Arg::with_name("verbose")
.short("v")
.long("verbose")
.multiple(true)
.set(ArgSettings::Global)
.help("Sets the level of verbosity"),
)
.arg(
Arg::with_name("noconfirm")
.long("noconfirm")
.set(ArgSettings::Global)
.help("Complete operation without prompting user"),
)
.subcommand(
SubCommand::with_name("install")
.about(
"Installs a package from either the AUR or the PacMan-defined repositories",
)
.aliases(&["-S", "ins"])
.arg(
Arg::with_name("package(s)")
.help("The name of the package(s) to install")
.required(true)
.multiple(true)
.index(1),
),
)
.subcommand(
SubCommand::with_name("remove")
.about("Removes a previously installed package")
.aliases(&["-R", "-Rs", "rm"])
.arg(
Arg::with_name("package(s)")
.help("The name of the package(s) to remove")
.required(true)
.multiple(true)
.index(1),
),
)
.subcommand(
SubCommand::with_name("search")
.about("Searches for the relevant packages in both the AUR and repos")
.aliases(&["-Ss", "sea"])
.arg(
Arg::with_name("aur")
.short("a")
.long("aur")
.help("Search only the AUR for the package"),
)
.arg(
Arg::with_name("repo")
.short("r")
.long("repo")
.help("Searches only local repos for the package"),
)
.arg(
Arg::with_name("package(s)")
.help("The name of the package to search for")
.required(true)
.multiple(false)
.index(1),
),
)
.subcommand(
SubCommand::with_name("query")
.about("Queries installed packages")
.aliases(&["-Q", "ls"])
.arg(
Arg::with_name("aur")
.short("a")
.help("Lists AUR/foreign packages"),
)
.arg(
Arg::with_name("repo")
.short("r")
.help("Lists repo/native packages"),
),
)
.subcommand(
SubCommand::with_name("upgrade")
.about("Upgrades locally installed packages to their latest versions")
.aliases(&["-Syu", "upg"]),
)
.subcommand(
SubCommand::with_name("compgen")
.about("Generates shell completions for given shell (bash by default)")
.aliases(&["-G", "cg"])
.arg(
Arg::with_name("shell")
.help("The name of the shell you want to generate completions for")
.possible_values(&["bash", "fish", "zsh", "pwsh", "elvish"])
.required(true),
),
)
.settings(&[
AppSettings::GlobalVersion,
AppSettings::VersionlessSubcommands,
AppSettings::ArgRequiredElseHelp,
AppSettings::InferSubcommands,
]);
app
}
let matches = build_app().get_matches();
let args: Args = Args::parse();
let verbosity: i32 = matches.occurrences_of("verbose") as i32;
let noconfirm: bool = matches.is_present("noconfirm");
let verbosity = args.verbose as i32;
let noconfirm = args.no_confirm;
let options = Options {
verbosity,
@ -142,174 +37,104 @@ fn main() {
init(options);
fn collect_matches(a: &ArgMatches) -> Vec<String> {
a.subcommand()
.1
.unwrap()
.values_of("package(s)")
.unwrap()
.into_iter()
.map(|s| s.to_string())
.collect()
match args.subcommand.unwrap_or_default() {
Operation::Install(install_args) => cmd_install(install_args, options),
Operation::Remove(remove_args) => cmd_remove(remove_args, options),
Operation::Search(search_args) => cmd_search(search_args, options),
Operation::Query(query_args) => cmd_query(query_args),
Operation::Upgrade => {
info("Performing system upgrade".to_string());
operations::upgrade(options);
}
}
}
if let true = matches.is_present("install") {
let packages = collect_matches(&matches);
let sorted = sort(&packages, options);
fn cmd_install(args: InstallArgs, options: Options) {
let packages = args.packages;
let sorted = sort(&packages, options);
info(format!(
"Attempting to install packages: {}",
packages.join(", ")
info(format!(
"Attempting to install packages: {}",
packages.join(", ")
));
if !sorted.repo.is_empty() {
operations::install(sorted.repo, options);
}
if !sorted.aur.is_empty() {
operations::aur_install(sorted.aur, options);
}
if !sorted.nf.is_empty() {
log(format!(
"Couldn't find packages: {} in repos or the AUR",
sorted.nf.join(", ")
));
}
if !sorted.repo.is_empty() {
operations::install(sorted.repo, options);
}
if !sorted.aur.is_empty() {
operations::aur_install(sorted.aur, options);
}
if !sorted.nf.is_empty() {
log(format!(
"Couldn't find packages: {} in repos or the AUR",
sorted.nf.join(", ")
));
}
let out = process::Command::new("bash")
.args(&["-c", "sudo find /etc -name *.pacnew"])
.output()
.expect("Something has gone wrong")
.stdout;
let out = process::Command::new("bash")
.args(&["-c", "sudo find /etc -name *.pacnew"])
.output()
.expect("Something has gone wrong")
.stdout;
if !String::from_utf8((*out).to_owned()).unwrap().is_empty() {
info(format!("You have .pacnew files in /etc ({}) that you haven't removed or acted upon, it is recommended you do that now", String::from_utf8((*out).to_owned()).unwrap().split_whitespace().collect::<Vec<&str>>().join(", ")));
}
}
if !String::from_utf8((*out).to_owned()).unwrap().is_empty() {
info(format!("You have .pacnew files in /etc ({}) that you haven't removed or acted upon, it is recommended you do that now", String::from_utf8((*out).to_owned()).unwrap().split_whitespace().collect::<Vec<&str>>().join(", ")));
}
fn cmd_remove(args: RemoveArgs, options: Options) {
let packages = args.packages;
info(format!("Uninstalling packages: {}", &packages.join(", ")));
operations::uninstall(packages, options);
}
exit(0);
fn cmd_search(args: SearchArgs, options: Options) {
let query_string = args.search.join(" ");
if args.aur {
info(format!("Searching AUR for {}", &query_string));
operations::aur_search(&query_string, options);
}
if let true = matches.is_present("remove") {
let packages = collect_matches(&matches);
info(format!("Uninstalling packages: {}", &packages.join(", ")));
operations::uninstall(packages, options);
exit(0);
if args.repo {
info(format!("Searching repos for {}", &query_string));
operations::search(&query_string, options);
}
if let true = matches.is_present("upgrade") {
info("Performing system upgrade".to_string());
operations::upgrade(options);
exit(0);
if !args.aur && !args.repo {
info(format!("Searching AUR and repos for {}", &query_string));
operations::search(&query_string, options);
operations::aur_search(&query_string, options);
}
}
if let true = matches.is_present("search") {
let packages = collect_matches(&matches);
if matches
.subcommand_matches("search")
.unwrap()
.is_present("aur")
{
info(format!("Searching AUR for {}", &packages[0]));
operations::aur_search(&packages[0], options);
}
if matches
.subcommand_matches("search")
.unwrap()
.is_present("repo")
{
info(format!("Searching repos for {}", &packages[0]));
operations::search(&packages[0], options);
}
if !matches
.subcommand_matches("search")
.unwrap()
.is_present("repo")
&& !matches
.subcommand_matches("search")
.unwrap()
.is_present("aur")
{
info(format!("Searching AUR and repos for {}", &packages[0]));
operations::search(&packages[0], options);
operations::aur_search(&packages[0], options);
}
exit(0);
fn cmd_query(args: QueryArgs) {
if args.aur {
Command::new("pacman")
.arg("-Qm")
.spawn()
.expect("Something has gone wrong")
.wait()
.unwrap();
}
if let true = matches.is_present("query") {
if matches
.subcommand_matches("query")
.unwrap()
.is_present("aur")
{
Command::new("pacman")
.arg("-Qm")
.spawn()
.expect("Something has gone wrong")
.wait()
.unwrap();
}
if matches
.subcommand_matches("query")
.unwrap()
.is_present("repo")
{
Command::new("pacman")
.arg("-Qn")
.spawn()
.expect("Something has gone wrong")
.wait()
.unwrap();
}
if !matches
.subcommand_matches("query")
.unwrap()
.is_present("aur")
&& !matches
.subcommand_matches("query")
.unwrap()
.is_present("repo")
{
Command::new("pacman")
.arg("-Qn")
.spawn()
.expect("Something has gone wrong")
.wait()
.unwrap();
Command::new("pacman")
.arg("-Qm")
.spawn()
.expect("Something has gone wrong")
.wait()
.unwrap();
}
exit(0);
if args.repo {
Command::new("pacman")
.arg("-Qn")
.spawn()
.expect("Something has gone wrong")
.wait()
.unwrap();
}
if let true = &matches.is_present("compgen") {
let mut app = build_app();
match matches
.subcommand_matches("compgen")
.unwrap()
.value_of("shell")
.unwrap()
{
"bash" => {
app.gen_completions_to("ame", Shell::Bash, &mut io::stdout());
}
"fish" => {
app.gen_completions_to("ame", Shell::Fish, &mut io::stdout());
}
"zsh" => {
app.gen_completions_to("ame", Shell::Zsh, &mut io::stdout());
}
"pwsh" => {
app.gen_completions_to("ame", Shell::PowerShell, &mut io::stdout());
}
"elvish" => {
app.gen_completions_to("ame", Shell::Elvish, &mut io::stdout());
}
_ => {}
}
if !args.repo && !args.aur {
Command::new("pacman")
.arg("-Qn")
.spawn()
.expect("Something has gone wrong")
.wait()
.unwrap();
Command::new("pacman")
.arg("-Qm")
.spawn()
.expect("Something has gone wrong")
.wait()
.unwrap();
}
}

@ -1,31 +1,11 @@
use crate::Options;
mod aur_install;
mod install;
mod search;
mod uninstall;
mod upgrade;
pub fn install(a: Vec<String>, options: Options) {
install::install(a, options);
}
pub fn uninstall(a: Vec<String>, options: Options) {
uninstall::uninstall(a, options);
}
pub fn search(a: &str, options: Options) {
search::repo_search(a, options);
}
pub fn aur_install(a: Vec<String>, options: Options) {
aur_install::aur_install(a, options);
}
pub fn aur_search(a: &str, options: Options) {
search::aur_search(a, options);
}
pub fn upgrade(options: Options) {
upgrade::upgrade(options);
}
pub use aur_install::*;
pub use install::*;
pub use search::{aur_search, repo_search as search};
pub use uninstall::*;
pub use upgrade::*;

Loading…
Cancel
Save