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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ eyre = "0.6"
heck = "0.5"
indexmap = "2"
phf_codegen = "0.14"
semver = "1"
serde = "1"
serde_yaml = "0.9"
toml = "1"
Expand Down
17 changes: 17 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ fn codegen_registry(aqua_packages: &[RegistryPackageRow]) {
r##"RegistryBackend{{
full: r#"{backend}"#,
platforms: &[],
min_version: None,
options: &[],
}}"##
));
Expand All @@ -215,11 +216,27 @@ fn codegen_registry(aqua_packages: &[RegistryPackageRow]) {
.collect::<Vec<_>>()
})
.unwrap_or_default();
let min_version = backend
.get("min_version")
.map(|value| {
let value = value
.as_str()
.expect("backend min_version must be a string");
assert_eq!(
version_order, "VersionOrder::Semver",
"[{short}] backend min_version requires version_order = semver"
);
semver::Version::parse(value)
.expect("backend min_version must be a semantic version");
format!("Some({})", raw_string_literal(value))
})
.unwrap_or_else(|| "None".to_string());
let backend_options = parse_options(backend.get("options"));
backends.push(format!(
r##"RegistryBackend{{
full: r#"{full}"#,
platforms: &[{platforms}],
min_version: {min_version},
options: &[{options}],
}}"##,
platforms = platforms
Expand Down
3 changes: 3 additions & 0 deletions docs/cli/test-tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

Test that a tool installs and runs

Includes newly published releases by disabling the global minimum release age
for this command.

## Arguments
- **`[TOOLS]…`** — Tool(s) to test

Expand Down
27 changes: 27 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,33 @@ registry's file metadata. Omit `bins` when that inferred list is correct. Set it
explicitly when the shorthand needs a different backend-independent command set,
such as commands bundled by a fallback backend that Aqua does not describe.

#### Minimum backend versions

When a backend supports only newer releases, set `min_version` on that backend.
For example, hk publishes Packslip manifests starting at 1.58.1:

```toml
version_order = "semver"
backends = [
{ full = "packslip:github.com/jdx/hk", min_version = "1.58.1" },
"aqua:jdx/hk",
]
bins = ["hk"]
```

The minimum is inclusive and must be a complete semantic version. It is only
supported for registry tools with `version_order = "semver"`; do not add it to
tools with opaque or source-ordered versions. `mise use hk@1.57` and
`mise use hk@1.58.0` select Aqua, while `mise use hk@1.58.1` selects Packslip.
A prefix overlapping the boundary, such as `1.58`, keeps the preferred backend.
`latest`, channels, and unresolved aliases retain normal backend priority;
aliases are checked again after resolution.

Selection still respects platform support and disabled backends. Explicit
backend identifiers, backend overrides, and a matching lockfile's recorded
backend remain authoritative. A failed download or signature verification does
not trigger fallback. A backend without `min_version` has no lower bound.

#### Idiomatic version files

Registry tools can opt into [idiomatic version files](/configuration.html#idiomatic-version-files)
Expand Down
17 changes: 9 additions & 8 deletions docs/dev-tools/backends/packslip.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ shell completions and agent skills.

Packslip is the preferred [Tier 1 backend](/registry.html#backends) for tools
whose publishers provide these manifests. For other tools, use
[aqua](/dev-tools/backends/aqua.html), [github](/dev-tools/backends/github.html),
[aqua](/dev-tools/backends/aqua.html), [GitHub](/dev-tools/backends/github.html),
or another supported backend. You do not need to install the Packslip CLI.

## Quick start {#usage}
Expand Down Expand Up @@ -92,17 +92,18 @@ for signed lists, withdrawals, and fallback behavior.

## Completions and skills {#completions}

hk publishes a [usage](https://usage.jdx.dev) CLI specification that mise can use
for shell completions. Install `usage`, then set up completions for your shell:
With [mise activated](/getting-started.html#activate-mise), installing hk also
makes its completions available:

```sh
mise use -g usage
mise completion zsh --tool hk --install
mise use hk
```

Follow any shell setup instructions printed by the command. The installed
completion file follows the hk version active in each project. Bash, fish, and
PowerShell are also supported.
Type `hk` and press Tab. mise loads the completion script declared by hk's
release and follows the hk version active in each project. No separate
completion installation or `usage` dependency is needed. Bash, zsh, fish, and
Comment thread
jdx marked this conversation as resolved.
PowerShell are supported. See [Packslip completions](/dev-tools/packslip-resources.html#completions)
for details and manual setup without shell activation.

<span id="skills"></span>

Expand Down
45 changes: 27 additions & 18 deletions docs/dev-tools/packslip-resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,33 @@ mise supports tool completions for zsh, bash, fish, and PowerShell. The installe
completion file follows the tool version active in each project, so you do not
need to reinstall completions after changing versions.

### Set up hk completions
### Use completions

hk publishes a [usage](https://usage.jdx.dev) CLI specification. Install hk
through Packslip and install `usage` to generate and run its completions:
With [mise activated](/getting-started.html#activate-mise), completions become
available when an installed tool is active in your project. For example:

```sh
mise use packslip:github.com/jdx/hk
mise use -g usage
mise use hk
```

Install the completion file for your shell:
Type `hk` and press Tab. hk publishes native completion scripts for bash, zsh,
fish, and PowerShell, so no extra setup command or `usage` installation is
needed. mise registers a loader in the shell; it reads the publisher's script
only when you complete a command. Switching projects or tool versions selects
the matching completion, and leaving the project removes its registration.

| Shell | Command |
| ---------- | ------------------------------------------------ |
| zsh | `mise completion zsh --tool hk --install` |
| bash | `mise completion bash --tool hk --install` |
| fish | `mise completion fish --tool hk --install` |
| PowerShell | `mise completion powershell --tool hk --install` |
### Manual setup without shell activation

For tools that declare completions in their Packslip manifest, mise can install
a completion file that loads those resources. Replace `TOOL` below with the
executable's name:

| Shell | Command |
| ---------- | -------------------------------------------------- |
| zsh | `mise completion zsh --tool TOOL --install` |
| bash | `mise completion bash --tool TOOL --install` |
| fish | `mise completion fish --tool TOOL --install` |
| PowerShell | `mise completion powershell --tool TOOL --install` |

Follow any one-time setup instructions printed by the command, then load the
completion file or start a new shell. mise writes the completion file but does
Expand All @@ -40,20 +49,20 @@ create unless you pass `--force`.
To print a completion script without installing it, omit `--install`:

```sh
mise completion zsh --tool hk
mise completion zsh --tool TOOL
```

For another tool, replace `hk` with its executable name. `--install` takes the
command name, not a backend identifier such as `packslip:github.com/jdx/hk`.
`--install` takes the command name, not a backend identifier such as
`packslip:github.com/jdx/hk`.
If a release contains several commands, choose the one you want to complete.
Without `--tool`, `mise completion` generates completions for mise itself.

### Generated completions

A publisher can provide a completion file, a static usage CLI specification,
or a command that generates either one. mise prefers static sources. A
usage-derived completion requires `usage` both when generating the script and
when completing commands in the shell.
usage-derived completion uses the engine embedded in mise; you do not need to
install `usage` separately.
Comment thread
jdx marked this conversation as resolved.

If a completion needs a publisher's generator command, mise runs it on demand
and caches successful output for the installed version, executable, and shell.
Expand Down Expand Up @@ -210,7 +219,7 @@ next completion uses that directory's active version.
| No completion declared | Confirm the release supports your shell and executable. If it does not, the publisher must add a completion or CLI spec. |
| `--install` rejects a tool identifier | Pass the executable name, such as `hk`, rather than `packslip:github.com/jdx/hk`. |
| A completion file already exists | Inspect the existing file before choosing to replace it with `--force`. |
| Script prints but tab completion does not work | Follow the shell setup printed by `--install`; check that the completion file is loaded and `usage` is on PATH if required. |
| Script prints but tab completion does not work | Check that mise is activated and the tool is active in this project. With manual setup, follow the instructions printed by `--install`. Mise handles usage-derived completions itself. |
| Completion generation fails | Check that the publisher's command produces nonempty output within the time and size limits. Report a failing generator to the publisher. |
| No skills listed | Check `mise skills ls`, the active version, and whether its manifest declares skills. Check `skills.fetch`; an exec-only skill also needs `packslip.exec` enabled during installation. |
| A skill link is skipped | Inspect the conflicting path; mise preserves user-owned files and directories. |
Expand Down
13 changes: 13 additions & 0 deletions docs/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ This will disable the [asdf](./dev-tools/backends/asdf.html) backend. See [Alias

You can also specify the full name for a tool using `mise use aqua:1password/cli` if you want to use a specific backend.

### Version-specific backends

A registry backend can declare the first tool version it supports. mise skips
it for older version requests and uses the next eligible backend. For example,
`mise use hk@1.58.0` uses Aqua, while `mise use hk@1.58.1` uses Packslip.
Older prefixes such as `hk@1.57` also use Aqua; `latest` and prefixes spanning
the boundary keep the normal backend priority.

These boundaries apply to registry shorthands. You can still choose a backend
explicitly, and matching lockfile entries preserve their recorded backend.
See [minimum backend versions](/contributing.html#minimum-backend-versions)
for the registry format.

### Environment Variable Overrides

You can override the backend for any tool using environment variables with the pattern `MISE_BACKENDS_<TOOL>`. This takes the highest priority and overrides any registry or alias configuration:
Expand Down
49 changes: 49 additions & 0 deletions e2e/backend/test_registry_min_version
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env bash

# hk started publishing Packslip manifests in 1.58.1. Earlier releases must
# continue to install through the registry shorthand, using Aqua.
export MISE_EXPERIMENTAL=0
export MISE_MINIMUM_RELEASE_AGE=0
export MISE_REGISTRY_FLOATING=0

# Registry CI must exercise the newly published preferred backend immediately.
MISE_MINIMUM_RELEASE_AGE=90d mise test-tool hk

assert_contains "mise ls-remote hk@1.57" "1.57.0"
assert_contains "mise ls-remote hk 1.57" "1.57.0"
assert_contains "mise ls-remote hk@sub-0.1:1.58.1" "1.57.0"
assert_contains "mise ls-remote hk@prefix:1.57" "1.57.0"
assert "mise latest hk@1.57" "1.57.0"
assert "mise latest hk 1.57" "1.57.0"
assert_not_contains "MISE_BACKENDS_HK=packslip:github.com/jdx/hk mise ls-remote hk@1.57" "1.57"
assert_fail_contains "MISE_DISABLE_BACKENDS=aqua mise latest hk@1.57" "none of its backends"

cat >mise.toml <<'TOML'
[tools]
hk = ["1.57.0", "1.58.1"]

[settings]
lockfile = true
TOML
mise install
assert_contains "mise exec hk@1.57.0 -- hk --version" "hk 1.57.0"
assert_contains "mise exec hk@1.58.1 -- hk --version" "hk 1.58.1"
assert_contains "cat mise.lock" 'backend = "aqua:jdx/hk"'
assert_contains "cat mise.lock" 'backend = "packslip:github.com/jdx/hk"'
assert_contains "MISE_OFFLINE=1 mise --locked exec hk@1.57.0 -- hk --version" "hk 1.57.0"
assert_contains "MISE_OFFLINE=1 mise --locked exec hk@1.58.1 -- hk --version" "hk 1.58.1"
assert_fail_contains "MISE_DISABLE_BACKENDS=aqua mise latest hk@1.57" "none of its backends"

# Aliases can cross the boundary after their version string is resolved.
cat >>mise.toml <<'TOML'
[tool_alias.hk.versions]
old = "1.57.0"
old_prefix = "prefix:1.57"
TOML
assert_contains "mise exec hk@old -- hk --version" "hk 1.57.0"
assert "mise latest hk@old" "1.57.0"
assert_contains "mise ls-remote hk@old" "1.57.0"
assert_contains "mise ls-remote hk@old_prefix" "1.57.0"

# Explicit backends remain explicit; no fallback after a verification error.
assert_fail_contains "mise install --force packslip:github.com/jdx/hk@1.57.0" "no release"
7 changes: 5 additions & 2 deletions e2e/env/test_env_module_tools_no_spurious_warning
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
# The fix changes dependency_env to use full_env_without_tools so it
# skips tools=true module resolution entirely.

# Pin this fixture so release timing and backend migrations do not affect
# the dependency_env regression being tested.

# 1. Install fnox tool and fnox-env plugin
mise plugins install fnox-env https://github.com/jdx/mise-env-fnox

cat >"$MISE_CONFIG_DIR/config.toml" <<'EOF'
[tools]
fnox = "latest"
fnox = "1.35.0"

[env]
_.fnox-env = { tools = true }
Expand Down Expand Up @@ -71,7 +74,7 @@ chmod +x "$INSTALL_DIR/bin/dummy-vfox-trigger"
# 4. Add the vfox tool to config alongside fnox + fnox-env
cat >"$MISE_CONFIG_DIR/config.toml" <<EOF
[tools]
fnox = "latest"
fnox = "1.35.0"
"vfox:$PLUGIN_NAME" = "1.0.0"

[env]
Expand Down
3 changes: 3 additions & 0 deletions man/man1/mise.1
Original file line number Diff line number Diff line change
Expand Up @@ -5651,6 +5651,9 @@ Tasks to validate
If not specified, validates all tasks
.SH "MISE TEST-TOOL"
Test that a tool installs and runs

Includes newly published releases by disabling the global minimum release age
for this command.
.PP
\fBUsage:\fR mise test\-tool [OPTIONS] [<TOOLS>] ...
.PP
Expand Down
6 changes: 6 additions & 0 deletions mise.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -4089,6 +4089,12 @@ If not specified, validates all tasks
}
}
cmd test-tool help="Test that a tool installs and runs" {
long_help #"""
Test that a tool installs and runs

Includes newly published releases by disabling the global minimum release age
for this command.
"""#
after_long_help "\u{1b}[1m\u{1b}[4mExamples:\u{1b}[22m\u{1b}[24m\n\n $ \u{1b}[1mmise test-tool ripgrep\u{1b}[22m\n"
flag "-a --all" help="Test every tool specified in registry/" {
conflicts TOOLS "--all-config"
Expand Down
7 changes: 6 additions & 1 deletion registry/aube.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
backends = ["aqua:jdx/aube", "github:jdx/aube", "cargo:aube"]
backends = [
{ full = "packslip:github.com/aubepkg/aube", min_version = "2.2.11" },
"aqua:jdx/aube",
"github:jdx/aube",
"cargo:aube",
]
bins = ["aube", "aubr", "aubx"]
description = "A fast Node.js package manager"
test = { cmd = "aube --version", expected = "{{version}}" }
Expand Down
5 changes: 4 additions & 1 deletion registry/communique.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
backends = ["github:jdx/communique"]
backends = [
{ full = "packslip:github.com/jdx/communique", min_version = "1.3.5" },
"github:jdx/communique",
]
bins = ["communique"]
description = "Editorialized release notes powered by AI"
test = { cmd = "communique --version", expected = "communique {{version}}" }
Expand Down
5 changes: 4 additions & 1 deletion registry/fnox.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
backends = ["github:jdx/fnox"]
backends = [
{ full = "packslip:github.com/jdx/fnox", min_version = "1.35.1" },
"github:jdx/fnox",
]
bins = ["fnox"]
description = "Fort Knox for your secrets"
test = { cmd = "fnox --version", expected = "fnox {{version}}" }
Expand Down
6 changes: 5 additions & 1 deletion registry/hk.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
backends = ["aqua:jdx/hk"]
backends = [
{ full = "packslip:github.com/jdx/hk", min_version = "1.58.1" },
"aqua:jdx/hk",
]
bins = ["hk"]
description = "git hook and pre-commit lint manager"
test = { cmd = "hk --version", expected = "hk {{version}}" }
version_order = "semver"
5 changes: 4 additions & 1 deletion registry/mr-boxington.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
backends = ["github:jdx/mr-boxington"]
backends = [
{ full = "packslip:github.com/jdx/mr-boxington", min_version = "1.8.3" },
"github:jdx/mr-boxington",
]
bins = ["mbx"]
description = "A Cargo wrapper with a shared, self-pruning compilation cache"
test = { cmd = "mbx --version", expected = "mbx {{version}}" }
Expand Down
6 changes: 5 additions & 1 deletion registry/pitchfork.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
backends = ["aqua:jdx/pitchfork"]
backends = [
{ full = "packslip:github.com/jdx/pitchfork", min_version = "2.24.2" },
"aqua:jdx/pitchfork",
]
Comment thread
jdx marked this conversation as resolved.
bins = ["pitchfork"]
description = "Daemons with DX"
test = { cmd = "pitchfork --version", expected = "pitchfork {{version}}" }
version_order = "semver"
2 changes: 2 additions & 0 deletions registry/usage.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
backends = [
{ full = "packslip:github.com/jdx/usage", min_version = "6.7.1" },
"aqua:jdx/usage",
{ full = "asdf:mise-plugins/mise-usage", platforms = [
"linux",
"macos",
] },
"cargo:usage-cli",
]
bins = ["usage"]
description = "A specification for CLIs"
test = { cmd = "usage --version", expected = "usage {{version}}" }
version_order = "semver"
Loading
Loading