From 5804807837ac4d89594fec91238c4037f5e00c25 Mon Sep 17 00:00:00 2001 From: Kevin Goslar Date: Mon, 21 Oct 2024 16:47:22 -0500 Subject: [PATCH] Use argument field structs (#290) --- src/cli/app_version.rs | 13 +++-- src/cli/args.rs | 98 +++++++++++++++++++++----------------- src/cli/command.rs | 13 +++-- src/cmd/available.rs | 15 ++++-- src/cmd/mod.rs | 10 ++-- src/cmd/run.rs | 6 +-- src/cmd/test.rs | 14 ++++-- src/cmd/update.rs | 13 +++-- src/cmd/versions.rs | 17 +++++-- src/cmd/which.rs | 15 ++++-- src/config/app_versions.rs | 2 +- src/config/config.rs | 33 ++++++++----- src/main.rs | 10 ++-- 13 files changed, 155 insertions(+), 104 deletions(-) diff --git a/src/cli/app_version.rs b/src/cli/app_version.rs index f8160373..0597e41d 100644 --- a/src/cli/app_version.rs +++ b/src/cli/app_version.rs @@ -3,7 +3,7 @@ use crate::config::{AppName, Version}; /// a request from the user to run a particular app #[derive(Debug, PartialEq)] pub struct AppVersion { - pub app: AppName, + pub app_name: AppName, pub version: Option, } @@ -11,7 +11,10 @@ impl AppVersion { pub fn new>(token: S) -> Self { let (app_name, version) = token.as_ref().split_once('@').unwrap_or((token.as_ref(), "")); let version = if version.is_empty() { None } else { Some(Version::from(version)) }; - AppVersion { app: app_name.into(), version } + AppVersion { + app_name: app_name.into(), + version, + } } } @@ -26,7 +29,7 @@ mod tests { let give = "shellcheck@0.9.0"; let have = AppVersion::new(give); let want = AppVersion { - app: AppName::from("shellcheck"), + app_name: AppName::from("shellcheck"), version: Some(Version::from("0.9.0")), }; pretty::assert_eq!(have, want); @@ -37,7 +40,7 @@ mod tests { let give = "shellcheck"; let have = AppVersion::new(give); let want = AppVersion { - app: AppName::from("shellcheck"), + app_name: AppName::from("shellcheck"), version: None, }; pretty::assert_eq!(have, want); @@ -48,7 +51,7 @@ mod tests { let give = "shellcheck@"; let have = AppVersion::new(give); let want = AppVersion { - app: AppName::from("shellcheck"), + app_name: AppName::from("shellcheck"), version: None, }; pretty::assert_eq!(have, want); diff --git a/src/cli/args.rs b/src/cli/args.rs index 32abd657..94b9a8fb 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -1,5 +1,5 @@ use super::{AppVersion, Command}; -use crate::cmd::run; +use crate::cmd::{self, available, run, test, update, versions}; use crate::prelude::*; /// all arguments that can be provided via the CLI @@ -93,34 +93,34 @@ pub fn parse(mut cli_args: impl Iterator) -> Result { return Ok(Args { command: Command::Setup }); } else if update { return Ok(Args { - command: Command::Update { verbose }, + command: Command::Update(update::Args { verbose }), }); } if test { return Ok(Args { - command: Command::Test { - app: app_version.map(|av| av.app), + command: Command::Test(test::Args { + start_at_app: app_version.map(|av| av.app_name), verbose, - }, + }), }); } - if let Some(AppVersion { app, version }) = app_version { + if let Some(AppVersion { app_name, version }) = app_version { if indicate_available { Ok(Args { - command: Command::Available { app, version, verbose }, + command: Command::Available(available::Args { app_name, version, verbose }), }) } else if which { Ok(Args { - command: Command::Which { app, version, verbose }, + command: Command::Which(cmd::which::Args { app_name, version, verbose }), }) } else if let Some(amount) = versions { Ok(Args { - command: Command::Versions { app, amount, verbose }, + command: Command::Versions(versions::Args { app_name, amount, verbose }), }) } else { Ok(Args { command: Command::RunApp(run::Args { - app, + app_name, version, app_args, error_on_output, @@ -173,6 +173,7 @@ mod tests { mod available { use super::super::parse_args; use crate::cli::{Args, Command}; + use crate::cmd::available; use crate::config::AppName; use crate::prelude::*; @@ -180,11 +181,11 @@ mod tests { fn with_app() { let have = parse_args(vec!["rta", "--available", "shellcheck"]); let want = Ok(Args { - command: Command::Available { - app: AppName::from("shellcheck"), + command: Command::Available(available::Args { + app_name: AppName::from("shellcheck"), version: None, verbose: false, - }, + }), }); pretty::assert_eq!(have, want); } @@ -193,11 +194,11 @@ mod tests { fn with_all_options() { let have = parse_args(vec!["rta", "--available", "--verbose", "shellcheck"]); let want = Ok(Args { - command: Command::Available { - app: AppName::from("shellcheck"), + command: Command::Available(available::Args { + app_name: AppName::from("shellcheck"), version: None, verbose: true, - }, + }), }); pretty::assert_eq!(have, want); } @@ -222,7 +223,7 @@ mod tests { let have = parse_args(vec!["rta", "--error-on-output", "app"]); let want = Ok(Args { command: Command::RunApp(run::Args { - app: AppName::from("app"), + app_name: AppName::from("app"), version: None, app_args: vec![], error_on_output: true, @@ -244,13 +245,17 @@ mod tests { mod test { use super::super::parse_args; use crate::cli::{Args, Command}; + use crate::cmd::test; use crate::config::AppName; #[test] fn no_app_no_verbose() { let have = parse_args(vec!["rta", "--test"]); let want = Ok(Args { - command: Command::Test { app: None, verbose: false }, + command: Command::Test(test::Args { + start_at_app: None, + verbose: false, + }), }); pretty::assert_eq!(have, want); } @@ -259,7 +264,10 @@ mod tests { fn no_app_verbose() { let have = parse_args(vec!["rta", "--test", "--verbose"]); let want = Ok(Args { - command: Command::Test { app: None, verbose: true }, + command: Command::Test(test::Args { + start_at_app: None, + verbose: true, + }), }); pretty::assert_eq!(have, want); } @@ -268,10 +276,10 @@ mod tests { fn app_no_verbose() { let have = parse_args(vec!["rta", "--test", "actionlint"]); let want = Ok(Args { - command: Command::Test { - app: Some(AppName::from("actionlint")), + command: Command::Test(test::Args { + start_at_app: Some(AppName::from("actionlint")), verbose: false, - }, + }), }); pretty::assert_eq!(have, want); } @@ -280,10 +288,10 @@ mod tests { fn app_verbose() { let have = parse_args(vec!["rta", "--test", "--verbose", "actionlint"]); let want = Ok(Args { - command: Command::Test { - app: Some(AppName::from("actionlint")), + command: Command::Test(test::Args { + start_at_app: Some(AppName::from("actionlint")), verbose: true, - }, + }), }); pretty::assert_eq!(have, want); } @@ -320,7 +328,7 @@ mod tests { let have = parse_args(vec!["rta", "--verbose", "app@2"]); let want = Ok(Args { command: Command::RunApp(run::Args { - app: AppName::from("app"), + app_name: AppName::from("app"), version: Some(Version::from("2")), app_args: vec![], error_on_output: false, @@ -336,7 +344,7 @@ mod tests { let have = parse_args(vec!["rta", "-v", "app@2"]); let want = Ok(Args { command: Command::RunApp(run::Args { - app: AppName::from("app"), + app_name: AppName::from("app"), version: Some(Version::from("2")), app_args: vec![], error_on_output: false, @@ -367,7 +375,7 @@ mod tests { let have = parse_args(vec!["rta", "--optional", "app@2", "arg1"]); let want = Ok(Args { command: Command::RunApp(run::Args { - app: AppName::from("app"), + app_name: AppName::from("app"), version: Some(Version::from("2")), app_args: vec![S("arg1")], error_on_output: false, @@ -401,6 +409,7 @@ mod tests { mod versions { use super::parse_args; use crate::cli::{args, Command}; + use crate::cmd::versions; use crate::config::AppName; use args::Args; @@ -408,11 +417,11 @@ mod tests { fn correct_usage() { let have = parse_args(vec!["rta", "--versions", "actionlint"]); let want = Ok(Args { - command: Command::Versions { - app: AppName::from("actionlint"), + command: Command::Versions(versions::Args { + app_name: AppName::from("actionlint"), amount: 10, verbose: false, - }, + }), }); pretty::assert_eq!(have, want); } @@ -421,11 +430,11 @@ mod tests { fn custom_amount() { let have = parse_args(vec!["rta", "--versions=20", "actionlint"]); let want = Ok(Args { - command: Command::Versions { - app: AppName::from("actionlint"), + command: Command::Versions(versions::Args { + app_name: AppName::from("actionlint"), amount: 20, verbose: false, - }, + }), }); pretty::assert_eq!(have, want); } @@ -441,6 +450,7 @@ mod tests { mod which { use super::super::parse_args; use crate::cli::{Args, Command}; + use crate::cmd; use crate::config::AppName; use crate::prelude::*; @@ -448,11 +458,11 @@ mod tests { fn with_app() { let have = parse_args(vec!["rta", "--which", "shellcheck"]); let want = Ok(Args { - command: Command::Which { - app: AppName::from("shellcheck"), + command: Command::Which(cmd::which::Args { + app_name: AppName::from("shellcheck"), version: None, verbose: false, - }, + }), }); pretty::assert_eq!(have, want); } @@ -461,11 +471,11 @@ mod tests { fn with_all_options() { let have = parse_args(vec!["rta", "--which", "--verbose", "shellcheck"]); let want = Ok(Args { - command: Command::Which { - app: AppName::from("shellcheck"), + command: Command::Which(cmd::which::Args { + app_name: AppName::from("shellcheck"), version: None, verbose: true, - }, + }), }); pretty::assert_eq!(have, want); } @@ -492,7 +502,7 @@ mod tests { let have = parse_args(vec!["rta", "app@2"]); let want = Ok(Args { command: Command::RunApp(run::Args { - app: AppName::from("app"), + app_name: AppName::from("app"), version: Some(Version::from("2")), app_args: vec![], error_on_output: false, @@ -508,7 +518,7 @@ mod tests { let have = parse_args(vec!["rta", "app@2", "--arg1", "arg2"]); let want = Ok(Args { command: Command::RunApp(run::Args { - app: AppName::from("app"), + app_name: AppName::from("app"), version: Some(Version::from("2")), app_args: vec![S("--arg1"), S("arg2")], error_on_output: false, @@ -532,7 +542,7 @@ mod tests { let have = parse_args(vec!["rta", "--verbose", "app@2", "--arg1", "arg2"]); let want = Ok(Args { command: Command::RunApp(run::Args { - app: AppName::from("app"), + app_name: AppName::from("app"), version: Some(Version::from("2")), app_args: vec![S("--arg1"), S("arg2")], error_on_output: false, @@ -548,7 +558,7 @@ mod tests { let have = parse_args(vec!["rta", "app@2", "--verbose", "--version"]); let want = Ok(Args { command: Command::RunApp(run::Args { - app: AppName::from("app"), + app_name: AppName::from("app"), version: Some(Version::from("2")), app_args: vec![S("--verbose"), S("--version")], error_on_output: false, diff --git a/src/cli/command.rs b/src/cli/command.rs index 1a3084b4..b93f5a33 100644 --- a/src/cli/command.rs +++ b/src/cli/command.rs @@ -1,18 +1,17 @@ -use crate::cmd::run; -use crate::config::{AppName, Version}; +use crate::cmd::{self, available, run, test, update, versions}; /// the main commands that run-this-app can execute #[derive(Debug, PartialEq)] pub enum Command { AppsLong, AppsShort, - Available { app: AppName, version: Option, verbose: bool }, + Available(available::Args), RunApp(run::Args), DisplayHelp, Setup, - Test { app: Option, verbose: bool }, - Which { app: AppName, version: Option, verbose: bool }, - Update { verbose: bool }, + Test(test::Args), + Which(cmd::which::Args), + Update(update::Args), Version, - Versions { app: AppName, amount: usize, verbose: bool }, + Versions(versions::Args), } diff --git a/src/cmd/available.rs b/src/cmd/available.rs index 7a9b12c1..e58e9faa 100644 --- a/src/cmd/available.rs +++ b/src/cmd/available.rs @@ -4,13 +4,13 @@ use crate::prelude::*; use crate::{apps, logger, platform, yard}; use std::process::ExitCode; -pub fn available(app_name: &AppName, version: Option, verbose: bool) -> Result { +pub fn available(args: Args) -> Result { let apps = apps::all(); - let app = apps.lookup(app_name)?; - let log = logger::new(verbose); + let app = apps.lookup(&args.app_name)?; + let log = logger::new(args.verbose); let platform = platform::detect(log)?; let yard = yard::load_or_create(&yard::production_location()?)?; - let versions = RequestedVersions::determine(app_name, version, &apps)?; + let versions = RequestedVersions::determine(&args.app_name, args.version, &apps)?; for version in versions { if load_or_install(app, &version, platform, &yard, log)?.is_some() { return Ok(ExitCode::SUCCESS); @@ -18,3 +18,10 @@ pub fn available(app_name: &AppName, version: Option, verbose: bool) -> } Ok(ExitCode::FAILURE) } + +#[derive(Debug, PartialEq)] +pub struct Args { + pub app_name: AppName, + pub version: Option, + pub verbose: bool, +} diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index 6bc3c5e3..8d305c2b 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -1,13 +1,13 @@ pub mod apps; -mod available; +pub mod available; mod help; pub mod run; mod setup; -mod test; -mod update; +pub mod test; +pub mod update; mod version; -mod versions; -mod which; +pub mod versions; +pub mod which; pub use available::available; pub use help::help; diff --git a/src/cmd/run.rs b/src/cmd/run.rs index 44226482..c518a740 100644 --- a/src/cmd/run.rs +++ b/src/cmd/run.rs @@ -11,11 +11,11 @@ use std::process::ExitCode; pub fn run(args: Args) -> Result { let apps = apps::all(); - let app = apps.lookup(&args.app)?; + let app = apps.lookup(&args.app_name)?; let log = logger::new(args.verbose); let platform = platform::detect(log)?; let yard = yard::load_or_create(&yard::production_location()?)?; - let versions = RequestedVersions::determine(&args.app, args.version, &apps)?; + let versions = RequestedVersions::determine(&args.app_name, args.version, &apps)?; for version in versions { if let Some(executable) = load_or_install(app, &version, platform, &yard, log)? { if args.error_on_output { @@ -35,7 +35,7 @@ pub fn run(args: Args) -> Result { #[derive(Debug, PartialEq)] pub struct Args { /// name of the app to execute - pub app: AppName, + pub app_name: AppName, /// possible versions of the app to execute pub version: Option, diff --git a/src/cmd/test.rs b/src/cmd/test.rs index 285f2498..ddded3dd 100644 --- a/src/cmd/test.rs +++ b/src/cmd/test.rs @@ -8,18 +8,18 @@ use colored::Colorize; use std::io; use std::process::ExitCode; -pub fn test(mut start_at_app: Option, verbose: bool) -> Result { +pub fn test(args: &mut Args) -> Result { let apps = apps::all(); - let log = logger::new(verbose); + let log = logger::new(args.verbose); let platform = platform::detect(log)?; let temp_folder = tempfile::tempdir().map_err(|err| UserError::CannotCreateTempDir { err: err.to_string() })?; let yard = yard::load_or_create(temp_folder.path())?; for app in apps { - if let Some(start_app_name) = &start_at_app { + if let Some(start_app_name) = &args.start_at_app { if app.name() != start_app_name { continue; } - start_at_app = None; + args.start_at_app = None; } log(Event::IntegrationTestNewApp { app: &app.name() }); let latest_version = app.latest_installable_version(log)?; @@ -68,3 +68,9 @@ pub fn test(mut start_at_app: Option, verbose: bool) -> Result, + pub verbose: bool, +} diff --git a/src/cmd/update.rs b/src/cmd/update.rs index e10f4746..47aeb1b6 100644 --- a/src/cmd/update.rs +++ b/src/cmd/update.rs @@ -4,13 +4,13 @@ use crate::logger::{self, Event}; use crate::prelude::*; use std::process::ExitCode; -pub fn update(verbose: bool) -> Result { +pub fn update(args: &Args) -> Result { let all_apps = apps::all(); let mut config = Config::load(&all_apps)?; - let log = logger::new(verbose); + let log = logger::new(args.verbose); for old_app in &mut config.apps { - let app = all_apps.lookup(&old_app.app)?; - log(Event::UpdateBegin { app: &old_app.app }); + let app = all_apps.lookup(&old_app.app_name)?; + log(Event::UpdateBegin { app: &old_app.app_name }); let latest = app.latest_installable_version(log)?; if let Some(previous) = &old_app.versions.update_largest_with(&latest) { log(Event::UpdateNewVersion { @@ -24,3 +24,8 @@ pub fn update(verbose: bool) -> Result { config.save()?; Ok(ExitCode::SUCCESS) } + +#[derive(Debug, PartialEq)] +pub struct Args { + pub verbose: bool, +} diff --git a/src/cmd/versions.rs b/src/cmd/versions.rs index d9b6ff55..b36700ab 100644 --- a/src/cmd/versions.rs +++ b/src/cmd/versions.rs @@ -3,14 +3,21 @@ use crate::prelude::*; use crate::{apps, logger}; use std::process::ExitCode; -pub fn versions(app_name: &AppName, amount: usize, verbose: bool) -> Result { +pub fn versions(args: &Args) -> Result { let apps = &apps::all(); - let app = apps.lookup(app_name)?; - let log = logger::new(verbose); - let versions = app.installable_versions(amount, log)?; - println!("{app_name} is available in these versions:"); + let app = apps.lookup(&args.app_name)?; + let log = logger::new(args.verbose); + let versions = app.installable_versions(args.amount, log)?; + println!("{} is available in these versions:", args.app_name); for version in versions { println!("- {version}"); } Ok(ExitCode::SUCCESS) } + +#[derive(Debug, PartialEq)] +pub struct Args { + pub app_name: AppName, + pub amount: usize, + pub verbose: bool, +} diff --git a/src/cmd/which.rs b/src/cmd/which.rs index 929b266f..95f1f493 100644 --- a/src/cmd/which.rs +++ b/src/cmd/which.rs @@ -4,13 +4,13 @@ use crate::prelude::*; use crate::{apps, logger, platform, yard}; use std::process::ExitCode; -pub fn which(app_name: &AppName, version: Option, verbose: bool) -> Result { +pub fn which(args: Args) -> Result { let apps = apps::all(); - let app = apps.lookup(app_name)?; - let log = logger::new(verbose); + let app = apps.lookup(&args.app_name)?; + let log = logger::new(args.verbose); let yard = yard::load_or_create(&yard::production_location()?)?; let platform = platform::detect(log)?; - let versions = RequestedVersions::determine(app_name, version, &apps)?; + let versions = RequestedVersions::determine(&args.app_name, args.version, &apps)?; for version in versions { if let Some(executable) = load_or_install(app, &version, platform, &yard, log)? { println!("{}", executable.0.to_string_lossy()); @@ -19,3 +19,10 @@ pub fn which(app_name: &AppName, version: Option, verbose: bool) -> Res } Ok(ExitCode::FAILURE) } + +#[derive(Debug, PartialEq)] +pub struct Args { + pub app_name: AppName, + pub version: Option, + pub verbose: bool, +} diff --git a/src/config/app_versions.rs b/src/config/app_versions.rs index 6cfbac9b..789361fb 100644 --- a/src/config/app_versions.rs +++ b/src/config/app_versions.rs @@ -2,6 +2,6 @@ use super::{AppName, RequestedVersions}; #[derive(Debug, PartialEq)] pub struct AppVersions { - pub app: AppName, + pub app_name: AppName, pub versions: RequestedVersions, } diff --git a/src/config/config.rs b/src/config/config.rs index b94e1719..bbdd2c6b 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -43,7 +43,11 @@ impl Config { } pub fn lookup(self, app_name: &AppName) -> Option { - self.apps.into_iter().find(|app| app.app == app_name).map(|app_version| app_version.versions) + self + .apps + .into_iter() + .find(|app| app.app_name == app_name) + .map(|app_version| app_version.versions) } pub fn save(&self) -> Result<()> { @@ -61,8 +65,8 @@ impl Config { impl Display for Config { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - for AppVersions { app, versions } in &self.apps { - f.write_str(app.as_str())?; + for AppVersions { app_name, versions } in &self.apps { + f.write_str(app_name.as_str())?; f.write_str(" ")?; f.write_str(&versions.join(", "))?; f.write_str("\n")?; @@ -100,7 +104,10 @@ fn parse_line(line_text: &str, line_no: usize, apps: &Apps) -> Result prelude::Result { match cli_args.command { Command::AppsLong => Ok(cmd::apps::long()), Command::AppsShort => Ok(cmd::apps::short()), - Command::Available { app, version, verbose } => cmd::available(&app, version, verbose), + Command::Available(args) => cmd::available(args), Command::RunApp(args) => cmd::run(args), Command::DisplayHelp => Ok(cmd::help()), Command::Setup => cmd::setup(), - Command::Test { app, verbose } => cmd::test(app, verbose), - Command::Which { app, version, verbose } => cmd::which(&app, version, verbose), - Command::Update { verbose } => cmd::update(verbose), + Command::Test(mut args) => cmd::test(&mut args), + Command::Which(args) => cmd::which(args), + Command::Update(args) => cmd::update(&args), Command::Version => Ok(cmd::version()), - Command::Versions { app, amount, verbose } => cmd::versions(&app, amount, verbose), + Command::Versions(args) => cmd::versions(&args), } }