Skip to content
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
7 changes: 6 additions & 1 deletion docs/cli/edit.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- @generated by usage-cli from usage spec -->
# `mise edit`

- **Usage**: `mise edit [-n --dry-run] [-t --tool-versions <TOOL_VERSIONS>] [PATH]`
- **Usage**: `mise edit [FLAGS] [PATH]`
- **Source code**: [`src/cli/edit.rs`](https://github.com/jdx/mise/blob/main/src/cli/edit.rs)

Edit mise.toml interactively
Expand All @@ -14,6 +14,10 @@ Path to the config file to create

## Flags

### `-g --global`

Edit the global config file (~/.config/mise/config.toml)

### `-n --dry-run`

Show what would be generated without writing to file
Expand All @@ -27,6 +31,7 @@ Examples:
```
mise edit # edit mise.toml interactively
mise edit .mise.toml # edit a specific file
mise edit -g # edit the global config file
mise edit -y # skip interactive editor
mise edit -n # preview without writing
```
2 changes: 1 addition & 1 deletion docs/cli/generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Generate files for various tools/services
## Subcommands

- [`mise generate bootstrap [FLAGS]`](/cli/generate/bootstrap.md)
- [`mise generate config [-n --dry-run] [-t --tool-versions <TOOL_VERSIONS>] [PATH]`](/cli/generate/config.md)
- [`mise generate config [FLAGS] [PATH]`](/cli/generate/config.md)
- [`mise generate devcontainer [FLAGS]`](/cli/generate/devcontainer.md)
- [`mise generate git-pre-commit [FLAGS]`](/cli/generate/git-pre-commit.md)
- [`mise generate github-action [FLAGS]`](/cli/generate/github-action.md)
Expand Down
15 changes: 10 additions & 5 deletions docs/cli/generate/config.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- @generated by usage-cli from usage spec -->
# `mise generate config`

- **Usage**: `mise generate config [-n --dry-run] [-t --tool-versions <TOOL_VERSIONS>] [PATH]`
- **Usage**: `mise generate config [FLAGS] [PATH]`
- **Source code**: [`src/cli/generate/config.rs`](https://github.com/jdx/mise/blob/main/src/cli/generate/config.rs)

Generate a mise.toml file
Expand All @@ -14,6 +14,10 @@ Path to the config file to create

## Flags

### `-g --global`

Generate the global config file (~/.config/mise/config.toml)

### `-n --dry-run`

Show what would be generated without writing to file
Expand All @@ -25,8 +29,9 @@ Path to a .tool-versions file to import tools from
Examples:

```
mise edit # edit mise.toml interactively
mise edit .mise.toml # edit a specific file
mise edit -y # skip interactive editor
mise edit -n # preview without writing
mise generate config # generate mise.toml interactively
mise generate config .mise.toml # generate a specific file
mise generate config -g # generate the global config file
mise generate config -y # skip interactive editor
mise generate config -n # preview without writing
```
4 changes: 2 additions & 2 deletions docs/cli/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ Can also use `MISE_NO_HOOKS=1`
- [`mise fmt [FLAGS]`](/cli/fmt.md)
- [`mise generate <SUBCOMMAND>`](/cli/generate.md)
- [`mise generate bootstrap [FLAGS]`](/cli/generate/bootstrap.md)
- [`mise generate config [-n --dry-run] [-t --tool-versions <TOOL_VERSIONS>] [PATH]`](/cli/generate/config.md)
- [`mise generate config [FLAGS] [PATH]`](/cli/generate/config.md)
- [`mise generate devcontainer [FLAGS]`](/cli/generate/devcontainer.md)
- [`mise generate git-pre-commit [FLAGS]`](/cli/generate/git-pre-commit.md)
- [`mise generate github-action [FLAGS]`](/cli/generate/github-action.md)
- [`mise generate task-docs [FLAGS]`](/cli/generate/task-docs.md)
- [`mise generate task-stubs [-d --dir <DIR>] [-m --mise-bin <MISE_BIN>]`](/cli/generate/task-stubs.md)
- [`mise generate tool-stub [FLAGS] <OUTPUT>`](/cli/generate/tool-stub.md)
- [`mise implode [-n --dry-run] [--config]`](/cli/implode.md)
- [`mise edit [-n --dry-run] [-t --tool-versions <TOOL_VERSIONS>] [PATH]`](/cli/edit.md)
- [`mise edit [FLAGS] [PATH]`](/cli/edit.md)
- [`mise install [FLAGS] [TOOL@VERSION]…`](/cli/install.md)
- [`mise install-into <TOOL@VERSION> <PATH>`](/cli/install-into.md)
- [`mise latest [-i --installed] [--before <BEFORE>] <TOOL@VERSION>`](/cli/latest.md)
Expand Down
29 changes: 29 additions & 0 deletions e2e/cli/test_edit_global
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash

# `mise edit --global` writes to the global config file path.

export MISE_GLOBAL_CONFIG_FILE="$PWD/global-config.toml"

assert_contains "mise edit --global --dry-run 2>&1" "global-config.toml"
assert_contains "mise edit -g -n 2>&1" "global-config.toml"

# A positional path overrides --global regardless of argument order.
assert_contains "mise edit --global custom.toml --dry-run 2>&1" "custom.toml"
assert_not_contains "mise edit --global custom.toml --dry-run 2>&1" "global-config.toml"
assert_contains "mise edit custom.toml --global --dry-run 2>&1" "custom.toml"
assert_not_contains "mise edit custom.toml --global --dry-run 2>&1" "global-config.toml"

# Without --global, the default config filename is used (regression guard).
assert_contains "mise edit --dry-run 2>&1" "mise.toml"
assert_not_contains "mise edit --dry-run 2>&1" "global-config.toml"

# --tool-versions merges into the resolved target file, not the local mise.toml.
cat >preexisting.toml <<EOF
[tools]
go = "1.22"
EOF
cat >.tool-versions <<EOF
node 22
EOF
assert_contains "mise edit preexisting.toml --tool-versions .tool-versions --dry-run 2>&1" 'go = "1.22"'
assert_contains "mise edit preexisting.toml --tool-versions .tool-versions --dry-run 2>&1" 'node = "22"'
6 changes: 6 additions & 0 deletions man/man1/mise.1
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,9 @@ Generate a mise.toml file
\fBOptions:\fR
.PP
.TP
\fB\-g, \-\-global\fR
Generate the global config file (~/.config/mise/config.toml)
.TP
\fB\-n, \-\-dry\-run\fR
Show what would be generated without writing to file
.TP
Expand Down Expand Up @@ -1281,6 +1284,9 @@ Edit mise.toml interactively
\fBOptions:\fR
.PP
.TP
\fB\-g, \-\-global\fR
Edit the global config file (~/.config/mise/config.toml)
.TP
\fB\-n, \-\-dry\-run\fR
Show what would be generated without writing to file
.TP
Expand Down
6 changes: 4 additions & 2 deletions mise.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ cmd generate subcommand_required=#true help="Generate files for various tools/se
}
}
cmd config help="Generate a mise.toml file" {
after_long_help "Examples:\n\n $ mise edit # edit mise.toml interactively\n $ mise edit .mise.toml # edit a specific file\n $ mise edit -y # skip interactive editor\n $ mise edit -n # preview without writing\n"
after_long_help "Examples:\n\n $ mise generate config # generate mise.toml interactively\n $ mise generate config .mise.toml # generate a specific file\n $ mise generate config -g # generate the global config file\n $ mise generate config -y # skip interactive editor\n $ mise generate config -n # preview without writing\n"
flag "-g --global" help="Generate the global config file (~/.config/mise/config.toml)"
flag "-n --dry-run" help="Show what would be generated without writing to file"
flag "-t --tool-versions" help="Path to a .tool-versions file to import tools from" {
arg <TOOL_VERSIONS>
Expand Down Expand Up @@ -482,7 +483,8 @@ cmd implode help="Removes mise CLI and all related data" {
flag --config help="Also remove config directory"
}
cmd edit help="Edit mise.toml interactively" {
after_long_help "Examples:\n\n $ mise edit # edit mise.toml interactively\n $ mise edit .mise.toml # edit a specific file\n $ mise edit -y # skip interactive editor\n $ mise edit -n # preview without writing\n"
after_long_help "Examples:\n\n $ mise edit # edit mise.toml interactively\n $ mise edit .mise.toml # edit a specific file\n $ mise edit -g # edit the global config file\n $ mise edit -y # skip interactive editor\n $ mise edit -n # preview without writing\n"
flag "-g --global" help="Edit the global config file (~/.config/mise/config.toml)"
flag "-n --dry-run" help="Show what would be generated without writing to file"
flag "-t --tool-versions" help="Path to a .tool-versions file to import tools from" {
arg <TOOL_VERSIONS>
Expand Down
40 changes: 30 additions & 10 deletions src/cli/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::backend::backend_type::BackendType;
use crate::cli::args::BackendArg;
use crate::cli::version::VERSION_PLAIN;
use crate::config::config_file;
use crate::config::{Config, Settings};
use crate::config::{Config, Settings, global_config_path};
use crate::file::display_path;
use crate::plugins::PluginType;
use crate::registry::REGISTRY;
Expand Down Expand Up @@ -122,6 +122,9 @@ impl BackendProvider for MiseBackendProvider {
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)]
pub struct Edit {
/// Edit the global config file (~/.config/mise/config.toml)
#[clap(long, short = 'g')]
global: bool,
/// Show what would be generated without writing to file
#[clap(long, short = 'n')]
dry_run: bool,
Expand All @@ -143,15 +146,32 @@ struct DetectedTool {
}

impl Edit {
pub(crate) fn new(
global: bool,
dry_run: bool,
path: Option<PathBuf>,
tool_versions: Option<PathBuf>,
) -> Self {
Self {
global,
dry_run,
path,
tool_versions,
}
}

pub async fn run(self) -> Result<()> {
let path = self
.path
.clone()
.unwrap_or_else(|| PathBuf::from(&*env::MISE_DEFAULT_CONFIG_FILENAME));
let path = if let Some(path) = self.path.clone() {
path
} else if self.global {
global_config_path()
} else {
PathBuf::from(&*env::MISE_DEFAULT_CONFIG_FILENAME)
};
Comment on lines +164 to +170

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The path resolution logic can be simplified by avoiding the clone() on self.path, as self is consumed by the run method.

Note: The path variable determined here should also be passed to self.tool_versions() (at line 160, though not visible in this diff hunk) to ensure that tool versions are imported into the correct file when using --global or an explicit path. Currently, tool_versions() (at line 259) hardcodes the target path to mise.toml, which would cause incorrect behavior when targeting the global config (it would read the local config, merge versions, and then write that result to the global path).

Suggested change
let path = if let Some(path) = self.path.clone() {
path
} else if self.global {
global_config_path()
} else {
PathBuf::from(&*env::MISE_DEFAULT_CONFIG_FILENAME)
};
let path = self.path.unwrap_or_else(|| {
if self.global {
global_config_path()
} else {
PathBuf::from(&*env::MISE_DEFAULT_CONFIG_FILENAME)
}
});


if let Some(tool_versions) = &self.tool_versions {
// Import from .tool-versions file
let doc = self.tool_versions(tool_versions).await?;
let doc = self.tool_versions(tool_versions, &path).await?;

if self.dry_run {
info!("would write to {}", display_path(&path));
Expand Down Expand Up @@ -250,9 +270,8 @@ impl Edit {
Ok(())
}

async fn tool_versions(&self, tool_versions: &Path) -> Result<String> {
let to =
config_file::parse_or_init(&PathBuf::from(&*env::MISE_DEFAULT_CONFIG_FILENAME)).await?;
async fn tool_versions(&self, tool_versions: &Path, path: &Path) -> Result<String> {
let to = config_file::parse_or_init(path).await?;
let from = config_file::parse(tool_versions).await?;
let tools = from.to_tool_request_set()?.tools;
for (ba, tools) in tools {
Expand Down Expand Up @@ -364,11 +383,12 @@ fn extract_version(tool: &str, path: &Path) -> Option<String> {
}
}

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

$ <bold>mise edit</bold> <dim># edit mise.toml interactively</dim>
$ <bold>mise edit .mise.toml</bold> <dim># edit a specific file</dim>
$ <bold>mise edit -g</bold> <dim># edit the global config file</dim>
$ <bold>mise edit -y</bold> <dim># skip interactive editor</dim>
$ <bold>mise edit -n</bold> <dim># preview without writing</dim>
"#
Expand Down
37 changes: 32 additions & 5 deletions src/cli/generate/config.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,43 @@
use std::path::PathBuf;

use clap::ValueHint;

use crate::Result;
use crate::cli::edit;
use crate::cli::edit::Edit;

/// Generate a mise.toml file
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, after_long_help = edit::AFTER_LONG_HELP)]
#[clap(verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)]
pub struct Config {
#[clap(flatten)]
edit: edit::Edit,
/// Generate the global config file (~/.config/mise/config.toml)
#[clap(long, short = 'g')]
global: bool,
/// Show what would be generated without writing to file
#[clap(long, short = 'n')]
dry_run: bool,
/// Path to the config file to create
#[clap(verbatim_doc_comment, value_hint = ValueHint::FilePath)]
path: Option<PathBuf>,
/// Path to a .tool-versions file to import tools from
#[clap(long, short, verbatim_doc_comment, value_hint = ValueHint::FilePath)]
tool_versions: Option<PathBuf>,
}

impl Config {
pub async fn run(self) -> Result<()> {
self.edit.run().await
Edit::new(self.global, self.dry_run, self.path, self.tool_versions)
.run()
.await
}
}

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

$ <bold>mise generate config</bold> <dim># generate mise.toml interactively</dim>
$ <bold>mise generate config .mise.toml</bold> <dim># generate a specific file</dim>
$ <bold>mise generate config -g</bold> <dim># generate the global config file</dim>
$ <bold>mise generate config -y</bold> <dim># skip interactive editor</dim>
$ <bold>mise generate config -n</bold> <dim># preview without writing</dim>
"#
);
12 changes: 12 additions & 0 deletions xtasks/fig/src/mise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,12 @@ const completionSpec: Fig.Spec = {
name: "config",
description: "Generate a mise.toml file",
options: [
{
name: ["-g", "--global"],
description:
"Generate the global config file (~/.config/mise/config.toml)",
isRepeatable: false,
},
{
name: ["-n", "--dry-run"],
description:
Expand Down Expand Up @@ -1455,6 +1461,12 @@ const completionSpec: Fig.Spec = {
name: "edit",
description: "Edit mise.toml interactively",
options: [
{
name: ["-g", "--global"],
description:
"Edit the global config file (~/.config/mise/config.toml)",
isRepeatable: false,
},
{
name: ["-n", "--dry-run"],
description: "Show what would be generated without writing to file",
Expand Down
Loading