Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added selector for mise use with no args #3570

Merged
merged 1 commit into from
Dec 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ fn codegen_registry() {
os
})
.unwrap_or_default();
let description = info
.get("description")
.map(|d| d.as_str().unwrap().to_string());
let depends = info
.get("depends")
.map(|depends| {
Expand All @@ -102,7 +105,10 @@ fn codegen_registry() {
})
.unwrap_or_default();
let rt = format!(
r#"RegistryTool{{short: "{short}", backends: vec!["{backends}"], aliases: &[{aliases}], test: &{test}, os: &[{os}], depends: &[{depends}], idiomatic_files: &[{idiomatic_files}]}}"#,
r#"RegistryTool{{short: "{short}", description: {description}, backends: vec!["{backends}"], aliases: &[{aliases}], test: &{test}, os: &[{os}], depends: &[{depends}], idiomatic_files: &[{idiomatic_files}]}}"#,
description = description
.map(|d| format!("Some(\"{}\")", d))
.unwrap_or("None".to_string()),
backends = fulls.join("\", \""),
aliases = aliases
.iter()
Expand Down
6 changes: 6 additions & 0 deletions docs/cli/use.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ Consider using mise.lock as a better alternative to pinning in mise.toml:

Examples:

```

# run with no arguments to use the interactive selector
$ mise use
```

```
# set the current version of node to 20.x in mise.toml of current directory
# will write the fuzzy version (e.g.: 20)
Expand Down
3 changes: 3 additions & 0 deletions mise.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -1573,6 +1573,9 @@ In the following order:

Use the `--global` flag to use the global config file instead."#
after_long_help r"Examples:

# run with no arguments to use the interactive selector
$ mise use

# set the current version of node to 20.x in mise.toml of current directory
# will write the fuzzy version (e.g.: 20)
Expand Down
14 changes: 10 additions & 4 deletions src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::toolset::{InstallOptions, ToolsetBuilder};
use crate::ui::{ctrlc, prompt, style, time};
use crate::{dirs, env, exit, file, ui};
use clap::{CommandFactory, ValueHint};
use console::Term;
use crossbeam_channel::{select, unbounded};
use demand::{DemandOption, Select};
use duct::IntoExecutablePath;
Expand Down Expand Up @@ -865,10 +866,15 @@ fn prompt_for_task() -> Result<Task> {
s = s.option(DemandOption::new(&t.name).description(&t.description));
}
ctrlc::show_cursor_after_ctrl_c();
let name = s.run()?;
match tasks.get(name) {
Some(task) => Ok((*task).clone()),
None => bail!("no tasks {} found", style::ered(name)),
match s.run() {
Ok(name) => match tasks.get(name) {
Some(task) => Ok(task.clone()),
None => bail!("no tasks {} found", style::ered(name)),
},
Err(err) => {
Term::stderr().show_cursor()?;
Err(eyre!(err))
}
}
}

Expand Down
11 changes: 9 additions & 2 deletions src/cli/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use crate::toolset::{InstallOptions, ResolveOptions, ToolVersion, ToolsetBuilder
use crate::ui::multi_progress_report::MultiProgressReport;
use crate::ui::progress_report::SingleReport;
use crate::{config, ui};
use console::Term;
use demand::DemandOption;
use eyre::{Context, Result};
use eyre::{eyre, Context, Result};

/// Upgrades outdated tools
///
Expand Down Expand Up @@ -186,7 +187,13 @@ impl Upgrade {
for out in outdated {
ms = ms.option(DemandOption::new(out.clone()));
}
Ok(ms.run()?.into_iter().collect())
match ms.run() {
Ok(selected) => Ok(selected.into_iter().collect()),
Err(e) => {
Term::stderr().show_cursor()?;
Err(eyre!(e))
}
}
}
}

Expand Down
43 changes: 35 additions & 8 deletions src/cli/use.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::path::{Path, PathBuf};

use console::style;
use eyre::Result;
use console::{style, Term};
use eyre::{eyre, Result};
use itertools::Itertools;
use path_absolutize::Absolutize;

Expand All @@ -12,9 +12,11 @@ use crate::env::{
MISE_DEFAULT_CONFIG_FILENAME, MISE_DEFAULT_TOOL_VERSIONS_FILENAME, MISE_GLOBAL_CONFIG_FILE,
};
use crate::file::display_path;
use crate::registry::REGISTRY;
use crate::toolset::{
InstallOptions, ResolveOptions, ToolRequest, ToolSource, ToolVersion, ToolsetBuilder,
};
use crate::ui::ctrlc;
use crate::ui::multi_progress_report::MultiProgressReport;
use crate::{config, env, file};

Expand All @@ -41,11 +43,7 @@ pub struct Use {
/// Tool options can be set with this syntax:
///
/// mise use ubi:BurntSushi/ripgrep[exe=rg]
#[clap(
value_name = "TOOL@VERSION",
verbatim_doc_comment,
required_unless_present = "remove"
)]
#[clap(value_name = "TOOL@VERSION", verbatim_doc_comment)]
tool: Vec<ToolArg>,

/// Force reinstall even if already installed
Expand Down Expand Up @@ -99,7 +97,10 @@ pub struct Use {
}

impl Use {
pub fn run(self) -> Result<()> {
pub fn run(mut self) -> Result<()> {
if self.tool.is_empty() && self.remove.is_empty() {
self.tool = vec![self.tool_selector()?];
}
let config = Config::try_get()?;
let mut ts = ToolsetBuilder::new()
.with_global_only(self.global)
Expand Down Expand Up @@ -249,6 +250,29 @@ impl Use {
);
Ok(())
}

fn tool_selector(&self) -> Result<ToolArg> {
let mut s = demand::Select::new("Select a tool to install")
.description("Select a tasks to run")
.filtering(true)
.filterable(true);
for rt in REGISTRY.values() {
if let Some(backend) = rt.backends().first() {
// TODO: populate registry with descriptions from aqua and other sources
// TODO: use the backend from the lockfile if available
let description = rt.description.unwrap_or(backend);
s = s.option(demand::DemandOption::new(rt).description(description));
}
}
ctrlc::show_cursor_after_ctrl_c();
match s.run() {
Ok(rt) => rt.short.parse(),
Err(err) => {
Term::stderr().show_cursor()?;
Err(eyre!(err))
}
}
}
}

fn config_file_from_dir(p: &Path) -> PathBuf {
Expand All @@ -270,6 +294,9 @@ fn config_file_from_dir(p: &Path) -> PathBuf {

static AFTER_LONG_HELP: &str = color_print::cstr!(
r#"<bold><underline>Examples:</underline></bold>

# run with no arguments to use the interactive selector
$ <bold>mise use</bold>

# set the current version of node to 20.x in mise.toml of current directory
# will write the fuzzy version (e.g.: 20)
Expand Down
8 changes: 8 additions & 0 deletions src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::config::SETTINGS;
use once_cell::sync::Lazy;
use std::collections::{BTreeMap, HashMap, HashSet};
use std::env::consts::OS;
use std::fmt::Display;
use std::iter::Iterator;
use strum::IntoEnumIterator;
use url::Url;
Expand All @@ -15,6 +16,7 @@ pub static REGISTRY: Lazy<BTreeMap<&'static str, RegistryTool>> =
#[derive(Debug, Clone)]
pub struct RegistryTool {
pub short: &'static str,
pub description: Option<&'static str>,
pub backends: Vec<&'static str>,
#[allow(unused)]
pub aliases: &'static [&'static str],
Expand Down Expand Up @@ -114,3 +116,9 @@ fn url_like(s: &str) -> bool {
|| s.starts_with("ssh://")
|| s.starts_with("git://")
}

impl Display for RegistryTool {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.short)
}
}
Loading