diff options
author | Canop <cano.petrole@gmail.com> | 2022-06-15 07:47:48 +0200 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2022-06-15 07:47:48 +0200 |
commit | 282fbc584554bc7db4d06e603cd05961ee2f060f (patch) | |
tree | aee4509c5dc976cfbb48b52232a2a7ff538f9820 | |
parent | 37201de6954d751451d010b8a97977c6da76d08f (diff) |
use clap derive for arguments
-rw-r--r-- | CHANGELOG.md | 6 | ||||
-rw-r--r-- | Cargo.lock | 55 | ||||
-rw-r--r-- | Cargo.toml | 6 | ||||
-rw-r--r-- | build.rs | 7 | ||||
-rw-r--r-- | resources/default-conf.hjson | 15 | ||||
-rw-r--r-- | src/app/app.rs | 9 | ||||
-rw-r--r-- | src/app/app_context.rs | 80 | ||||
-rw-r--r-- | src/cli/app_launch_args.rs | 22 | ||||
-rw-r--r-- | src/cli/args.rs | 200 | ||||
-rw-r--r-- | src/cli/clap_args.rs | 235 | ||||
-rw-r--r-- | src/cli/install_launch_args.rs | 19 | ||||
-rw-r--r-- | src/cli/mod.rs | 110 | ||||
-rw-r--r-- | src/print.rs | 83 | ||||
-rw-r--r-- | src/shell_install/mod.rs | 82 | ||||
-rw-r--r-- | src/tree/tree_options.rs | 55 | ||||
-rw-r--r-- | src/verb/external_execution.rs | 11 |
16 files changed, 455 insertions, 540 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a5517f..70ba8a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ -### next +### v1.13.2 - ??? +<a name="v1.13.2"></a> - advice to hit alt-i and|or alt-h when no file is visible - Fix #556 -- update many dependencies - examples on search modes in help screen - Fix #559 +- list of syntactic themes in default conf +- the --file-export-path launch argument which was deprecated since broot 1.6 has been removed (redirect the output of broot instead) ### v1.13.1 - 2022-05-30 <a name="v1.13.1"></a> @@ -255,14 +255,16 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.18" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" +checksum = "a836566fa5f52f7ddf909a8a2f9029b9f78ca584cd95cf7e87f8073110f4c5c9" dependencies = [ "atty", "bitflags", + "clap_derive", "clap_lex", "indexmap", + "lazy_static", "strsim", "termcolor", "textwrap", @@ -270,18 +272,31 @@ dependencies = [ [[package]] name = "clap_complete" -version = "3.1.4" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da92e6facd8d73c22745a5d3cbb59bdf8e46e3235c923e516527d8e81eec14a4" +checksum = "0f6ebaab5f25e4f0312dfa07cb30a755204b96e6531457c2cfdecfdf5f2adf40" dependencies = [ "clap", ] [[package]] +name = "clap_derive" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986fd75d1dfd2c34eb8c9275ae38ad87ea9478c9b79e87f1801f7d866dfb1e37" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "clap_lex" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" dependencies = [ "os_str_bytes", ] @@ -645,9 +660,9 @@ dependencies = [ [[package]] name = "flume" -version = "0.10.12" +version = "0.10.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a" +checksum = "1ceeb589a3157cac0ab8cc585feb749bd2cea5cb55a6ee802ad72d9fd38303da" dependencies = [ "futures-core", "futures-sink", @@ -1371,6 +1386,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] name = "proc-macro-hack" version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -26,7 +26,7 @@ base64 = "0.13" bet = "1.0" char_reader = "0.1" chrono = "0.4" -clap = "3.1" +clap = { version = "3.2.1", features = ["derive"] } cli-log = "2.0" crokey = "0.4.1" crossbeam = "0.8" @@ -74,8 +74,8 @@ users = "0.11" is_executable = "1.0.1" [build-dependencies] -clap = "3.1" -clap_complete = "3.1" +clap = { version = "3.2.1", features = ["derive"] } +clap_complete = "3.2.1" [profile.dev] debug = false @@ -2,6 +2,7 @@ // It builds shell completion scripts. use { + clap::CommandFactory, clap_complete::{Generator, Shell}, std::{ env, @@ -9,14 +10,14 @@ use { }, }; -include!("src/cli/clap_args.rs"); +include!("src/cli/args.rs"); fn write_completions_file<G: Generator + Copy, P: AsRef<OsStr>>(generator: G, out_dir: P) { - let mut app = clap_app(); + let mut args = Args::command(); for name in &["broot", "br"] { clap_complete::generate_to( generator, - &mut app, + &mut args, name.to_string(), &out_dir, ).expect("clap complete generation failed"); diff --git a/resources/default-conf.hjson b/resources/default-conf.hjson index dc5bb6f..33fe8ed 100644 --- a/resources/default-conf.hjson +++ b/resources/default-conf.hjson @@ -356,4 +356,19 @@ # Change this if you sometimes want to have more than 2 panels # open # max_panels_count: 2 + + + ############################################################### + # Syntax Theme + # + # If you want to choose the them used for preview, uncomment + # one of the following lines: + # + # syntax_theme: base16-ocean.light + # syntax_theme: base16-ocean.dark + # syntax_theme: base16-mocha.dark + # syntax_theme: base16-mocha.light + # syntax_theme: InspiredGitHub + # syntax_theme: "Solarized (dark)" + # syntax_theme: "Solarized (light)" } diff --git a/src/app/app.rs b/src/app/app.rs index 73bbc6d..7f75c11 100644 --- a/src/app/app.rs +++ b/src/app/app.rs @@ -2,6 +2,7 @@ use { super::*, crate::{ browser::BrowserState, + cli::TriBool, command::{Command, Sequence}, conf::Conf, display::{Areas, Screen, W}, @@ -80,8 +81,8 @@ impl App { PanelId::from(0), Box::new( BrowserState::new( - con.launch_args.root.clone(), - con.launch_args.tree_options.clone(), + con.initial_root.clone(), + con.initial_tree_options.clone(), screen, con, &Dam::unlimited(), @@ -663,10 +664,10 @@ impl App { let event_source = EventSource::new()?; let rx_events = event_source.receiver(); let mut dam = Dam::from(rx_events); - let skin = AppSkin::new(conf, con.launch_args.color == Some(false)); + let skin = AppSkin::new(conf, con.launch_args.color == TriBool::No); let mut app_state = AppState { stage: Stage::default(), - root: con.launch_args.root.clone(), + root: con.initial_root.clone(), other_panel_path: None, }; diff --git a/src/app/app_context.rs b/src/app/app_context.rs index 518bafa..d3424e3 100644 --- a/src/app/app_context.rs +++ b/src/app/app_context.rs @@ -1,19 +1,21 @@ use { super::*, crate::{ - cli::AppLaunchArgs, + cli::{Args, TriBool}, conf::Conf, - errors::ConfError, + errors::*, file_sum, icon::*, pattern::SearchModeMap, path::SpecialPath, skin::ExtColorMap, + tree::TreeOptions, verb::VerbStore, }, std::{ convert::{TryFrom, TryInto}, - path::PathBuf, + io, + path::{Path, PathBuf}, }, }; @@ -22,12 +24,18 @@ use { /// life of the App pub struct AppContext { + /// The initial tree root + pub initial_root: PathBuf, + + /// Initial tree options + pub initial_tree_options: TreeOptions, + /// where's the config file we're using /// This vec can't be empty pub config_paths: Vec<PathBuf>, /// all the arguments specified at launch - pub launch_args: AppLaunchArgs, + pub launch_args: Args, /// the verbs in use (builtins and configured ones) pub verb_store: VerbStore, @@ -82,10 +90,10 @@ pub struct AppContext { impl AppContext { pub fn from( - launch_args: AppLaunchArgs, + launch_args: Args, verb_store: VerbStore, config: &Conf, - ) -> Result<Self, ConfError> { + ) -> Result<Self, ProgramError> { let config_paths = config.files.clone(); let standard_status = StandardStatus::new(&verb_store); let true_colors = if let Some(value) = config.true_colors { @@ -105,11 +113,12 @@ impl AppContext { .map(|map| map.try_into()) .transpose()? .unwrap_or_default(); - let ext_colors = ExtColorMap::try_from(&config.ext_colors)?; + let ext_colors = ExtColorMap::try_from(&config.ext_colors) + .map_err(ConfError::from)?; let file_sum_threads_count = config.file_sum_threads_count .unwrap_or(file_sum::DEFAULT_THREAD_COUNT); if file_sum_threads_count < 1 || file_sum_threads_count > 50 { - return Err(ConfError::InvalidThreadsCount{ count: file_sum_threads_count }); + return Err(ConfError::InvalidThreadsCount{ count: file_sum_threads_count }.into()); } let max_panels_count = config.max_panels_count .unwrap_or(2) @@ -122,7 +131,21 @@ impl AppContext { let max_staged_count = config.max_staged_count .unwrap_or(10_000) .clamp(10, 100_000); + let initial_root = get_root_path(&launch_args)?; + + // tree options are built from the default_flags + // found in the config file(s) (if any) then overriden + // by the cli args + let mut initial_tree_options = TreeOptions::default(); + initial_tree_options.apply_config(config)?; + initial_tree_options.apply_launch_args(&launch_args); + if launch_args.color == TriBool::No { + initial_tree_options.show_selection_mark = true; + } + Ok(Self { + initial_root, + initial_tree_options, config_paths, launch_args, verb_store, @@ -165,3 +188,44 @@ fn are_true_colors_available() -> bool { true } } + +fn get_root_path(cli_args: &Args) -> Result<PathBuf, ProgramError> { + let mut root = cli_args + .root + .as_ref() + .map_or(std::env::current_dir()?, PathBuf::from); + if !root.exists() { + return Err(TreeBuildError::FileNotFound { + path: format!("{:?}", &root), + }.into()); + } + if !root.is_dir() { + // we try to open the parent directory if the passed file isn't one + if let Some(parent) = root.parent() { + info!("Passed path isn't a directory => opening parent instead"); + root = parent.to_path_buf(); + } else { + // let's give up + return Err(TreeBuildError::NotADirectory { + path: format!("{:?}", &root), + }.into()); + } + } + Ok(canonicalize_root(&root)?) +} + +#[cfg(not(windows))] +fn canonicalize_root(root: &Path) -> io::Result<PathBuf> { + root.canonicalize() +} + +#[cfg(windows)] +fn canonicalize_root(root: &Path) -> io::Result<PathBuf> { + Ok(if root.is_relative() { + env::current_dir()?.join(root) + } else { + root.to_path_buf() + }) +} + + diff --git a/src/cli/app_launch_args.rs b/src/cli/app_launch_args.rs deleted file mode 100644 index 03b25ae..0000000 --- a/src/cli/app_launch_args.rs +++ /dev/null @@ -1,22 +0,0 @@ -use { - crate::{ - tree::TreeOptions, - }, - std::{ - path::PathBuf, - }, -}; - - -/// the parsed program launch arguments which are kept for the -/// life of the program -pub struct AppLaunchArgs { - pub root: PathBuf, // what should be the initial root - pub file_export_path: Option<String>, // where to write the produced path (if required with --out) - deprecated - pub cmd_export_path: Option<String>, // where to write the produced command (if required with --outcmd) - pub tree_options: TreeOptions, // initial tree options - pub commands: Option<String>, // commands passed as cli argument, still unparsed - pub height: Option<u16>, // an optional height to replace the screen's one - pub color: Option<bool>, // whether to display colors and styles - pub listen: Option<String>, // if some, broot will start in serve mode on this socket -} diff --git a/src/cli/args.rs b/src/cli/args.rs new file mode 100644 index 0000000..9ad810e --- /dev/null +++ b/src/cli/args.rs @@ -0,0 +1,200 @@ +use { + std::{ + path::PathBuf, + str::FromStr, + }, +}; + +#[derive(Debug, clap::Parser)] +/// A tree explorer and a customizable launcher +/// +/// Complete documentation lives at https://dystroy.org/broot" +#[clap(author, version, about)] +pub struct Args { + + /// Show the last modified date of files and directories" + #[clap(short, long, action)] + pub dates: bool, + + /// Don't show the last modified date" + #[clap(short='D', long, action)] + pub no_dates: bool, + + #[clap(short='f', long, action)] + /// Only show folders + pub only_folders: bool, + + /// Show folders and files alike + #[clap(short='F', long, action)] + pub no_only_folders: bool, + + /// Show filesystem info on top + #[clap(long, action)] + pub show_root_fs: bool, + + /// Show git statuses on files and stats on repo + #[clap(short='g', long, action)] + pub show_git_info: bool, + + /// Don't show git statuses on files and stats on repo + #[clap(short='G', long, action)] + pub no_show_git_info: bool, + + #[clap(long, action)] + /// Only show files having an interesting git status, including hidden ones + pub git_status: bool, + + #[clap(short='h', long, action)] + /// Show hidden files + pub hidden: bool, + + #[clap(short='H', long, action)] + /// Don't show hidden files + pub no_hidden: bool, + + #[clap(short='i', long, action)] + /// Show git ignored files + pub git_ignored: bool, + + #[clap(short='I', long, action)] + /// Don't show git ignored files + pub no_git_ignored: bool, + + #[clap(short='p', long, action)] + /// Show permissions + pub permissions: bool, + + #[clap(short='P', long, action)] + /// Don't show permissions + pub no_permissions: bool, + + #[clap(short='s', long, action)] + /// Show the size of files and directories + pub sizes: bool, + + #[clap(short='S', long, action)] + /// Don't show sizes + pub no_sizes: bool, + + #[clap(long, action)] + /// Sort by count (only show one level of the tree) + pub sort_by_count: bool, + + #[clap(long, action)] + /// Sort by date (only show one level of the tree) + pub sort_by_date: bool, + + #[clap(long, action)] + /// Sort by size (only show one level of the tree) + pub sort_by_size: bool, + + /// Sort by size, show ignored and hidden files + #[clap(short, long, action)] + pub whale_spotting: bool, + + /// Don't sort + #[clap(long, action)] + pub no_sort: bool, + + /// Trim the root too and don't show a scrollbar + #[clap(short='t', long, action)] + pub trim_root: bool, + + /// Don't trim the root level, show a scrollbar + #[clap(short='T', long, action)] + pub no_trim_root: bool, + + /// Where to write the produced cmd (if any) + #[clap(long, value_parser)] + pub cmd_export_path: Option<PathBuf>, + + /// Semicolon separated commands to execute + #[clap(short, long, value_parser)] + pub commands: Option<String>, + + /// Whether to have styles and colors (auto is default and usually OK) + #[clap(long, arg_enum, value_parser, default_value="auto")] + pub color: TriBool, + + /// Semicolon separated paths to specific config files"), + #[clap(long, value_parser)] + pub conf: Option<String>, + + /// Height (if you don't want to fill the screen or for file export) + #[clap(long, value_parser)] + pub height: Option<u16>, + + /// Install or reinstall the br shell function + #[clap(long, action)] + pub install: bool, + + /// Where to write the produced cmd (if any) + #[clap(long, value_parser)] + pub set_install_state: Option<ShellInstallState>, + + /// Print to stdout the br function for a given shell + #[clap(long, value_parser)] + pub print_shell_function: Option<String>, + + /// A socket to listen to for commands + #[cfg(unix)] + #[clap(long, value_parser)] + pub listen: Option<String>, + + /// Ask for the current root of the remote broot + #[cfg(unix)] + #[clap(long, action)] + pub get_root: bool, + + /// A socket that broot sends commands to before quitting + #[cfg(unix)] + #[clap(long, value_parser)] + pub send: Option<String>, + + /// Root Directory + #[clap(value_parser, value_name="FILE")] + pub root: Option<PathBuf>, +} + +/// This is an Option<bool> but I didn't find any way to configure +/// clap to parse an Option<T> as I want +#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ArgEnum)] +pub enum TriBool { + Auto, + Yes, + No, +} +impl TriBool { + pub fn unwrap_or_else<F>(self, f: F) -> bool + where + F: FnOnce() -> bool + { + match self { + Self::Auto => f(), + Self::Yes => true, + Self::No => false, + } + } +} + +#[derive(Debug, Clone, Copy, clap::ValueEnum)] +pub enum ShellInstallState { + Undefined, // before any install, this is the initial state + Refused, + Installed, +} +impl FromStr for ShellInstallState { + type Err = String; + fn from_str(state: &str) -> Result<Self, Self::Err> { + match state { + "undefined" => Ok(Self::Undefined), + "refused" => Ok(Self::Refused), + "installed" => Ok(Self::Installed), + _ => Err( + // not supposed to happen because claps check the values + format!("unexpected install state: {:?}", state) + ), + } + } +} + diff --git a/src/cli/clap_args.rs b/src/cli/clap_args.rs deleted file mode 100644 index 0ac9524..0000000 --- a/src/cli/clap_args.rs +++ /dev/null @@ -1,235 +0,0 @@ -/// this module generate the clap App, which defines -/// launch arguments - -/// Declare the possible CLI arguments -pub fn clap_app() -> clap::Command<'static> { - let app = clap::Command::new("broot") - .version(env!("CARGO_PKG_VERSION")) - .author("dystroy <denys.seguret@gmail.com>") - .about( - "A tree explorer and a customizable launcher\n\ - Complete documentation lives at https://dystroy.org/broot" - ) - .arg(clap::Arg::new("ROOT").help("sets the root directory")) - // tree flags - .arg( - clap::Arg::new("dates") - .short('d') - .long("dates") - .help("Show the last modified date of files and directories"), - ) - .arg( - clap::Arg::new("no-dates") - .short('D') - .long("no-dates") - .help("Don't show last modified date"), - ) - .arg( - clap::Arg::new("only-folders") - .short('f') - .long("only-folders") - .help("Only show folders"), - ) - .arg( - clap::Arg::new("no-only-folders") - .short('F') - .long("no-only-folders") - .help("Show folders and files alike"), - ) - .arg( - clap::Arg::new("show-root-fs") - .long("show-root-fs") - .help("Show filesystem info on top"), - ) - .arg( - clap::Arg::new("show-git-info") - .short('g') - .long("show-git-info") - .help("Show git statuses on files and stats on repo"), - ) - .arg( - clap::Arg::new("no-show-git-info") - .short('G') - .long("no-show-git-info") - .help("Don't show git statuses on files"), - ) - .arg( - clap::Arg::new("git-status") - .long("git-status") - .help("Only show files having an interesting git status, including hidden ones"), - ) - .arg( - clap::Arg::new("hidden") - .short('h') - .long("hidden") - .help("Show hidden files"), - ) - .arg( - clap::Arg::new("no-hidden") - .short('H') - .long("no-hidden") - .help("Don't show hidden files"), - ) - .arg( - clap::Arg::new("show-gitignored") - .short('i') - .long("show-gitignored") - .help("Show files which should be ignored according to git"), - ) - .arg( - clap::Arg::new("no-show-gitignored") - .short('I') - .long("no-show-gitignored") - .help("Don't show gitignored files"), - ) - .arg( - clap::Arg::new("permissions") - .short('p') - .long("permissions") - .help("Show permissions, with owner and group"), - ) - .arg( - clap::Arg::new("no-permissions") - .short('P') - .long("no-permissions") - .help("Don't show permissions"), - ) - .arg( - clap::Arg::new("sizes") - .short('s') - .long("sizes") - .help("Show the size of files and directories"), - ) - .arg( - clap::Arg::new("no-sizes") - .short('S') - .long("no-sizes") - .help("Don't show sizes"), - ) - .arg( - clap::Arg::new("sort-by-count") - .long("sort-by-count") - .help("Sort by count (only show one level of the tree)"), - ) - .arg( - clap::Arg::new("sort-by-date") - .long("sort-by-date") - .help("Sort by date (only show one level of the tree)"), - ) - .arg( - clap::Arg::new("sort-by-size") - .long("sort-by-size") - .help("Sort by size (only show one level of the tree)"), - ) - .arg( - clap::Arg::new("whale-spotting") - .short('w') - .long("whale-spotting") - .help("Sort by size, show ignored and hidden files"), - ) - .arg( - clap::Arg::new("no-sort") - .long("no-sort") - .help("Don't sort"), - ) - .arg( - clap::Arg::new("trim-root") - .short('t') - .long("trim-root") - .help("Trim the root too and don't show a scrollbar"), - ) - .arg( - clap::Arg::new("no-trim-root") - .short('T') - .long("no-trim-root") - .help("Don't trim the root level, show a scrollbar"), - ) - // other options - .arg( - clap::Arg::new("cmd-export-path") - .long("outcmd") - .takes_value(true) - .help("Where to write the produced cmd (if any)"), - ) - .arg( - clap::Arg::new("commands") - .short('c') - .long("cmd") - .takes_value(true) - .help("Semicolon separated commands to execute"), - ) - .arg( - clap::Arg::new("color") - .long("color") - .takes_value(true) - .possible_values(&["yes", "no", "auto"]) - .default_value("auto") - .help("Whether to have styles and colors (auto is default and usually OK)"), - ) - .arg( - clap::Arg::new("conf") - .long("conf") - .takes_value(true) - .help("Semicolon separated paths to specific config files"), - ) - .arg( - clap::Arg::new("height") - .long("height") - .help("Height (if you don't want to fill the screen or for file export)") - .takes_value(true), - ) - .arg( - clap::Arg::new("file-export-path") // deprecated since broot 1.6 - .short('o') - .long("out") - .takes_value(true) - .hide(true) - .help("Where to write the produced path (if any)"), - ) - .arg( - clap::Arg::new("install") - .long("install") - .help("Install or reinstall the br shell function"), - ) - .arg( - clap::Arg::new("set-install-state") - .long("set-install-state") - .takes_value(true) - .value_name("state") - .possible_values(&["undefined", "refused", "installed"]) - .help("Set the installation state (for use in install script)"), - ) - .arg( - clap::Arg::new("print-shell-function") - .long("print-shell-function") - .takes_value(true) - .value_name("shell") - .help("Print to stdout the br function for a given shell"), - ) - .setting(clap::AppSettings::DeriveDisplayOrder); - #[cfg(unix)] - let app = app - .arg( - clap::Arg::new("listen") - .long("listen") - .takes_value(true) - .help("Listen for commands") - ) - .arg( - clap::Arg::new("get-root") - .long("get-root") - .help("Ask for the current root of the remote broot") - ) - .arg( - clap::Arg::new("send") - .long("send") - .takes_value(true) - .help("send commands to a remote broot then quits") - ); - app -} - -#[test] -fn verify_app() { - clap_app().debug_assert(); -} diff --git a/src/cli/install_launch_args.rs b/src/cli/install_launch_args.rs index c688e12..e5b1d01 100644 --- a/src/cli/install_launch_args.rs +++ b/src/cli/install_launch_args.rs @@ -3,12 +3,10 @@ use { crate::{ errors::ProgramError, - shell_install::ShellInstallState, + cli::{Args, ShellInstallState}, }, - clap::{self, ArgMatches}, std::{ env, - str::FromStr, }, }; @@ -21,7 +19,7 @@ pub struct InstallLaunchArgs { pub print_shell_function: Option<String>, // shell function to print on stdout } impl InstallLaunchArgs { - pub fn from(cli_args: &ArgMatches) -> Result<Self, ProgramError> { + pub fn from(args: &Args) -> Result<Self, ProgramError> { let mut install = None; if let Ok(s) = env::var("BR_INSTALL") { if s == "yes" { @@ -33,18 +31,13 @@ impl InstallLaunchArgs { } } // the cli arguments may override the env var value - if cli_args.is_present("install") { + if args.install { install = Some(true); - } else if cli_args.value_of("cmd-export-path").is_some() { + } else if args.cmd_export_path.is_some() { install = Some(false); } - let print_shell_function = cli_args - .value_of("print-shell-function") - .map(str::to_string); - let set_install_state = cli_args - .value_of("set-install-state") - .map(ShellInstallState::from_str) - .transpose()?; + let print_shell_function = args.print_shell_function.clone(); + let set_install_state = args.set_install_state; Ok(Self { install, set_install_state, diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 29c5152..310a7ed 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,12 +1,13 @@ //! this module manages reading and translating //! the arguments passed on launch of the application. -pub mod clap_args; -mod app_launch_args; +//mod app_launch_args; +mod args; mod install_launch_args; pub use { - app_launch_args::*, + //app_launch_args::*, + args::*, install_launch_args::*, }; @@ -15,13 +16,12 @@ use { app::{App, AppContext}, conf::Conf, display, - errors::{ProgramError, TreeBuildError}, + errors::ProgramError, launchable::Launchable, - shell_install::ShellInstall, - tree::TreeOptions, + shell_install::{ShellInstall, write_state}, verb::VerbStore, }, - clap::{self, ArgMatches}, + clap::Parser, crossterm::{ self, cursor, @@ -30,65 +30,25 @@ use { QueueableCommand, }, std::{ - env, io::{self, Write}, - path::{Path, PathBuf}, + path::PathBuf, }, }; -#[cfg(not(windows))] -fn canonicalize_root(root: &Path) -> io::Result<PathBuf> { - root.canonicalize() -} - -#[cfg(windows)] -fn canonicalize_root(root: &Path) -> io::Result<PathBuf> { - Ok(if root.is_relative() { - env::current_dir()?.join(root) - } else { - root.to_path_buf() - }) -} - -fn get_root_path(cli_args: &ArgMatches) -> Result<PathBuf, ProgramError> { - let mut root = cli_args - .value_of("ROOT") - .map_or(env::current_dir()?, PathBuf::from); - if !root.exists() { - return Err(TreeBuildError::FileNotFound { - path: format!("{:?}", &root), - }.into()); - } - if !root.is_dir() { - // we try to open the parent directory if the passed file isn't one - if let Some(parent) = root.parent() { - info!("Passed path isn't a directory => opening paren |