diff --git a/mise.usage.kdl b/mise.usage.kdl index ed97c5aa0..fafa9f301 100644 --- a/mise.usage.kdl +++ b/mise.usage.kdl @@ -13,15 +13,15 @@ usage "Usage: mise [OPTIONS] " flag "-C --cd" help="Change directory before running command" global=true { arg "" } -flag "-P --profile" help="Set the profile (environment)" global=true { - arg "" -} flag "--debug" help="Sets log level to debug" hide=true global=true flag "--log-level" help="Set the log output verbosity" hide=true global=true { arg "" { choices "error" "warn" "info" "debug" "trace" } } +flag "-P --profile" help="Set the profile (environment)" global=true { + arg "" +} flag "-q --quiet" help="Suppress non-error messages" global=true flag "--trace" help="Sets log level to trace" hide=true global=true flag "-v --verbose" help="Show extra output (use -vv for even more)" var=true global=true count=true diff --git a/schema/mise.json b/schema/mise.json index a840a99a4..3966dc8e6 100644 --- a/schema/mise.json +++ b/schema/mise.json @@ -337,6 +337,10 @@ "description": "How long to wait before updating plugins automatically (note this isn't currently implemented).", "type": "string" }, + "profile": { + "description": "Profile to use for mise.${MISE_ENV}.toml files.", + "type": "string" + }, "python": { "additionalProperties": false, "properties": { diff --git a/settings.toml b/settings.toml index 65352fadb..dd7c93fa3 100644 --- a/settings.toml +++ b/settings.toml @@ -410,6 +410,12 @@ type = "String" default = "7d" description = "How long to wait before updating plugins automatically (note this isn't currently implemented)." +[profile] +env = "MISE_PROFILE" +type = "String" +description = "Profile to use for mise.${MISE_ENV}.toml files." +optional = true + [python.compile] env = "MISE_PYTHON_COMPILE" type = "Bool" diff --git a/src/cli/args/cd_arg.rs b/src/cli/args/cd_arg.rs index 1f80f38b4..73d336cfb 100644 --- a/src/cli/args/cd_arg.rs +++ b/src/cli/args/cd_arg.rs @@ -1,12 +1,15 @@ use std::path::PathBuf; use clap::{Arg, ArgAction}; +use once_cell::sync::Lazy; #[derive(Clone)] pub struct CdArg; +pub static CD_ARG: Lazy = Lazy::new(CdArg::arg); + impl CdArg { - pub fn arg() -> Arg { + fn arg() -> Arg { Arg::new("cd") .value_parser(clap::value_parser!(PathBuf)) .short('C') diff --git a/src/cli/args/log_level_arg.rs b/src/cli/args/log_level_arg.rs index b9bda9cf2..1360a73a8 100644 --- a/src/cli/args/log_level_arg.rs +++ b/src/cli/args/log_level_arg.rs @@ -1,10 +1,15 @@ use clap::{Arg, ArgAction}; +use once_cell::sync::Lazy; + +pub static LOG_LEVEL_ARG: Lazy = Lazy::new(LogLevelArg::arg); +pub static DEBUG_ARG: Lazy = Lazy::new(DebugArg::arg); +pub static TRACE_ARG: Lazy = Lazy::new(TraceArg::arg); #[derive(Clone)] pub struct LogLevelArg; impl LogLevelArg { - pub fn arg() -> clap::Arg { + fn arg() -> clap::Arg { Arg::new("log-level") .long("log-level") .value_name("LEVEL") @@ -18,7 +23,7 @@ impl LogLevelArg { pub struct DebugArg; impl DebugArg { - pub fn arg() -> clap::Arg { + fn arg() -> clap::Arg { Arg::new("debug") .long("debug") .help("Sets log level to debug") @@ -31,7 +36,7 @@ impl DebugArg { pub struct TraceArg; impl TraceArg { - pub fn arg() -> clap::Arg { + fn arg() -> clap::Arg { Arg::new("trace") .long("trace") .help("Sets log level to trace") diff --git a/src/cli/args/mod.rs b/src/cli/args/mod.rs index d248e431e..e53144fe9 100644 --- a/src/cli/args/mod.rs +++ b/src/cli/args/mod.rs @@ -1,12 +1,12 @@ pub use backend_arg::BackendArg; -pub use cd_arg::CdArg; +pub use cd_arg::CD_ARG; pub use env_var_arg::EnvVarArg; -pub use log_level_arg::{DebugArg, LogLevelArg, TraceArg}; -pub use profile_arg::ProfileArg; -pub use quiet_arg::QuietArg; +pub use log_level_arg::{DEBUG_ARG, LOG_LEVEL_ARG, TRACE_ARG}; +pub use profile_arg::PROFILE_ARG; +pub use quiet_arg::QUIET_ARG; pub use tool_arg::{ToolArg, ToolVersionType}; -pub use verbose_arg::VerboseArg; -pub use yes_arg::YesArg; +pub use verbose_arg::VERBOSE_ARG; +pub use yes_arg::YES_ARG; mod backend_arg; mod cd_arg; diff --git a/src/cli/args/profile_arg.rs b/src/cli/args/profile_arg.rs index 9c1d99b2e..39b754566 100644 --- a/src/cli/args/profile_arg.rs +++ b/src/cli/args/profile_arg.rs @@ -1,10 +1,13 @@ use clap::{Arg, ArgAction}; +use once_cell::sync::Lazy; #[derive(Clone, Debug)] pub struct ProfileArg; +pub static PROFILE_ARG: Lazy = Lazy::new(ProfileArg::arg); + impl ProfileArg { - pub fn arg() -> Arg { + fn arg() -> Arg { Arg::new("profile") .short('P') .long("profile") diff --git a/src/cli/args/quiet_arg.rs b/src/cli/args/quiet_arg.rs index 4e4b1aba4..90e1ca9b1 100644 --- a/src/cli/args/quiet_arg.rs +++ b/src/cli/args/quiet_arg.rs @@ -1,10 +1,13 @@ use clap::{Arg, ArgAction}; +use once_cell::sync::Lazy; #[derive(Clone)] pub struct QuietArg; +pub static QUIET_ARG: Lazy = Lazy::new(QuietArg::arg); + impl QuietArg { - pub fn arg() -> Arg { + fn arg() -> Arg { Arg::new("quiet") .short('q') .long("quiet") diff --git a/src/cli/args/verbose_arg.rs b/src/cli/args/verbose_arg.rs index 8efde3e53..54ddbec77 100644 --- a/src/cli/args/verbose_arg.rs +++ b/src/cli/args/verbose_arg.rs @@ -1,10 +1,13 @@ use clap::{Arg, ArgAction}; +use once_cell::sync::Lazy; #[derive(Clone)] pub struct VerboseArg; +pub static VERBOSE_ARG: Lazy = Lazy::new(VerboseArg::arg); + impl VerboseArg { - pub fn arg() -> clap::Arg { + fn arg() -> clap::Arg { Arg::new("verbose") .short('v') .long("verbose") diff --git a/src/cli/args/yes_arg.rs b/src/cli/args/yes_arg.rs index 56064c268..47ae0e763 100644 --- a/src/cli/args/yes_arg.rs +++ b/src/cli/args/yes_arg.rs @@ -1,9 +1,12 @@ use clap::{Arg, ArgAction}; +use once_cell::sync::Lazy; pub struct YesArg; +pub static YES_ARG: Lazy = Lazy::new(YesArg::arg); + impl YesArg { - pub fn arg() -> Arg { + fn arg() -> Arg { Arg::new("yes") .short('y') .long("yes") diff --git a/src/cli/ls.rs b/src/cli/ls.rs index fbbd7e2ae..4c2da8662 100644 --- a/src/cli/ls.rs +++ b/src/cli/ls.rs @@ -7,6 +7,7 @@ use console::style; use eyre::{ensure, Result}; use indexmap::IndexMap; use itertools::Itertools; +use rayon::prelude::*; use serde_derive::Serialize; use tabled::{Table, Tabled}; use versions::Versioning; @@ -161,15 +162,18 @@ impl Ls { // .into_iter() // .map(|(plugin, tv, source)| (plugin.to_string(), tv.to_string())) // .collect_vec(); - let rows = runtimes.into_iter().map(|(p, tv, source)| Row { - tool: p.clone(), - version: (p.as_ref(), &tv, &source).into(), - requested: match source.is_some() { - true => Some(tv.request.version()), - false => None, - }, - source, - }); + let rows = runtimes + .into_par_iter() + .map(|(p, tv, source)| Row { + tool: p.clone(), + version: (p.as_ref(), &tv, &source).into(), + requested: match source.is_some() { + true => Some(tv.request.version()), + false => None, + }, + source, + }) + .collect::>(); let mut table = Table::new(rows); table::default_style(&mut table, self.no_header); miseprintln!("{}", table.to_string()); diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 57d7befa6..996e0eb56 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,10 +1,10 @@ -use clap::{FromArgMatches, Subcommand}; -use color_eyre::Result; -use indoc::indoc; - use crate::config::Settings; use crate::ui::ctrlc; use crate::{eager, logger, migrate, shims}; +use clap::{FromArgMatches, Subcommand}; +use color_eyre::Result; +use indoc::indoc; +use once_cell::sync::Lazy; mod activate; mod alias; @@ -179,28 +179,28 @@ impl Commands { } } -impl Cli { - pub fn command() -> clap::Command { - Commands::augment_subcommands( - clap::Command::new("mise") - .version(version::VERSION.to_string()) - .about(env!("CARGO_PKG_DESCRIPTION")) - .author("Jeff Dickey <@jdx>") - .long_about(LONG_ABOUT) - .arg_required_else_help(true) - .subcommand_required(true) - .after_long_help(AFTER_LONG_HELP) - .arg(args::CdArg::arg()) - .arg(args::ProfileArg::arg()) - .arg(args::DebugArg::arg()) - .arg(args::LogLevelArg::arg()) - .arg(args::QuietArg::arg()) - .arg(args::TraceArg::arg()) - .arg(args::VerboseArg::arg()) - .arg(args::YesArg::arg()), - ) - } +pub static CLI: Lazy = Lazy::new(|| { + Commands::augment_subcommands( + clap::Command::new("mise") + .version(version::VERSION.to_string()) + .about(env!("CARGO_PKG_DESCRIPTION")) + .author("Jeff Dickey <@jdx>") + .long_about(LONG_ABOUT) + .arg_required_else_help(true) + .subcommand_required(true) + .after_long_help(AFTER_LONG_HELP) + .arg(args::CD_ARG.clone()) + .arg(args::DEBUG_ARG.clone()) + .arg(args::LOG_LEVEL_ARG.clone()) + .arg(args::PROFILE_ARG.clone()) + .arg(args::QUIET_ARG.clone()) + .arg(args::TRACE_ARG.clone()) + .arg(args::VERBOSE_ARG.clone()) + .arg(args::YES_ARG.clone()), + ) +}); +impl Cli { pub fn run(args: &Vec) -> Result<()> { crate::env::ARGS.write().unwrap().clone_from(args); time!("run init"); @@ -209,13 +209,11 @@ impl Cli { ctrlc::init()?; version::print_version_if_requested(args)?; - let matches = Self::command() - .try_get_matches_from(args) - .unwrap_or_else(|_| { - Self::command() - .subcommands(external::commands()) - .get_matches_from(args) - }); + let matches = CLI.clone().try_get_matches_from(args).unwrap_or_else(|_| { + CLI.clone() + .subcommands(external::commands()) + .get_matches_from(args) + }); time!("run get_matches_from"); Settings::add_cli_matches(&matches); time!("run add_cli_matches"); diff --git a/src/cli/render_help.rs b/src/cli/render_help.rs index 919139e54..82dd5f43e 100644 --- a/src/cli/render_help.rs +++ b/src/cli/render_help.rs @@ -2,7 +2,7 @@ use eyre::Result; use indoc::formatdoc; use itertools::Itertools; -use crate::cli::Cli; +use crate::cli::CLI; use crate::file; /// internal command to generate markdown from help @@ -34,7 +34,8 @@ fn render_command_ts() -> String { }}; "#}); doc.push_str("export const commands: { [key: string]: Command } = {\n"); - let mut cli = Cli::command() + let mut cli = CLI + .clone() .term_width(80) .max_term_width(80) .disable_help_subcommand(true) diff --git a/src/cli/render_mangen.rs b/src/cli/render_mangen.rs index f7aa4c60c..207cb00f7 100644 --- a/src/cli/render_mangen.rs +++ b/src/cli/render_mangen.rs @@ -4,7 +4,7 @@ use std::{env, fs}; use eyre::Result; use xx::file; -use crate::cli::{version, Cli}; +use crate::cli::{version, CLI}; /// internal command to generate markdown from help #[derive(Debug, clap::Args)] @@ -13,7 +13,8 @@ pub struct RenderMangen {} impl RenderMangen { pub fn run(self) -> Result<()> { - let cli = Cli::command() + let cli = CLI + .clone() .version(version::V.to_string()) .disable_colored_help(true); diff --git a/src/cli/run.rs b/src/cli/run.rs index d14045255..2de7d8948 100644 --- a/src/cli/run.rs +++ b/src/cli/run.rs @@ -7,7 +7,7 @@ use std::sync::Mutex; use std::time::SystemTime; use super::args::ToolArg; -use crate::cli::Cli; +use crate::cli::CLI; use crate::cmd::CmdLineRunner; use crate::config::{CONFIG, SETTINGS}; use crate::errors::Error; @@ -140,8 +140,7 @@ impl Run { } fn get_clap_command(&self) -> clap::Command { - Cli::command() - .get_subcommands() + CLI.get_subcommands() .find(|s| s.get_name() == "run") .unwrap() .clone() diff --git a/src/cli/usage.rs b/src/cli/usage.rs index f47ad6ab6..e694e5576 100644 --- a/src/cli/usage.rs +++ b/src/cli/usage.rs @@ -1,7 +1,7 @@ use clap::builder::Resettable; use eyre::Result; -use crate::cli; +use crate::cli::CLI; /// Generate a usage CLI spec /// @@ -12,7 +12,7 @@ pub struct Usage {} impl Usage { pub fn run(self) -> Result<()> { - let cli = cli::Cli::command().version(Resettable::Reset); + let cli = CLI.clone().version(Resettable::Reset); let mut spec: usage::Spec = cli.into(); let run = spec.cmd.subcommands.get_mut("run").unwrap(); run.args = vec![]; diff --git a/src/env.rs b/src/env.rs index 77314de40..d99315226 100644 --- a/src/env.rs +++ b/src/env.rs @@ -5,14 +5,13 @@ use std::string::ToString; use std::sync::RwLock; use std::{path, process}; -use itertools::Itertools; -use log::LevelFilter; -use once_cell::sync::Lazy; - -use crate::cli::args::ProfileArg; +use crate::cli::args::PROFILE_ARG; use crate::env_diff::{EnvDiff, EnvDiffOperation, EnvDiffPatches}; use crate::file::replace_path; use crate::hook_env::{deserialize_watches, HookEnvWatches}; +use itertools::Itertools; +use log::LevelFilter; +use once_cell::sync::Lazy; pub static ARGS: RwLock> = RwLock::new(vec![]); #[cfg(unix)] @@ -343,8 +342,8 @@ fn prefer_stale(args: &[String]) -> bool { } fn environment(args: &[String]) -> Option { - let long_arg = format!("--{}", ProfileArg::arg().get_long().unwrap_or_default()); - let short_arg = format!("-{}", ProfileArg::arg().get_short().unwrap_or_default()); + let long_arg = format!("--{}", PROFILE_ARG.get_long().unwrap_or_default()); + let short_arg = format!("-{}", PROFILE_ARG.get_short().unwrap_or_default()); args.windows(2) .find_map(|window| {