Skip to content

Commit

Permalink
fix: add hidden settings/task --complete option
Browse files Browse the repository at this point in the history
Fixes #3898
Fixes #3805
  • Loading branch information
jdx committed Jan 1, 2025
1 parent 13ed2e0 commit 636ca08
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 84 deletions.
40 changes: 25 additions & 15 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,7 @@ fn codegen_registry() {
fn codegen_settings() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("settings.rs");
let mut lines = vec![r#"
#[derive(Config, Default, Debug, Clone, Serialize)]
let mut lines = vec![r#"#[derive(Config, Default, Debug, Clone, Serialize)]
#[config(partial_attr(derive(Clone, Serialize, Default)))]
pub struct Settings {"#
.to_string()];
Expand Down Expand Up @@ -246,11 +245,11 @@ pub struct Settings {"#
.collect::<Vec<_>>();
for (child, props) in &nested_settings {
lines.push(format!(
r#"#[derive(Config, Default, Debug, Clone, Serialize)]
r#"
#[derive(Config, Default, Debug, Clone, Serialize)]
#[config(partial_attr(derive(Clone, Serialize, Default)))]
#[config(partial_attr(serde(deny_unknown_fields)))]
pub struct Settings{name} {{
"#,
pub struct Settings{name} {{"#,
name = child.to_upper_camel_case()
));

Expand All @@ -262,31 +261,42 @@ pub struct Settings{name} {{

lines.push(
r#"
pub static SETTINGS_META: Lazy<IndexMap<String, SettingsMeta>> = Lazy::new(|| {
indexmap!{
"#
.to_string(),
pub static SETTINGS_META: Lazy<IndexMap<&'static str, SettingsMeta>> = Lazy::new(|| {
indexmap!{"#
.to_string(),
);
for (name, props) in &settings {
let props = props.as_table().unwrap();
if let Some(type_) = props.get("type").map(|v| v.as_str().unwrap()) {
lines.push(format!(
r#" "{name}".to_string() => SettingsMeta {{
type_: SettingsType::{type_},
}},"#,
r#" "{name}" => SettingsMeta {{
type_: SettingsType::{type_},"#,
));
if let Some(description) = props.get("description") {
let description = description.as_str().unwrap().to_string();
lines.push(format!(
r####" description: r###"{description}"###,"####
));
}
lines.push(" },".to_string());
}
}
for (name, props) in &nested_settings {
for (key, props) in props.as_table().unwrap() {
let props = props.as_table().unwrap();
if let Some(type_) = props.get("type").map(|v| v.as_str().unwrap()) {
lines.push(format!(
r#" "{name}.{key}".to_string() => SettingsMeta {{
type_: SettingsType::{type_},
}},"#,
r#" "{name}.{key}" => SettingsMeta {{
type_: SettingsType::{type_},"#,
));
}
if let Some(description) = props.get("description") {
let description = description.as_str().unwrap().to_string();
lines.push(format!(
r####" description: r###"{description}"###,"####
));
}
lines.push(" },".to_string());
}
}
lines.push(
Expand Down
11 changes: 8 additions & 3 deletions docs/cli/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
- **Usage**: `mise settings [FLAGS] [SETTING] [VALUE] <SUBCOMMAND>`
- **Source code**: [`src/cli/settings.rs`](https://github.com/jdx/mise/blob/main/src/cli/settings.rs)

Manage settings
Show current settings

This is the contents of ~/.config/mise/config.toml

Note that aliases are also stored in this file
but managed separately with `mise aliases`

## Arguments

### `[SETTING]`

Setting name to get/set
List keys under this key

### `[VALUE]`

Expand All @@ -25,7 +30,7 @@ Use the local config file instead of the global one

### `-a --all`

List all settings
Display settings set to the default

### `-J --json`

Expand Down
6 changes: 3 additions & 3 deletions docs/dev-tools/comparison-to-asdf.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ mise use -g npm:prettier@3

## Other considerations

* [mise seems to be far more popular than asdf at least on homebrew](https://formulae.brew.sh/analytics/install-on-request/30d/)
* despite asdf having a 9-year lead—I believe I've put much more hours into mise than asdf developers have put into asdf. As a result, mise is pretty complete, you won't find issues/discussions with loads of +1's for mise like you will for [asdf](https://github.com/asdf-vm/asdf/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
* mise's stargazer count is growing more rapidly—it's likely only a few more months until it overtakes asdf in terms of total stars:
- [mise seems to be far more popular than asdf at least on homebrew](https://formulae.brew.sh/analytics/install-on-request/30d/)
- despite asdf having a 9-year lead—I believe I've put much more hours into mise than asdf developers have put into asdf. As a result, mise is pretty complete, you won't find issues/discussions with loads of +1's for mise like you will for [asdf](https://github.com/asdf-vm/asdf/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
- mise's stargazer count is growing more rapidly—it's likely only a few more months until it overtakes asdf in terms of total stars:

![star-history-202511 (1)](https://github.com/user-attachments/assets/3f3d2484-99fb-434e-931b-4291f2f96761)

Expand Down
22 changes: 15 additions & 7 deletions mise.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,12 @@ By default, this command modifies `mise.toml` in the current directory."
arg "[ENV_VARS]..." help="Environment variable(s) to set\ne.g.: NODE_ENV=production" required=false var=true
}
cmd "settings" help="Manage settings" {
long_help r"Show current settings

This is the contents of ~/.config/mise/config.toml

Note that aliases are also stored in this file
but managed separately with `mise aliases`"
after_long_help r#"Examples:
# list all settings
$ mise settings
Expand All @@ -1190,12 +1196,13 @@ cmd "settings" help="Manage settings" {
# set the value of the setting "node.mirror_url" to "https://npm.taobao.org/mirrors/node"
$ mise settings node.mirror_url https://npm.taobao.org/mirrors/node
"#
flag "-a --all" help="List all settings"
flag "-a --all" help="Display settings set to the default"
flag "--complete" help="Print all settings with descriptions for shell completions" hide=true
flag "-l --local" help="Use the local config file instead of the global one" global=true
flag "-J --json" help="Output in JSON format"
flag "--json-extended" help="Output in JSON format with sources"
flag "-T --toml" help="Output in TOML format"
arg "[SETTING]" help="Setting name to get/set" required=false
arg "[SETTING]" help="List keys under this key" required=false
arg "[VALUE]" help="Setting value to set" required=false
cmd "add" help="Adds a setting to the configuration file" {
long_help r"Adds a setting to the configuration file
Expand Down Expand Up @@ -1244,7 +1251,8 @@ but managed separately with `mise aliases`"
...
"#
flag "-a --all" help="Display settings set to the default"
flag "-l --local" help="Use the local config file instead of the global one"
flag "--complete" help="Print all settings with descriptions for shell completions" hide=true
flag "-l --local" help="Use the local config file instead of the global one" global=true
flag "-J --json" help="Output in JSON format"
flag "--json-extended" help="Output in JSON format with sources"
flag "-T --toml" help="Output in TOML format"
Expand Down Expand Up @@ -1353,6 +1361,7 @@ cmd "tasks" help="Manage tasks" {
$ mise tasks ls
"
flag "--no-header" help="Do not print table header" global=true
flag "--complete" help="Display tasks for usage completion" hide=true
flag "-x --extended" help="Show all columns" global=true
flag "--hidden" help="Show hidden tasks" global=true
flag "--sort" help="Sort by column. Default is name." global=true {
Expand Down Expand Up @@ -1484,6 +1493,7 @@ tasks will override the global ones if they have the same name."
$ mise tasks ls
"
flag "--no-header" help="Do not print table header" global=true
flag "--complete" help="Display tasks for usage completion" hide=true
flag "-x --extended" help="Show all columns" global=true
flag "--hidden" help="Show hidden tasks" global=true
flag "--sort" help="Sort by column. Default is name." global=true {
Expand Down Expand Up @@ -2058,10 +2068,8 @@ complete "config_file" type="file"
complete "new_plugin" run="mise plugins --all"
complete "plugin" run="mise plugins --core --user"
complete "prefix" run="mise ls-remote {{words[PREV]}}"
complete "setting" run="mise settings | awk '{print $1}'"
complete "task" run=r#"
mise tasks --json | jq -r '.[] | (.name | gsub(":"; "\\:")) + ":" + (.description | gsub(":"; "\\:"))'
"# descriptions=true
complete "setting" run="mise settings --complete" descriptions=true
complete "task" run="mise tasks ls --complete" descriptions=true

complete "tool@version" run=r#"
cur="{{words[CURRENT]}}"
Expand Down
6 changes: 2 additions & 4 deletions src/assets/mise-extra.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ complete "config_file" type="file"
complete "new_plugin" run="mise plugins --all"
complete "plugin" run="mise plugins --core --user"
complete "prefix" run="mise ls-remote {{words[PREV]}}"
complete "setting" run="mise settings | awk '{print $1}'"
complete "task" run=r#"
mise tasks --json | jq -r '.[] | (.name | gsub(":"; "\\:")) + ":" + (.description | gsub(":"; "\\:"))'
"# descriptions=true
complete "setting" run="mise settings --complete" descriptions=true
complete "task" run="mise tasks ls --complete" descriptions=true

complete "tool@version" run=r#"
cur="{{words[CURRENT]}}"
Expand Down
2 changes: 1 addition & 1 deletion src/cli/config/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl ConfigSet {
let expected_type = if !self.key.starts_with("settings.") {
None
} else {
SETTINGS_META.get(&(*last_key).to_string())
SETTINGS_META.get(*last_key)
};
match expected_type {
Some(meta) => match meta.type_ {
Expand Down
28 changes: 21 additions & 7 deletions src/cli/settings/ls.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::config;
use crate::config::settings::SettingsPartial;
use crate::config::settings::{SettingsPartial, SETTINGS_META};
use crate::config::{Settings, ALL_TOML_CONFIG_FILES, SETTINGS};
use crate::file::display_path;
use crate::ui::table;
Expand All @@ -14,34 +14,41 @@ use tabled::{Table, Tabled};
/// Note that aliases are also stored in this file
/// but managed separately with `mise aliases`
#[derive(Debug, clap::Args)]
#[clap(visible_alias = "list", after_long_help = AFTER_LONG_HELP, verbatim_doc_comment)]
#[clap(after_long_help = AFTER_LONG_HELP, verbatim_doc_comment)]
pub struct SettingsLs {
/// List keys under this key
pub setting: Option<String>,

/// Display settings set to the default
#[clap(long, short)]
pub all: bool,
all: bool,

/// Print all settings with descriptions for shell completions
#[clap(long, hide = true)]
complete: bool,

/// Use the local config file instead of the global one
#[clap(long, short)]
#[clap(long, short, global = true)]
pub local: bool,

/// Output in JSON format
#[clap(long, short = 'J', group = "output")]
pub json: bool,
json: bool,

/// Output in JSON format with sources
#[clap(long, group = "output")]
pub json_extended: bool,
json_extended: bool,

/// Output in TOML format
#[clap(long, short = 'T', group = "output")]
pub toml: bool,
toml: bool,
}

impl SettingsLs {
pub fn run(self) -> Result<()> {
if self.complete {
return self.complete();
}
let mut rows: Vec<Row> = if self.local {
let source = config::local_toml_config_path();
let partial = Settings::parse_settings_file(&source).unwrap_or_default();
Expand Down Expand Up @@ -90,6 +97,13 @@ impl SettingsLs {
Ok(())
}

fn complete(&self) -> Result<()> {
for (k, sm) in SETTINGS_META.iter() {
println!("{k}:{}", sm.description.replace(":", "\\:"));
}
Ok(())
}

fn print_json(&self, rows: Vec<Row>) -> Result<()> {
let mut table = serde_json::Map::new();
for row in rows {
Expand Down
45 changes: 9 additions & 36 deletions src/cli/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,19 @@ pub struct Settings {
#[clap(subcommand)]
command: Option<Commands>,

/// Setting name to get/set
#[clap(conflicts_with = "all")]
setting: Option<String>,
#[clap(flatten)]
ls: ls::SettingsLs,

/// Setting value to set
#[clap(conflicts_with = "all")]
value: Option<String>,

/// List all settings
#[clap(long, short)]
all: bool,

/// Use the local config file instead of the global one
#[clap(long, short, verbatim_doc_comment, global = true)]
local: bool,

/// Output in JSON format
#[clap(long, short = 'J', group = "output")]
pub json: bool,

/// Output in JSON format with sources
#[clap(long, group = "output")]
pub json_extended: bool,

/// Output in TOML format
#[clap(long, short = 'T', group = "output")]
pub toml: bool,
}

#[derive(Debug, Subcommand)]
enum Commands {
Add(add::SettingsAdd),
Get(get::SettingsGet),
#[clap(visible_alias = "list")]
Ls(ls::SettingsLs),
Set(set::SettingsSet),
Unset(unset::SettingsUnset),
Expand All @@ -68,32 +48,25 @@ impl Settings {
let cmd = self.command.unwrap_or_else(|| {
if let Some(value) = self.value {
Commands::Set(set::SettingsSet {
setting: self.setting.unwrap(),
setting: self.ls.setting.unwrap(),
value,
local: self.local,
local: self.ls.local,
})
} else if let Some(setting) = self.setting {
} else if let Some(setting) = self.ls.setting {
if let Some((setting, value)) = setting.split_once('=') {
Commands::Set(set::SettingsSet {
setting: setting.to_string(),
value: value.to_string(),
local: self.local,
local: self.ls.local,
})
} else {
Commands::Get(get::SettingsGet {
setting,
local: self.local,
local: self.ls.local,
})
}
} else {
Commands::Ls(ls::SettingsLs {
all: self.all,
setting: None,
local: self.local,
json: self.json,
json_extended: self.json_extended,
toml: self.toml,
})
Commands::Ls(self.ls)
}
});

Expand Down
Loading

0 comments on commit 636ca08

Please sign in to comment.