diff --git a/.github/workflows/hyperfine.yml b/.github/workflows/hyperfine.yml index 0eaa622353..7ee1d66962 100644 --- a/.github/workflows/hyperfine.yml +++ b/.github/workflows/hyperfine.yml @@ -67,6 +67,7 @@ jobs: - name: Comment on PR uses: thollander/actions-comment-pull-request@v3 if: github.event_name == 'pull_request' + continue-on-error: true #if: "startsWith(github.event.pull_request.title, 'perf:') || startsWith(github.event.pull_request.title, 'chore: release')" with: file-path: comment.md diff --git a/docs/cli/index.md b/docs/cli/index.md index 6272758b04..2d626d02c9 100644 --- a/docs/cli/index.md +++ b/docs/cli/index.md @@ -71,7 +71,7 @@ Answer yes to all confirmation prompts - [`mise plugins uninstall [-p --purge] [-a --all] [PLUGIN]...`](/cli/plugins/uninstall.md) - [`mise plugins update [-j --jobs ] [PLUGIN]...`](/cli/plugins/update.md) - [`mise prune [FLAGS] [PLUGIN]...`](/cli/prune.md) -- [`mise registry [-b --backend ] [NAME]`](/cli/registry.md) +- [`mise registry [-b --backend ] [--hide-aliased] [NAME]`](/cli/registry.md) - [`mise reshim [-f --force]`](/cli/reshim.md) - [`mise run [FLAGS]`](/cli/run.md) - [`mise self-update [FLAGS] [VERSION]`](/cli/self-update.md) diff --git a/docs/cli/registry.md b/docs/cli/registry.md index e224b2182f..31167e0015 100644 --- a/docs/cli/registry.md +++ b/docs/cli/registry.md @@ -1,6 +1,6 @@ # `mise registry` -- **Usage**: `mise registry [-b --backend ] [NAME]` +- **Usage**: `mise registry [-b --backend ] [--hide-aliased] [NAME]` - **Source code**: [`src/cli/registry.rs`](https://github.com/jdx/mise/blob/main/src/cli/registry.rs) List available tools to install @@ -21,6 +21,10 @@ Show only the specified tool's full name Show only tools for this backend +### `--hide-aliased` + +Hide aliased tools + Examples: $ mise registry diff --git a/docs/dev-tools/backends/aqua.md b/docs/dev-tools/backends/aqua.md index f2de48fddb..68ecfbd275 100644 --- a/docs/dev-tools/backends/aqua.md +++ b/docs/dev-tools/backends/aqua.md @@ -1,4 +1,4 @@ -# Aqua Backend +# Aqua Backend [Aqua](https://aquaproj.github.io/) tools may be used natively in mise. Aqua is encouraged as a backend for new tools if they cannot be used with ubi as aqua tools directly fetch tarballs from the vendor without requiring unsafe diff --git a/docs/dev-tools/backends/index.md b/docs/dev-tools/backends/index.md index f82973f6cb..639b492cd4 100644 --- a/docs/dev-tools/backends/index.md +++ b/docs/dev-tools/backends/index.md @@ -3,6 +3,7 @@ In addition to asdf plugins, you can also directly install CLIs with some package managers. - [asdf](/dev-tools/backends/asdf) +- [aqua](/dev-tools/backends/aqua) - [Cargo](/dev-tools/backends/cargo) - [Go](/dev-tools/backends/go) - [NPM](/dev-tools/backends/npm) diff --git a/docs/registry.md b/docs/registry.md index 1b205631f9..c6acde0ece 100644 --- a/docs/registry.md +++ b/docs/registry.md @@ -250,7 +250,6 @@ editLink: false | gcc-arm-none-eabi | [asdf:dlech/asdf-gcc-arm-none-eabi](https://github.com/dlech/asdf-gcc-arm-none-eabi) | | gcloud | [asdf:jthegedus/asdf-gcloud](https://github.com/jthegedus/asdf-gcloud) | | getenvoy | [asdf:asdf-community/asdf-getenvoy](https://github.com/asdf-community/asdf-getenvoy) | -| gh | [ubi:cli/cli](https://github.com/cli/cli) [asdf:bartlomiejdanek/asdf-github-cli](https://github.com/bartlomiejdanek/asdf-github-cli) | | ghc | [asdf:sestrella/asdf-ghcup](https://github.com/sestrella/asdf-ghcup) | | ghidra | [asdf:Honeypot95/asdf-ghidra](https://github.com/Honeypot95/asdf-ghidra) | | ghorg | [aqua:gabrie30/ghorg](https://github.com/gabrie30/ghorg) [asdf:gbloquel/asdf-ghorg](https://github.com/gbloquel/asdf-ghorg) | @@ -352,7 +351,7 @@ editLink: false | jbang | [asdf:jbangdev/jbang-asdf](https://github.com/jbangdev/jbang-asdf) | | jfrog-cli | [asdf:LozanoMatheus/asdf-jfrog-cli](https://github.com/LozanoMatheus/asdf-jfrog-cli) | | jib | [asdf:joschi/asdf-jib](https://github.com/joschi/asdf-jib) | -| jiq | [asdf:chessmango/asdf-jiq](https://github.com/chessmango/asdf-jiq) | +| jiq | [aqua:fiatjaf/jiq](https://github.com/fiatjaf/jiq) [asdf:chessmango/asdf-jiq](https://github.com/chessmango/asdf-jiq) | | jless | [aqua:PaulJuliusMartinez/jless](https://github.com/PaulJuliusMartinez/jless) [asdf:jc00ke/asdf-jless](https://github.com/jc00ke/asdf-jless) | | jmespath | [asdf:skyzyx/asdf-jmespath](https://github.com/skyzyx/asdf-jmespath) | | jmeter | [asdf:comdotlinux/asdf-jmeter](https://github.com/comdotlinux/asdf-jmeter) | @@ -405,7 +404,7 @@ editLink: false | kube-capacity | [aqua:robscott/kube-capacity](https://github.com/robscott/kube-capacity) [asdf:looztra/asdf-kube-capacity](https://github.com/looztra/asdf-kube-capacity) | | kube-code-generator | [asdf:jimmidyson/asdf-kube-code-generator](https://github.com/jimmidyson/asdf-kube-code-generator) | | kube-controller-tools | [asdf:jimmidyson/asdf-kube-controller-tools](https://github.com/jimmidyson/asdf-kube-controller-tools) | -| kube-credential-cache | [asdf:ryodocx/kube-credential-cache](https://github.com/ryodocx/kube-credential-cache) | +| kube-credential-cache | [aqua:ryodocx/kube-credential-cache](https://github.com/ryodocx/kube-credential-cache) [asdf:ryodocx/kube-credential-cache](https://github.com/ryodocx/kube-credential-cache) | | kube-linter | [aqua:stackrox/kube-linter](https://github.com/stackrox/kube-linter) [asdf:devlincashman/asdf-kube-linter](https://github.com/devlincashman/asdf-kube-linter) | | kube-score | [aqua:zegl/kube-score](https://github.com/zegl/kube-score) [asdf:bageljp/asdf-kube-score](https://github.com/bageljp/asdf-kube-score) | | kubebuilder | [aqua:kubernetes-sigs/kubebuilder](https://github.com/kubernetes-sigs/kubebuilder) [asdf:virtualstaticvoid/asdf-kubebuilder](https://github.com/virtualstaticvoid/asdf-kubebuilder) | @@ -417,6 +416,7 @@ editLink: false | kubectl-buildkit | [asdf:ezcater/asdf-kubectl-buildkit](https://github.com/ezcater/asdf-kubectl-buildkit) | | kubectl-convert | [aqua:kubernetes/kubectl-convert](https://github.com/kubernetes/kubectl-convert) [asdf:iul1an/asdf-kubectl-convert](https://github.com/iul1an/asdf-kubectl-convert) | | kubectl-kots | [asdf:ganta/asdf-kubectl-kots](https://github.com/ganta/asdf-kubectl-kots) | +| kubectl-kuttl | [aqua:kudobuilder/kuttl](https://github.com/kudobuilder/kuttl) [asdf:jimmidyson/asdf-kuttl](https://github.com/jimmidyson/asdf-kuttl) | | kubectx | [aqua:ahmetb/kubectx](https://github.com/ahmetb/kubectx) [asdf:https://gitlab.com/wt0f/asdf-kubectx](https://gitlab.com/wt0f/asdf-kubectx) | | kubefedctl | [asdf:kvokka/asdf-kubefedctl](https://github.com/kvokka/asdf-kubefedctl) | | kubefirst | [asdf:Claywd/asdf-kubefirst](https://github.com/Claywd/asdf-kubefirst) | @@ -429,10 +429,9 @@ editLink: false | kubeshark | [aqua:kubeshark/kubeshark](https://github.com/kubeshark/kubeshark) [asdf:carnei-ro/asdf-kubeshark](https://github.com/carnei-ro/asdf-kubeshark) | | kubespy | [aqua:pulumi/kubespy](https://github.com/pulumi/kubespy) [asdf:jfreeland/asdf-kubespy](https://github.com/jfreeland/asdf-kubespy) | | kubeval | [aqua:instrumenta/kubeval](https://github.com/instrumenta/kubeval) [asdf:stefansedich/asdf-kubeval](https://github.com/stefansedich/asdf-kubeval) | -| kubevela | [asdf:gustavclausen/asdf-kubevela](https://github.com/gustavclausen/asdf-kubevela) | +| kubevela | [aqua:kubevela/kubevela](https://github.com/kubevela/kubevela) [asdf:gustavclausen/asdf-kubevela](https://github.com/gustavclausen/asdf-kubevela) | | kubie | [aqua:sbstp/kubie](https://github.com/sbstp/kubie) [asdf:johnhamelink/asdf-kubie](https://github.com/johnhamelink/asdf-kubie) | -| kustomize | [asdf:Banno/asdf-kustomize](https://github.com/Banno/asdf-kustomize) | -| kuttl | [asdf:jimmidyson/asdf-kuttl](https://github.com/jimmidyson/asdf-kuttl) | +| kustomize | [aqua:kubernetes-sigs/kustomize](https://github.com/kubernetes-sigs/kustomize) [asdf:Banno/asdf-kustomize](https://github.com/Banno/asdf-kustomize) | | kwt | [aqua:carvel-dev/kwt](https://github.com/carvel-dev/kwt) [asdf:vmware-tanzu/asdf-carvel](https://github.com/vmware-tanzu/asdf-carvel) | | lab | [aqua:zaquestion/lab](https://github.com/zaquestion/lab) [asdf:particledecay/asdf-lab](https://github.com/particledecay/asdf-lab) | | lane | [asdf:CodeReaper/asdf-lane](https://github.com/CodeReaper/asdf-lane) | @@ -467,7 +466,7 @@ editLink: false | mark | [asdf:jfreeland/asdf-mark](https://github.com/jfreeland/asdf-mark) | | markdownlint-cli2 | [npm:markdownlint-cli2](https://www.npmjs.com/package/markdownlint-cli2) [asdf:paulo-ferraz-oliveira/asdf-markdownlint-cli2](https://github.com/paulo-ferraz-oliveira/asdf-markdownlint-cli2) | | marp-cli | [aqua:marp-team/marp-cli](https://github.com/marp-team/marp-cli) [asdf:xataz/asdf-marp-cli](https://github.com/xataz/asdf-marp-cli) | -| mask | [asdf:aaaaninja/asdf-mask](https://github.com/aaaaninja/asdf-mask) | +| mask | [aqua:jacobdeichert/mask](https://github.com/jacobdeichert/mask) [asdf:aaaaninja/asdf-mask](https://github.com/aaaaninja/asdf-mask) | | maven | [asdf:mise-plugins/asdf-maven](https://github.com/mise-plugins/asdf-maven) [vfox:version-fox/vfox-maven](https://github.com/version-fox/vfox-maven) | | mc | [asdf:penpyt/asdf-mc](https://github.com/penpyt/asdf-mc) | | mdbook | [asdf:cipherstash/asdf-mdbook](https://github.com/cipherstash/asdf-mdbook) | @@ -479,7 +478,7 @@ editLink: false | meson | [asdf:asdf-community/asdf-meson](https://github.com/asdf-community/asdf-meson) | | micronaut | [asdf:weibemoura/asdf-micronaut](https://github.com/weibemoura/asdf-micronaut) | | mill | [asdf:asdf-community/asdf-mill](https://github.com/asdf-community/asdf-mill) | -| mimirtool | [asdf:asdf-community/asdf-mimirtool](https://github.com/asdf-community/asdf-mimirtool) | +| mimirtool | [aqua:grafana/mimir/mimirtool](https://github.com/grafana/mimir/mimirtool) [asdf:asdf-community/asdf-mimirtool](https://github.com/asdf-community/asdf-mimirtool) | | minify | [aqua:tdewolff/minify](https://github.com/tdewolff/minify) [asdf:axilleas/asdf-minify](https://github.com/axilleas/asdf-minify) | | minikube | [aqua:kubernetes/minikube](https://github.com/kubernetes/minikube) [asdf:alvarobp/asdf-minikube](https://github.com/alvarobp/asdf-minikube) | | minio | [asdf:aeons/asdf-minio](https://github.com/aeons/asdf-minio) | @@ -551,7 +550,7 @@ editLink: false | perl | [asdf:ouest/asdf-perl](https://github.com/ouest/asdf-perl) | | php | [asdf:asdf-community/asdf-php](https://github.com/asdf-community/asdf-php) [vfox:version-fox/vfox-php](https://github.com/version-fox/vfox-php) | | pint | [aqua:cloudflare/pint](https://github.com/cloudflare/pint) [asdf:sam-burrell/asdf-pint](https://github.com/sam-burrell/asdf-pint) | -| pipectl | [asdf:pipe-cd/asdf-pipectl](https://github.com/pipe-cd/asdf-pipectl) | +| pipectl | [aqua:pipe-cd/pipecd/pipectl](https://github.com/pipe-cd/pipecd/pipectl) [asdf:pipe-cd/asdf-pipectl](https://github.com/pipe-cd/asdf-pipectl) | | pipelight | [asdf:kogeletey/asdf-pipelight](https://github.com/kogeletey/asdf-pipelight) | | pipenv | [asdf:mise-plugins/mise-pipenv](https://github.com/mise-plugins/mise-pipenv) | | pipx | [asdf:yozachar/asdf-pipx](https://github.com/yozachar/asdf-pipx) | @@ -608,7 +607,6 @@ editLink: false | restic | [asdf:xataz/asdf-restic](https://github.com/xataz/asdf-restic) | | restish | [ubi:danielgtaylor/restish](https://github.com/danielgtaylor/restish) [go:github.com/danielgtaylor/restish](https://pkg.go.dev/github.com/danielgtaylor/restish) | | revive | [aqua:mgechev/revive](https://github.com/mgechev/revive) [asdf:bjw-s/asdf-revive](https://github.com/bjw-s/asdf-revive) | -| rg | [aqua:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [ubi:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [asdf:https://gitlab.com/wt0f/asdf-ripgrep](https://gitlab.com/wt0f/asdf-ripgrep) | | richgo | [aqua:kyoh86/richgo](https://github.com/kyoh86/richgo) [asdf:paxosglobal/asdf-richgo](https://github.com/paxosglobal/asdf-richgo) | | riff | [asdf:abinet/asdf-riff](https://github.com/abinet/asdf-riff) | | ripgrep | [aqua:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [ubi:BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) [asdf:https://gitlab.com/wt0f/asdf-ripgrep](https://gitlab.com/wt0f/asdf-ripgrep) | @@ -672,7 +670,7 @@ editLink: false | sqldef | [asdf:cometkim/asdf-sqldef](https://github.com/cometkim/asdf-sqldef) | | sqlite | [asdf:cLupus/asdf-sqlite](https://github.com/cLupus/asdf-sqlite) | | sshuttle | [asdf:xanmanning/asdf-sshuttle](https://github.com/xanmanning/asdf-sshuttle) | -| stack | [asdf:sestrella/asdf-ghcup](https://github.com/sestrella/asdf-ghcup) | +| stack | [aqua:commercialhaskell/stack](https://github.com/commercialhaskell/stack) [asdf:sestrella/asdf-ghcup](https://github.com/sestrella/asdf-ghcup) | | starboard | [aqua:aquasecurity/starboard](https://github.com/aquasecurity/starboard) [asdf:zufardhiyaulhaq/asdf-starboard](https://github.com/zufardhiyaulhaq/asdf-starboard) | | starknet-foundry | [asdf:foundry-rs/asdf-starknet-foundry](https://github.com/foundry-rs/asdf-starknet-foundry) | | starport | [asdf:nikever/asdf-starport](https://github.com/nikever/asdf-starport) | diff --git a/mise.toml b/mise.toml index ff43ee5320..7f1be9c372 100644 --- a/mise.toml +++ b/mise.toml @@ -15,7 +15,6 @@ cargo-binstall = "latest" "cargo:git-cliff" = "latest" "npm:markdownlint-cli" = "latest" "npm:prettier" = "3" -direnv = "latest" actionlint = "latest" ripgrep = "latest" "pipx:toml-sort" = "latest" diff --git a/mise.usage.kdl b/mise.usage.kdl index 09763d9a9f..95f76059de 100644 --- a/mise.usage.kdl +++ b/mise.usage.kdl @@ -850,6 +850,7 @@ For example, `poetry` is shorthand for `asdf:mise-plugins/mise-poetry`." flag "-b --backend" help="Show only tools for this backend" { arg "" } + flag "--hide-aliased" help="Hide aliased tools" arg "[NAME]" help="Show only the specified tool's full name" } cmd "reshim" help="Creates new shims based on bin paths from currently installed tools." { diff --git a/registry.toml b/registry.toml index c5e4fec155..ffb9bb381c 100644 --- a/registry.toml +++ b/registry.toml @@ -380,7 +380,7 @@ jb.backends = ["asdf:beardix/asdf-jb"] jbang.backends = ["asdf:jbangdev/jbang-asdf"] jfrog-cli.backends = ["asdf:LozanoMatheus/asdf-jfrog-cli"] jib.backends = ["asdf:joschi/asdf-jib"] -jiq.backends = ["asdf:chessmango/asdf-jiq"] +jiq.backends = ["aqua:fiatjaf/jiq", "asdf:chessmango/asdf-jiq"] jless.backends = ["aqua:PaulJuliusMartinez/jless", "asdf:jc00ke/asdf-jless"] jmespath.backends = ["asdf:skyzyx/asdf-jmespath"] jmeter.backends = ["asdf:comdotlinux/asdf-jmeter"] @@ -433,7 +433,7 @@ ktlint.backends = ["asdf:esensar/asdf-ktlint"] kube-capacity.backends = ["aqua:robscott/kube-capacity", "asdf:looztra/asdf-kube-capacity"] kube-code-generator.backends = ["asdf:jimmidyson/asdf-kube-code-generator"] kube-controller-tools.backends = ["asdf:jimmidyson/asdf-kube-controller-tools"] -kube-credential-cache.backends = ["asdf:ryodocx/kube-credential-cache"] +kube-credential-cache.backends = ["aqua:ryodocx/kube-credential-cache", "asdf:ryodocx/kube-credential-cache"] kube-linter.backends = ["aqua:stackrox/kube-linter", "asdf:devlincashman/asdf-kube-linter"] kube-score.backends = ["aqua:zegl/kube-score", "asdf:bageljp/asdf-kube-score"] kubebuilder.backends = ["aqua:kubernetes-sigs/kubebuilder", "asdf:virtualstaticvoid/asdf-kubebuilder"] @@ -445,6 +445,10 @@ kubectl-bindrole.backends = ["asdf:looztra/asdf-kubectl-bindrole"] kubectl-buildkit.backends = ["asdf:ezcater/asdf-kubectl-buildkit"] kubectl-convert.backends = ["aqua:kubernetes/kubectl-convert", "asdf:iul1an/asdf-kubectl-convert"] kubectl-kots.backends = ["asdf:ganta/asdf-kubectl-kots"] +kubectl-kuttl.aliases = ["kuttl"] +kubectl-kuttl.backends = ["aqua:kudobuilder/kuttl", "asdf:jimmidyson/asdf-kuttl"] +kubectl-kuttl.os = ["linux", "macos"] +kubectl-kuttl.test = ["kubectl-kuttl --version", "kubectl-kuttl version {{version}}"] kubectx.backends = ["aqua:ahmetb/kubectx", "asdf:https://gitlab.com/wt0f/asdf-kubectx"] kubefedctl.backends = ["asdf:kvokka/asdf-kubefedctl"] kubefirst.backends = ["asdf:Claywd/asdf-kubefirst"] @@ -457,10 +461,11 @@ kubesec.backends = ["aqua:controlplaneio/kubesec", "asdf:vitalis/asdf-kubesec"] kubeshark.backends = ["aqua:kubeshark/kubeshark", "asdf:carnei-ro/asdf-kubeshark"] kubespy.backends = ["aqua:pulumi/kubespy", "asdf:jfreeland/asdf-kubespy"] kubeval.backends = ["aqua:instrumenta/kubeval", "asdf:stefansedich/asdf-kubeval"] -kubevela.backends = ["asdf:gustavclausen/asdf-kubevela"] +kubevela.backends = ["aqua:kubevela/kubevela", "asdf:gustavclausen/asdf-kubevela"] +kubevela.test = ["vela version", "CLI Version: {{version}}"] kubie.backends = ["aqua:sbstp/kubie", "asdf:johnhamelink/asdf-kubie"] -kustomize.backends = ["asdf:Banno/asdf-kustomize"] -kuttl.backends = ["asdf:jimmidyson/asdf-kuttl"] +kustomize.backends = ["aqua:kubernetes-sigs/kustomize", "asdf:Banno/asdf-kustomize"] +kustomize.test = ["kustomize version", "v{{version}}"] kwt.backends = ["aqua:carvel-dev/kwt", "asdf:vmware-tanzu/asdf-carvel"] lab.backends = ["aqua:zaquestion/lab", "asdf:particledecay/asdf-lab"] lane.backends = ["asdf:CodeReaper/asdf-lane"] @@ -495,7 +500,8 @@ mani.backends = ["asdf:anweber/asdf-mani"] mark.backends = ["asdf:jfreeland/asdf-mark"] markdownlint-cli2.backends = ["npm:markdownlint-cli2", "asdf:paulo-ferraz-oliveira/asdf-markdownlint-cli2"] marp-cli.backends = ["aqua:marp-team/marp-cli", "asdf:xataz/asdf-marp-cli"] -mask.backends = ["asdf:aaaaninja/asdf-mask"] +mask.backends = ["aqua:jacobdeichert/mask", "asdf:aaaaninja/asdf-mask"] +mask.test = ["mask --version", "mask {{version}}"] maven.backends = ["asdf:mise-plugins/asdf-maven", "vfox:version-fox/vfox-maven"] mc.backends = ["asdf:penpyt/asdf-mc"] mdbook.backends = ["asdf:cipherstash/asdf-mdbook"] @@ -509,7 +515,9 @@ mercury.backends = ["asdf:susurri/asdf-mercury"] meson.backends = ["asdf:asdf-community/asdf-meson"] micronaut.backends = ["asdf:weibemoura/asdf-micronaut"] mill.backends = ["asdf:asdf-community/asdf-mill"] -mimirtool.backends = ["asdf:asdf-community/asdf-mimirtool"] +mimirtool.backends = ["aqua:grafana/mimir/mimirtool", "asdf:asdf-community/asdf-mimirtool"] +mimirtool.test = ["mimir version", "Mimirtool, version {{version}}"] +mimirtool.os = ["linux", "macos"] minify.backends = ["aqua:tdewolff/minify", "asdf:axilleas/asdf-minify"] minikube.backends = ["aqua:kubernetes/minikube", "asdf:alvarobp/asdf-minikube"] minio.backends = ["asdf:aeons/asdf-minio"] @@ -581,7 +589,9 @@ periphery.backends = ["asdf:MontakOleg/asdf-periphery"] perl.backends = ["asdf:ouest/asdf-perl"] php.backends = ["asdf:asdf-community/asdf-php", "vfox:version-fox/vfox-php"] pint.backends = ["aqua:cloudflare/pint", "asdf:sam-burrell/asdf-pint"] -pipectl.backends = ["asdf:pipe-cd/asdf-pipectl"] +pipectl.backends = ["aqua:pipe-cd/pipecd/pipectl", "asdf:pipe-cd/asdf-pipectl"] +pipectl.test = ["pipecd version", "Version: v{{version}}"] +pipectl.os = ["linux", "macos"] pipelight.backends = ["asdf:kogeletey/asdf-pipelight"] pipenv.backends = ["asdf:mise-plugins/mise-pipenv"] pipx.backends = ["asdf:yozachar/asdf-pipx"] @@ -705,7 +715,8 @@ spruce.backends = ["aqua:geofffranks/spruce", "asdf:woneill/asdf-spruce"] sqldef.backends = ["asdf:cometkim/asdf-sqldef"] sqlite.backends = ["asdf:cLupus/asdf-sqlite"] sshuttle.backends = ["asdf:xanmanning/asdf-sshuttle"] -stack.backends = ["asdf:sestrella/asdf-ghcup"] +stack.backends = ["aqua:commercialhaskell/stack", "asdf:sestrella/asdf-ghcup"] +stack.test = ["stack --version", "Version {{version}}"] starboard.backends = ["aqua:aquasecurity/starboard", "asdf:zufardhiyaulhaq/asdf-starboard"] starknet-foundry.backends = ["asdf:foundry-rs/asdf-starknet-foundry"] starport.backends = ["asdf:nikever/asdf-starport"] diff --git a/scripts/render-registry.js b/scripts/render-registry.js index 3c65058240..66b0605f25 100755 --- a/scripts/render-registry.js +++ b/scripts/render-registry.js @@ -7,7 +7,7 @@ process.env.MISE_ASDF = 1; process.env.MISE_VFOX = 1; process.env.MISE_EXPERIMENTAL = 1; -const stdout = execSync("mise registry", { encoding: "utf-8" }); +const stdout = execSync("mise registry --hide-aliased", { encoding: "utf-8" }); const output = [ `--- diff --git a/src/aqua/aqua_registry.rs b/src/aqua/aqua_registry.rs index 6ec73f6940..e0065d7d97 100644 --- a/src/aqua/aqua_registry.rs +++ b/src/aqua/aqua_registry.rs @@ -175,13 +175,13 @@ impl AquaPackage { .find(|vo| vo.version_constraint == "true" || semver_match(&vo.version_constraint)) } - pub fn format(&self, v: &str) -> &str { + pub fn format(&self, v: &str) -> Result<&str> { if self.r#type == AquaPackageType::GithubArchive { - return "tar.gz"; + return Ok("tar.gz"); } - if self.format.is_empty() { + let format = if self.format.is_empty() { let asset = if !self.asset.is_empty() { - self.asset(v) + self.asset(v)? } else if !self.url.is_empty() { self.url.to_string() } else { @@ -212,33 +212,39 @@ impl AquaPackage { "tbz2" => "tar.bz2", format => format, } - } + }; + Ok(format) } - pub fn asset(&self, v: &str) -> String { + pub fn asset(&self, v: &str) -> Result { self.parse_aqua_str(&self.asset, v, &Default::default()) } - pub fn asset_strs(&self, v: &str) -> IndexSet { - let mut strs = IndexSet::from([self.asset(v)]); + pub fn asset_strs(&self, v: &str) -> Result> { + let mut strs = IndexSet::from([self.asset(v)?]); if cfg!(macos) { let mut ctx = HashMap::default(); ctx.insert("ARCH".to_string(), "arm64".to_string()); - strs.insert(self.parse_aqua_str(&self.asset, v, &ctx)); + strs.insert(self.parse_aqua_str(&self.asset, v, &ctx)?); } else if cfg!(windows) { strs.insert(format!( "{}.exe", - self.parse_aqua_str(&self.asset, v, &Default::default()) + self.parse_aqua_str(&self.asset, v, &Default::default())? )); } - strs + Ok(strs) } - pub fn url(&self, v: &str) -> String { + pub fn url(&self, v: &str) -> Result { self.parse_aqua_str(&self.url, v, &Default::default()) } - fn parse_aqua_str(&self, s: &str, v: &str, overrides: &HashMap) -> String { + fn parse_aqua_str( + &self, + s: &str, + v: &str, + overrides: &HashMap, + ) -> Result { let os = os(); let mut arch = arch(); if os == "darwin" && arch == "arm64" && self.rosetta2 { @@ -253,8 +259,14 @@ impl AquaPackage { .map(|s| s.to_string()) .unwrap_or_else(|| s.to_string()) }; + let semver = if let Some(prefix) = &self.version_prefix { + v.strip_prefix(prefix).unwrap_or(v) + } else { + v + }; let mut ctx = hashmap! { "Version".to_string() => replace(v), + "SemVer".to_string() => replace(semver), "OS".to_string() => replace(os), "GOOS".to_string() => replace(os), "GOARCH".to_string() => replace(arch), @@ -267,8 +279,8 @@ impl AquaPackage { } impl AquaFile { - pub fn src(&self, pkg: &AquaPackage, v: &str) -> Option { - let asset = pkg.asset(v); + pub fn src(&self, pkg: &AquaPackage, v: &str) -> Result> { + let asset = pkg.asset(v)?; let asset = asset.strip_suffix(".tar.gz").unwrap_or(&asset); let asset = asset.strip_suffix(".tar.xz").unwrap_or(asset); let asset = asset.strip_suffix(".tar.bz2").unwrap_or(asset); @@ -286,6 +298,7 @@ impl AquaFile { self.src .as_ref() .map(|src| pkg.parse_aqua_str(src, v, &ctx)) + .transpose() } } diff --git a/src/aqua/aqua_template.rs b/src/aqua/aqua_template.rs index abd75cb2b3..d9cab671b8 100644 --- a/src/aqua/aqua_template.rs +++ b/src/aqua/aqua_template.rs @@ -1,15 +1,18 @@ +use eyre::{bail, ContextCompat, Result}; use heck::ToTitleCase; use itertools::Itertools; use std::collections::HashMap; +use std::fmt::Debug; type Context = HashMap; -pub fn render(tmpl: &str, ctx: &Context) -> String { +pub fn render(tmpl: &str, ctx: &Context) -> Result { let mut result = String::new(); let mut in_tag = false; let mut tag = String::new(); let chars = tmpl.chars().collect_vec(); let mut i = 0; + let parser = Parser { ctx }; while i < chars.len() { let c = chars[i]; let next = chars.get(i + 1).cloned().unwrap_or(' '); @@ -18,7 +21,8 @@ pub fn render(tmpl: &str, ctx: &Context) -> String { i += 1; } else if in_tag && c == '}' && next == '}' { in_tag = false; - result += &parse(&tag, ctx); + let tokens = lex(&tag)?; + result += &parser.parse(tokens.iter().collect())?; tag.clear(); i += 1; } else if in_tag { @@ -28,40 +32,128 @@ pub fn render(tmpl: &str, ctx: &Context) -> String { } i += 1; } - result + Ok(result) } -fn parse(mut code: &str, ctx: &Context) -> String { - type Op = Box String>; - let mut ops: Vec = Vec::new(); - if code.starts_with("title ") { - code = &code[6..]; - ops.push(Box::new(|s: &str| s.to_title_case())); - } - if code.starts_with("trimV ") { - code = &code[6..]; - ops.push(Box::new(|s: &str| s.trim_start_matches('v').to_string())); - } - let mut val = if let Some(key) = code.strip_prefix(".") { - if let Some(val) = ctx.get(key) { - val.to_string() +#[derive(Debug, Clone, PartialEq, strum::EnumIs)] +enum Token<'a> { + Key(&'a str), + String(&'a str), + Func(&'a str), + Whitespace(&'a str), + Pipe, +} + +fn lex(code: &str) -> Result> { + let mut tokens = vec![]; + let mut code = code.trim(); + while !code.is_empty() { + if code.starts_with(" ") { + let end = code + .chars() + .enumerate() + .find(|(_, c)| !c.is_whitespace()) + .map(|(i, _)| i); + if let Some(end) = end { + tokens.push(Token::Whitespace(&code[..end])); + code = &code[end..]; + } else { + break; + } + } else if code.starts_with("|") { + tokens.push(Token::Pipe); + code = &code[1..]; + } else if code.starts_with('"') { + for (end, _) in code[1..].match_indices('"') { + if code.chars().nth(end) != Some('\\') { + tokens.push(Token::String(&code[1..end + 1])); + code = &code[end + 2..]; + break; + } + } + } else if code.starts_with(".") { + let end = code.split_whitespace().next().unwrap().len(); + tokens.push(Token::Key(&code[1..end])); + code = &code[end..]; + } else if code.starts_with("|") { + tokens.push(Token::Pipe); + code = &code[1..]; } else { - warn!("unable to find key in context: {key}"); - "".to_string() + let func = code.split_whitespace().next().unwrap(); + tokens.push(Token::Func(func)); + code = &code[func.len()..]; } - } else if code.starts_with('"') && code.ends_with('"') { - // TODO: handle quotes in the middle of code - code[1..code.len() - 1].to_string() - } else { - warn!("unable to parse aqua template: {code}"); - "".to_string() - }; - - for op in ops.into_iter().rev() { - val = op(&val); } + Ok(tokens) +} + +struct Parser<'a> { + ctx: &'a Context, +} - val +impl Parser<'_> { + fn parse(&self, tokens: Vec<&Token>) -> Result { + let mut s = String::new(); + let mut tokens = tokens.iter(); + let expect_whitespace = |t: Option<&&Token>| { + if let Some(token) = t { + if let Token::Whitespace(_) = token { + Ok(()) + } else { + bail!("expected whitespace, found: {token:?}"); + } + } else { + bail!("expected whitespace, found: end of input"); + } + }; + let next_arg = |tokens: &mut std::slice::Iter<&Token>| -> Result { + expect_whitespace(tokens.next())?; + let arg = tokens.next().wrap_err("missing argument")?; + self.parse(vec![arg]) + }; + while let Some(token) = tokens.next() { + match token { + Token::Key(key) => { + if let Some(val) = self.ctx.get(*key) { + s = val.to_string() + } else { + bail!("unable to find key in context: {key}"); + } + } + Token::String(str) => s = str.to_string(), + Token::Func(func) => match *func { + "title" => { + let arg = next_arg(&mut tokens)?; + s = arg.to_title_case(); + } + "trimV" => { + let arg = next_arg(&mut tokens)?; + s = arg.trim_start_matches('v').to_string(); + } + "trimPrefix" => { + let prefix = next_arg(&mut tokens)?; + let str = next_arg(&mut tokens)?; + if let Some(str) = str.strip_prefix(&prefix) { + s = str.to_string(); + } else { + s = str.to_string(); + } + } + _ => bail!("unexpected function: {func}"), + }, + Token::Whitespace(_) => {} + Token::Pipe => { + let mut tokens = tokens.cloned().collect_vec(); + let whitespace = Token::Whitespace(" "); + let str = Token::String(&s); + tokens.push(&whitespace); + tokens.push(&str); + return self.parse(tokens); + } + } + } + Ok(s) + } } #[cfg(test)] @@ -74,7 +166,7 @@ mod tests { let tmpl = "Hello, {{.OS}}!"; let mut ctx = HashMap::new(); ctx.insert("OS".to_string(), "world".to_string()); - assert_eq!(render(tmpl, &ctx), "Hello, world!"); + assert_eq!(render(tmpl, &ctx).unwrap(), "Hello, world!"); } macro_rules! parse_tests { @@ -84,16 +176,47 @@ mod tests { fn $name() { let (input, expected, ctx): (&str, &str, HashMap<&str, &str>) = $value; let ctx = ctx.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect(); - assert_eq!(expected, parse(input, &ctx)); + let parser = Parser { ctx: &ctx }; + let tokens = lex(input).unwrap(); + assert_eq!(expected, parser.parse(tokens.iter().collect()).unwrap()); } )* }} parse_tests!( - test_parse1: (".OS", "world", hashmap!{"OS" => "world"}), - test_parse2: ("\"world\"", "world", hashmap!{}), - test_parse3: ("XXX", "", hashmap!{}), - test_parse4: (r#"title "world""#, "World", hashmap!{}), - test_parse5: (r#"trimV "v1.0.0""#, "1.0.0", hashmap!{}), + test_parse_key: (".OS", "world", hashmap!{"OS" => "world"}), + test_parse_string: ("\"world\"", "world", hashmap!{}), + test_parse_title: (r#"title "world""#, "World", hashmap!{}), + test_parse_trimv: (r#"trimV "v1.0.0""#, "1.0.0", hashmap!{}), + test_parse_trim_prefix: (r#"trimPrefix "v" "v1.0.0""#, "1.0.0", hashmap!{}), + test_parse_trim_prefix2: (r#"trimPrefix "v" "1.0.0""#, "1.0.0", hashmap!{}), + test_parse_pipe: (r#"trimPrefix "foo-" "foo-v1.0.0" | trimV"#, "1.0.0", hashmap!{}), ); + + #[test] + fn test_parse_err() { + let parser = Parser { + ctx: &HashMap::new(), + }; + let tokens = lex("foo").unwrap(); + assert!(parser.parse(tokens.iter().collect()).is_err()); + } + + #[test] + fn test_lex() { + assert_eq!( + lex(r#"trimPrefix "foo-" "foo-v1.0.0" | trimV"#).unwrap(), + vec![ + Token::Func("trimPrefix"), + Token::Whitespace(" "), + Token::String("foo-"), + Token::Whitespace(" "), + Token::String("foo-v1.0.0"), + Token::Whitespace(" "), + Token::Pipe, + Token::Whitespace(" "), + Token::Func("trimV"), + ] + ); + } } diff --git a/src/backend/aqua.rs b/src/backend/aqua.rs index eb7928204b..a6ac53c931 100644 --- a/src/backend/aqua.rs +++ b/src/backend/aqua.rs @@ -44,12 +44,17 @@ impl Backend for AquaBackend { pkg.repo_owner, pkg.repo_name ))? .into_iter() - .map(|r| { - let mut v = r.tag_name.strip_prefix('v').unwrap_or(&r.tag_name); + .filter_map(|r| { + let mut v = r.tag_name.as_str(); if let Some(prefix) = &pkg.version_prefix { - v = v.strip_prefix(prefix).unwrap_or(v); + if let Some(_v) = v.strip_prefix(prefix) { + v = _v + } else { + return None; + } } - v.to_string() + v = v.strip_prefix('v').unwrap_or(v); + Some(v.to_string()) }) .rev() .collect_vec(), @@ -67,21 +72,22 @@ impl Backend for AquaBackend { } fn install_version_impl(&self, ctx: &InstallContext) -> eyre::Result<()> { - if !cfg!(windows) { - SETTINGS.ensure_experimental("aqua")?; - } let mut v = format!("v{}", ctx.tv.version); let pkg = AQUA_REGISTRY .package_with_version(&self.id, &v)? .wrap_err_with(|| format!("no aqua registry found for {}", self.id))?; if let Some(prefix) = &pkg.version_prefix { - v = format!("{}{}", prefix, ctx.tv.version); + v = format!("{}{}", prefix, v); } validate(&pkg)?; let url = match self.fetch_url(&pkg, &v) { Ok(url) => url, Err(err) => { - v = ctx.tv.version.to_string(); + if let Some(prefix) = &pkg.version_prefix { + v = format!("{}{}", prefix, ctx.tv.version); + } else { + v = ctx.tv.version.to_string(); + } self.fetch_url(&pkg, &v).map_err(|e| err.wrap_err(e))? } }; @@ -97,7 +103,7 @@ impl Backend for AquaBackend { .package_with_version(&self.id, &tv.version)? .wrap_err_with(|| format!("no aqua registry found for {}", self.ba))?; - let srcs = self.srcs(&pkg, tv); + let srcs = self.srcs(&pkg, tv)?; if srcs.is_empty() { return Ok(vec![tv.install_path()]); } @@ -143,7 +149,7 @@ impl AquaBackend { self.github_archive_url(pkg, v) } AquaPackageType::Http => { - let url = pkg.url(v); + let url = pkg.url(v)?; HTTP.head(&url)?; Ok(url) } @@ -153,7 +159,7 @@ impl AquaBackend { fn github_release_url(&self, pkg: &AquaPackage, v: &str) -> Result { let gh_id = format!("{}/{}", pkg.repo_owner, pkg.repo_name); let gh_release = github::get_release(&gh_id, v)?; - let asset_strs = pkg.asset_strs(v); + let asset_strs = pkg.asset_strs(v)?; let asset = gh_release .assets .iter() @@ -197,7 +203,7 @@ impl AquaBackend { ctx.pr.set_message(format!("installing {filename}")); let install_path = ctx.tv.install_path(); file::remove_all(&install_path)?; - let format = pkg.format(v); + let format = pkg.format(v)?; let bin_path = install_path.join(pkg.files.first().map(|f| &f.name).unwrap_or(&pkg.repo_name)); let mut tar_opts = TarOptions { @@ -236,7 +242,7 @@ impl AquaBackend { bail!("unsupported format: {}", format); } - for (src, dst) in self.srcs(pkg, &ctx.tv) { + for (src, dst) in self.srcs(pkg, &ctx.tv)? { if src != dst { if cfg!(windows) { file::copy(&src, &dst)?; @@ -249,26 +255,28 @@ impl AquaBackend { Ok(()) } - fn srcs(&self, pkg: &AquaPackage, tv: &ToolVersion) -> Vec<(PathBuf, PathBuf)> { + fn srcs(&self, pkg: &AquaPackage, tv: &ToolVersion) -> Result> { pkg.files .iter() - .flat_map(|f| { + .map(|f| { let srcs = if let Some(prefix) = &pkg.version_prefix { - vec![f.src(pkg, &format!("{}{}", prefix, tv.version))] + vec![f.src(pkg, &format!("{}{}", prefix, tv.version))?] } else { vec![ - f.src(pkg, &tv.version), - f.src(pkg, &format!("v{}", tv.version)), + f.src(pkg, &tv.version)?, + f.src(pkg, &format!("v{}", tv.version))?, ] }; - srcs.into_iter() + Ok(srcs + .into_iter() .flatten() .map(|src| tv.install_path().join(src)) .map(|src| { let dst = src.parent().unwrap().join(f.name.as_str()); (src, dst) - }) + })) }) + .flatten_ok() .collect() } } diff --git a/src/cli/direnv/envrc.rs b/src/cli/direnv/envrc.rs index 4be1ecbea0..bd43d37c23 100644 --- a/src/cli/direnv/envrc.rs +++ b/src/cli/direnv/envrc.rs @@ -55,26 +55,3 @@ impl Envrc { Ok(()) } } - -#[cfg(test)] -mod tests { - - use insta::assert_snapshot; - - use crate::test::reset; - use crate::{dirs, file}; - - #[test] - fn test_direnv_envrc() { - reset(); - let stdout = assert_cli!("direnv", "envrc"); - let envrc = file::read_to_string(stdout.trim()).unwrap(); - let envrc = envrc.replace(dirs::HOME.to_string_lossy().as_ref(), "~"); - let envrc = envrc - .lines() - .filter(|l| !l.starts_with("export REMOTE_")) - .collect::>() - .join("\n"); - assert_snapshot!(envrc); - } -} diff --git a/src/cli/direnv/exec.rs b/src/cli/direnv/exec.rs index be0623ef2b..9bba196623 100644 --- a/src/cli/direnv/exec.rs +++ b/src/cli/direnv/exec.rs @@ -47,18 +47,3 @@ fn env_cmd() -> Expression { fn env_cmd() -> Expression { cmd!("direnv", "dump") } - -#[cfg(test)] -mod tests { - use pretty_assertions::assert_str_eq; - - use crate::cli::tests::grep; - use crate::test::reset; - - #[test] - fn test_direnv_exec() { - reset(); - let stdout = assert_cli!("direnv", "exec"); - assert_str_eq!(grep(stdout, "JDXCODE_TINY="), "JDXCODE_TINY=3.1.0"); - } -} diff --git a/src/cli/registry.rs b/src/cli/registry.rs index ff59c6d250..c35d2d5ac7 100644 --- a/src/cli/registry.rs +++ b/src/cli/registry.rs @@ -20,6 +20,10 @@ pub struct Registry { /// Show only tools for this backend #[clap(short, long)] backend: Option, + + /// Hide aliased tools + #[clap(long)] + hide_aliased: bool, } impl Registry { @@ -45,6 +49,7 @@ impl Registry { let data = REGISTRY .iter() .filter(|(short, _)| !SETTINGS.disable_tools.contains(**short)) + .filter(|(short, rt)| !self.hide_aliased || **short == rt.short) .map(|(short, rt)| Row::from((short.to_string(), filter_backend(rt).join(" ")))) .filter(|row| !row.backends.is_empty()) .sorted_by(|a, b| a.short.cmp(&b.short)); diff --git a/src/registry.rs b/src/registry.rs index 3319e63c5e..46878ff94e 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -36,9 +36,6 @@ impl RegistryTool { if cfg!(windows) { backend_types.remove("asdf"); } - if cfg!(unix) && !SETTINGS.experimental { - backend_types.remove("aqua"); - } backend_types }); self.backends diff --git a/tasks/fig/src/mise.ts b/tasks/fig/src/mise.ts index 6d0dd629dc..ef342cf519 100644 --- a/tasks/fig/src/mise.ts +++ b/tasks/fig/src/mise.ts @@ -1681,6 +1681,13 @@ const completionSpec: Fig.Spec = { "isOptional": false, "isVariadic": false } + }, + { + "name": [ + "--hide-aliased" + ], + "description": "Hide aliased tools", + "isRepeatable": false } ], "args": [