Skip to content
Merged
5 changes: 3 additions & 2 deletions src/cli/alias/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ mod unset;

#[derive(Debug, clap::Args)]
#[clap(
about = "Manage version aliases.",
visible_alias = "a",
name = "tool-alias",
about = "Manage tool version aliases.",
alias = "alias",
alias = "aliases"
Comment on lines +15 to 16

Copilot AI Dec 17, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The backwards-compatible aliases should be marked as hidden to discourage their use in favor of the new tool-alias command name. Add hide = true to these alias attributes or use hidden_alias instead of alias.

Suggested change
alias = "alias",
alias = "aliases"
hidden_alias = "alias",
hidden_alias = "aliases"

Copilot uses AI. Check for mistakes.
)]
pub struct Alias {
Expand Down
4 changes: 2 additions & 2 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ pub struct Cli {
#[strum(serialize_all = "kebab-case")]
pub enum Commands {
Activate(activate::Activate),
Alias(Box<alias::Alias>),
ToolAlias(Box<alias::Alias>),
Asdf(asdf::Asdf),
Backends(backends::Backends),
BinPaths(bin_paths::BinPaths),
Expand Down Expand Up @@ -257,7 +257,7 @@ impl Commands {
pub async fn run(self) -> Result<()> {
match self {
Self::Activate(cmd) => cmd.run(),
Self::Alias(cmd) => cmd.run().await,
Self::ToolAlias(cmd) => cmd.run().await,
Self::Asdf(cmd) => cmd.run().await,
Self::Backends(cmd) => cmd.run().await,
Self::BinPaths(cmd) => cmd.run().await,
Expand Down
64 changes: 37 additions & 27 deletions src/config/config_file/mise_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl MiseToml {
self.doc_mut()?
.get_mut()
.unwrap()
.entry("alias")
.entry("tool_alias")
.or_insert_with(table)
.as_table_like_mut()
.unwrap()
Expand All @@ -218,15 +218,15 @@ impl MiseToml {
}

pub fn set_alias(&mut self, fa: &BackendArg, from: &str, to: &str) -> eyre::Result<()> {
self.alias
self.tool_alias
.entry(fa.short.to_string())
.or_default()
.versions
.insert(from.into(), to.into());
self.doc_mut()?
.get_mut()
.unwrap()
.entry("alias")
.entry("tool_alias")
.or_insert_with(table)
.as_table_like_mut()
.unwrap()
Expand All @@ -245,42 +245,52 @@ impl MiseToml {
pub fn remove_backend_alias(&mut self, fa: &BackendArg) -> eyre::Result<()> {
let mut doc = self.doc_mut()?;
let doc = doc.get_mut().unwrap();
if let Some(aliases) = doc.get_mut("alias").and_then(|v| v.as_table_mut()) {
aliases.remove(&fa.short);
if aliases.is_empty() {
doc.as_table_mut().remove("alias");
// Remove from both tool_alias and deprecated alias sections
for section in ["tool_alias", "alias"] {
if let Some(aliases) = doc.get_mut(section).and_then(|v| v.as_table_mut()) {
aliases.remove(&fa.short);
if aliases.is_empty() {
doc.as_table_mut().remove(section);
}
}
}
Ok(())
}

pub fn remove_alias(&mut self, fa: &BackendArg, from: &str) -> eyre::Result<()> {
if let Some(aliases) = self.alias.get_mut(&fa.short) {
aliases.versions.shift_remove(from);
if aliases.versions.is_empty() && aliases.backend.is_none() {
self.alias.shift_remove(&fa.short);
// Remove from both tool_alias and deprecated alias in memory
for alias_map in [&mut self.tool_alias, &mut self.alias] {
if let Some(aliases) = alias_map.get_mut(&fa.short) {
aliases.versions.shift_remove(from);
if aliases.versions.is_empty() && aliases.backend.is_none() {
alias_map.shift_remove(&fa.short);
}
}
}
let mut doc = self.doc_mut()?;
let doc = doc.get_mut().unwrap();
if let Some(aliases) = doc.get_mut("alias").and_then(|v| v.as_table_mut()) {
if let Some(alias) = aliases
.get_mut(&fa.to_string())
.and_then(|v| v.as_table_mut())
{
if let Some(versions) = alias.get_mut("versions").and_then(|v| v.as_table_mut()) {
versions.remove(from);
if versions.is_empty() {
alias.remove("versions");
// Remove from both tool_alias and deprecated alias sections in doc
for section in ["tool_alias", "alias"] {
if let Some(aliases) = doc.get_mut(section).and_then(|v| v.as_table_mut()) {
if let Some(alias) = aliases
.get_mut(&fa.to_string())
.and_then(|v| v.as_table_mut())
{
if let Some(versions) = alias.get_mut("versions").and_then(|v| v.as_table_mut())
{
versions.remove(from);
if versions.is_empty() {
alias.remove("versions");
}
}
if alias.is_empty() {
aliases.remove(&fa.to_string());
}
}
if alias.is_empty() {
aliases.remove(&fa.to_string());
if aliases.is_empty() {
doc.as_table_mut().remove(section);
}
}
if aliases.is_empty() {
doc.as_table_mut().remove("alias");
}
}
Ok(())
}
Expand Down Expand Up @@ -1957,7 +1967,7 @@ mod tests {
file::write(
&p,
formatdoc! {r#"
[alias.node.versions]
[tool_alias.node.versions]
16 = "16.0.0"
18 = "18.0.0"
"#},
Expand All @@ -1970,7 +1980,7 @@ mod tests {
cf.set_alias(&node, "20", "20.0.0").unwrap();
cf.set_alias(&python, "3.10", "3.10.0").unwrap();

assert_debug_snapshot!(cf.alias);
assert_debug_snapshot!(cf.tool_alias);
let cf: Box<dyn ConfigFile> = Box::new(cf);
assert_snapshot!(cf);
file::remove_file(&p).unwrap();
Expand Down
Loading