feat: `mise format` (#3461)

* feat: `mise format`

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
jdx 2024-12-10 19:53:29 -06:00 committed by GitHub
parent 507ee27a73
commit 6c28f1f752
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 258 additions and 10 deletions

148
Cargo.lock generated
View File

@ -34,6 +34,19 @@ dependencies = [
"cpufeatures",
]
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
@ -141,6 +154,12 @@ dependencies = [
"derive_arbitrary",
]
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "arrayvec"
version = "0.5.2"
@ -201,6 +220,12 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "beef"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
[[package]]
name = "binstall-tar"
version = "0.4.42"
@ -590,6 +615,12 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "countme"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
[[package]]
name = "cpufeatures"
version = "0.2.16"
@ -718,7 +749,7 @@ checksum = "eaa2c11e844048ceff84f99d2c85ebe2fd025fb89f21cf5378431c8e7458d71a"
dependencies = [
"console",
"fuzzy-matcher",
"itertools",
"itertools 0.13.0",
"once_cell",
"termcolor",
]
@ -1241,6 +1272,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.15.2"
@ -1684,6 +1721,15 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.13.0"
@ -1877,6 +1923,29 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "logos"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf8b031682c67a8e3d5446840f9573eb7fe26efe7ec8d195c9ac4c0647c502f1"
dependencies = [
"logos-derive",
]
[[package]]
name = "logos-derive"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d849148dbaf9661a6151d1ca82b13bb4c4c128146a88d05253b38d4e2f496c"
dependencies = [
"beef",
"fnv",
"proc-macro2",
"quote",
"regex-syntax 0.6.29",
"syn 1.0.109",
]
[[package]]
name = "lua-src"
version = "547.0.0"
@ -2057,7 +2126,7 @@ dependencies = [
"indicatif",
"indoc",
"insta",
"itertools",
"itertools 0.13.0",
"junction",
"log",
"md-5",
@ -2091,6 +2160,7 @@ dependencies = [
"strum",
"sys-info",
"tabled",
"taplo",
"tar",
"tempfile",
"tera",
@ -2126,7 +2196,7 @@ dependencies = [
"mlua_derive",
"num-traits",
"parking_lot",
"rustc-hash",
"rustc-hash 2.1.0",
"serde",
"serde-value",
]
@ -2150,7 +2220,7 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "870d71c172fcf491c6b5fb4c04160619a2ee3e5a42a1402269c66bcbf1dd4deb"
dependencies = [
"itertools",
"itertools 0.13.0",
"once_cell",
"proc-macro-error2",
"proc-macro2",
@ -2641,7 +2711,7 @@ dependencies = [
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustc-hash 2.1.0",
"rustls",
"socket2",
"thiserror 2.0.6",
@ -2659,7 +2729,7 @@ dependencies = [
"getrandom",
"rand",
"ring",
"rustc-hash",
"rustc-hash 2.1.0",
"rustls",
"rustls-pki-types",
"slab",
@ -2890,12 +2960,30 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3"
[[package]]
name = "rowan"
version = "0.15.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d"
dependencies = [
"countme",
"hashbrown 0.14.5",
"rustc-hash 1.1.0",
"text-size",
]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc-hash"
version = "2.1.0"
@ -3495,6 +3583,27 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "taplo"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "010941ac4171eaf12f1e26dfc11dadaf78619ea2330940fef01fe6bb0442d14d"
dependencies = [
"ahash",
"arc-swap",
"either",
"globset",
"itertools 0.10.5",
"logos",
"once_cell",
"rowan",
"serde",
"serde_json",
"thiserror 1.0.69",
"time",
"tracing",
]
[[package]]
name = "tar"
version = "0.4.43"
@ -3582,6 +3691,12 @@ dependencies = [
"syn 2.0.90",
]
[[package]]
name = "text-size"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
[[package]]
name = "thiserror"
version = "1.0.69"
@ -3639,6 +3754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
@ -3796,9 +3912,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.90",
]
[[package]]
name = "tracing-core"
version = "0.1.33"
@ -3876,7 +4004,7 @@ dependencies = [
"bzip2",
"document-features",
"flate2",
"itertools",
"itertools 0.13.0",
"lazy-regex",
"log",
"platforms",
@ -4011,7 +4139,7 @@ dependencies = [
"clap",
"heck 0.5.0",
"indexmap 2.7.0",
"itertools",
"itertools 0.13.0",
"kdl",
"log",
"miette",
@ -4068,7 +4196,7 @@ version = "6.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f25d498b63d1fdb376b4250f39ab3a5ee8d103957346abacd911e2d8b612c139"
dependencies = [
"itertools",
"itertools 0.13.0",
"nom",
"serde",
]
@ -4081,7 +4209,7 @@ checksum = "d4c44e4ec114bba1eeed55bc3a47ced72545cd2ffa04ce0ec0bdba1fb535807d"
dependencies = [
"homedir",
"indexmap 2.7.0",
"itertools",
"itertools 0.13.0",
"log",
"mlua",
"once_cell",

View File

@ -110,6 +110,7 @@ siphasher = "1"
strum = { version = "0.26", features = ["derive"] }
sys-info = "0.9"
tabled = { version = "0.17", features = ["ansi"] }
taplo = "0.13"
tar = "0.4"
tempfile = "3"
tera = "1"

View File

@ -105,6 +105,9 @@ export const commands: { [key: string]: Command } = {
exec: {
hide: false,
},
format: {
hide: false,
},
generate: {
hide: false,
subcommands: {

17
docs/cli/format.md Normal file
View File

@ -0,0 +1,17 @@
# `mise format`
- **Usage**: `mise format [-a --all]`
- **Aliases**: `fmt`
- **Source code**: [`src/cli/format.rs`](https://github.com/jdx/mise/blob/main/src/cli/format.rs)
Formats mise.toml
## Flags
### `-a --all`
Format all files from the current directory
Examples:
mise format

View File

@ -69,6 +69,7 @@ Answer yes to all confirmation prompts
- [`mise en [-s --shell <SHELL>] [DIR]`](/cli/en.md)
- [`mise env [FLAGS] [TOOL@VERSION]...`](/cli/env.md)
- [`mise exec [FLAGS] [TOOL@VERSION]... [COMMAND]...`](/cli/exec.md)
- [`mise format [-a --all]`](/cli/format.md)
- [`mise generate <SUBCOMMAND>`](/cli/generate.md)
- [`mise generate git-pre-commit [FLAGS]`](/cli/generate/git-pre-commit.md)
- [`mise generate github-action [FLAGS]`](/cli/generate/github-action.md)

View File

@ -89,6 +89,9 @@ Exports env vars to activate mise a single time
mise\-exec(1)
Execute a command with tool(s) set
.TP
mise\-format(1)
Formats mise.toml
.TP
mise\-generate(1)
[experimental] Generate files for various tools/services
.TP

View File

@ -424,6 +424,14 @@ The "--" separates runtimes from the commands to pass along to the subprocess."#
arg "[TOOL@VERSION]..." help="Tool(s) to start e.g.: node@20 python@3.10" var=true
arg "[COMMAND]..." help="Command string to execute (same as --command)" var=true
}
cmd "format" help="Formats mise.toml" {
alias "fmt"
after_long_help r"Examples:
$ mise format
"
flag "-a --all" help="Format all files from the current directory"
}
cmd "generate" subcommand_required=true help="[experimental] Generate files for various tools/services" {
alias "gen"
alias "g" hide=true

67
src/cli/format.rs Normal file
View File

@ -0,0 +1,67 @@
use crate::config::ALL_TOML_CONFIG_FILES;
use crate::{config, dirs, file};
use eyre::bail;
use taplo::formatter::Options;
/// Formats mise.toml
#[derive(Debug, clap::Args)]
#[clap(visible_alias="fmt", verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)]
pub struct Format {
/// Format all files from the current directory
#[clap(short, long)]
pub all: bool,
}
impl Format {
pub fn run(self) -> eyre::Result<()> {
let cwd = dirs::CWD.clone().unwrap_or_default();
let configs = if self.all {
ALL_TOML_CONFIG_FILES.clone()
} else {
config::config_files_in_dir(&cwd)
};
if configs.is_empty() {
bail!("No config file found in current directory");
}
for p in configs {
if !p.ends_with("toml") {
continue;
}
let toml = file::read_to_string(&p)?;
let toml = taplo::formatter::format(
&toml,
Options {
align_entries: false,
align_comments: true,
align_single_comments: true,
array_trailing_comma: true,
array_auto_expand: true,
inline_table_expand: true,
array_auto_collapse: true,
compact_arrays: true,
compact_inline_tables: false,
compact_entries: false,
column_width: 80,
indent_tables: false,
indent_entries: false,
indent_string: " ".to_string(),
trailing_newline: true,
reorder_keys: false,
reorder_arrays: false,
allowed_blank_lines: 2,
crlf: false,
},
);
file::write(&p, &toml)?;
}
Ok(())
}
}
static AFTER_LONG_HELP: &str = color_print::cstr!(
r#"<bold><underline>Examples:</underline></bold>
$ <bold>mise format</bold>
"#
);

View File

@ -24,6 +24,7 @@ mod en;
mod env;
pub mod exec;
mod external;
mod format;
mod generate;
mod global;
mod hook_env;
@ -167,6 +168,7 @@ pub enum Commands {
En(en::En),
Env(env::Env),
Exec(exec::Exec),
Format(format::Format),
Generate(generate::Generate),
Global(global::Global),
HookEnv(hook_env::HookEnv),
@ -228,6 +230,7 @@ impl Commands {
Self::En(cmd) => cmd.run(),
Self::Env(cmd) => cmd.run(),
Self::Exec(cmd) => cmd.run(),
Self::Format(cmd) => cmd.run(),
Self::Generate(cmd) => cmd.run(),
Self::Global(cmd) => cmd.run(),
Self::HookEnv(cmd) => cmd.run(),

View File

@ -992,6 +992,23 @@ const completionSpec: Fig.Spec = {
}
]
},
{
"name": [
"format",
"fmt"
],
"description": "Formats mise.toml",
"options": [
{
"name": [
"-a",
"--all"
],
"description": "Format all files from the current directory",
"isRepeatable": false
}
]
},
{
"name": [
"generate",