Skip to content

Commit

Permalink
feat: added .tool-versions -> mise.toml converter (#3693)
Browse files Browse the repository at this point in the history
Fixes #970
  • Loading branch information
jdx authored Dec 18, 2024
1 parent 127e164 commit 5311de5
Show file tree
Hide file tree
Showing 13 changed files with 166 additions and 19 deletions.
3 changes: 3 additions & 0 deletions docs/.vitepress/cli_commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ export const commands: { [key: string]: Command } = {
generate: {
hide: false,
subcommands: {
config: {
hide: false,
},
"git-pre-commit": {
hide: false,
},
Expand Down
2 changes: 1 addition & 1 deletion docs/cli/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Output in JSON format

## Subcommands

- [`mise config generate [-o --output <OUTPUT>]`](/cli/config/generate.md)
- [`mise config generate [-t --tool-versions <TOOL_VERSIONS>] [-o --output <OUTPUT>]`](/cli/config/generate.md)
- [`mise config get [-f --file <FILE>] [KEY]`](/cli/config/get.md)
- [`mise config ls [--no-header] [-J --json]`](/cli/config/ls.md)
- [`mise config set [-f --file <FILE>] [-t --type <TYPE>] <KEY> <VALUE>`](/cli/config/set.md)
6 changes: 5 additions & 1 deletion docs/cli/config/generate.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# `mise config generate`

- **Usage**: `mise config generate [-o --output <OUTPUT>]`
- **Usage**: `mise config generate [-t --tool-versions <TOOL_VERSIONS>] [-o --output <OUTPUT>]`
- **Aliases**: `g`
- **Source code**: [`src/cli/config/generate.rs`](https://github.com/jdx/mise/blob/main/src/cli/config/generate.rs)

[experimental] Generate a mise.toml file

## Flags

### `-t --tool-versions <TOOL_VERSIONS>`

Path to a .tool-versions file to import tools from

### `-o --output <OUTPUT>`

Output to file instead of stdout
Expand Down
1 change: 1 addition & 0 deletions docs/cli/generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

## Subcommands

- [`mise generate config [-t --tool-versions <TOOL_VERSIONS>] [-o --output <OUTPUT>]`](/cli/generate/config.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)
24 changes: 24 additions & 0 deletions docs/cli/generate/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# `mise generate config`

- **Usage**: `mise generate config [-t --tool-versions <TOOL_VERSIONS>] [-o --output <OUTPUT>]`
- **Aliases**: `g`
- **Source code**: [`src/cli/generate/config.rs`](https://github.com/jdx/mise/blob/main/src/cli/generate/config.rs)

[experimental] Generate a mise.toml file

## Flags

### `-t --tool-versions <TOOL_VERSIONS>`

Path to a .tool-versions file to import tools from

### `-o --output <OUTPUT>`

Output to file instead of stdout

Examples:

```
mise cf generate > mise.toml
mise cf generate --output=mise.toml
```
3 changes: 2 additions & 1 deletion docs/cli/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Can also use `MISE_NO_CONFIG=1`
- [`mise cache prune [--dry-run] [-v --verbose...] [PLUGIN]...`](/cli/cache/prune.md)
- [`mise completion [--include-bash-completion-lib] [SHELL]`](/cli/completion.md)
- [`mise config [--no-header] [-J --json] <SUBCOMMAND>`](/cli/config.md)
- [`mise config generate [-o --output <OUTPUT>]`](/cli/config/generate.md)
- [`mise config generate [-t --tool-versions <TOOL_VERSIONS>] [-o --output <OUTPUT>]`](/cli/config/generate.md)
- [`mise config get [-f --file <FILE>] [KEY]`](/cli/config/get.md)
- [`mise config ls [--no-header] [-J --json]`](/cli/config/ls.md)
- [`mise config set [-f --file <FILE>] [-t --type <TYPE>] <KEY> <VALUE>`](/cli/config/set.md)
Expand All @@ -84,6 +84,7 @@ Can also use `MISE_NO_CONFIG=1`
- [`mise exec [FLAGS] [TOOL@VERSION]... [-- COMMAND]...`](/cli/exec.md)
- [`mise fmt [-a --all]`](/cli/fmt.md)
- [`mise generate <SUBCOMMAND>`](/cli/generate.md)
- [`mise generate config [-t --tool-versions <TOOL_VERSIONS>] [-o --output <OUTPUT>]`](/cli/generate/config.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)
Expand Down
10 changes: 10 additions & 0 deletions e2e/generate/test_generate_config
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

cat <<EOF >.tool-versions
node 22
python 3.9 3.10 3.11
EOF

assert "mise generate config --tool-versions .tool-versions" '[tools]
node = "22"
python = ["3.9", "3.10", "3.11"]'
17 changes: 17 additions & 0 deletions mise.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ cmd "config" help="Manage config files" {
$ mise cf generate > mise.toml
$ mise cf generate --output=mise.toml
"
flag "-t --tool-versions" help="Path to a .tool-versions file to import tools from" {
arg "<TOOL_VERSIONS>"
}
flag "-o --output" help="Output to file instead of stdout" {
arg "<OUTPUT>"
}
Expand Down Expand Up @@ -467,6 +470,20 @@ Sorts keys and cleans up whitespace in mise.toml"
cmd "generate" subcommand_required=true help="[experimental] Generate files for various tools/services" {
alias "gen"
alias "g" hide=true
cmd "config" help="[experimental] Generate a mise.toml file" {
alias "g"
after_long_help r"Examples:

$ mise cf generate > mise.toml
$ mise cf generate --output=mise.toml
"
flag "-t --tool-versions" help="Path to a .tool-versions file to import tools from" {
arg "<TOOL_VERSIONS>"
}
flag "-o --output" help="Output to file instead of stdout" {
arg "<OUTPUT>"
}
}
cmd "git-pre-commit" help="[experimental] Generate a git pre-commit hook" {
alias "pre-commit"
long_help r"[experimental] Generate a git pre-commit hook
Expand Down
50 changes: 35 additions & 15 deletions src/cli/config/generate.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,54 @@
use std::path::PathBuf;
use std::path::{Path, PathBuf};

use clap::ValueHint;
use eyre::Result;

use crate::config::Settings;
use crate::config::{config_file, SETTINGS};
use crate::file;
use crate::file::display_path;

/// [experimental] Generate a mise.toml file
#[derive(Debug, clap::Args)]
#[clap(visible_alias = "g", verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)]
pub struct ConfigGenerate {
/// Path to a .tool-versions file to import tools from
#[clap(long, short, verbatim_doc_comment, value_hint = ValueHint::FilePath)]
tool_versions: Option<PathBuf>,
/// Output to file instead of stdout
#[clap(long, short, verbatim_doc_comment, value_hint = ValueHint::FilePath)]
output: Option<PathBuf>,
}

impl ConfigGenerate {
pub fn run(self) -> Result<()> {
let settings = Settings::try_get()?;
settings.ensure_experimental("`mise config generate`")?;
let doc = r#"
SETTINGS.ensure_experimental("`mise config generate`")?;
let doc = if let Some(tool_versions) = &self.tool_versions {
self.tool_versions(tool_versions)?
} else {
self.default()
};
if let Some(output) = &self.output {
info!("writing to {}", display_path(output));
file::write(output, doc)?;
} else {
miseprintln!("{doc}");
}

Ok(())
}

fn tool_versions(&self, tool_versions: &Path) -> Result<String> {
let mut to = config_file::parse_or_init(&PathBuf::from("mise.toml"))?;
let from = config_file::parse(tool_versions)?;
let tools = from.to_tool_request_set()?.tools;
for (ba, tools) in tools {
to.replace_versions(&ba, tools)?;
}
to.dump()
}

fn default(&self) -> String {
r#"
# # mise config files are hierarchical. mise will find all of the config files
# # in all parent directories and merge them together.
# # You might have a structure like:
Expand Down Expand Up @@ -71,20 +99,12 @@ impl ConfigGenerate {
# # setup a custom alias so you can run `mise use -g node@work` for node-16.x
# work = '16'
"#
.trim();
if let Some(output) = &self.output {
info!("writing to {}", display_path(output));
file::write(output, doc)?;
} else {
miseprintln!("{doc}");
}

Ok(())
.to_string()
}
}

// TODO: fill this out
static AFTER_LONG_HELP: &str = color_print::cstr!(
pub static AFTER_LONG_HELP: &str = color_print::cstr!(
r#"<bold><underline>Examples:</underline></bold>
$ <bold>mise cf generate > mise.toml</bold>
Expand Down
2 changes: 1 addition & 1 deletion src/cli/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clap::Subcommand;
use eyre::Result;
mod generate;
pub(crate) mod generate;
mod get;
mod ls;
mod set;
Expand Down
16 changes: 16 additions & 0 deletions src/cli/generate/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use crate::cli::config::generate;
use crate::Result;

/// [experimental] Generate a mise.toml file
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, after_long_help = generate::AFTER_LONG_HELP)]
pub struct Config {
#[clap(flatten)]
generate: generate::ConfigGenerate,
}

impl Config {
pub fn run(self) -> Result<()> {
self.generate.run()
}
}
3 changes: 3 additions & 0 deletions src/cli/generate/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use clap::Subcommand;

mod config;
mod git_pre_commit;
mod github_action;
mod task_docs;
Expand All @@ -14,6 +15,7 @@ pub struct Generate {

#[derive(Debug, Subcommand)]
enum Commands {
Config(config::Config),
GitPreCommit(git_pre_commit::GitPreCommit),
GithubAction(github_action::GithubAction),
TaskDocs(task_docs::TaskDocs),
Expand All @@ -22,6 +24,7 @@ enum Commands {
impl Commands {
pub fn run(self) -> eyre::Result<()> {
match self {
Self::Config(cmd) => cmd.run(),
Self::GitPreCommit(cmd) => cmd.run(),
Self::GithubAction(cmd) => cmd.run(),
Self::TaskDocs(cmd) => cmd.run(),
Expand Down
48 changes: 48 additions & 0 deletions xtasks/fig/src/mise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,19 @@ const completionSpec: Fig.Spec = {
],
"description": "[experimental] Generate a mise.toml file",
"options": [
{
"name": [
"-t",
"--tool-versions"
],
"description": "Path to a .tool-versions file to import tools from",
"isRepeatable": false,
"args": {
"name": "tool_versions",
"isOptional": false,
"isVariadic": false
}
},
{
"name": [
"-o",
Expand Down Expand Up @@ -1038,6 +1051,41 @@ const completionSpec: Fig.Spec = {
],
"description": "[experimental] Generate files for various tools/services",
"subcommands": [
{
"name": [
"config",
"g"
],
"description": "[experimental] Generate a mise.toml file",
"options": [
{
"name": [
"-t",
"--tool-versions"
],
"description": "Path to a .tool-versions file to import tools from",
"isRepeatable": false,
"args": {
"name": "tool_versions",
"isOptional": false,
"isVariadic": false
}
},
{
"name": [
"-o",
"--output"
],
"description": "Output to file instead of stdout",
"isRepeatable": false,
"args": {
"name": "output",
"isOptional": false,
"isVariadic": false
}
}
]
},
{
"name": [
"git-pre-commit",
Expand Down

0 comments on commit 5311de5

Please sign in to comment.