diff --git a/CHANGELOG.md b/CHANGELOG.md
index 916c409529..e0d03f8ebc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,54 @@
# Changelog
+## [2026.2.2](https://github.com/jdx/mise/compare/v2026.2.1..v2026.2.2) - 2026-02-03
+
+### 🚀 Features
+
+- **(asset-matcher)** enable `mingw-w64` detection for windows packages by @lchagnoleau in [#7981](https://github.com/jdx/mise/pull/7981)
+- **(crates/vfox)** add download_path to BackendInstall context by @malept in [#7959](https://github.com/jdx/mise/pull/7959)
+- **(python)** rework `python.uv_venv_auto` setting by @halms in [#7905](https://github.com/jdx/mise/pull/7905)
+- add "Did you mean?" suggestions and inactive tool warnings by @jdx in [#7965](https://github.com/jdx/mise/pull/7965)
+
+### 🐛 Bug Fixes
+
+- **(hook-env)** skip remote version fetching for uninstalled tools in prefer-offline mode by @jdx in [#7976](https://github.com/jdx/mise/pull/7976)
+- **(install.sh)** Corret `setup` to `set up` by @gogolok in [#7980](https://github.com/jdx/mise/pull/7980)
+- retry spawn on ETXTBSY (Text file busy) by @jdx in [#7964](https://github.com/jdx/mise/pull/7964)
+- improve ToolOptions parsing to support comma separated values by @roele in [#7971](https://github.com/jdx/mise/pull/7971)
+
+### 📚 Documentation
+
+- improve plugin documentation with comparisons and template links by @jdx in [#7962](https://github.com/jdx/mise/pull/7962)
+
+### 📦️ Dependency Updates
+
+- bump hyper-util, system-configuration, lru, aws-sdk, and others by @jdx in [#7977](https://github.com/jdx/mise/pull/7977)
+
+### Chore
+
+- **(vfox)** add LuaCATS type definitions for plugin IDE support by @jdx in [#7961](https://github.com/jdx/mise/pull/7961)
+- **(vfox)** add `download_path` to `BackendInstallCtx` type defintion by @malept in [#7973](https://github.com/jdx/mise/pull/7973)
+- add stylua linting for vfox plugin Lua files by @jdx in [#7960](https://github.com/jdx/mise/pull/7960)
+- use system Rust for PPA builds on Ubuntu 26.04+ by @jdx in [#7956](https://github.com/jdx/mise/pull/7956)
+
+### New Contributors
+
+- @gogolok made their first contribution in [#7980](https://github.com/jdx/mise/pull/7980)
+
+### 📦 Aqua Registry Updates
+
+#### New Packages (4)
+
+- [`autobrr/mkbrr`](https://github.com/autobrr/mkbrr)
+- [`dodobrands/Peekie`](https://github.com/dodobrands/Peekie)
+- [`grpc/grpc-java/protoc-gen-grpc-java`](https://github.com/grpc/grpc-java/protoc-gen-grpc-java)
+- [`str4d/age-plugin-yubikey`](https://github.com/str4d/age-plugin-yubikey)
+
+#### Updated Packages (3)
+
+- [`biomejs/biome`](https://github.com/biomejs/biome)
+- [`rust-cross/cargo-zigbuild`](https://github.com/rust-cross/cargo-zigbuild)
+- [`siderolabs/talos`](https://github.com/siderolabs/talos)
## [2026.2.1](https://github.com/jdx/mise/compare/v2026.2.0..v2026.2.1) - 2026-02-02
### 🚀 Features
diff --git a/Cargo.lock b/Cargo.lock
index f224ec6120..3a86fc8bc4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -229,7 +229,7 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "aqua-registry"
-version = "2026.1.8"
+version = "2026.2.0"
dependencies = [
"expr-lang",
"eyre",
@@ -5041,7 +5041,7 @@ dependencies = [
[[package]]
name = "mise"
-version = "2026.2.1"
+version = "2026.2.2"
dependencies = [
"age",
"aho-corasick",
@@ -8825,7 +8825,7 @@ dependencies = [
[[package]]
name = "vfox"
-version = "2026.2.0"
+version = "2026.2.1"
dependencies = [
"clap",
"env_logger",
diff --git a/Cargo.toml b/Cargo.toml
index 26e03bb8e8..b09f5db989 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ members = [
[package]
name = "mise"
-version = "2026.2.1"
+version = "2026.2.2"
edition = "2024"
description = "The front-end to your dev env"
authors = ["Jeff Dickey (@jdx)"]
diff --git a/README.md b/README.md
index 4ee27b318d..47b3a37c9b 100644
--- a/README.md
+++ b/README.md
@@ -61,7 +61,7 @@ $ ~/.local/bin/mise --version
/ / / / / / (__ ) __/_____/ __/ / / /_____/ /_/ / / /_/ / /__/ __/
/_/ /_/ /_/_/____/\___/ \___/_/ /_/ / .___/_/\__,_/\___/\___/
/_/ by @jdx
-2026.2.1 macos-arm64 (2026-02-02)
+2026.2.2 macos-arm64 (2026-02-03)
```
Hook mise into your shell (pick the right one for your shell):
diff --git a/completions/_mise b/completions/_mise
index b15ac20bfb..4c4d7f6618 100644
--- a/completions/_mise
+++ b/completions/_mise
@@ -23,7 +23,7 @@ _mise() {
return 1
fi
- local spec_file="${TMPDIR:-/tmp}/usage__usage_spec_mise_2026_2_1.spec"
+ local spec_file="${TMPDIR:-/tmp}/usage__usage_spec_mise_2026_2_2.spec"
if [[ ! -f "$spec_file" ]]; then
mise usage > "$spec_file"
fi
diff --git a/completions/mise.bash b/completions/mise.bash
index 6b324f7759..b1ef3bac20 100644
--- a/completions/mise.bash
+++ b/completions/mise.bash
@@ -9,7 +9,7 @@ _mise() {
local cur prev words cword was_split comp_args
_comp_initialize -n : -- "$@" || return
- local spec_file="${TMPDIR:-/tmp}/usage__usage_spec_mise_2026_2_1.spec"
+ local spec_file="${TMPDIR:-/tmp}/usage__usage_spec_mise_2026_2_2.spec"
if [[ ! -f "$spec_file" ]]; then
mise usage > "$spec_file"
fi
diff --git a/completions/mise.fish b/completions/mise.fish
index 3a357623d9..ee914c8ae5 100644
--- a/completions/mise.fish
+++ b/completions/mise.fish
@@ -8,7 +8,7 @@ if ! type -p usage &> /dev/null
return 1
end
set -l tmpdir (if set -q TMPDIR; echo $TMPDIR; else; echo /tmp; end)
-set -l spec_file "$tmpdir/usage__usage_spec_mise_2026_2_1.spec"
+set -l spec_file "$tmpdir/usage__usage_spec_mise_2026_2_2.spec"
if not test -f "$spec_file"
mise usage | string collect > "$spec_file"
end
diff --git a/completions/mise.ps1 b/completions/mise.ps1
index b2c4c27fc5..aeb7b34733 100644
--- a/completions/mise.ps1
+++ b/completions/mise.ps1
@@ -10,7 +10,7 @@ Register-ArgumentCompleter -Native -CommandName 'mise' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$tmpDir = if ($env:TEMP) { $env:TEMP } else { [System.IO.Path]::GetTempPath() }
- $specFile = Join-Path $tmpDir "usage__usage_spec_mise_2026_2_1.kdl"
+ $specFile = Join-Path $tmpDir "usage__usage_spec_mise_2026_2_2.kdl"
if (-not (Test-Path $specFile)) {
mise usage | Out-File -FilePath $specFile -Encoding utf8
diff --git a/crates/aqua-registry/Cargo.toml b/crates/aqua-registry/Cargo.toml
index b93292ad3d..77ad7fe8a6 100644
--- a/crates/aqua-registry/Cargo.toml
+++ b/crates/aqua-registry/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "aqua-registry"
-version = "2026.1.8"
+version = "2026.2.0"
edition = "2024"
description = "Aqua registry backend for mise"
authors = ["Jeff Dickey (@jdx)"]
diff --git a/crates/aqua-registry/aqua-registry/pkgs/autobrr/mkbrr/registry.yaml b/crates/aqua-registry/aqua-registry/pkgs/autobrr/mkbrr/registry.yaml
new file mode 100644
index 0000000000..2ef5a1c248
--- /dev/null
+++ b/crates/aqua-registry/aqua-registry/pkgs/autobrr/mkbrr/registry.yaml
@@ -0,0 +1,21 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/aquaproj/aqua/main/json-schema/registry.json
+packages:
+ - type: github_release
+ repo_owner: autobrr
+ repo_name: mkbrr
+ description: mkbrr is a tool to create, modify and inspect torrent files. Fast
+ version_constraint: "false"
+ version_overrides:
+ - version_constraint: "true"
+ asset: mkbrr_{{trimV .Version}}_{{.OS}}_{{.Arch}}.{{.Format}}
+ format: tar.gz
+ windows_arm_emulation: true
+ replacements:
+ amd64: x86_64
+ checksum:
+ type: github_release
+ asset: mkbrr_{{trimV .Version}}_checksums.txt
+ algorithm: sha256
+ overrides:
+ - goos: windows
+ format: zip
diff --git a/crates/aqua-registry/aqua-registry/pkgs/biomejs/biome/registry.yaml b/crates/aqua-registry/aqua-registry/pkgs/biomejs/biome/registry.yaml
index d496972f0f..cf30408cc3 100644
--- a/crates/aqua-registry/aqua-registry/pkgs/biomejs/biome/registry.yaml
+++ b/crates/aqua-registry/aqua-registry/pkgs/biomejs/biome/registry.yaml
@@ -17,26 +17,20 @@ packages:
format: raw
replacements:
amd64: x64
- supported_envs:
- - linux
- - darwin
+ windows: win32
- version_constraint: semver("<= 2.3.8")
version_prefix: "@biomejs/biome@"
asset: biome-{{.OS}}-{{.Arch}}
format: raw
replacements:
amd64: x64
- supported_envs:
- - linux
- - darwin
+ windows: win32
- version_constraint: "true"
version_prefix: "@biomejs/biome@"
asset: biome-{{.OS}}-{{.Arch}}
format: raw
replacements:
amd64: x64
- supported_envs:
- - linux
- - darwin
+ windows: win32
github_artifact_attestations:
signer_workflow: biomejs/biome/.github/workflows/release.yml
diff --git a/crates/aqua-registry/aqua-registry/pkgs/dodobrands/Peekie/registry.yaml b/crates/aqua-registry/aqua-registry/pkgs/dodobrands/Peekie/registry.yaml
new file mode 100644
index 0000000000..73560775fe
--- /dev/null
+++ b/crates/aqua-registry/aqua-registry/pkgs/dodobrands/Peekie/registry.yaml
@@ -0,0 +1,17 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/aquaproj/aqua/main/json-schema/registry.json
+packages:
+ - type: github_release
+ repo_owner: dodobrands
+ repo_name: Peekie
+ description: Swift package for parsing Xcode .xcresult files with support for XCTest and Swift Testing frameworks
+ files:
+ - name: peekie
+ version_constraint: "false"
+ version_overrides:
+ - version_constraint: semver("<= 4.0.2")
+ no_asset: true
+ - version_constraint: "true"
+ asset: peekie_{{.Version}}_{{.OS}}_{{.Arch}}.{{.Format}}
+ format: tar.gz
+ supported_envs:
+ - darwin/arm64
diff --git a/crates/aqua-registry/aqua-registry/pkgs/grpc/grpc-java/protoc-gen-grpc-java/registry.yaml b/crates/aqua-registry/aqua-registry/pkgs/grpc/grpc-java/protoc-gen-grpc-java/registry.yaml
new file mode 100644
index 0000000000..01f6f0d827
--- /dev/null
+++ b/crates/aqua-registry/aqua-registry/pkgs/grpc/grpc-java/protoc-gen-grpc-java/registry.yaml
@@ -0,0 +1,19 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/aquaproj/aqua/main/json-schema/registry.json
+packages:
+ - name: grpc/grpc-java/protoc-gen-grpc-java
+ type: http
+ repo_owner: grpc
+ repo_name: grpc-java
+ description: The Java gRPC implementation. HTTP/2 based RPC
+ url: https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/{{trimV .Version}}/protoc-gen-grpc-java-{{trimV .Version}}-{{.OS}}-{{.Arch}}.exe
+ format: raw
+ windows_arm_emulation: true
+ replacements:
+ darwin: osx
+ amd64: x86_64
+ arm64: aarch_64
+ checksum:
+ type: http
+ url: https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/{{trimV .Version}}/protoc-gen-grpc-java-{{trimV .Version}}-{{.OS}}-{{.Arch}}.exe.sha256
+ file_format: raw
+ algorithm: sha256
diff --git a/crates/aqua-registry/aqua-registry/pkgs/rust-cross/cargo-zigbuild/registry.yaml b/crates/aqua-registry/aqua-registry/pkgs/rust-cross/cargo-zigbuild/registry.yaml
index 2c4492a2d0..17f57b40f2 100644
--- a/crates/aqua-registry/aqua-registry/pkgs/rust-cross/cargo-zigbuild/registry.yaml
+++ b/crates/aqua-registry/aqua-registry/pkgs/rust-cross/cargo-zigbuild/registry.yaml
@@ -61,7 +61,7 @@ packages:
- linux/arm64
- darwin
- windows
- - version_constraint: "true"
+ - version_constraint: semver("<= 0.21.4")
asset: cargo-zigbuild-{{.Version}}.{{.Arch}}-{{.OS}}.{{.Format}}
format: tar.gz
replacements:
@@ -83,3 +83,24 @@ packages:
asset: cargo-zigbuild-{{.Version}}.{{.OS}}-{{.Arch}}.{{.Format}}
replacements:
amd64: x64
+ - version_constraint: "true"
+ asset: cargo-zigbuild-{{.Arch}}-{{.OS}}.{{.Format}}
+ format: tar.xz
+ replacements:
+ amd64: x86_64
+ arm64: aarch64
+ darwin: apple-darwin
+ linux: unknown-linux-gnu
+ windows: pc-windows-msvc
+ checksum:
+ type: github_release
+ asset: "{{.Asset}}.sha256"
+ algorithm: sha256
+ files:
+ - name: cargo-zigbuild
+ src: "{{.AssetWithoutExt}}/{{.FileName}}"
+ overrides:
+ - goos: windows
+ format: zip
+ files:
+ - name: cargo-zigbuild
diff --git a/crates/aqua-registry/aqua-registry/pkgs/siderolabs/talos/registry.yaml b/crates/aqua-registry/aqua-registry/pkgs/siderolabs/talos/registry.yaml
index 24e9ec84e5..5d4e800dbc 100644
--- a/crates/aqua-registry/aqua-registry/pkgs/siderolabs/talos/registry.yaml
+++ b/crates/aqua-registry/aqua-registry/pkgs/siderolabs/talos/registry.yaml
@@ -5,16 +5,83 @@ packages:
repo_name: talos
aliases:
- name: talos-systems/talos
- description: Talos is a modern OS for Kubernetes. talosctl is a CLI for out-of-band management of Kubernetes nodes created by Talos
- supported_envs:
- - darwin
- - linux
- - amd64
+ description: Talos Linux is a modern Linux distribution built for Kubernetes
+ version_filter: not (Version matches "-(alpha|beta|rc)")
asset: talosctl-{{.OS}}-{{.Arch}}
+ format: raw
files:
- name: talosctl
- format: raw
- checksum:
- type: github_release
- asset: sha512sum.txt
- algorithm: sha512
+ version_constraint: "false"
+ version_overrides:
+ - version_constraint: Version == "v1.2.9"
+ windows_arm_emulation: true
+ checksum:
+ type: github_release
+ asset: sha512sum.txt
+ algorithm: sha512
+ - version_constraint: semver("<= 0.2.0")
+ asset: osctl-{{.OS}}-{{.Arch}}
+ files:
+ - name: osctl
+ rosetta2: true
+ checksum:
+ type: github_release
+ asset: sha256sum.txt
+ algorithm: sha256
+ supported_envs:
+ - linux/amd64
+ - darwin/amd64
+ - version_constraint: semver("<= 0.3.3")
+ asset: osctl-{{.OS}}-{{.Arch}}
+ files:
+ - name: osctl
+ rosetta2: true
+ checksum:
+ type: github_release
+ asset: sha512sum.txt
+ algorithm: sha512
+ supported_envs:
+ - linux/amd64
+ - darwin/amd64
+ - version_constraint: semver("<= 0.10.4")
+ rosetta2: true
+ checksum:
+ type: github_release
+ asset: sha256sum.txt
+ algorithm: sha256
+ supported_envs:
+ - linux
+ - darwin/amd64
+ - version_constraint: semver("<= 0.12.3")
+ checksum:
+ type: github_release
+ asset: sha256sum.txt
+ algorithm: sha256
+ supported_envs:
+ - linux
+ - darwin
+ - version_constraint: semver("<= 1.8.4")
+ windows_arm_emulation: true
+ checksum:
+ type: github_release
+ asset: sha256sum.txt
+ algorithm: sha256
+ - version_constraint: semver("<= 1.11.3")
+ checksum:
+ type: github_release
+ asset: sha256sum.txt
+ algorithm: sha256
+ - version_constraint: "true"
+ checksum:
+ type: github_release
+ asset: sha256sum.txt
+ algorithm: sha256
+ cosign:
+ opts:
+ - --certificate-identity
+ - https://github.com/siderolabs/talos/.github/workflows/ci.yaml@refs/tags/{{.Version}}
+ - --certificate-oidc-issuer
+ - https://token.actions.githubusercontent.com
+ bundle:
+ type: github_release
+ asset: sha256sum.txt.bundle
diff --git a/crates/aqua-registry/aqua-registry/pkgs/str4d/age-plugin-yubikey/registry.yaml b/crates/aqua-registry/aqua-registry/pkgs/str4d/age-plugin-yubikey/registry.yaml
new file mode 100644
index 0000000000..1e49b55556
--- /dev/null
+++ b/crates/aqua-registry/aqua-registry/pkgs/str4d/age-plugin-yubikey/registry.yaml
@@ -0,0 +1,50 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/aquaproj/aqua/main/json-schema/registry.json
+packages:
+ - type: github_release
+ repo_owner: str4d
+ repo_name: age-plugin-yubikey
+ description: YubiKey plugin for age
+ version_constraint: "false"
+ files:
+ - name: age-plugin-yubikey
+ src: age-plugin-yubikey/age-plugin-yubikey
+ version_overrides:
+ - version_constraint: semver("<= 0.3.0")
+ asset: age-plugin-yubikey-{{.Version}}-{{.Arch}}-{{.OS}}.{{.Format}}
+ format: tar.gz
+ rosetta2: true
+ windows_arm_emulation: true
+ replacements:
+ amd64: x86_64
+ overrides:
+ - goos: windows
+ format: zip
+ supported_envs:
+ - darwin
+ - windows
+ - amd64
+ - version_constraint: semver("<= 0.4.0")
+ asset: age-plugin-yubikey-{{.Version}}-{{.Arch}}-{{.OS}}.{{.Format}}
+ format: tar.gz
+ windows_arm_emulation: true
+ replacements:
+ amd64: x86_64
+ overrides:
+ - goos: windows
+ format: zip
+ supported_envs:
+ - darwin
+ - amd64
+ - version_constraint: "true"
+ asset: age-plugin-yubikey-{{.Version}}-{{.Arch}}-{{.OS}}.{{.Format}}
+ format: tar.gz
+ windows_arm_emulation: true
+ replacements:
+ amd64: x86_64
+ overrides:
+ - goos: windows
+ format: zip
+ supported_envs:
+ - darwin/arm64
+ - linux/amd64
+ - windows
diff --git a/crates/vfox/Cargo.toml b/crates/vfox/Cargo.toml
index b4932bd5fe..a66205df3f 100644
--- a/crates/vfox/Cargo.toml
+++ b/crates/vfox/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "vfox"
-version = "2026.2.0"
+version = "2026.2.1"
edition = "2024"
license = "MIT"
description = "Interface to vfox plugins"
diff --git a/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/available.lua
index c83fa2df26..c0c5d2554c 100644
--- a/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/available.lua
@@ -2,38 +2,38 @@
--- @param ctx table Empty table used as context, for future extension
--- @return table Descriptions of available versions and accompanying tool descriptions
function PLUGIN:Available(ctx)
- local http = require("http")
- local env = require("env")
+ local http = require("http")
+ local env = require("env")
- local base_url = env.ANDROID_SDK_MIRROR_URL or "https://dl.google.com/android/repository"
- local metadata_url = base_url .. "/repository2-3.xml"
+ local base_url = env.ANDROID_SDK_MIRROR_URL or "https://dl.google.com/android/repository"
+ local metadata_url = base_url .. "/repository2-3.xml"
- local resp = http.get({ url = metadata_url })
- if resp.status_code ~= 200 then
- error("Failed to fetch Android SDK metadata: HTTP " .. resp.status_code)
- end
+ local resp = http.get({ url = metadata_url })
+ if resp.status_code ~= 200 then
+ error("Failed to fetch Android SDK metadata: HTTP " .. resp.status_code)
+ end
- local versions = {}
- local seen = {}
+ local versions = {}
+ local seen = {}
- -- Parse XML to find cmdline-tools packages
- -- Look for remotePackage elements with path="cmdline-tools;VERSION"
- for path_attr in resp.body:gmatch('remotePackage%s+path="([^"]+)"') do
- -- Match cmdline-tools;VERSION pattern, excluding "latest"
- local version = path_attr:match("^cmdline%-tools;(.+)$")
- if version and version ~= "latest" and not seen[version] then
- seen[version] = true
- table.insert(versions, {
- version = version,
- note = "",
- })
- end
- end
+ -- Parse XML to find cmdline-tools packages
+ -- Look for remotePackage elements with path="cmdline-tools;VERSION"
+ for path_attr in resp.body:gmatch('remotePackage%s+path="([^"]+)"') do
+ -- Match cmdline-tools;VERSION pattern, excluding "latest"
+ local version = path_attr:match("^cmdline%-tools;(.+)$")
+ if version and version ~= "latest" and not seen[version] then
+ seen[version] = true
+ table.insert(versions, {
+ version = version,
+ note = "",
+ })
+ end
+ end
- -- Sort versions (simple string sort, works for numeric versions)
- table.sort(versions, function(a, b)
- return a.version < b.version
- end)
+ -- Sort versions (simple string sort, works for numeric versions)
+ table.sort(versions, function(a, b)
+ return a.version < b.version
+ end)
- return versions
+ return versions
end
diff --git a/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/env_keys.lua
index 63458b7c1c..6b4ef47b84 100644
--- a/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/env_keys.lua
@@ -3,26 +3,26 @@
--- @field ctx.version string The version
--- @return table Environment variables
function PLUGIN:EnvKeys(ctx)
- local file = require("file")
+ local file = require("file")
- local install_path = ctx.path
- local version = ctx.version
+ local install_path = ctx.path
+ local version = ctx.version
- -- Structure is: install_path/cmdline-tools/VERSION/bin
- local bin_path = file.join_path(install_path, "cmdline-tools", version, "bin")
+ -- Structure is: install_path/cmdline-tools/VERSION/bin
+ local bin_path = file.join_path(install_path, "cmdline-tools", version, "bin")
- return {
- {
- key = "PATH",
- value = bin_path,
- },
- {
- key = "ANDROID_HOME",
- value = install_path,
- },
- {
- key = "ANDROID_SDK_ROOT",
- value = install_path,
- },
- }
+ return {
+ {
+ key = "PATH",
+ value = bin_path,
+ },
+ {
+ key = "ANDROID_HOME",
+ value = install_path,
+ },
+ {
+ key = "ANDROID_SDK_ROOT",
+ value = install_path,
+ },
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/post_install.lua
index 68ac795dd3..3c9ffd5964 100644
--- a/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/post_install.lua
@@ -4,46 +4,46 @@
--- @field ctx.rootPath string The installation root path
--- @field ctx.sdkInfo table SDK information including version
function PLUGIN:PostInstall(ctx)
- local file = require("file")
+ local file = require("file")
- local root_path = ctx.rootPath
+ local root_path = ctx.rootPath
- -- Get the version from sdkInfo
- local version = nil
- for _, info in pairs(ctx.sdkInfo) do
- version = info.version
- break
- end
+ -- Get the version from sdkInfo
+ local version = nil
+ for _, info in pairs(ctx.sdkInfo) do
+ version = info.version
+ break
+ end
- if not version then
- error("Could not determine version from sdkInfo")
- end
+ if not version then
+ error("Could not determine version from sdkInfo")
+ end
- -- vfox extracts cmdline-tools contents directly to rootPath
- -- But Android SDK expects: ANDROID_HOME/cmdline-tools/VERSION/bin/sdkmanager
- -- So we need to reorganize: move rootPath/* to rootPath/cmdline-tools/VERSION/
+ -- vfox extracts cmdline-tools contents directly to rootPath
+ -- But Android SDK expects: ANDROID_HOME/cmdline-tools/VERSION/bin/sdkmanager
+ -- So we need to reorganize: move rootPath/* to rootPath/cmdline-tools/VERSION/
- local temp_path = root_path .. "-temp"
- local target_path = file.join_path(root_path, "cmdline-tools", version)
+ local temp_path = root_path .. "-temp"
+ local target_path = file.join_path(root_path, "cmdline-tools", version)
- -- Move current rootPath to temp location
- os.execute("mv " .. root_path .. " " .. temp_path)
+ -- Move current rootPath to temp location
+ os.execute("mv " .. root_path .. " " .. temp_path)
- -- Recreate rootPath with proper structure
- os.execute("mkdir -p " .. target_path)
+ -- Recreate rootPath with proper structure
+ os.execute("mkdir -p " .. target_path)
- -- Move contents from temp to target
- os.execute("mv " .. temp_path .. "/* " .. target_path .. "/")
+ -- Move contents from temp to target
+ os.execute("mv " .. temp_path .. "/* " .. target_path .. "/")
- -- Clean up temp
- os.execute("rm -rf " .. temp_path)
+ -- Clean up temp
+ os.execute("rm -rf " .. temp_path)
- -- Verify installation
- local sdkmanager_path = file.join_path(target_path, "bin", "sdkmanager")
- if not file.exists(sdkmanager_path) then
- error("Installation verification failed: sdkmanager not found at " .. sdkmanager_path)
- end
+ -- Verify installation
+ local sdkmanager_path = file.join_path(target_path, "bin", "sdkmanager")
+ if not file.exists(sdkmanager_path) then
+ error("Installation verification failed: sdkmanager not found at " .. sdkmanager_path)
+ end
- -- Make sure binaries are executable (for Unix systems)
- os.execute("chmod +x " .. file.join_path(target_path, "bin", "*") .. " 2>/dev/null || true")
+ -- Make sure binaries are executable (for Unix systems)
+ os.execute("chmod +x " .. file.join_path(target_path, "bin", "*") .. " 2>/dev/null || true")
end
diff --git a/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/pre_install.lua
index 6f1d886170..459c921db2 100644
--- a/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-android-sdk/hooks/pre_install.lua
@@ -2,106 +2,106 @@
--- @param ctx {version: string} (User-input version)
--- @return table Version information
function PLUGIN:PreInstall(ctx)
- local http = require("http")
- local env = require("env")
-
- local version = ctx.version
-
- -- Determine OS (from global RUNTIME object)
- local os_type = RUNTIME.osType
- local android_sdk_os
- if os_type == "darwin" then
- android_sdk_os = "macosx"
- elseif os_type == "linux" then
- android_sdk_os = "linux"
- elseif os_type == "windows" then
- android_sdk_os = "windows"
- else
- error("Unsupported OS type: " .. os_type)
- end
-
- -- Determine architecture (from global RUNTIME object)
- local arch_type = RUNTIME.archType
- local android_sdk_arch
- if arch_type == "amd64" or arch_type == "x86_64" then
- android_sdk_arch = "x64"
- elseif arch_type == "arm64" or arch_type == "aarch64" then
- android_sdk_arch = "aarch64"
- else
- error("Unsupported architecture: " .. arch_type)
- end
-
- local base_url = env.ANDROID_SDK_MIRROR_URL or "https://dl.google.com/android/repository"
- local metadata_url = base_url .. "/repository2-3.xml"
-
- local resp = http.get({ url = metadata_url })
- if resp.status_code ~= 200 then
- error("Failed to fetch Android SDK metadata: HTTP " .. resp.status_code)
- end
-
- -- Parse the XML to find the matching package
- local package_pattern = 'remotePackage%s+path="cmdline%-tools;'
- .. version:gsub("%-", "%%-")
- .. '".-'
- local package_block = resp.body:match(package_pattern)
-
- if not package_block then
- error("Version " .. version .. " not found in Android SDK repository")
- end
-
- -- Find archives block
- local archives_block = package_block:match("(.-)")
- if not archives_block then
- error("No archives found for version " .. version)
- end
-
- -- Find matching archive for our OS/arch
- local best_archive = nil
-
- for archive in archives_block:gmatch("(.-)") do
- local host_os = archive:match("([^<]+)")
- local host_arch = archive:match("([^<]+)")
-
- -- Match if OS matches and either no arch specified or arch matches
- if host_os == android_sdk_os then
- if host_arch == nil or host_arch == android_sdk_arch then
- best_archive = archive
- -- Prefer exact arch match
- if host_arch == android_sdk_arch then
- break
- end
- end
- end
- end
-
- if not best_archive then
- error("No archive found for " .. android_sdk_os .. ":" .. android_sdk_arch)
- end
-
- -- Extract complete block (contains url, size, checksum)
- local complete_block = best_archive:match("(.-)")
- if not complete_block then
- error("No complete block found in archive")
- end
-
- -- Extract URL
- local url = complete_block:match("([^<]+)")
- if not url then
- error("No URL found in archive")
- end
-
- -- Make URL absolute if it's relative
- if not url:match("^https?://") then
- url = base_url .. "/" .. url
- end
-
- local result = {
- version = version,
- url = url,
- }
-
- -- Note: Android SDK only provides sha1 checksums, which vfox doesn't support yet
- -- Checksum verification is skipped for now
-
- return result
+ local http = require("http")
+ local env = require("env")
+
+ local version = ctx.version
+
+ -- Determine OS (from global RUNTIME object)
+ local os_type = RUNTIME.osType
+ local android_sdk_os
+ if os_type == "darwin" then
+ android_sdk_os = "macosx"
+ elseif os_type == "linux" then
+ android_sdk_os = "linux"
+ elseif os_type == "windows" then
+ android_sdk_os = "windows"
+ else
+ error("Unsupported OS type: " .. os_type)
+ end
+
+ -- Determine architecture (from global RUNTIME object)
+ local arch_type = RUNTIME.archType
+ local android_sdk_arch
+ if arch_type == "amd64" or arch_type == "x86_64" then
+ android_sdk_arch = "x64"
+ elseif arch_type == "arm64" or arch_type == "aarch64" then
+ android_sdk_arch = "aarch64"
+ else
+ error("Unsupported architecture: " .. arch_type)
+ end
+
+ local base_url = env.ANDROID_SDK_MIRROR_URL or "https://dl.google.com/android/repository"
+ local metadata_url = base_url .. "/repository2-3.xml"
+
+ local resp = http.get({ url = metadata_url })
+ if resp.status_code ~= 200 then
+ error("Failed to fetch Android SDK metadata: HTTP " .. resp.status_code)
+ end
+
+ -- Parse the XML to find the matching package
+ local package_pattern = 'remotePackage%s+path="cmdline%-tools;'
+ .. version:gsub("%-", "%%-")
+ .. '".-'
+ local package_block = resp.body:match(package_pattern)
+
+ if not package_block then
+ error("Version " .. version .. " not found in Android SDK repository")
+ end
+
+ -- Find archives block
+ local archives_block = package_block:match("(.-)")
+ if not archives_block then
+ error("No archives found for version " .. version)
+ end
+
+ -- Find matching archive for our OS/arch
+ local best_archive = nil
+
+ for archive in archives_block:gmatch("(.-)") do
+ local host_os = archive:match("([^<]+)")
+ local host_arch = archive:match("([^<]+)")
+
+ -- Match if OS matches and either no arch specified or arch matches
+ if host_os == android_sdk_os then
+ if host_arch == nil or host_arch == android_sdk_arch then
+ best_archive = archive
+ -- Prefer exact arch match
+ if host_arch == android_sdk_arch then
+ break
+ end
+ end
+ end
+ end
+
+ if not best_archive then
+ error("No archive found for " .. android_sdk_os .. ":" .. android_sdk_arch)
+ end
+
+ -- Extract complete block (contains url, size, checksum)
+ local complete_block = best_archive:match("(.-)")
+ if not complete_block then
+ error("No complete block found in archive")
+ end
+
+ -- Extract URL
+ local url = complete_block:match("([^<]+)")
+ if not url then
+ error("No URL found in archive")
+ end
+
+ -- Make URL absolute if it's relative
+ if not url:match("^https?://") then
+ url = base_url .. "/" .. url
+ end
+
+ local result = {
+ version = version,
+ url = url,
+ }
+
+ -- Note: Android SDK only provides sha1 checksums, which vfox doesn't support yet
+ -- Checksum verification is skipped for now
+
+ return result
end
diff --git a/crates/vfox/embedded-plugins/vfox-android-sdk/metadata.lua b/crates/vfox/embedded-plugins/vfox-android-sdk/metadata.lua
index 7f393550d2..57cafeb663 100644
--- a/crates/vfox/embedded-plugins/vfox-android-sdk/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-android-sdk/metadata.lua
@@ -18,6 +18,6 @@ PLUGIN.description = "Android SDK Command-line Tools"
PLUGIN.minRuntimeVersion = "0.3.0"
--- Some things that need user to be attention!
PLUGIN.notes = {
- "Requires Java 11+ to be installed",
- "Set ANDROID_SDK_MIRROR_URL to use a mirror",
+ "Requires Java 11+ to be installed",
+ "Set ANDROID_SDK_MIRROR_URL to use a mirror",
}
diff --git a/crates/vfox/embedded-plugins/vfox-ant/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-ant/hooks/available.lua
index b32c9c8c73..8621fcd48b 100644
--- a/crates/vfox/embedded-plugins/vfox-ant/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-ant/hooks/available.lua
@@ -4,11 +4,11 @@ local util = require("util")
--- @param ctx table Empty table used as context, for future extension
--- @return table Descriptions of available versions and accompanying tool descriptions
function PLUGIN:Available(ctx)
- local versions = util.parseVersions()
+ local versions = util.parseVersions()
- table.sort(versions, function(a, b)
- return util.compareVersions(a.version, b.version)
- end)
+ table.sort(versions, function(a, b)
+ return util.compareVersions(a.version, b.version)
+ end)
- return versions
+ return versions
end
diff --git a/crates/vfox/embedded-plugins/vfox-ant/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-ant/hooks/env_keys.lua
index 049038cfc8..14147c5f4e 100644
--- a/crates/vfox/embedded-plugins/vfox-ant/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-ant/hooks/env_keys.lua
@@ -2,15 +2,15 @@
--- This allows plugins to define custom environment variables (including PATH settings)
--- @param ctx {path: string} Context information (SDK installation directory)
function PLUGIN:EnvKeys(ctx)
- local mainPath = ctx.path
- return {
- {
- key = "PATH",
- value = mainPath .. "/bin",
- },
- {
- key = "ANT_HOME",
- value = mainPath,
- },
- }
+ local mainPath = ctx.path
+ return {
+ {
+ key = "PATH",
+ value = mainPath .. "/bin",
+ },
+ {
+ key = "ANT_HOME",
+ value = mainPath,
+ },
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-ant/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-ant/hooks/post_install.lua
index f363f9fbdc..4c2ed55966 100644
--- a/crates/vfox/embedded-plugins/vfox-ant/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-ant/hooks/post_install.lua
@@ -3,6 +3,6 @@
--- @param ctx table
--- @field ctx.rootPath string SDK installation directory
function PLUGIN:PostInstall(ctx)
- -- The tarball extracts to apache-ant-{version}/ directory
- -- mise should handle this automatically
+ -- The tarball extracts to apache-ant-{version}/ directory
+ -- mise should handle this automatically
end
diff --git a/crates/vfox/embedded-plugins/vfox-ant/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-ant/hooks/pre_install.lua
index 2b825fd6f7..645d60dc82 100644
--- a/crates/vfox/embedded-plugins/vfox-ant/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-ant/hooks/pre_install.lua
@@ -6,34 +6,34 @@ local util = require("util")
--- @param ctx {version: string} (User-input version)
--- @return table Version information
function PLUGIN:PreInstall(ctx)
- local version = ctx.version
+ local version = ctx.version
- -- Try to get checksum (sha512 first, then sha1)
- local checksums = {
- { type = "sha512", url = util.CHECKSUM_URL:format(version, "sha512") },
- { type = "sha1", url = util.CHECKSUM_URL:format(version, "sha1") },
- }
+ -- Try to get checksum (sha512 first, then sha1)
+ local checksums = {
+ { type = "sha512", url = util.CHECKSUM_URL:format(version, "sha512") },
+ { type = "sha1", url = util.CHECKSUM_URL:format(version, "sha1") },
+ }
- for _, checksum in ipairs(checksums) do
- local resp, err = http.get({
- url = checksum.url,
- })
- if err == nil and resp.status_code == 200 then
- local hash = string.match(resp.body, "^(%S+)")
- if hash then
- local result = {
- version = version,
- url = util.FILE_URL:format(version),
- }
- result[checksum.type] = hash
- return result
- end
- end
- end
+ for _, checksum in ipairs(checksums) do
+ local resp, err = http.get({
+ url = checksum.url,
+ })
+ if err == nil and resp.status_code == 200 then
+ local hash = string.match(resp.body, "^(%S+)")
+ if hash then
+ local result = {
+ version = version,
+ url = util.FILE_URL:format(version),
+ }
+ result[checksum.type] = hash
+ return result
+ end
+ end
+ end
- -- No checksum found, return without checksum
- return {
- version = version,
- url = util.FILE_URL:format(version),
- }
+ -- No checksum found, return without checksum
+ return {
+ version = version,
+ url = util.FILE_URL:format(version),
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-ant/lib/util.lua b/crates/vfox/embedded-plugins/vfox-ant/lib/util.lua
index 420e3e2095..84dfd44b05 100644
--- a/crates/vfox/embedded-plugins/vfox-ant/lib/util.lua
+++ b/crates/vfox/embedded-plugins/vfox-ant/lib/util.lua
@@ -9,7 +9,7 @@ util.CHECKSUM_URL = "https://archive.apache.org/dist/ant/binaries/apache-ant-%s-
function util.parseVersions()
local resp, err = http.get({
- url = util.ARCHIVE_URL
+ url = util.ARCHIVE_URL,
})
if err ~= nil or resp.status_code ~= 200 then
error("Failed to fetch version list: " .. (err or "HTTP " .. resp.status_code))
diff --git a/crates/vfox/embedded-plugins/vfox-ant/metadata.lua b/crates/vfox/embedded-plugins/vfox-ant/metadata.lua
index e6ff426b02..587fa88a7a 100644
--- a/crates/vfox/embedded-plugins/vfox-ant/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-ant/metadata.lua
@@ -16,5 +16,5 @@ PLUGIN.description = "Apache Ant build tool"
--- !!! OPTIONAL !!!
PLUGIN.minRuntimeVersion = "0.3.0"
PLUGIN.notes = {
- "Apache Ant is a Java library and command-line tool for building Java applications.",
+ "Apache Ant is a Java library and command-line tool for building Java applications.",
}
diff --git a/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/available.lua
index c006dddbf7..5ec666aa46 100644
--- a/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/available.lua
@@ -4,37 +4,37 @@ local http = require("http")
--- @param ctx table Empty table, no data provided. Always {}.
--- @return table Version list
function PLUGIN:Available(ctx)
- local result = {}
-
- local resp = http.get({
- url = "https://repo1.maven.org/maven2/org/asciidoctor/asciidoctorj/",
- })
-
- if resp.status_code ~= 200 then
- error("Failed to fetch versions from Maven Central: " .. resp.status_code)
- end
-
- -- Parse version directories from Maven Central HTML
- -- Pattern matches:
- for version in resp.body:gmatch(' 1 or (major == 1 and minor >= 5) then
- table.insert(result, {
- version = version,
- })
- end
- end
- end
-
- -- Sort versions (newest first)
- table.sort(result, function(a, b)
- return compare_versions(a.version, b.version)
- end)
-
- return result
+ local result = {}
+
+ local resp = http.get({
+ url = "https://repo1.maven.org/maven2/org/asciidoctor/asciidoctorj/",
+ })
+
+ if resp.status_code ~= 200 then
+ error("Failed to fetch versions from Maven Central: " .. resp.status_code)
+ end
+
+ -- Parse version directories from Maven Central HTML
+ -- Pattern matches:
+ for version in resp.body:gmatch(' 1 or (major == 1 and minor >= 5) then
+ table.insert(result, {
+ version = version,
+ })
+ end
+ end
+ end
+
+ -- Sort versions (newest first)
+ table.sort(result, function(a, b)
+ return compare_versions(a.version, b.version)
+ end)
+
+ return result
end
--- Compare two version strings
@@ -42,20 +42,20 @@ end
--- @param v2 string
--- @return boolean true if v1 > v2
function compare_versions(v1, v2)
- local function parse(v)
- local parts = {}
- for num in v:gmatch("(%d+)") do
- table.insert(parts, tonumber(num))
- end
- return parts
- end
-
- local p1, p2 = parse(v1), parse(v2)
- for i = 1, math.max(#p1, #p2) do
- local n1, n2 = p1[i] or 0, p2[i] or 0
- if n1 ~= n2 then
- return n1 > n2
- end
- end
- return false
+ local function parse(v)
+ local parts = {}
+ for num in v:gmatch("(%d+)") do
+ table.insert(parts, tonumber(num))
+ end
+ return parts
+ end
+
+ local p1, p2 = parse(v1), parse(v2)
+ for i = 1, math.max(#p1, #p2) do
+ local n1, n2 = p1[i] or 0, p2[i] or 0
+ if n1 ~= n2 then
+ return n1 > n2
+ end
+ end
+ return false
end
diff --git a/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/env_keys.lua
index eea59e79f9..2de582c5d8 100644
--- a/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/env_keys.lua
@@ -2,11 +2,11 @@
--- @param ctx {path: string} (Installation path)
--- @return table Environment variables
function PLUGIN:EnvKeys(ctx)
- -- mise flattens the zip structure, so bin is directly in ctx.path
- return {
- {
- key = "PATH",
- value = ctx.path .. "/bin",
- },
- }
+ -- mise flattens the zip structure, so bin is directly in ctx.path
+ return {
+ {
+ key = "PATH",
+ value = ctx.path .. "/bin",
+ },
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/pre_install.lua
index eb96b9b75d..0a7b80d096 100644
--- a/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-asciidoctorj/hooks/pre_install.lua
@@ -4,19 +4,19 @@ local http = require("http")
--- @param ctx {version: string} (User-input version)
--- @return table Version information
function PLUGIN:PreInstall(ctx)
- local version = ctx.version
+ local version = ctx.version
- local base_url = "https://repo1.maven.org/maven2/org/asciidoctor/asciidoctorj/"
- local download_url = base_url .. version .. "/asciidoctorj-" .. version .. "-bin.zip"
+ local base_url = "https://repo1.maven.org/maven2/org/asciidoctor/asciidoctorj/"
+ local download_url = base_url .. version .. "/asciidoctorj-" .. version .. "-bin.zip"
- -- Verify URL exists
- local resp = http.head({ url = download_url })
- if resp.status_code ~= 200 then
- error("Download URL not found: " .. download_url .. " (status: " .. resp.status_code .. ")")
- end
+ -- Verify URL exists
+ local resp = http.head({ url = download_url })
+ if resp.status_code ~= 200 then
+ error("Download URL not found: " .. download_url .. " (status: " .. resp.status_code .. ")")
+ end
- return {
- version = version,
- url = download_url,
- }
+ return {
+ version = version,
+ url = download_url,
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-asciidoctorj/metadata.lua b/crates/vfox/embedded-plugins/vfox-asciidoctorj/metadata.lua
index 7148ab50a9..0cad0eed42 100644
--- a/crates/vfox/embedded-plugins/vfox-asciidoctorj/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-asciidoctorj/metadata.lua
@@ -16,6 +16,6 @@ PLUGIN.description = "AsciidoctorJ - the official library for running Asciidocto
--- !!! OPTIONAL !!!
PLUGIN.minRuntimeVersion = "0.3.0"
PLUGIN.notes = {
- "Provides the asciidoctorj command for converting AsciiDoc documents",
- "Requires Java to be installed",
+ "Provides the asciidoctorj command for converting AsciiDoc documents",
+ "Requires Java to be installed",
}
diff --git a/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/available.lua
index 60d4ac0135..4b04a9720d 100644
--- a/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/available.lua
@@ -5,50 +5,50 @@ local json = require("json")
--- @param ctx table Empty table, no data provided. Always {}.
--- @return table Version list
function PLUGIN:Available(ctx)
- local result = {}
- local page = 1
- local per_page = 100
+ local result = {}
+ local page = 1
+ local per_page = 100
- while true do
- local url = "https://api.github.com/repos/Azure/azure-functions-core-tools/releases?per_page="
- .. per_page
- .. "&page="
- .. page
- local resp = http.get({
- url = url,
- headers = {
- ["Accept"] = "application/vnd.github.v3+json",
- },
- })
+ while true do
+ local url = "https://api.github.com/repos/Azure/azure-functions-core-tools/releases?per_page="
+ .. per_page
+ .. "&page="
+ .. page
+ local resp = http.get({
+ url = url,
+ headers = {
+ ["Accept"] = "application/vnd.github.v3+json",
+ },
+ })
- if resp.status_code ~= 200 then
- if page == 1 then
- error("Failed to fetch releases from GitHub: " .. resp.status_code)
- end
- break
- end
+ if resp.status_code ~= 200 then
+ if page == 1 then
+ error("Failed to fetch releases from GitHub: " .. resp.status_code)
+ end
+ break
+ end
- local releases = json.decode(resp.body)
- if #releases == 0 then
- break
- end
+ local releases = json.decode(resp.body)
+ if #releases == 0 then
+ break
+ end
- for _, release in ipairs(releases) do
- if not release.prerelease and not release.draft then
- local version = release.tag_name
- table.insert(result, {
- version = version,
- note = release.name or "",
- })
- end
- end
+ for _, release in ipairs(releases) do
+ if not release.prerelease and not release.draft then
+ local version = release.tag_name
+ table.insert(result, {
+ version = version,
+ note = release.name or "",
+ })
+ end
+ end
- page = page + 1
- -- Limit to avoid too many API calls
- if page > 5 then
- break
- end
- end
+ page = page + 1
+ -- Limit to avoid too many API calls
+ if page > 5 then
+ break
+ end
+ end
- return result
+ return result
end
diff --git a/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/env_keys.lua
index 6370f63010..215ffa462b 100644
--- a/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/env_keys.lua
@@ -2,11 +2,11 @@
--- @param ctx {path: string} (Installation path)
--- @return table Environment variables
function PLUGIN:EnvKeys(ctx)
- -- The func binary is at the root of the extracted zip
- return {
- {
- key = "PATH",
- value = ctx.path,
- },
- }
+ -- The func binary is at the root of the extracted zip
+ return {
+ {
+ key = "PATH",
+ value = ctx.path,
+ },
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/post_install.lua
index 55f163f5b5..696bac8f9e 100644
--- a/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/post_install.lua
@@ -2,23 +2,23 @@
--- @param ctx table
--- @field ctx.rootPath string Installation root path
function PLUGIN:PostInstall(ctx)
- local os_type = RUNTIME.osType
+ local os_type = RUNTIME.osType
- -- On Unix systems, we need to make the binary executable
- if os_type ~= "windows" then
- local func_path = ctx.rootPath .. "/func"
- -- Use os.execute to chmod +x the binary
- local result = os.execute("chmod +x " .. func_path)
- if result ~= 0 and result ~= true then
- -- Some Lua versions return true on success, others return 0
- print("Warning: could not chmod +x " .. func_path)
- end
+ -- On Unix systems, we need to make the binary executable
+ if os_type ~= "windows" then
+ local func_path = ctx.rootPath .. "/func"
+ -- Use os.execute to chmod +x the binary
+ local result = os.execute("chmod +x " .. func_path)
+ if result ~= 0 and result ~= true then
+ -- Some Lua versions return true on success, others return 0
+ print("Warning: could not chmod +x " .. func_path)
+ end
- -- Also chmod other potential executables
- local gozip_path = ctx.rootPath .. "/gozip"
- os.execute("chmod +x " .. gozip_path .. " 2>/dev/null")
+ -- Also chmod other potential executables
+ local gozip_path = ctx.rootPath .. "/gozip"
+ os.execute("chmod +x " .. gozip_path .. " 2>/dev/null")
- local createdump_path = ctx.rootPath .. "/createdump"
- os.execute("chmod +x " .. createdump_path .. " 2>/dev/null")
- end
+ local createdump_path = ctx.rootPath .. "/createdump"
+ os.execute("chmod +x " .. createdump_path .. " 2>/dev/null")
+ end
end
diff --git a/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/pre_install.lua
index 8d02313fbb..91f7f089d4 100644
--- a/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/hooks/pre_install.lua
@@ -4,44 +4,44 @@ local http = require("http")
--- @param ctx {version: string} (User-input version)
--- @return table Version information
function PLUGIN:PreInstall(ctx)
- local version = ctx.version
- local os_type = RUNTIME.osType
- local arch_type = RUNTIME.archType
+ local version = ctx.version
+ local os_type = RUNTIME.osType
+ local arch_type = RUNTIME.archType
- -- Map OS type to Azure naming convention
- local os_name
- if os_type == "darwin" then
- os_name = "osx"
- elseif os_type == "windows" then
- os_name = "win"
- else
- os_name = "linux"
- end
+ -- Map OS type to Azure naming convention
+ local os_name
+ if os_type == "darwin" then
+ os_name = "osx"
+ elseif os_type == "windows" then
+ os_name = "win"
+ else
+ os_name = "linux"
+ end
- -- Map architecture
- local arch
- if arch_type == "amd64" or arch_type == "x86_64" then
- arch = "x64"
- elseif arch_type == "arm64" or arch_type == "aarch64" then
- arch = "arm64"
- elseif arch_type == "386" or arch_type == "i386" or arch_type == "i686" then
- arch = "x86"
- else
- arch = arch_type
- end
+ -- Map architecture
+ local arch
+ if arch_type == "amd64" or arch_type == "x86_64" then
+ arch = "x64"
+ elseif arch_type == "arm64" or arch_type == "aarch64" then
+ arch = "arm64"
+ elseif arch_type == "386" or arch_type == "i386" or arch_type == "i686" then
+ arch = "x86"
+ else
+ arch = arch_type
+ end
- local base_url = "https://github.com/Azure/azure-functions-core-tools/releases/download/"
- local filename = "Azure.Functions.Cli." .. os_name .. "-" .. arch .. "." .. version .. ".zip"
- local download_url = base_url .. version .. "/" .. filename
+ local base_url = "https://github.com/Azure/azure-functions-core-tools/releases/download/"
+ local filename = "Azure.Functions.Cli." .. os_name .. "-" .. arch .. "." .. version .. ".zip"
+ local download_url = base_url .. version .. "/" .. filename
- -- Verify URL exists
- local resp = http.head({ url = download_url })
- if resp.status_code ~= 200 and resp.status_code ~= 302 then
- error("Download URL not found: " .. download_url .. " (status: " .. resp.status_code .. ")")
- end
+ -- Verify URL exists
+ local resp = http.head({ url = download_url })
+ if resp.status_code ~= 200 and resp.status_code ~= 302 then
+ error("Download URL not found: " .. download_url .. " (status: " .. resp.status_code .. ")")
+ end
- return {
- version = version,
- url = download_url,
- }
+ return {
+ version = version,
+ url = download_url,
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/metadata.lua b/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/metadata.lua
index a90a88125b..545a0767a1 100644
--- a/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-azure-functions-core-tools/metadata.lua
@@ -16,5 +16,5 @@ PLUGIN.description = "Azure Functions Core Tools - Command line tools for Azure
--- !!! OPTIONAL !!!
PLUGIN.minRuntimeVersion = "0.3.0"
PLUGIN.notes = {
- "Provides the 'func' command for local Azure Functions development",
+ "Provides the 'func' command for local Azure Functions development",
}
diff --git a/crates/vfox/embedded-plugins/vfox-bfs/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-bfs/hooks/available.lua
index 1904af0987..649ef2dbd5 100644
--- a/crates/vfox/embedded-plugins/vfox-bfs/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-bfs/hooks/available.lua
@@ -2,17 +2,17 @@
--- @param ctx table Context object (unused for this plugin)
--- @return table Array of version objects with 'version' field
function PLUGIN:Available(ctx)
- local util = require("util")
- local versions = util.get_versions()
+ local util = require("util")
+ local versions = util.get_versions()
- -- Sort versions (newest first)
- table.sort(versions, util.version_compare)
+ -- Sort versions (newest first)
+ table.sort(versions, util.version_compare)
- -- Convert to vfox format
- local result = {}
- for _, v in ipairs(versions) do
- table.insert(result, { version = v })
- end
+ -- Convert to vfox format
+ local result = {}
+ for _, v in ipairs(versions) do
+ table.insert(result, { version = v })
+ end
- return result
+ return result
end
diff --git a/crates/vfox/embedded-plugins/vfox-bfs/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-bfs/hooks/env_keys.lua
index 394431d4f7..85a3111807 100644
--- a/crates/vfox/embedded-plugins/vfox-bfs/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-bfs/hooks/env_keys.lua
@@ -2,10 +2,10 @@
--- This allows plugins to define custom environment variables (including PATH settings)
--- @param ctx {path: string} Context information (SDK installation directory)
function PLUGIN:EnvKeys(ctx)
- return {
- {
- key = "PATH",
- value = ctx.path .. "/bin",
- },
- }
+ return {
+ {
+ key = "PATH",
+ value = ctx.path .. "/bin",
+ },
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-bfs/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-bfs/hooks/post_install.lua
index 1efe84fceb..379f05d2e8 100644
--- a/crates/vfox/embedded-plugins/vfox-bfs/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-bfs/hooks/post_install.lua
@@ -2,37 +2,37 @@
--- @param ctx table
--- @field ctx.rootPath string SDK installation directory
function PLUGIN:PostInstall(ctx)
- local rootPath = ctx.rootPath
+ local rootPath = ctx.rootPath
- -- mise extracts the tarball and moves content directly to rootPath
- -- So rootPath IS the source directory
+ -- mise extracts the tarball and moves content directly to rootPath
+ -- So rootPath IS the source directory
- -- Check if configure script exists (to verify we're in the right place)
- local check_cmd = string.format('test -f "%s/configure"', rootPath)
- local exists = os.execute(check_cmd)
- if not exists then
- error(
- "Could not find configure script in " .. rootPath .. ". The source may not have been extracted correctly."
- )
- end
+ -- Check if configure script exists (to verify we're in the right place)
+ local check_cmd = string.format('test -f "%s/configure"', rootPath)
+ local exists = os.execute(check_cmd)
+ if not exists then
+ error(
+ "Could not find configure script in " .. rootPath .. ". The source may not have been extracted correctly."
+ )
+ end
- -- Build bfs using configure && make
- -- RELEASE=y enables optimizations
- local build_cmd = string.format(
- 'cd "%s" && ./configure RELEASE=y && make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)',
- rootPath
- )
+ -- Build bfs using configure && make
+ -- RELEASE=y enables optimizations
+ local build_cmd = string.format(
+ 'cd "%s" && ./configure RELEASE=y && make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)',
+ rootPath
+ )
- print("Compiling bfs from source...")
- local result = os.execute(build_cmd)
- if not result then
- error("Failed to compile bfs. Make sure you have a C compiler (gcc/clang) and make installed.")
- end
+ print("Compiling bfs from source...")
+ local result = os.execute(build_cmd)
+ if not result then
+ error("Failed to compile bfs. Make sure you have a C compiler (gcc/clang) and make installed.")
+ end
- -- bfs binary is built in bin/ subdirectory
- -- Make sure it's executable
- local binPath = rootPath .. "/bin"
- os.execute(string.format('chmod +x "%s/bfs"', binPath))
+ -- bfs binary is built in bin/ subdirectory
+ -- Make sure it's executable
+ local binPath = rootPath .. "/bin"
+ os.execute(string.format('chmod +x "%s/bfs"', binPath))
- print("bfs compiled successfully!")
+ print("bfs compiled successfully!")
end
diff --git a/crates/vfox/embedded-plugins/vfox-bfs/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-bfs/hooks/pre_install.lua
index b0a32f7591..6bd71953e7 100644
--- a/crates/vfox/embedded-plugins/vfox-bfs/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-bfs/hooks/pre_install.lua
@@ -2,14 +2,14 @@
--- @param ctx {version: string} Context containing version info (The version to install)
--- @return table Installation info including download URL
function PLUGIN:PreInstall(ctx)
- local version = ctx.version
+ local version = ctx.version
- -- bfs releases source tarballs on GitHub
- -- URL format: https://github.com/tavianator/bfs/archive/refs/tags/{version}.tar.gz
- local url = string.format("https://github.com/tavianator/bfs/archive/refs/tags/%s.tar.gz", version)
+ -- bfs releases source tarballs on GitHub
+ -- URL format: https://github.com/tavianator/bfs/archive/refs/tags/{version}.tar.gz
+ local url = string.format("https://github.com/tavianator/bfs/archive/refs/tags/%s.tar.gz", version)
- return {
- version = version,
- url = url,
- }
+ return {
+ version = version,
+ url = url,
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-bpkg/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-bpkg/hooks/available.lua
index 27c095f10b..7c5ee01fec 100644
--- a/crates/vfox/embedded-plugins/vfox-bpkg/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-bpkg/hooks/available.lua
@@ -18,7 +18,7 @@ function PLUGIN:Available(ctx)
local resp, err = http.get({
url = "https://api.github.com/repos/bpkg/bpkg/tags",
- headers = headers
+ headers = headers,
})
if err ~= nil then
diff --git a/crates/vfox/embedded-plugins/vfox-carthage/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-carthage/hooks/available.lua
index 7300c59376..dd2d0e7d0d 100644
--- a/crates/vfox/embedded-plugins/vfox-carthage/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-carthage/hooks/available.lua
@@ -2,17 +2,17 @@
--- @param ctx table Context object (unused for this plugin)
--- @return table Array of version objects with 'version' field
function PLUGIN:Available(ctx)
- local util = require("util")
- local versions = util.get_versions()
+ local util = require("util")
+ local versions = util.get_versions()
- -- Sort versions (newest first)
- table.sort(versions, util.version_compare)
+ -- Sort versions (newest first)
+ table.sort(versions, util.version_compare)
- -- Convert to vfox format
- local result = {}
- for _, v in ipairs(versions) do
- table.insert(result, { version = v })
- end
+ -- Convert to vfox format
+ local result = {}
+ for _, v in ipairs(versions) do
+ table.insert(result, { version = v })
+ end
- return result
+ return result
end
diff --git a/crates/vfox/embedded-plugins/vfox-carthage/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-carthage/hooks/env_keys.lua
index 394431d4f7..85a3111807 100644
--- a/crates/vfox/embedded-plugins/vfox-carthage/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-carthage/hooks/env_keys.lua
@@ -2,10 +2,10 @@
--- This allows plugins to define custom environment variables (including PATH settings)
--- @param ctx {path: string} Context information (SDK installation directory)
function PLUGIN:EnvKeys(ctx)
- return {
- {
- key = "PATH",
- value = ctx.path .. "/bin",
- },
- }
+ return {
+ {
+ key = "PATH",
+ value = ctx.path .. "/bin",
+ },
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-carthage/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-carthage/hooks/post_install.lua
index 0cd7b9ca2a..319e1b2004 100644
--- a/crates/vfox/embedded-plugins/vfox-carthage/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-carthage/hooks/post_install.lua
@@ -2,63 +2,63 @@
--- @param ctx table
--- @field ctx.rootPath string SDK installation directory
function PLUGIN:PostInstall(ctx)
- local rootPath = ctx.rootPath
+ local rootPath = ctx.rootPath
- -- Check if we're on macOS (carthage is macOS only)
- if RUNTIME.osType ~= "darwin" then
- error("Carthage is only available for macOS")
- end
+ -- Check if we're on macOS (carthage is macOS only)
+ if RUNTIME.osType ~= "darwin" then
+ error("Carthage is only available for macOS")
+ end
- -- Find the downloaded .pkg file
- local find_cmd = string.format('ls "%s"/*.pkg 2>/dev/null | head -1', rootPath)
- local handle = io.popen(find_cmd)
- if not handle then
- error("Failed to find .pkg file")
- end
- local pkg_path = handle:read("*l")
- handle:close()
+ -- Find the downloaded .pkg file
+ local find_cmd = string.format('ls "%s"/*.pkg 2>/dev/null | head -1', rootPath)
+ local handle = io.popen(find_cmd)
+ if not handle then
+ error("Failed to find .pkg file")
+ end
+ local pkg_path = handle:read("*l")
+ handle:close()
- if not pkg_path or pkg_path == "" then
- error("Could not find Carthage.pkg in " .. rootPath)
- end
+ if not pkg_path or pkg_path == "" then
+ error("Could not find Carthage.pkg in " .. rootPath)
+ end
- -- Create extraction directory
- local expand_dir = rootPath .. "/expanded"
- os.execute(string.format('mkdir -p "%s"', expand_dir))
+ -- Create extraction directory
+ local expand_dir = rootPath .. "/expanded"
+ os.execute(string.format('mkdir -p "%s"', expand_dir))
- -- Expand the .pkg file using pkgutil
- local expand_cmd = string.format('pkgutil --expand "%s" "%s"', pkg_path, expand_dir)
- local result = os.execute(expand_cmd)
- if not result then
- error("Failed to expand .pkg file")
- end
+ -- Expand the .pkg file using pkgutil
+ local expand_cmd = string.format('pkgutil --expand "%s" "%s"', pkg_path, expand_dir)
+ local result = os.execute(expand_cmd)
+ if not result then
+ error("Failed to expand .pkg file")
+ end
- -- Find the payload and extract it
- -- The payload is typically in CarthageApp.pkg/Payload
- local payload_dir = expand_dir .. "/CarthageApp.pkg"
- local extract_cmd = string.format('cd "%s" && cat Payload | gunzip | cpio -id 2>/dev/null', payload_dir)
- result = os.execute(extract_cmd)
- if not result then
- error("Failed to extract payload from .pkg")
- end
+ -- Find the payload and extract it
+ -- The payload is typically in CarthageApp.pkg/Payload
+ local payload_dir = expand_dir .. "/CarthageApp.pkg"
+ local extract_cmd = string.format('cd "%s" && cat Payload | gunzip | cpio -id 2>/dev/null', payload_dir)
+ result = os.execute(extract_cmd)
+ if not result then
+ error("Failed to extract payload from .pkg")
+ end
- -- Create bin directory and move carthage binary
- local binDir = rootPath .. "/bin"
- os.execute(string.format('mkdir -p "%s"', binDir))
+ -- Create bin directory and move carthage binary
+ local binDir = rootPath .. "/bin"
+ os.execute(string.format('mkdir -p "%s"', binDir))
- local move_cmd = string.format('mv "%s/usr/local/bin/carthage" "%s/carthage"', payload_dir, binDir)
- result = os.execute(move_cmd)
- if not result then
- error("Failed to move carthage binary to bin directory")
- end
+ local move_cmd = string.format('mv "%s/usr/local/bin/carthage" "%s/carthage"', payload_dir, binDir)
+ result = os.execute(move_cmd)
+ if not result then
+ error("Failed to move carthage binary to bin directory")
+ end
- -- Make executable and remove quarantine
- os.execute(string.format('chmod +x "%s/carthage"', binDir))
- os.execute(string.format('xattr -d com.apple.quarantine "%s/carthage" 2>/dev/null || true', binDir))
+ -- Make executable and remove quarantine
+ os.execute(string.format('chmod +x "%s/carthage"', binDir))
+ os.execute(string.format('xattr -d com.apple.quarantine "%s/carthage" 2>/dev/null || true', binDir))
- -- Clean up
- os.execute(string.format('rm -rf "%s"', expand_dir))
- os.execute(string.format('rm -f "%s"', pkg_path))
+ -- Clean up
+ os.execute(string.format('rm -rf "%s"', expand_dir))
+ os.execute(string.format('rm -f "%s"', pkg_path))
- print("Carthage installed successfully!")
+ print("Carthage installed successfully!")
end
diff --git a/crates/vfox/embedded-plugins/vfox-carthage/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-carthage/hooks/pre_install.lua
index 1d35799fe2..b03166551c 100644
--- a/crates/vfox/embedded-plugins/vfox-carthage/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-carthage/hooks/pre_install.lua
@@ -2,13 +2,13 @@
--- @param ctx {version: string} Context containing version info (The version to install)
--- @return table Installation info including download URL
function PLUGIN:PreInstall(ctx)
- local version = ctx.version
+ local version = ctx.version
- -- Carthage releases .pkg files on GitHub
- local url = string.format("https://github.com/Carthage/Carthage/releases/download/%s/Carthage.pkg", version)
+ -- Carthage releases .pkg files on GitHub
+ local url = string.format("https://github.com/Carthage/Carthage/releases/download/%s/Carthage.pkg", version)
- return {
- version = version,
- url = url,
- }
+ return {
+ version = version,
+ url = url,
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/available.lua
index 9f96b00a35..da043d1d32 100644
--- a/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/available.lua
@@ -5,37 +5,37 @@ local json = require("json")
--- @param ctx table Context
--- @return table Available versions
function PLUGIN:Available(ctx)
- local results = {}
+ local results = {}
- -- Fetch releases from GitHub API (tags show up as releases)
- local resp, err = http.get({
- url = "https://api.github.com/repos/cisco/ChezScheme/tags?per_page=100",
- })
+ -- Fetch releases from GitHub API (tags show up as releases)
+ local resp, err = http.get({
+ url = "https://api.github.com/repos/cisco/ChezScheme/tags?per_page=100",
+ })
- if err ~= nil then
- error("Failed to fetch versions: " .. err)
- end
+ if err ~= nil then
+ error("Failed to fetch versions: " .. err)
+ end
- if resp.status_code ~= 200 then
- error("Failed to fetch versions: HTTP " .. resp.status_code)
- end
+ if resp.status_code ~= 200 then
+ error("Failed to fetch versions: HTTP " .. resp.status_code)
+ end
- local tags = json.decode(resp.body)
+ local tags = json.decode(resp.body)
- for _, tag in ipairs(tags) do
- local version = tag.name
- -- Remove 'v' prefix if present
- if version:sub(1, 1) == "v" then
- version = version:sub(2)
- end
- -- Only include version-like tags (e.g., 10.3.0, 9.5.8)
- if version:match("^%d+%.%d+") then
- table.insert(results, {
- version = version,
- note = "",
- })
- end
- end
+ for _, tag in ipairs(tags) do
+ local version = tag.name
+ -- Remove 'v' prefix if present
+ if version:sub(1, 1) == "v" then
+ version = version:sub(2)
+ end
+ -- Only include version-like tags (e.g., 10.3.0, 9.5.8)
+ if version:match("^%d+%.%d+") then
+ table.insert(results, {
+ version = version,
+ note = "",
+ })
+ end
+ end
- return results
+ return results
end
diff --git a/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/env_keys.lua
index 178b91cc48..9dfbd0adc6 100644
--- a/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/env_keys.lua
@@ -2,10 +2,10 @@
--- @param ctx {path: string} (Installation path)
--- @return table Environment variables
function PLUGIN:EnvKeys(ctx)
- return {
- {
- key = "PATH",
- value = ctx.path .. "/bin",
- },
- }
+ return {
+ {
+ key = "PATH",
+ value = ctx.path .. "/bin",
+ },
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/post_install.lua
index 7a1d8b1d88..26200c5155 100644
--- a/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/post_install.lua
@@ -2,52 +2,52 @@
--- @param ctx table
--- @field ctx.rootPath string Installation root path
function PLUGIN:PostInstall(ctx)
- local os_type = RUNTIME.osType
-
- -- Windows uses the .exe installer, not source compilation
- if os_type == "windows" then
- print("Windows installation requires the ChezScheme.exe installer from GitHub releases")
- print("Please download and run it manually from:")
- print("https://github.com/cisco/ChezScheme/releases")
- return
- end
-
- local root_path = ctx.rootPath
-
- -- The tarball extracts with contents at root level (no top-level directory to strip)
- -- We need to run configure and make install
- print("Compiling Chez Scheme from source...")
-
- -- Configure with install prefix
- local configure_cmd = "cd " .. root_path .. " && ./configure --installprefix=" .. root_path
- print("Running: " .. configure_cmd)
- local result = os.execute(configure_cmd)
- if result ~= 0 and result ~= true then
- error("Configure failed")
- end
-
- -- Build
- local make_cmd = "cd " .. root_path .. " && make"
- print("Running: make")
- result = os.execute(make_cmd)
- if result ~= 0 and result ~= true then
- error("Make failed")
- end
-
- -- Install to the prefix directory
- local install_cmd = "cd " .. root_path .. " && make install"
- print("Running: make install")
- result = os.execute(install_cmd)
- if result ~= 0 and result ~= true then
- error("Make install failed")
- end
-
- -- Clean up build artifacts to save space (optional)
- os.execute(
- "cd "
- .. root_path
- .. " && rm -rf boot c examples mats s unicode workarea Makefile configure LOG NOTICE 2>/dev/null"
- )
-
- print("Chez Scheme compilation complete!")
+ local os_type = RUNTIME.osType
+
+ -- Windows uses the .exe installer, not source compilation
+ if os_type == "windows" then
+ print("Windows installation requires the ChezScheme.exe installer from GitHub releases")
+ print("Please download and run it manually from:")
+ print("https://github.com/cisco/ChezScheme/releases")
+ return
+ end
+
+ local root_path = ctx.rootPath
+
+ -- The tarball extracts with contents at root level (no top-level directory to strip)
+ -- We need to run configure and make install
+ print("Compiling Chez Scheme from source...")
+
+ -- Configure with install prefix
+ local configure_cmd = "cd " .. root_path .. " && ./configure --installprefix=" .. root_path
+ print("Running: " .. configure_cmd)
+ local result = os.execute(configure_cmd)
+ if result ~= 0 and result ~= true then
+ error("Configure failed")
+ end
+
+ -- Build
+ local make_cmd = "cd " .. root_path .. " && make"
+ print("Running: make")
+ result = os.execute(make_cmd)
+ if result ~= 0 and result ~= true then
+ error("Make failed")
+ end
+
+ -- Install to the prefix directory
+ local install_cmd = "cd " .. root_path .. " && make install"
+ print("Running: make install")
+ result = os.execute(install_cmd)
+ if result ~= 0 and result ~= true then
+ error("Make install failed")
+ end
+
+ -- Clean up build artifacts to save space (optional)
+ os.execute(
+ "cd "
+ .. root_path
+ .. " && rm -rf boot c examples mats s unicode workarea Makefile configure LOG NOTICE 2>/dev/null"
+ )
+
+ print("Chez Scheme compilation complete!")
end
diff --git a/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/pre_install.lua
index 5beedc8a77..f135bf6ca3 100644
--- a/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-chezscheme/hooks/pre_install.lua
@@ -3,13 +3,13 @@
--- @param ctx {version: string} (Version to install)
--- @return table File info with URL
function PLUGIN:PreInstall(ctx)
- local version = ctx.version
+ local version = ctx.version
- -- Source tarball URL pattern: csv{version}.tar.gz
- local url = "https://github.com/cisco/ChezScheme/releases/download/v" .. version .. "/csv" .. version .. ".tar.gz"
+ -- Source tarball URL pattern: csv{version}.tar.gz
+ local url = "https://github.com/cisco/ChezScheme/releases/download/v" .. version .. "/csv" .. version .. ".tar.gz"
- return {
- url = url,
- version = version,
- }
+ return {
+ url = url,
+ version = version,
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-chicken/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-chicken/hooks/available.lua
index 2cbf3a78fb..3a331d1940 100644
--- a/crates/vfox/embedded-plugins/vfox-chicken/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-chicken/hooks/available.lua
@@ -4,7 +4,7 @@
function PLUGIN:Available(ctx)
local http = require("http")
local resp, err = http.get({
- url = "https://foldling.org/dust/"
+ url = "https://foldling.org/dust/",
})
if err ~= nil then
error("Failed to fetch version list: " .. err)
@@ -18,7 +18,7 @@ function PLUGIN:Available(ctx)
-- Parse HTML for chicken tarballs: chicken-VERSION-ARCH-OS-VARIANT.tar.gz
-- Only match versioned releases, not "master"
- for version in resp.body:gmatch('chicken%-([0-9]+%.[0-9]+%.[0-9]+)%-') do
+ for version in resp.body:gmatch("chicken%-([0-9]+%.[0-9]+%.[0-9]+)%-") do
if not seen[version] then
seen[version] = true
table.insert(versions, {
diff --git a/crates/vfox/embedded-plugins/vfox-chicken/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-chicken/hooks/post_install.lua
index 4a835870da..0c9955a002 100644
--- a/crates/vfox/embedded-plugins/vfox-chicken/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-chicken/hooks/post_install.lua
@@ -13,7 +13,8 @@ function PLUGIN:PostInstall(ctx)
local libchicken = file.join_path(lib_path, "libchicken.dylib")
-- Create a shell script to fix library paths
- local script = string.format([[
+ local script = string.format(
+ [[
#!/bin/bash
set -e
LIB="%s"
@@ -32,7 +33,10 @@ for bin in chicken csc csi chicken-install chicken-uninstall chicken-status chic
fi
fi
done
-]], lib_path, bin_path)
+]],
+ lib_path,
+ bin_path
+ )
-- Write and execute the script
local script_path = root_path .. "/fix_libs.sh"
diff --git a/crates/vfox/embedded-plugins/vfox-chicken/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-chicken/hooks/pre_install.lua
index 0c82564611..4b94fb2af1 100644
--- a/crates/vfox/embedded-plugins/vfox-chicken/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-chicken/hooks/pre_install.lua
@@ -24,7 +24,7 @@ function PLUGIN:PreInstall(ctx)
end
arch = "x86_64"
os_name = "linux"
- variant = "gnu" -- Use GNU libc version by default
+ variant = "gnu" -- Use GNU libc version by default
elseif os_type == "freebsd" then
if arch_type ~= "amd64" then
error("CHICKEN only has amd64 binaries for FreeBSD.")
diff --git a/crates/vfox/embedded-plugins/vfox-chromedriver/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-chromedriver/hooks/available.lua
index 5bad7ceddf..c43446c543 100644
--- a/crates/vfox/embedded-plugins/vfox-chromedriver/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-chromedriver/hooks/available.lua
@@ -11,7 +11,7 @@ function PLUGIN:Available(ctx)
url = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json",
headers = {
["Accept"] = "application/json",
- }
+ },
})
if err ~= nil then
diff --git a/crates/vfox/embedded-plugins/vfox-chromedriver/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-chromedriver/hooks/pre_install.lua
index b23be2e25a..9910a816c2 100644
--- a/crates/vfox/embedded-plugins/vfox-chromedriver/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-chromedriver/hooks/pre_install.lua
@@ -39,7 +39,7 @@ function PLUGIN:PreInstall(ctx)
url = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json",
headers = {
["Accept"] = "application/json",
- }
+ },
})
if err ~= nil then
diff --git a/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/available.lua
index 0f1a4b7e4e..c7713af698 100644
--- a/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/available.lua
@@ -2,17 +2,17 @@
--- @param ctx table Context object (unused for this plugin)
--- @return table Array of version objects with 'version' field
function PLUGIN:Available(ctx)
- local util = require("util")
- local versions = util.get_versions()
+ local util = require("util")
+ local versions = util.get_versions()
- -- Sort versions (newest first)
- table.sort(versions, util.version_compare)
+ -- Sort versions (newest first)
+ table.sort(versions, util.version_compare)
- -- Convert to vfox format
- local result = {}
- for _, v in ipairs(versions) do
- table.insert(result, { version = v })
- end
+ -- Convert to vfox format
+ local result = {}
+ for _, v in ipairs(versions) do
+ table.insert(result, { version = v })
+ end
- return result
+ return result
end
diff --git a/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/env_keys.lua
index 394431d4f7..85a3111807 100644
--- a/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/env_keys.lua
@@ -2,10 +2,10 @@
--- This allows plugins to define custom environment variables (including PATH settings)
--- @param ctx {path: string} Context information (SDK installation directory)
function PLUGIN:EnvKeys(ctx)
- return {
- {
- key = "PATH",
- value = ctx.path .. "/bin",
- },
- }
+ return {
+ {
+ key = "PATH",
+ value = ctx.path .. "/bin",
+ },
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/post_install.lua
index 2d43bc4728..4ff97b0cb9 100644
--- a/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/post_install.lua
@@ -2,88 +2,88 @@
--- @param ctx table
--- @field ctx.rootPath string SDK installation directory
function PLUGIN:PostInstall(ctx)
- local rootPath = ctx.rootPath
- local binDir = rootPath .. "/bin"
+ local rootPath = ctx.rootPath
+ local binDir = rootPath .. "/bin"
- -- Create bin directory
- os.execute(string.format('mkdir -p "%s"', binDir))
+ -- Create bin directory
+ os.execute(string.format('mkdir -p "%s"', binDir))
- if RUNTIME.osType == "darwin" then
- -- macOS: single binary file was downloaded
- -- Find the downloaded binary (clickhouse-macos or clickhouse-macos-aarch64)
- local find_cmd = string.format('ls "%s"/clickhouse-macos* 2>/dev/null | head -1', rootPath)
- local handle = io.popen(find_cmd)
- if not handle then
- error("Failed to find clickhouse binary")
- end
- local binary_path = handle:read("*l")
- handle:close()
+ if RUNTIME.osType == "darwin" then
+ -- macOS: single binary file was downloaded
+ -- Find the downloaded binary (clickhouse-macos or clickhouse-macos-aarch64)
+ local find_cmd = string.format('ls "%s"/clickhouse-macos* 2>/dev/null | head -1', rootPath)
+ local handle = io.popen(find_cmd)
+ if not handle then
+ error("Failed to find clickhouse binary")
+ end
+ local binary_path = handle:read("*l")
+ handle:close()
- if not binary_path or binary_path == "" then
- error("Could not find clickhouse-macos binary in " .. rootPath)
- end
+ if not binary_path or binary_path == "" then
+ error("Could not find clickhouse-macos binary in " .. rootPath)
+ end
- -- Move and rename to bin/clickhouse
- local move_cmd = string.format('mv "%s" "%s/clickhouse"', binary_path, binDir)
- local result = os.execute(move_cmd)
- if not result then
- error("Failed to move clickhouse binary")
- end
+ -- Move and rename to bin/clickhouse
+ local move_cmd = string.format('mv "%s" "%s/clickhouse"', binary_path, binDir)
+ local result = os.execute(move_cmd)
+ if not result then
+ error("Failed to move clickhouse binary")
+ end
- -- Make executable and remove quarantine
- os.execute(string.format('chmod +x "%s/clickhouse"', binDir))
- os.execute(string.format('xattr -d com.apple.quarantine "%s/clickhouse" 2>/dev/null || true', binDir))
- else
- -- Linux: tarball was extracted
- -- The tarball extracts to usr/bin/clickhouse
- local src_binary = rootPath .. "/usr/bin/clickhouse"
+ -- Make executable and remove quarantine
+ os.execute(string.format('chmod +x "%s/clickhouse"', binDir))
+ os.execute(string.format('xattr -d com.apple.quarantine "%s/clickhouse" 2>/dev/null || true', binDir))
+ else
+ -- Linux: tarball was extracted
+ -- The tarball extracts to usr/bin/clickhouse
+ local src_binary = rootPath .. "/usr/bin/clickhouse"
- -- Check if binary exists at expected location
- local check_cmd = string.format('test -f "%s"', src_binary)
- if not os.execute(check_cmd) then
- -- Try alternate location
- src_binary = rootPath .. "/clickhouse"
- check_cmd = string.format('test -f "%s"', src_binary)
- if not os.execute(check_cmd) then
- error("Could not find clickhouse binary after extraction")
- end
- end
+ -- Check if binary exists at expected location
+ local check_cmd = string.format('test -f "%s"', src_binary)
+ if not os.execute(check_cmd) then
+ -- Try alternate location
+ src_binary = rootPath .. "/clickhouse"
+ check_cmd = string.format('test -f "%s"', src_binary)
+ if not os.execute(check_cmd) then
+ error("Could not find clickhouse binary after extraction")
+ end
+ end
- -- Move binary to bin/
- local move_cmd = string.format('mv "%s" "%s/clickhouse"', src_binary, binDir)
- local result = os.execute(move_cmd)
- if not result then
- -- Try copying instead
- move_cmd = string.format('cp "%s" "%s/clickhouse"', src_binary, binDir)
- result = os.execute(move_cmd)
- if not result then
- error("Failed to copy clickhouse binary to bin/")
- end
- end
+ -- Move binary to bin/
+ local move_cmd = string.format('mv "%s" "%s/clickhouse"', src_binary, binDir)
+ local result = os.execute(move_cmd)
+ if not result then
+ -- Try copying instead
+ move_cmd = string.format('cp "%s" "%s/clickhouse"', src_binary, binDir)
+ result = os.execute(move_cmd)
+ if not result then
+ error("Failed to copy clickhouse binary to bin/")
+ end
+ end
- -- Make executable
- os.execute(string.format('chmod +x "%s/clickhouse"', binDir))
+ -- Make executable
+ os.execute(string.format('chmod +x "%s/clickhouse"', binDir))
- -- Clean up extracted directories
- os.execute(
- string.format('rm -rf "%s/usr" "%s/install" "%s/etc" 2>/dev/null || true', rootPath, rootPath, rootPath)
- )
- end
+ -- Clean up extracted directories
+ os.execute(
+ string.format('rm -rf "%s/usr" "%s/install" "%s/etc" 2>/dev/null || true', rootPath, rootPath, rootPath)
+ )
+ end
- -- Create symlinks for clickhouse subcommands
- local symlinks = {
- "clickhouse-client",
- "clickhouse-server",
- "clickhouse-local",
- "clickhouse-benchmark",
- "clickhouse-compressor",
- "clickhouse-format",
- "clickhouse-obfuscator",
- }
+ -- Create symlinks for clickhouse subcommands
+ local symlinks = {
+ "clickhouse-client",
+ "clickhouse-server",
+ "clickhouse-local",
+ "clickhouse-benchmark",
+ "clickhouse-compressor",
+ "clickhouse-format",
+ "clickhouse-obfuscator",
+ }
- for _, link in ipairs(symlinks) do
- os.execute(string.format('ln -sf clickhouse "%s/%s" 2>/dev/null || true', binDir, link))
- end
+ for _, link in ipairs(symlinks) do
+ os.execute(string.format('ln -sf clickhouse "%s/%s" 2>/dev/null || true', binDir, link))
+ end
- print("ClickHouse installed successfully!")
+ print("ClickHouse installed successfully!")
end
diff --git a/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/pre_install.lua
index c2a8c546d3..493885d28a 100644
--- a/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-clickhouse/hooks/pre_install.lua
@@ -2,39 +2,39 @@
--- @param ctx {version: string} Context containing version info (The version to install)
--- @return table Installation info including download URL
function PLUGIN:PreInstall(ctx)
- local util = require("util")
- local version = ctx.version
- local arch = util.get_arch()
- local trimmed_version = util.trim_version_suffix(version)
- local url
+ local util = require("util")
+ local version = ctx.version
+ local arch = util.get_arch()
+ local trimmed_version = util.trim_version_suffix(version)
+ local url
- if RUNTIME.osType == "darwin" then
- -- macOS: single binary file
- -- clickhouse-macos (x86_64) or clickhouse-macos-aarch64 (arm64)
- if arch == "arm64" then
- url = string.format(
- "https://github.com/ClickHouse/ClickHouse/releases/download/v%s/clickhouse-macos-aarch64",
- version
- )
- else
- url = string.format(
- "https://github.com/ClickHouse/ClickHouse/releases/download/v%s/clickhouse-macos",
- version
- )
- end
- else
- -- Linux: tarball
- -- clickhouse-common-static-{trimmed_version}-{arch}.tgz
- url = string.format(
- "https://github.com/ClickHouse/ClickHouse/releases/download/v%s/clickhouse-common-static-%s-%s.tgz",
- version,
- trimmed_version,
- arch
- )
- end
+ if RUNTIME.osType == "darwin" then
+ -- macOS: single binary file
+ -- clickhouse-macos (x86_64) or clickhouse-macos-aarch64 (arm64)
+ if arch == "arm64" then
+ url = string.format(
+ "https://github.com/ClickHouse/ClickHouse/releases/download/v%s/clickhouse-macos-aarch64",
+ version
+ )
+ else
+ url = string.format(
+ "https://github.com/ClickHouse/ClickHouse/releases/download/v%s/clickhouse-macos",
+ version
+ )
+ end
+ else
+ -- Linux: tarball
+ -- clickhouse-common-static-{trimmed_version}-{arch}.tgz
+ url = string.format(
+ "https://github.com/ClickHouse/ClickHouse/releases/download/v%s/clickhouse-common-static-%s-%s.tgz",
+ version,
+ trimmed_version,
+ arch
+ )
+ end
- return {
- version = version,
- url = url,
- }
+ return {
+ version = version,
+ url = url,
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-dotnet/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-dotnet/hooks/available.lua
index c7fb97a86e..3fb774a35a 100644
--- a/crates/vfox/embedded-plugins/vfox-dotnet/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-dotnet/hooks/available.lua
@@ -60,7 +60,12 @@ function PLUGIN:Available(ctx)
seen[version] = true
local note = channelNote
-- Mark previews and RCs
- if string.match(version, "preview") or string.match(version, "rc") or string.match(version, "alpha") or string.match(version, "beta") then
+ if
+ string.match(version, "preview")
+ or string.match(version, "rc")
+ or string.match(version, "alpha")
+ or string.match(version, "beta")
+ then
note = "Preview"
end
table.insert(result, {
@@ -78,7 +83,12 @@ function PLUGIN:Available(ctx)
if not seen[version] then
seen[version] = true
local note = channelNote
- if string.match(version, "preview") or string.match(version, "rc") or string.match(version, "alpha") or string.match(version, "beta") then
+ if
+ string.match(version, "preview")
+ or string.match(version, "rc")
+ or string.match(version, "alpha")
+ or string.match(version, "beta")
+ then
note = "Preview"
end
table.insert(result, {
diff --git a/crates/vfox/embedded-plugins/vfox-dotnet/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-dotnet/hooks/post_install.lua
index b8bf47648a..f10b5e117d 100644
--- a/crates/vfox/embedded-plugins/vfox-dotnet/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-dotnet/hooks/post_install.lua
@@ -13,7 +13,15 @@ function PLUGIN:PostInstall(ctx)
if RUNTIME.osType == "windows" then
-- Windows: Use PowerShell script
local scriptPath = path .. sep .. "dotnet-install.ps1"
- cmd.exec("powershell -ExecutionPolicy Bypass -File " .. scriptPath .. " -InstallDir " .. path .. " -Version " .. version .. " -NoPath")
+ cmd.exec(
+ "powershell -ExecutionPolicy Bypass -File "
+ .. scriptPath
+ .. " -InstallDir "
+ .. path
+ .. " -Version "
+ .. version
+ .. " -NoPath"
+ )
-- Clean up installer script
os.remove(scriptPath)
else
diff --git a/crates/vfox/embedded-plugins/vfox-gcloud/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-gcloud/hooks/available.lua
index 03b2f2005f..3404afebd7 100644
--- a/crates/vfox/embedded-plugins/vfox-gcloud/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-gcloud/hooks/available.lua
@@ -15,88 +15,88 @@ local available_versions = nil
--- Fetch versions from GCS with pagination
local function fetch_versions()
- local versions = {}
- local seen = {}
- local page_token = nil
-
- repeat
- -- Build URL with query parameters
- local url = GCS_API_URL .. "?prefix=" .. GCS_PREFIX .. "&fields=kind,nextPageToken,items(name)"
- if page_token then
- url = url .. "&pageToken=" .. page_token
- end
-
- -- Fetch page
- local resp, err = http.get({
- url = url,
- })
-
- if err ~= nil or resp.status_code ~= 200 then
- error("Failed to fetch versions from GCS: " .. (err or "status " .. resp.status_code))
- end
-
- local data = json.decode(resp.body)
-
- -- Extract versions from object names
- -- Pattern: google-cloud-sdk-{version}-linux-x86_64.tar.gz
- for _, item in ipairs(data.items or {}) do
- local name = item.name
- local version = string.match(name, "^google%-cloud%-sdk%-([%d%.]+)%-linux%-x86_64%.tar%.gz$")
- if version and not seen[version] then
- seen[version] = true
- table.insert(versions, version)
- end
- end
-
- page_token = data.nextPageToken
- until page_token == nil
-
- return versions
+ local versions = {}
+ local seen = {}
+ local page_token = nil
+
+ repeat
+ -- Build URL with query parameters
+ local url = GCS_API_URL .. "?prefix=" .. GCS_PREFIX .. "&fields=kind,nextPageToken,items(name)"
+ if page_token then
+ url = url .. "&pageToken=" .. page_token
+ end
+
+ -- Fetch page
+ local resp, err = http.get({
+ url = url,
+ })
+
+ if err ~= nil or resp.status_code ~= 200 then
+ error("Failed to fetch versions from GCS: " .. (err or "status " .. resp.status_code))
+ end
+
+ local data = json.decode(resp.body)
+
+ -- Extract versions from object names
+ -- Pattern: google-cloud-sdk-{version}-linux-x86_64.tar.gz
+ for _, item in ipairs(data.items or {}) do
+ local name = item.name
+ local version = string.match(name, "^google%-cloud%-sdk%-([%d%.]+)%-linux%-x86_64%.tar%.gz$")
+ if version and not seen[version] then
+ seen[version] = true
+ table.insert(versions, version)
+ end
+ end
+
+ page_token = data.nextPageToken
+ until page_token == nil
+
+ return versions
end
--- Compare version strings for sorting
local function compare_versions(a, b)
- local function parse_version(v)
- local parts = {}
- for part in string.gmatch(v, "([^%.]+)") do
- table.insert(parts, tonumber(part) or 0)
- end
- return parts
- end
-
- local va = parse_version(a)
- local vb = parse_version(b)
-
- for i = 1, math.max(#va, #vb) do
- local na = va[i] or 0
- local nb = vb[i] or 0
- if na ~= nb then
- return na > nb
- end
- end
- return false
+ local function parse_version(v)
+ local parts = {}
+ for part in string.gmatch(v, "([^%.]+)") do
+ table.insert(parts, tonumber(part) or 0)
+ end
+ return parts
+ end
+
+ local va = parse_version(a)
+ local vb = parse_version(b)
+
+ for i = 1, math.max(#va, #vb) do
+ local na = va[i] or 0
+ local nb = vb[i] or 0
+ if na ~= nb then
+ return na > nb
+ end
+ end
+ return false
end
function PLUGIN:Available(ctx)
- -- Use cached versions if available
- if available_versions ~= nil then
- return available_versions
- end
-
- local versions = fetch_versions()
-
- -- Sort versions in descending order (newest first) to match vfox conventions
- table.sort(versions, compare_versions)
-
- -- Build result table
- local result = {}
- for _, version in ipairs(versions) do
- table.insert(result, {
- version = version,
- note = "",
- })
- end
-
- available_versions = result
- return result
+ -- Use cached versions if available
+ if available_versions ~= nil then
+ return available_versions
+ end
+
+ local versions = fetch_versions()
+
+ -- Sort versions in descending order (newest first) to match vfox conventions
+ table.sort(versions, compare_versions)
+
+ -- Build result table
+ local result = {}
+ for _, version in ipairs(versions) do
+ table.insert(result, {
+ version = version,
+ note = "",
+ })
+ end
+
+ available_versions = result
+ return result
end
diff --git a/crates/vfox/embedded-plugins/vfox-gcloud/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-gcloud/hooks/env_keys.lua
index 3dfde1e072..1f8488051d 100644
--- a/crates/vfox/embedded-plugins/vfox-gcloud/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-gcloud/hooks/env_keys.lua
@@ -5,19 +5,19 @@
local file = require("file")
function PLUGIN:EnvKeys(ctx)
- local version_path = ctx.path
+ local version_path = ctx.path
- -- The SDK extracts directly to the version path
- local bin_path = file.join_path(version_path, "bin")
+ -- The SDK extracts directly to the version path
+ local bin_path = file.join_path(version_path, "bin")
- return {
- {
- key = "PATH",
- value = bin_path,
- },
- {
- key = "CLOUDSDK_ROOT_DIR",
- value = version_path,
- },
- }
+ return {
+ {
+ key = "PATH",
+ value = bin_path,
+ },
+ {
+ key = "CLOUDSDK_ROOT_DIR",
+ value = version_path,
+ },
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-gcloud/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-gcloud/hooks/post_install.lua
index 6fc988ade8..bfeb0abb65 100644
--- a/crates/vfox/embedded-plugins/vfox-gcloud/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-gcloud/hooks/post_install.lua
@@ -7,76 +7,76 @@ local file = require("file")
--- Compare version strings
--- Returns true if v1 >= v2
local function version_gte(v1, v2)
- local function parse_version(v)
- local parts = {}
- for part in string.gmatch(v, "([^%.]+)") do
- table.insert(parts, tonumber(part) or 0)
- end
- return parts
- end
+ local function parse_version(v)
+ local parts = {}
+ for part in string.gmatch(v, "([^%.]+)") do
+ table.insert(parts, tonumber(part) or 0)
+ end
+ return parts
+ end
- local va = parse_version(v1)
- local vb = parse_version(v2)
+ local va = parse_version(v1)
+ local vb = parse_version(v2)
- for i = 1, math.max(#va, #vb) do
- local na = va[i] or 0
- local nb = vb[i] or 0
- if na > nb then
- return true
- elseif na < nb then
- return false
- end
- end
- return true
+ for i = 1, math.max(#va, #vb) do
+ local na = va[i] or 0
+ local nb = vb[i] or 0
+ if na > nb then
+ return true
+ elseif na < nb then
+ return false
+ end
+ end
+ return true
end
function PLUGIN:PostInstall(ctx)
- local root_path = ctx.rootPath
- local version = ctx.version or ""
+ local root_path = ctx.rootPath
+ local version = ctx.version or ""
- -- The SDK extracts directly to the root path
- local sdk_path = root_path
- local install_script = file.join_path(sdk_path, "install.sh")
+ -- The SDK extracts directly to the root path
+ local sdk_path = root_path
+ local install_script = file.join_path(sdk_path, "install.sh")
- -- Check if install script exists
- if not file.exists(install_script) then
- -- On Windows, use install.bat
- if RUNTIME.osType == "windows" or RUNTIME.osType == "Windows" then
- install_script = file.join_path(sdk_path, "install.bat")
- end
- end
+ -- Check if install script exists
+ if not file.exists(install_script) then
+ -- On Windows, use install.bat
+ if RUNTIME.osType == "windows" or RUNTIME.osType == "Windows" then
+ install_script = file.join_path(sdk_path, "install.bat")
+ end
+ end
- if not file.exists(install_script) then
- -- Some versions might not have an install script, skip silently
- return
- end
+ if not file.exists(install_script) then
+ -- Some versions might not have an install script, skip silently
+ return
+ end
- -- Build install command arguments
- local args = {
- "--usage-reporting",
- "false",
- "--path-update",
- "false",
- "--quiet",
- }
+ -- Build install command arguments
+ local args = {
+ "--usage-reporting",
+ "false",
+ "--path-update",
+ "false",
+ "--quiet",
+ }
- -- For versions >= 352.0.0, disable Python installation
- -- (gcloud bundles its own Python in newer versions)
- if version ~= "" and version_gte(version, "352.0.0") then
- table.insert(args, "--install-python")
- table.insert(args, "false")
- end
+ -- For versions >= 352.0.0, disable Python installation
+ -- (gcloud bundles its own Python in newer versions)
+ if version ~= "" and version_gte(version, "352.0.0") then
+ table.insert(args, "--install-python")
+ table.insert(args, "false")
+ end
- -- Run the install script
- local cmd_str
- if RUNTIME.osType == "windows" or RUNTIME.osType == "Windows" then
- cmd_str = '"' .. install_script .. '" ' .. table.concat(args, " ")
- else
- cmd_str = 'sh "' .. install_script .. '" ' .. table.concat(args, " ")
- end
+ -- Run the install script
+ local cmd_str
+ if RUNTIME.osType == "windows" or RUNTIME.osType == "Windows" then
+ cmd_str = '"' .. install_script .. '" ' .. table.concat(args, " ")
+ else
+ cmd_str = 'sh "' .. install_script .. '" ' .. table.concat(args, " ")
+ end
- local status = os.execute(cmd_str)
- if status ~= 0 and status ~= true then
- error("Failed to run gcloud install script")
- end
+ local status = os.execute(cmd_str)
+ if status ~= 0 and status ~= true then
+ error("Failed to run gcloud install script")
+ end
end
diff --git a/crates/vfox/embedded-plugins/vfox-gcloud/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-gcloud/hooks/pre_install.lua
index cab5d5f59b..a2da200e46 100644
--- a/crates/vfox/embedded-plugins/vfox-gcloud/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-gcloud/hooks/pre_install.lua
@@ -10,105 +10,105 @@ local BASE_URL = "https://storage.googleapis.com/" .. GCS_BUCKET
--- Get OS name for download URL
local function get_os_name()
- local os_type = RUNTIME.osType
- if os_type == "darwin" or os_type == "Darwin" then
- return "darwin"
- elseif os_type == "linux" or os_type == "Linux" then
- return "linux"
- elseif os_type == "windows" or os_type == "Windows" then
- return "windows"
- else
- error("Unsupported operating system: " .. os_type)
- end
+ local os_type = RUNTIME.osType
+ if os_type == "darwin" or os_type == "Darwin" then
+ return "darwin"
+ elseif os_type == "linux" or os_type == "Linux" then
+ return "linux"
+ elseif os_type == "windows" or os_type == "Windows" then
+ return "windows"
+ else
+ error("Unsupported operating system: " .. os_type)
+ end
end
--- Get architecture name for download URL
local function get_arch_name()
- local arch_type = RUNTIME.archType
- local os_name = get_os_name()
-
- if arch_type == "amd64" or arch_type == "x86_64" then
- return "x86_64"
- elseif arch_type == "arm64" or arch_type == "aarch64" then
- -- macOS uses arm64, Linux uses aarch64
- if os_name == "darwin" then
- return "arm"
- else
- return "arm"
- end
- elseif arch_type == "386" or arch_type == "x86" then
- return "x86"
- else
- error("Unsupported architecture: " .. arch_type)
- end
+ local arch_type = RUNTIME.archType
+ local os_name = get_os_name()
+
+ if arch_type == "amd64" or arch_type == "x86_64" then
+ return "x86_64"
+ elseif arch_type == "arm64" or arch_type == "aarch64" then
+ -- macOS uses arm64, Linux uses aarch64
+ if os_name == "darwin" then
+ return "arm"
+ else
+ return "arm"
+ end
+ elseif arch_type == "386" or arch_type == "x86" then
+ return "x86"
+ else
+ error("Unsupported architecture: " .. arch_type)
+ end
end
--- Get file extension based on OS
local function get_extension()
- local os_name = get_os_name()
- if os_name == "windows" then
- return ".zip"
- else
- return ".tar.gz"
- end
+ local os_name = get_os_name()
+ if os_name == "windows" then
+ return ".zip"
+ else
+ return ".tar.gz"
+ end
end
--- Build the download filename
local function build_filename(version)
- local os_name = get_os_name()
- local arch_name = get_arch_name()
- local ext = get_extension()
+ local os_name = get_os_name()
+ local arch_name = get_arch_name()
+ local ext = get_extension()
- -- Format: google-cloud-sdk-{version}-{os}-{arch}.tar.gz
- -- For bundled Python (recommended): google-cloud-sdk-{version}-{os}-{arch}-bundled-python.tar.gz
- return "google-cloud-sdk-" .. version .. "-" .. os_name .. "-" .. arch_name .. ext
+ -- Format: google-cloud-sdk-{version}-{os}-{arch}.tar.gz
+ -- For bundled Python (recommended): google-cloud-sdk-{version}-{os}-{arch}-bundled-python.tar.gz
+ return "google-cloud-sdk-" .. version .. "-" .. os_name .. "-" .. arch_name .. ext
end
--- Fetch SHA256 checksum for the file
local function fetch_checksum(filename)
- -- Google provides checksums at a .sha256 file
- local checksum_url = BASE_URL .. "/" .. filename .. ".sha256"
+ -- Google provides checksums at a .sha256 file
+ local checksum_url = BASE_URL .. "/" .. filename .. ".sha256"
- local resp, err = http.get({
- url = checksum_url,
- })
+ local resp, err = http.get({
+ url = checksum_url,
+ })
- if err ~= nil or resp.status_code ~= 200 then
- -- Checksum file might not exist for all versions
- return nil
- end
+ if err ~= nil or resp.status_code ~= 200 then
+ -- Checksum file might not exist for all versions
+ return nil
+ end
- -- The file contains just the hash
- local hash = string.match(resp.body, "^(%x+)")
- return hash
+ -- The file contains just the hash
+ local hash = string.match(resp.body, "^(%x+)")
+ return hash
end
function PLUGIN:PreInstall(ctx)
- local version = ctx.version
+ local version = ctx.version
- local filename = build_filename(version)
- local url = BASE_URL .. "/" .. filename
+ local filename = build_filename(version)
+ local url = BASE_URL .. "/" .. filename
- -- Verify the file exists
- local resp, err = http.head({
- url = url,
- })
+ -- Verify the file exists
+ local resp, err = http.head({
+ url = url,
+ })
- if err ~= nil or resp.status_code == 404 then
- error("Version " .. version .. " not found for this platform. URL: " .. url)
- end
+ if err ~= nil or resp.status_code == 404 then
+ error("Version " .. version .. " not found for this platform. URL: " .. url)
+ end
- -- Try to fetch checksum
- local checksum = fetch_checksum(filename)
+ -- Try to fetch checksum
+ local checksum = fetch_checksum(filename)
- local result = {
- version = version,
- url = url,
- }
+ local result = {
+ version = version,
+ url = url,
+ }
- if checksum then
- result.sha256 = checksum
- end
+ if checksum then
+ result.sha256 = checksum
+ end
- return result
+ return result
end
diff --git a/crates/vfox/embedded-plugins/vfox-gcloud/metadata.lua b/crates/vfox/embedded-plugins/vfox-gcloud/metadata.lua
index e9a2727120..949a3dc72e 100644
--- a/crates/vfox/embedded-plugins/vfox-gcloud/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-gcloud/metadata.lua
@@ -18,8 +18,8 @@ PLUGIN.description = "Google Cloud SDK (gcloud CLI)"
PLUGIN.minRuntimeVersion = "0.3.0"
--- Some things that need user attention
PLUGIN.notes = {
- "After installation, you may need to run 'gcloud init' to configure your account.",
- "Additional components can be installed with 'gcloud components install '.",
+ "After installation, you may need to run 'gcloud init' to configure your account.",
+ "Additional components can be installed with 'gcloud components install '.",
}
--- Legacy configuration filenames for determining tool version
diff --git a/crates/vfox/embedded-plugins/vfox-leiningen/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-leiningen/hooks/available.lua
index f78b3e96a0..85bc3f323a 100644
--- a/crates/vfox/embedded-plugins/vfox-leiningen/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-leiningen/hooks/available.lua
@@ -6,7 +6,7 @@ function PLUGIN:Available(ctx)
local json = require("json")
local resp, err = http.get({
- url = "https://api.github.com/repos/technomancy/leiningen/releases"
+ url = "https://api.github.com/repos/technomancy/leiningen/releases",
})
if err ~= nil then
@@ -25,7 +25,7 @@ function PLUGIN:Available(ctx)
if version then
table.insert(results, {
version = version,
- note = release.prerelease and "prerelease" or ""
+ note = release.prerelease and "prerelease" or "",
})
end
end
diff --git a/crates/vfox/embedded-plugins/vfox-leiningen/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-leiningen/hooks/env_keys.lua
index a2eb1a4ec8..fae4c74311 100644
--- a/crates/vfox/embedded-plugins/vfox-leiningen/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-leiningen/hooks/env_keys.lua
@@ -7,11 +7,11 @@ function PLUGIN:EnvKeys(ctx)
return {
{
key = "PATH",
- value = mainPath .. "/bin"
+ value = mainPath .. "/bin",
},
{
key = "LEIN_HOME",
- value = mainPath
- }
+ value = mainPath,
+ },
}
end
diff --git a/crates/vfox/embedded-plugins/vfox-leiningen/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-leiningen/hooks/post_install.lua
index 05046d71e9..91a97633f8 100644
--- a/crates/vfox/embedded-plugins/vfox-leiningen/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-leiningen/hooks/post_install.lua
@@ -24,20 +24,25 @@ function PLUGIN:PostInstall(ctx)
local destJar = selfInstallDir .. "/" .. jarName
-- The JAR might be at rootPath directly or we need to find it
- local moveCmd = string.format('mv "%s" "%s" 2>/dev/null || find "%s" -name "*.jar" -exec mv {} "%s" \\;',
- sourceJar, destJar, rootPath, destJar)
+ local moveCmd = string.format(
+ 'mv "%s" "%s" 2>/dev/null || find "%s" -name "*.jar" -exec mv {} "%s" \\;',
+ sourceJar,
+ destJar,
+ rootPath,
+ destJar
+ )
os.execute(moveCmd)
-- Download the lein script
print("Downloading lein script...")
local resp, err = http.get({
- url = "https://raw.githubusercontent.com/technomancy/leiningen/" .. version .. "/bin/lein"
+ url = "https://raw.githubusercontent.com/technomancy/leiningen/" .. version .. "/bin/lein",
})
if err ~= nil then
-- Try stable branch as fallback
resp, err = http.get({
- url = "https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein"
+ url = "https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein",
})
if err ~= nil then
error("Failed to download lein script: " .. err)
diff --git a/crates/vfox/embedded-plugins/vfox-leiningen/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-leiningen/hooks/pre_install.lua
index 8aed5265a5..e84ca08213 100644
--- a/crates/vfox/embedded-plugins/vfox-leiningen/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-leiningen/hooks/pre_install.lua
@@ -6,6 +6,10 @@ function PLUGIN:PreInstall(ctx)
return {
version = version,
- url = "https://github.com/technomancy/leiningen/releases/download/" .. version .. "/leiningen-" .. version .. "-standalone.jar"
+ url = "https://github.com/technomancy/leiningen/releases/download/"
+ .. version
+ .. "/leiningen-"
+ .. version
+ .. "-standalone.jar",
}
end
diff --git a/crates/vfox/embedded-plugins/vfox-leiningen/metadata.lua b/crates/vfox/embedded-plugins/vfox-leiningen/metadata.lua
index a6db07085b..f1dd1d086c 100644
--- a/crates/vfox/embedded-plugins/vfox-leiningen/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-leiningen/metadata.lua
@@ -7,5 +7,5 @@ PLUGIN.license = "MIT"
PLUGIN.description = "Leiningen - automating Clojure projects without setting your hair on fire"
PLUGIN.minRuntimeVersion = "0.3.0"
PLUGIN.notes = {
- "Requires Java to be installed"
+ "Requires Java to be installed",
}
diff --git a/crates/vfox/embedded-plugins/vfox-lua/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-lua/hooks/available.lua
index e609896fc6..980d8f6735 100644
--- a/crates/vfox/embedded-plugins/vfox-lua/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-lua/hooks/available.lua
@@ -2,34 +2,34 @@
--- @param ctx table Context provided by vfox
--- @return table Available versions
function PLUGIN:Available(ctx)
- local http = require("http")
+ local http = require("http")
- local result = {}
- local seen = {}
+ local result = {}
+ local seen = {}
- -- Fetch the Lua FTP page
- local resp, err = http.get({
- url = "https://www.lua.org/ftp/",
- })
+ -- Fetch the Lua FTP page
+ local resp, err = http.get({
+ url = "https://www.lua.org/ftp/",
+ })
- if err ~= nil then
- error("Failed to fetch Lua versions: " .. err)
- end
+ if err ~= nil then
+ error("Failed to fetch Lua versions: " .. err)
+ end
- if resp.status_code ~= 200 then
- error("Failed to fetch Lua versions, status: " .. resp.status_code)
- end
+ if resp.status_code ~= 200 then
+ error("Failed to fetch Lua versions, status: " .. resp.status_code)
+ end
- -- Parse HTML to extract lua-X.Y.Z.tar.gz filenames
- -- Pattern matches: lua-5.4.8.tar.gz, lua-5.1.tar.gz, etc.
- for version in string.gmatch(resp.body, "lua%-(%d+%.%d+[%.%d]*).tar.gz") do
- if not seen[version] then
- seen[version] = true
- table.insert(result, {
- version = version,
- })
- end
- end
+ -- Parse HTML to extract lua-X.Y.Z.tar.gz filenames
+ -- Pattern matches: lua-5.4.8.tar.gz, lua-5.1.tar.gz, etc.
+ for version in string.gmatch(resp.body, "lua%-(%d+%.%d+[%.%d]*).tar.gz") do
+ if not seen[version] then
+ seen[version] = true
+ table.insert(result, {
+ version = version,
+ })
+ end
+ end
- return result
+ return result
end
diff --git a/crates/vfox/embedded-plugins/vfox-lua/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-lua/hooks/env_keys.lua
index 96d0824f48..9d775e5deb 100644
--- a/crates/vfox/embedded-plugins/vfox-lua/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-lua/hooks/env_keys.lua
@@ -2,57 +2,57 @@
--- @param ctx table Context provided by vfox
--- @return table Environment configuration
function PLUGIN:EnvKeys(ctx)
- local sdkInfo = ctx.sdkInfo["lua"]
- local version = sdkInfo.version
- local installDir = sdkInfo.path
+ local sdkInfo = ctx.sdkInfo["lua"]
+ local version = sdkInfo.version
+ local installDir = sdkInfo.path
- -- Extract major.minor version for Lua paths
- local shortVersion = string.match(version, "^(%d+%.%d+)")
+ -- Extract major.minor version for Lua paths
+ local shortVersion = string.match(version, "^(%d+%.%d+)")
- local envs = {
- {
- key = "PATH",
- value = installDir .. "/bin",
- },
- }
+ local envs = {
+ {
+ key = "PATH",
+ value = installDir .. "/bin",
+ },
+ }
- -- Add LuaRocks bin to PATH if it exists
- local luarocksBin = installDir .. "/luarocks/bin"
- local f = io.open(luarocksBin, "r")
- if f ~= nil then
- f:close()
- table.insert(envs, {
- key = "PATH",
- value = luarocksBin,
- })
- end
+ -- Add LuaRocks bin to PATH if it exists
+ local luarocksBin = installDir .. "/luarocks/bin"
+ local f = io.open(luarocksBin, "r")
+ if f ~= nil then
+ f:close()
+ table.insert(envs, {
+ key = "PATH",
+ value = luarocksBin,
+ })
+ end
- -- Set LUA_INIT for package paths (similar to asdf-lua)
- if shortVersion then
- local packagePath = string.format(
- "package.path = package.path .. ';%s/share/lua/%s/?.lua;%s/share/lua/%s/?/init.lua;%s/luarocks/share/lua/%s/?.lua;%s/luarocks/share/lua/%s/?/init.lua'",
- installDir,
- shortVersion,
- installDir,
- shortVersion,
- installDir,
- shortVersion,
- installDir,
- shortVersion
- )
- local packageCpath = string.format(
- "package.cpath = package.cpath .. ';%s/lib/lua/%s/?.so;%s/luarocks/lib/lua/%s/?.so'",
- installDir,
- shortVersion,
- installDir,
- shortVersion
- )
+ -- Set LUA_INIT for package paths (similar to asdf-lua)
+ if shortVersion then
+ local packagePath = string.format(
+ "package.path = package.path .. ';%s/share/lua/%s/?.lua;%s/share/lua/%s/?/init.lua;%s/luarocks/share/lua/%s/?.lua;%s/luarocks/share/lua/%s/?/init.lua'",
+ installDir,
+ shortVersion,
+ installDir,
+ shortVersion,
+ installDir,
+ shortVersion,
+ installDir,
+ shortVersion
+ )
+ local packageCpath = string.format(
+ "package.cpath = package.cpath .. ';%s/lib/lua/%s/?.so;%s/luarocks/lib/lua/%s/?.so'",
+ installDir,
+ shortVersion,
+ installDir,
+ shortVersion
+ )
- table.insert(envs, {
- key = "LUA_INIT",
- value = packagePath .. "\n" .. packageCpath,
- })
- end
+ table.insert(envs, {
+ key = "LUA_INIT",
+ value = packagePath .. "\n" .. packageCpath,
+ })
+ end
- return envs
+ return envs
end
diff --git a/crates/vfox/embedded-plugins/vfox-lua/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-lua/hooks/post_install.lua
index 732e2441a9..834b971ae1 100644
--- a/crates/vfox/embedded-plugins/vfox-lua/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-lua/hooks/post_install.lua
@@ -2,115 +2,115 @@
--- @param ctx table Context provided by vfox
--- @field ctx.sdkInfo table SDK information with version and path
function PLUGIN:PostInstall(ctx)
- local http = require("http")
- local json = require("json")
-
- local sdkInfo = ctx.sdkInfo["lua"]
- local version = sdkInfo.version
- local sdkPath = sdkInfo.path
-
- -- mise extracts tarball and strips top-level directory, so sdkPath IS the source directory
-
- -- Determine OS-specific make target
- local os_type = RUNTIME.osType
- local make_target = "guess"
-
- if os_type == "darwin" then
- make_target = "macosx"
- elseif os_type == "linux" then
- -- For Lua < 5.4, use "linux", otherwise "guess"
- local major, minor = string.match(version, "^(%d+)%.(%d+)")
- if major and minor then
- local ver_num = tonumber(major) * 100 + tonumber(minor)
- if ver_num < 504 then
- make_target = "linux"
- end
- end
- end
-
- -- Build Lua
- local major = tonumber(string.match(version, "^(%d+)"))
- local buildCmd
-
- if major and major >= 5 then
- -- Lua 5.x: use make local target which creates install/ subdirectory
- buildCmd = string.format("cd '%s' && make %s && make local", sdkPath, make_target)
- else
- -- Older versions
- buildCmd = string.format("cd '%s' && make && make install INSTALL_ROOT=install", sdkPath)
- end
-
- local status = os.execute(buildCmd)
- if status ~= 0 and status ~= true then
- error("Failed to build Lua: make failed")
- end
-
- -- After make local, files are in install/ subdirectory
- -- Move them to the root of sdkPath (overwriting source files is fine)
- local moveCmd = string.format("cd '%s' && mv install/* . 2>/dev/null || cp -r install/* . 2>/dev/null", sdkPath)
- os.execute(moveCmd)
-
- -- Install LuaRocks for Lua 5.x
- if major and major >= 5 then
- -- Get latest LuaRocks version from GitHub releases
- local luarocksVersion = "3.11.1" -- Default fallback
-
- local resp, err = http.get({
- url = "https://api.github.com/repos/luarocks/luarocks/releases/latest",
- })
-
- if err == nil and resp.status_code == 200 then
- local data = json.decode(resp.body)
- if data ~= nil and type(data) == "table" then
- local tag = data["tag_name"]
- if tag then
- -- Remove 'v' prefix if present
- luarocksVersion = string.gsub(tag, "^v", "")
- end
- end
- end
-
- -- Download and install LuaRocks
- local luarocksUrl = "https://github.com/luarocks/luarocks/archive/refs/tags/v" .. luarocksVersion .. ".tar.gz"
- local luarocksArchive = sdkPath .. "/luarocks.tar.gz"
-
- local downloadCmd = string.format("curl -sL '%s' -o '%s'", luarocksUrl, luarocksArchive)
- status = os.execute(downloadCmd)
- if status ~= 0 and status ~= true then
- -- LuaRocks installation is optional, don't fail
- return
- end
-
- local extractCmd = string.format("cd '%s' && tar xzf luarocks.tar.gz", sdkPath)
- status = os.execute(extractCmd)
- if status ~= 0 and status ~= true then
- return
- end
-
- local luarocksDir = sdkPath .. "/luarocks-" .. luarocksVersion
- local configureCmd = string.format(
- "cd '%s' && ./configure --with-lua='%s' --with-lua-include='%s/include' --with-lua-lib='%s/lib' --prefix='%s/luarocks' 2>/dev/null",
- luarocksDir,
- sdkPath,
- sdkPath,
- sdkPath,
- sdkPath
- )
- status = os.execute(configureCmd)
- if status ~= 0 and status ~= true then
- -- Clean up and return without luarocks
- os.execute(string.format("rm -rf '%s/luarocks.tar.gz' '%s/luarocks-'*", sdkPath, sdkPath))
- return
- end
-
- local bootstrapCmd = string.format("cd '%s' && make bootstrap 2>&1", luarocksDir)
- os.execute(bootstrapCmd)
-
- -- Clean up LuaRocks source
- os.execute(string.format("rm -rf '%s/luarocks.tar.gz' '%s/luarocks-'*", sdkPath, sdkPath))
- end
-
- -- Clean up Lua source files (keep only bin, lib, include, man, share, luarocks)
- local cleanCmd = string.format("cd '%s' && rm -rf src doc Makefile README install 2>/dev/null", sdkPath)
- os.execute(cleanCmd)
+ local http = require("http")
+ local json = require("json")
+
+ local sdkInfo = ctx.sdkInfo["lua"]
+ local version = sdkInfo.version
+ local sdkPath = sdkInfo.path
+
+ -- mise extracts tarball and strips top-level directory, so sdkPath IS the source directory
+
+ -- Determine OS-specific make target
+ local os_type = RUNTIME.osType
+ local make_target = "guess"
+
+ if os_type == "darwin" then
+ make_target = "macosx"
+ elseif os_type == "linux" then
+ -- For Lua < 5.4, use "linux", otherwise "guess"
+ local major, minor = string.match(version, "^(%d+)%.(%d+)")
+ if major and minor then
+ local ver_num = tonumber(major) * 100 + tonumber(minor)
+ if ver_num < 504 then
+ make_target = "linux"
+ end
+ end
+ end
+
+ -- Build Lua
+ local major = tonumber(string.match(version, "^(%d+)"))
+ local buildCmd
+
+ if major and major >= 5 then
+ -- Lua 5.x: use make local target which creates install/ subdirectory
+ buildCmd = string.format("cd '%s' && make %s && make local", sdkPath, make_target)
+ else
+ -- Older versions
+ buildCmd = string.format("cd '%s' && make && make install INSTALL_ROOT=install", sdkPath)
+ end
+
+ local status = os.execute(buildCmd)
+ if status ~= 0 and status ~= true then
+ error("Failed to build Lua: make failed")
+ end
+
+ -- After make local, files are in install/ subdirectory
+ -- Move them to the root of sdkPath (overwriting source files is fine)
+ local moveCmd = string.format("cd '%s' && mv install/* . 2>/dev/null || cp -r install/* . 2>/dev/null", sdkPath)
+ os.execute(moveCmd)
+
+ -- Install LuaRocks for Lua 5.x
+ if major and major >= 5 then
+ -- Get latest LuaRocks version from GitHub releases
+ local luarocksVersion = "3.11.1" -- Default fallback
+
+ local resp, err = http.get({
+ url = "https://api.github.com/repos/luarocks/luarocks/releases/latest",
+ })
+
+ if err == nil and resp.status_code == 200 then
+ local data = json.decode(resp.body)
+ if data ~= nil and type(data) == "table" then
+ local tag = data["tag_name"]
+ if tag then
+ -- Remove 'v' prefix if present
+ luarocksVersion = string.gsub(tag, "^v", "")
+ end
+ end
+ end
+
+ -- Download and install LuaRocks
+ local luarocksUrl = "https://github.com/luarocks/luarocks/archive/refs/tags/v" .. luarocksVersion .. ".tar.gz"
+ local luarocksArchive = sdkPath .. "/luarocks.tar.gz"
+
+ local downloadCmd = string.format("curl -sL '%s' -o '%s'", luarocksUrl, luarocksArchive)
+ status = os.execute(downloadCmd)
+ if status ~= 0 and status ~= true then
+ -- LuaRocks installation is optional, don't fail
+ return
+ end
+
+ local extractCmd = string.format("cd '%s' && tar xzf luarocks.tar.gz", sdkPath)
+ status = os.execute(extractCmd)
+ if status ~= 0 and status ~= true then
+ return
+ end
+
+ local luarocksDir = sdkPath .. "/luarocks-" .. luarocksVersion
+ local configureCmd = string.format(
+ "cd '%s' && ./configure --with-lua='%s' --with-lua-include='%s/include' --with-lua-lib='%s/lib' --prefix='%s/luarocks' 2>/dev/null",
+ luarocksDir,
+ sdkPath,
+ sdkPath,
+ sdkPath,
+ sdkPath
+ )
+ status = os.execute(configureCmd)
+ if status ~= 0 and status ~= true then
+ -- Clean up and return without luarocks
+ os.execute(string.format("rm -rf '%s/luarocks.tar.gz' '%s/luarocks-'*", sdkPath, sdkPath))
+ return
+ end
+
+ local bootstrapCmd = string.format("cd '%s' && make bootstrap 2>&1", luarocksDir)
+ os.execute(bootstrapCmd)
+
+ -- Clean up LuaRocks source
+ os.execute(string.format("rm -rf '%s/luarocks.tar.gz' '%s/luarocks-'*", sdkPath, sdkPath))
+ end
+
+ -- Clean up Lua source files (keep only bin, lib, include, man, share, luarocks)
+ local cleanCmd = string.format("cd '%s' && rm -rf src doc Makefile README install 2>/dev/null", sdkPath)
+ os.execute(cleanCmd)
end
diff --git a/crates/vfox/embedded-plugins/vfox-lua/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-lua/hooks/pre_install.lua
index 5e6f9cb84b..d3bdde7be2 100644
--- a/crates/vfox/embedded-plugins/vfox-lua/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-lua/hooks/pre_install.lua
@@ -2,10 +2,10 @@
--- @param ctx table Context provided by vfox
--- @return table Pre-install info
function PLUGIN:PreInstall(ctx)
- local version = ctx.version
+ local version = ctx.version
- return {
- version = version,
- url = "https://www.lua.org/ftp/lua-" .. version .. ".tar.gz",
- }
+ return {
+ version = version,
+ url = "https://www.lua.org/ftp/lua-" .. version .. ".tar.gz",
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-lua/metadata.lua b/crates/vfox/embedded-plugins/vfox-lua/metadata.lua
index b84c824839..bd8ab7c0e5 100644
--- a/crates/vfox/embedded-plugins/vfox-lua/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-lua/metadata.lua
@@ -6,6 +6,6 @@ PLUGIN.license = "MIT"
PLUGIN.description = "Lua version manager - compiles from source"
PLUGIN.minRuntimeVersion = "0.3.0"
PLUGIN.notes = {
- "Compiles Lua from source. Requires a C compiler (gcc/clang).",
- "Automatically installs LuaRocks for Lua 5.x versions.",
+ "Compiles Lua from source. Requires a C compiler (gcc/clang).",
+ "Automatically installs LuaRocks for Lua 5.x versions.",
}
diff --git a/crates/vfox/embedded-plugins/vfox-neovim/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-neovim/hooks/available.lua
index d999bccb7f..e21ba75125 100644
--- a/crates/vfox/embedded-plugins/vfox-neovim/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-neovim/hooks/available.lua
@@ -64,7 +64,7 @@ function PLUGIN:Available(ctx)
url = "https://api.github.com/repos/neovim/neovim/releases",
headers = {
["Accept"] = "application/vnd.github.v3+json",
- }
+ },
})
if err ~= nil then
diff --git a/crates/vfox/embedded-plugins/vfox-neovim/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-neovim/hooks/env_keys.lua
index a70dc2198d..24b27d6c59 100644
--- a/crates/vfox/embedded-plugins/vfox-neovim/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-neovim/hooks/env_keys.lua
@@ -5,7 +5,7 @@ function PLUGIN:EnvKeys(ctx)
return {
{
key = "PATH",
- value = main_path .. "/bin"
- }
+ value = main_path .. "/bin",
+ },
}
end
diff --git a/crates/vfox/embedded-plugins/vfox-neovim/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-neovim/hooks/pre_install.lua
index ae9646823c..6dcb6347fa 100644
--- a/crates/vfox/embedded-plugins/vfox-neovim/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-neovim/hooks/pre_install.lua
@@ -48,7 +48,7 @@ function PLUGIN:PreInstall(ctx)
url = "https://api.github.com/repos/neovim/neovim/releases/tags/" .. tag,
headers = {
["Accept"] = "application/vnd.github.v3+json",
- }
+ },
})
if err ~= nil then
diff --git a/crates/vfox/embedded-plugins/vfox-pipenv/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-pipenv/hooks/available.lua
index 8aa428424a..75ce2b69c0 100644
--- a/crates/vfox/embedded-plugins/vfox-pipenv/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-pipenv/hooks/available.lua
@@ -6,71 +6,71 @@ local json = require("json")
--- @param v2 string
--- @return boolean true if v1 > v2
local function compare_versions(v1, v2)
- local function parse(v)
- local parts = {}
- -- Handle pre-release versions like 2020.4.1b2, 2020.4.1.dev1
- local main = v:match("^([%d%.]+)")
- if main then
- for num in main:gmatch("(%d+)") do
- table.insert(parts, tonumber(num))
- end
- end
- -- Pre-release versions should sort before release versions
- if v:match("[abrc]%d*$") or v:match("%.dev%d*$") then
- table.insert(parts, -1)
- else
- table.insert(parts, 0)
- end
- return parts
- end
+ local function parse(v)
+ local parts = {}
+ -- Handle pre-release versions like 2020.4.1b2, 2020.4.1.dev1
+ local main = v:match("^([%d%.]+)")
+ if main then
+ for num in main:gmatch("(%d+)") do
+ table.insert(parts, tonumber(num))
+ end
+ end
+ -- Pre-release versions should sort before release versions
+ if v:match("[abrc]%d*$") or v:match("%.dev%d*$") then
+ table.insert(parts, -1)
+ else
+ table.insert(parts, 0)
+ end
+ return parts
+ end
- local p1, p2 = parse(v1), parse(v2)
- for i = 1, math.max(#p1, #p2) do
- local n1, n2 = p1[i] or 0, p2[i] or 0
- if n1 ~= n2 then
- return n1 > n2
- end
- end
- return false
+ local p1, p2 = parse(v1), parse(v2)
+ for i = 1, math.max(#p1, #p2) do
+ local n1, n2 = p1[i] or 0, p2[i] or 0
+ if n1 ~= n2 then
+ return n1 > n2
+ end
+ end
+ return false
end
--- Get the available version list from PyPI.
--- @param ctx table Empty table, no data provided. Always {}.
--- @return table Version list
function PLUGIN:Available(ctx)
- local resp, err = http.get({
- url = "https://pypi.org/pypi/pipenv/json",
- })
+ local resp, err = http.get({
+ url = "https://pypi.org/pypi/pipenv/json",
+ })
- if err ~= nil or resp.status_code ~= 200 then
- error("Failed to fetch pipenv versions from PyPI: " .. (err or ("HTTP " .. resp.status_code)))
- end
+ if err ~= nil or resp.status_code ~= 200 then
+ error("Failed to fetch pipenv versions from PyPI: " .. (err or ("HTTP " .. resp.status_code)))
+ end
- local data = json.decode(resp.body)
- if not data or not data.releases then
- error("Invalid response from PyPI")
- end
+ local data = json.decode(resp.body)
+ if not data or not data.releases then
+ error("Invalid response from PyPI")
+ end
- local result = {}
- for version, release_info in pairs(data.releases) do
- -- Skip versions with no files (yanked or broken releases)
- if release_info and #release_info > 0 then
- local note = ""
- -- Mark pre-release versions
- if version:match("[abrc]%d*$") or version:match("%.dev%d*$") then
- note = "pre-release"
- end
- table.insert(result, {
- version = version,
- note = note,
- })
- end
- end
+ local result = {}
+ for version, release_info in pairs(data.releases) do
+ -- Skip versions with no files (yanked or broken releases)
+ if release_info and #release_info > 0 then
+ local note = ""
+ -- Mark pre-release versions
+ if version:match("[abrc]%d*$") or version:match("%.dev%d*$") then
+ note = "pre-release"
+ end
+ table.insert(result, {
+ version = version,
+ note = note,
+ })
+ end
+ end
- -- Sort versions (newest first)
- table.sort(result, function(a, b)
- return compare_versions(a.version, b.version)
- end)
+ -- Sort versions (newest first)
+ table.sort(result, function(a, b)
+ return compare_versions(a.version, b.version)
+ end)
- return result
+ return result
end
diff --git a/crates/vfox/embedded-plugins/vfox-pipenv/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-pipenv/hooks/env_keys.lua
index 09460fa8ef..a1b1aabe27 100644
--- a/crates/vfox/embedded-plugins/vfox-pipenv/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-pipenv/hooks/env_keys.lua
@@ -2,78 +2,78 @@
--- This allows plugins to define custom environment variables (including PATH settings)
--- @param ctx {path: string} Context information (SDK installation directory)
function PLUGIN:EnvKeys(ctx)
- local version_path = ctx.path
- local result = {}
+ local version_path = ctx.path
+ local result = {}
- -- Add wrapper_bin to PATH for pipenv command
- if RUNTIME.osType == "windows" then
- table.insert(result, {
- key = "PATH",
- value = version_path .. "\\wrapper_bin",
- })
- else
- table.insert(result, {
- key = "PATH",
- value = version_path .. "/wrapper_bin",
- })
- end
+ -- Add wrapper_bin to PATH for pipenv command
+ if RUNTIME.osType == "windows" then
+ table.insert(result, {
+ key = "PATH",
+ value = version_path .. "\\wrapper_bin",
+ })
+ else
+ table.insert(result, {
+ key = "PATH",
+ value = version_path .. "/wrapper_bin",
+ })
+ end
- -- Check for Pipfile in current directory to auto-activate virtualenv
- local cwd = os.getenv("PWD")
- if not cwd then
- -- Fallback: try to get cwd via shell command
- local handle = io.popen("pwd 2>/dev/null")
- if handle then
- cwd = handle:read("*a"):gsub("%s+$", "")
- handle:close()
- end
- end
+ -- Check for Pipfile in current directory to auto-activate virtualenv
+ local cwd = os.getenv("PWD")
+ if not cwd then
+ -- Fallback: try to get cwd via shell command
+ local handle = io.popen("pwd 2>/dev/null")
+ if handle then
+ cwd = handle:read("*a"):gsub("%s+$", "")
+ handle:close()
+ end
+ end
- if cwd and cwd ~= "" then
- local pipfile_path = cwd .. "/Pipfile"
- local f = io.open(pipfile_path, "r")
- if f then
- f:close()
+ if cwd and cwd ~= "" then
+ local pipfile_path = cwd .. "/Pipfile"
+ local f = io.open(pipfile_path, "r")
+ if f then
+ f:close()
- -- Pipfile exists, try to get the virtualenv path
- local pipenv_cmd = version_path
- if RUNTIME.osType == "windows" then
- pipenv_cmd = pipenv_cmd .. "\\wrapper_bin\\pipenv"
- else
- pipenv_cmd = pipenv_cmd .. "/wrapper_bin/pipenv"
- end
+ -- Pipfile exists, try to get the virtualenv path
+ local pipenv_cmd = version_path
+ if RUNTIME.osType == "windows" then
+ pipenv_cmd = pipenv_cmd .. "\\wrapper_bin\\pipenv"
+ else
+ pipenv_cmd = pipenv_cmd .. "/wrapper_bin/pipenv"
+ end
- local venv_handle =
- io.popen('PIPENV_PIPFILE="' .. pipfile_path .. '" "' .. pipenv_cmd .. '" --venv 2>/dev/null')
- if venv_handle then
- local venv_path = venv_handle:read("*a"):gsub("%s+$", "")
- venv_handle:close()
+ local venv_handle =
+ io.popen('PIPENV_PIPFILE="' .. pipfile_path .. '" "' .. pipenv_cmd .. '" --venv 2>/dev/null')
+ if venv_handle then
+ local venv_path = venv_handle:read("*a"):gsub("%s+$", "")
+ venv_handle:close()
- if venv_path and venv_path ~= "" then
- -- Verify the venv exists
- local venv_bin = venv_path .. "/bin"
- local test_file = io.open(venv_bin .. "/python", "r")
- if test_file then
- test_file:close()
+ if venv_path and venv_path ~= "" then
+ -- Verify the venv exists
+ local venv_bin = venv_path .. "/bin"
+ local test_file = io.open(venv_bin .. "/python", "r")
+ if test_file then
+ test_file:close()
- -- Add virtualenv activation
- table.insert(result, {
- key = "VIRTUAL_ENV",
- value = venv_path,
- })
- table.insert(result, {
- key = "PIPENV_ACTIVE",
- value = "1",
- })
- table.insert(result, {
- key = "PATH",
- value = venv_bin,
- })
- end
- end
- end
- end
- end
+ -- Add virtualenv activation
+ table.insert(result, {
+ key = "VIRTUAL_ENV",
+ value = venv_path,
+ })
+ table.insert(result, {
+ key = "PIPENV_ACTIVE",
+ value = "1",
+ })
+ table.insert(result, {
+ key = "PATH",
+ value = venv_bin,
+ })
+ end
+ end
+ end
+ end
+ end
- return result
+ return result
end
diff --git a/crates/vfox/embedded-plugins/vfox-pipenv/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-pipenv/hooks/post_install.lua
index 4c8b4571ba..b5cbb9037e 100644
--- a/crates/vfox/embedded-plugins/vfox-pipenv/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-pipenv/hooks/post_install.lua
@@ -3,107 +3,107 @@
--- @field ctx.rootPath string SDK installation root path
--- @field ctx.sdkInfo table SDK info containing version
function PLUGIN:PostInstall(ctx)
- local rootPath = ctx.rootPath
+ local rootPath = ctx.rootPath
- -- Extract version from rootPath (e.g., /path/to/installs/pipenv/2024.0.1)
- -- The version is the last component of the path
- local version = rootPath:match("([^/\\]+)$")
- if not version then
- error("Could not extract version from rootPath: " .. rootPath)
- end
+ -- Extract version from rootPath (e.g., /path/to/installs/pipenv/2024.0.1)
+ -- The version is the last component of the path
+ local version = rootPath:match("([^/\\]+)$")
+ if not version then
+ error("Could not extract version from rootPath: " .. rootPath)
+ end
- -- Find Python interpreter
- local python_cmd = nil
- local python_candidates = { "python3", "python" }
+ -- Find Python interpreter
+ local python_cmd = nil
+ local python_candidates = { "python3", "python" }
- for _, candidate in ipairs(python_candidates) do
- local check = os.execute(candidate .. " --version >/dev/null 2>&1")
- if check == 0 or check == true then
- -- Verify it's Python 3.7+
- local handle =
- io.popen(candidate .. ' -c "import sys; print(sys.version_info.major, sys.version_info.minor)"')
- if handle then
- local output = handle:read("*a")
- handle:close()
- local major, minor = output:match("(%d+)%s+(%d+)")
- if major and minor then
- major = tonumber(major)
- minor = tonumber(minor)
- if major >= 3 and minor >= 7 then
- python_cmd = candidate
- break
- end
- end
- end
- end
- end
+ for _, candidate in ipairs(python_candidates) do
+ local check = os.execute(candidate .. " --version >/dev/null 2>&1")
+ if check == 0 or check == true then
+ -- Verify it's Python 3.7+
+ local handle =
+ io.popen(candidate .. ' -c "import sys; print(sys.version_info.major, sys.version_info.minor)"')
+ if handle then
+ local output = handle:read("*a")
+ handle:close()
+ local major, minor = output:match("(%d+)%s+(%d+)")
+ if major and minor then
+ major = tonumber(major)
+ minor = tonumber(minor)
+ if major >= 3 and minor >= 7 then
+ python_cmd = candidate
+ break
+ end
+ end
+ end
+ end
+ end
- if not python_cmd then
- error("Python 3.7+ is required but not found in PATH")
- end
+ if not python_cmd then
+ error("Python 3.7+ is required but not found in PATH")
+ end
- -- Create virtual environment
- local venv_cmd = python_cmd .. ' -m venv --copies "' .. rootPath .. '"'
- local result = os.execute(venv_cmd)
- if result ~= 0 and result ~= true then
- error("Failed to create virtual environment")
- end
+ -- Create virtual environment
+ local venv_cmd = python_cmd .. ' -m venv --copies "' .. rootPath .. '"'
+ local result = os.execute(venv_cmd)
+ if result ~= 0 and result ~= true then
+ error("Failed to create virtual environment")
+ end
- -- Determine the path separator and bin directory based on OS
- local bin_dir = "bin"
- local path_sep = "/"
- local script_ext = ""
- local activate_script = "activate"
+ -- Determine the path separator and bin directory based on OS
+ local bin_dir = "bin"
+ local path_sep = "/"
+ local script_ext = ""
+ local activate_script = "activate"
- if RUNTIME.osType == "windows" then
- bin_dir = "Scripts"
- path_sep = "\\"
- script_ext = ".bat"
- activate_script = "activate.bat"
- end
+ if RUNTIME.osType == "windows" then
+ bin_dir = "Scripts"
+ path_sep = "\\"
+ script_ext = ".bat"
+ activate_script = "activate.bat"
+ end
- local venv_bin = rootPath .. path_sep .. bin_dir
- local pip_cmd = venv_bin .. path_sep .. "pip"
+ local venv_bin = rootPath .. path_sep .. bin_dir
+ local pip_cmd = venv_bin .. path_sep .. "pip"
- -- Install pipenv inside virtual environment
- local install_cmd = '"' .. pip_cmd .. '" install --quiet pipenv==' .. version
- result = os.execute(install_cmd)
- if result ~= 0 and result ~= true then
- error("Failed to install pipenv==" .. version)
- end
+ -- Install pipenv inside virtual environment
+ local install_cmd = '"' .. pip_cmd .. '" install --quiet pipenv==' .. version
+ result = os.execute(install_cmd)
+ if result ~= 0 and result ~= true then
+ error("Failed to install pipenv==" .. version)
+ end
- -- Create wrapper scripts directory
- local wrapper_dir = rootPath .. path_sep .. "wrapper_bin"
- os.execute('mkdir -p "' .. wrapper_dir .. '"')
+ -- Create wrapper scripts directory
+ local wrapper_dir = rootPath .. path_sep .. "wrapper_bin"
+ os.execute('mkdir -p "' .. wrapper_dir .. '"')
- -- Create wrapper scripts for pipenv executables
- local executables = { "pipenv", "pipenv-resolver" }
+ -- Create wrapper scripts for pipenv executables
+ local executables = { "pipenv", "pipenv-resolver" }
- if RUNTIME.osType == "windows" then
- -- Windows batch wrapper
- for _, exe in ipairs(executables) do
- local wrapper_path = wrapper_dir .. path_sep .. exe .. ".cmd"
- local wrapper_file = io.open(wrapper_path, "w")
- if wrapper_file then
- wrapper_file:write("@echo off\r\n")
- wrapper_file:write('call "' .. venv_bin .. path_sep .. activate_script .. '"\r\n')
- wrapper_file:write("set PIPENV_IGNORE_VIRTUALENVS=1\r\n")
- wrapper_file:write('"' .. venv_bin .. path_sep .. exe .. '" %*\r\n')
- wrapper_file:close()
- end
- end
- else
- -- Unix shell wrapper
- for _, exe in ipairs(executables) do
- local wrapper_path = wrapper_dir .. path_sep .. exe
- local wrapper_file = io.open(wrapper_path, "w")
- if wrapper_file then
- wrapper_file:write("#!/usr/bin/env bash\n")
- wrapper_file:write('source "' .. venv_bin .. "/" .. activate_script .. '"\n')
- wrapper_file:write('PIPENV_IGNORE_VIRTUALENVS=1 "' .. venv_bin .. "/" .. exe .. '" "$@"\n')
- wrapper_file:close()
- os.execute('chmod +x "' .. wrapper_path .. '"')
- end
- end
- end
+ if RUNTIME.osType == "windows" then
+ -- Windows batch wrapper
+ for _, exe in ipairs(executables) do
+ local wrapper_path = wrapper_dir .. path_sep .. exe .. ".cmd"
+ local wrapper_file = io.open(wrapper_path, "w")
+ if wrapper_file then
+ wrapper_file:write("@echo off\r\n")
+ wrapper_file:write('call "' .. venv_bin .. path_sep .. activate_script .. '"\r\n')
+ wrapper_file:write("set PIPENV_IGNORE_VIRTUALENVS=1\r\n")
+ wrapper_file:write('"' .. venv_bin .. path_sep .. exe .. '" %*\r\n')
+ wrapper_file:close()
+ end
+ end
+ else
+ -- Unix shell wrapper
+ for _, exe in ipairs(executables) do
+ local wrapper_path = wrapper_dir .. path_sep .. exe
+ local wrapper_file = io.open(wrapper_path, "w")
+ if wrapper_file then
+ wrapper_file:write("#!/usr/bin/env bash\n")
+ wrapper_file:write('source "' .. venv_bin .. "/" .. activate_script .. '"\n')
+ wrapper_file:write('PIPENV_IGNORE_VIRTUALENVS=1 "' .. venv_bin .. "/" .. exe .. '" "$@"\n')
+ wrapper_file:close()
+ os.execute('chmod +x "' .. wrapper_path .. '"')
+ end
+ end
+ end
end
diff --git a/crates/vfox/embedded-plugins/vfox-pipenv/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-pipenv/hooks/pre_install.lua
index 4ece5f08af..b4f59e200a 100644
--- a/crates/vfox/embedded-plugins/vfox-pipenv/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-pipenv/hooks/pre_install.lua
@@ -6,27 +6,27 @@ local json = require("json")
--- @param ctx {version: string} (User-input version)
--- @return table Version information
function PLUGIN:PreInstall(ctx)
- local version = ctx.version
+ local version = ctx.version
- -- Validate version exists on PyPI
- local resp, err = http.get({
- url = "https://pypi.org/pypi/pipenv/" .. version .. "/json",
- })
+ -- Validate version exists on PyPI
+ local resp, err = http.get({
+ url = "https://pypi.org/pypi/pipenv/" .. version .. "/json",
+ })
- if err ~= nil then
- error("Failed to validate pipenv version: " .. err)
- end
+ if err ~= nil then
+ error("Failed to validate pipenv version: " .. err)
+ end
- if resp.status_code == 404 then
- error("Pipenv version " .. version .. " not found on PyPI")
- end
+ if resp.status_code == 404 then
+ error("Pipenv version " .. version .. " not found on PyPI")
+ end
- if resp.status_code ~= 200 then
- error("Failed to validate pipenv version: HTTP " .. resp.status_code)
- end
+ if resp.status_code ~= 200 then
+ error("Failed to validate pipenv version: HTTP " .. resp.status_code)
+ end
- -- No download URL needed - we install via pip in PostInstall
- return {
- version = version,
- }
+ -- No download URL needed - we install via pip in PostInstall
+ return {
+ version = version,
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-pipenv/metadata.lua b/crates/vfox/embedded-plugins/vfox-pipenv/metadata.lua
index cd04e9675b..b10b0336f9 100644
--- a/crates/vfox/embedded-plugins/vfox-pipenv/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-pipenv/metadata.lua
@@ -16,6 +16,6 @@ PLUGIN.description = "Python Development Workflow for Humans - https://pipenv.py
--- !!! OPTIONAL !!!
PLUGIN.minRuntimeVersion = "0.3.0"
PLUGIN.notes = {
- "Requires Python 3.7+ to be installed and available in PATH",
- "If the Python interpreter used during installation is removed, pipenv will stop working and needs to be reinstalled",
+ "Requires Python 3.7+ to be installed and available in PATH",
+ "If the Python interpreter used during installation is removed, pipenv will stop working and needs to be reinstalled",
}
diff --git a/crates/vfox/embedded-plugins/vfox-poetry/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-poetry/hooks/available.lua
index 36561cc231..2e93d136e1 100644
--- a/crates/vfox/embedded-plugins/vfox-poetry/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-poetry/hooks/available.lua
@@ -7,7 +7,7 @@ function PLUGIN:Available(ctx)
-- Fetch releases from GitHub API
local resp, err = http.get({
- url = "https://api.github.com/repos/python-poetry/poetry/tags?per_page=100"
+ url = "https://api.github.com/repos/python-poetry/poetry/tags?per_page=100",
})
if err ~= nil then
error("Failed to fetch version list: " .. err)
diff --git a/crates/vfox/embedded-plugins/vfox-poetry/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-poetry/hooks/env_keys.lua
index 4d47ffadc0..c09beaf0e9 100644
--- a/crates/vfox/embedded-plugins/vfox-poetry/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-poetry/hooks/env_keys.lua
@@ -86,7 +86,9 @@ function PLUGIN:EnvKeys(ctx)
-- Get the virtualenv path from poetry
local poetry_bin = ctx.path .. "/bin/poetry"
- local handle = io.popen("cd '" .. pyproject_dir .. "' && " .. path_prefix .. "'" .. poetry_bin .. "' env info --path 2>/dev/null")
+ local handle = io.popen(
+ "cd '" .. pyproject_dir .. "' && " .. path_prefix .. "'" .. poetry_bin .. "' env info --path 2>/dev/null"
+ )
if not handle then
return env_keys
end
@@ -99,7 +101,9 @@ function PLUGIN:EnvKeys(ctx)
os.execute("cd '" .. pyproject_dir .. "' && " .. path_prefix .. "'" .. poetry_bin .. "' run true 2>/dev/null")
-- Try again to get the path
- handle = io.popen("cd '" .. pyproject_dir .. "' && " .. path_prefix .. "'" .. poetry_bin .. "' env info --path 2>/dev/null")
+ handle = io.popen(
+ "cd '" .. pyproject_dir .. "' && " .. path_prefix .. "'" .. poetry_bin .. "' env info --path 2>/dev/null"
+ )
if handle then
venv_path = handle:read("*l")
handle:close()
diff --git a/crates/vfox/embedded-plugins/vfox-poetry/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-poetry/hooks/post_install.lua
index a69d18a984..4810172664 100644
--- a/crates/vfox/embedded-plugins/vfox-poetry/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-poetry/hooks/post_install.lua
@@ -8,7 +8,8 @@ function PLUGIN:PostInstall(ctx)
local version = ctx.sdkInfo["poetry"].version
-- Run the Poetry installer via bash script
- local script = string.format([[
+ local script = string.format(
+ [[
#!/bin/bash
set -e
@@ -28,7 +29,14 @@ if version_ge "%s" "2.0.0"; then
elif version_ge "%s" "1.2.0"; then
"%s/bin/poetry" config virtualenvs.prefer-active-python true
fi
-]], install_path, version, version, install_path, version, install_path)
+]],
+ install_path,
+ version,
+ version,
+ install_path,
+ version,
+ install_path
+ )
-- Write and execute the script
local script_path = install_path .. "/install_poetry.sh"
diff --git a/crates/vfox/embedded-plugins/vfox-postgres/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-postgres/hooks/available.lua
index 389b074447..29a1d75220 100644
--- a/crates/vfox/embedded-plugins/vfox-postgres/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-postgres/hooks/available.lua
@@ -2,65 +2,65 @@
--- @param ctx table Context provided by vfox
--- @return table Available versions
function PLUGIN:Available(ctx)
- local http = require("http")
+ local http = require("http")
- local result = {}
- local seen = {}
+ local result = {}
+ local seen = {}
- -- Fetch the PostgreSQL source directory listing
- local resp, err = http.get({
- url = "https://ftp.postgresql.org/pub/source/",
- })
+ -- Fetch the PostgreSQL source directory listing
+ local resp, err = http.get({
+ url = "https://ftp.postgresql.org/pub/source/",
+ })
- if err ~= nil then
- error("Failed to fetch PostgreSQL versions: " .. err)
- end
+ if err ~= nil then
+ error("Failed to fetch PostgreSQL versions: " .. err)
+ end
- if resp.status_code ~= 200 then
- error("Failed to fetch PostgreSQL versions, status: " .. resp.status_code)
- end
+ if resp.status_code ~= 200 then
+ error("Failed to fetch PostgreSQL versions, status: " .. resp.status_code)
+ end
- -- Parse HTML to extract version directories
- -- Format: >v17.2/<, >v16.6/<, >v9.6.24/<
- for version in string.gmatch(resp.body, ">v([0-9]+%.[0-9]+[%.0-9]*)/<") do
- if not seen[version] then
- seen[version] = true
- table.insert(result, {
- version = version,
- })
- end
- end
+ -- Parse HTML to extract version directories
+ -- Format: >v17.2/<, >v16.6/<, >v9.6.24/<
+ for version in string.gmatch(resp.body, ">v([0-9]+%.[0-9]+[%.0-9]*)/<") do
+ if not seen[version] then
+ seen[version] = true
+ table.insert(result, {
+ version = version,
+ })
+ end
+ end
- -- Sort versions semantically (descending order - newest first)
- table.sort(result, function(a, b)
- return compare_versions(b.version, a.version)
- end)
+ -- Sort versions semantically (descending order - newest first)
+ table.sort(result, function(a, b)
+ return compare_versions(b.version, a.version)
+ end)
- return result
+ return result
end
--- Compare two version strings semantically
--- Returns true if v1 < v2 (for ascending sort)
function compare_versions(v1, v2)
- local parts1 = split_version(v1)
- local parts2 = split_version(v2)
+ local parts1 = split_version(v1)
+ local parts2 = split_version(v2)
- local max_len = math.max(#parts1, #parts2)
- for i = 1, max_len do
- local p1 = parts1[i] or 0
- local p2 = parts2[i] or 0
- if p1 ~= p2 then
- return p1 < p2
- end
- end
- return false
+ local max_len = math.max(#parts1, #parts2)
+ for i = 1, max_len do
+ local p1 = parts1[i] or 0
+ local p2 = parts2[i] or 0
+ if p1 ~= p2 then
+ return p1 < p2
+ end
+ end
+ return false
end
--- Split a version string into numeric parts
function split_version(version)
- local parts = {}
- for part in string.gmatch(version, "([0-9]+)") do
- table.insert(parts, tonumber(part))
- end
- return parts
+ local parts = {}
+ for part in string.gmatch(version, "([0-9]+)") do
+ table.insert(parts, tonumber(part))
+ end
+ return parts
end
diff --git a/crates/vfox/embedded-plugins/vfox-postgres/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-postgres/hooks/env_keys.lua
index 9139b130a5..ffac1a46be 100644
--- a/crates/vfox/embedded-plugins/vfox-postgres/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-postgres/hooks/env_keys.lua
@@ -2,27 +2,27 @@
--- @param ctx table Context provided by vfox
--- @return table Environment configuration
function PLUGIN:EnvKeys(ctx)
- local sdkInfo = ctx.sdkInfo["postgres"]
- local installDir = sdkInfo.path
+ local sdkInfo = ctx.sdkInfo["postgres"]
+ local installDir = sdkInfo.path
- local envs = {
- {
- key = "PATH",
- value = installDir .. "/bin",
- },
- {
- key = "PGDATA",
- value = installDir .. "/data",
- },
- }
+ local envs = {
+ {
+ key = "PATH",
+ value = installDir .. "/bin",
+ },
+ {
+ key = "PGDATA",
+ value = installDir .. "/data",
+ },
+ }
- -- Add LD_LIBRARY_PATH on Linux
- if RUNTIME.osType == "linux" then
- table.insert(envs, {
- key = "LD_LIBRARY_PATH",
- value = installDir .. "/lib",
- })
- end
+ -- Add LD_LIBRARY_PATH on Linux
+ if RUNTIME.osType == "linux" then
+ table.insert(envs, {
+ key = "LD_LIBRARY_PATH",
+ value = installDir .. "/lib",
+ })
+ end
- return envs
+ return envs
end
diff --git a/crates/vfox/embedded-plugins/vfox-postgres/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-postgres/hooks/post_install.lua
index fbc79d670c..a60a98cc92 100644
--- a/crates/vfox/embedded-plugins/vfox-postgres/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-postgres/hooks/post_install.lua
@@ -2,178 +2,178 @@
--- @param ctx table Context provided by vfox
--- @field ctx.sdkInfo table SDK information with version and path
function PLUGIN:PostInstall(ctx)
- local sdkInfo = ctx.sdkInfo["postgres"]
- local version = sdkInfo.version
- local sdkPath = sdkInfo.path
-
- -- mise extracts tarball and strips top-level directory, so sdkPath IS the source directory
-
- -- Build configure options
- local configureOptions = "--prefix='" .. sdkPath .. "'"
- local envPrefix = "" -- Environment variables to prepend to configure command
-
- -- Add common options
- configureOptions = configureOptions .. " --with-openssl --with-zlib"
-
- -- Try to add UUID support (e2fs on Linux, BSD on macOS)
- local os_type = RUNTIME.osType
- local homebrew_prefix = os.getenv("HOMEBREW_PREFIX") or "/opt/homebrew"
-
- if os_type == "darwin" then
- -- Homebrew paths
- local openssl_path = homebrew_prefix .. "/opt/openssl"
- local icu_path = homebrew_prefix .. "/opt/icu4c"
- local ossp_uuid_path = homebrew_prefix .. "/opt/ossp-uuid"
- local util_linux_path = homebrew_prefix .. "/opt/util-linux"
-
- -- Build library and include paths
- local lib_paths = {}
- local include_paths = {}
- local f
-
- -- Check if OpenSSL exists in Homebrew
- f = io.open(openssl_path .. "/lib", "r")
- if f ~= nil then
- f:close()
- table.insert(lib_paths, openssl_path .. "/lib")
- table.insert(include_paths, openssl_path .. "/include")
- end
-
- -- Check if ICU exists in Homebrew (PostgreSQL 17+ requires ICU by default)
- f = io.open(icu_path .. "/lib", "r")
- if f ~= nil then
- f:close()
- table.insert(lib_paths, icu_path .. "/lib")
- table.insert(include_paths, icu_path .. "/include")
- -- Set PKG_CONFIG_PATH for ICU (prepend to configure command)
- local pkg_config_path = os.getenv("PKG_CONFIG_PATH") or ""
- if pkg_config_path ~= "" then
- pkg_config_path = icu_path .. "/lib/pkgconfig:" .. pkg_config_path
- else
- pkg_config_path = icu_path .. "/lib/pkgconfig"
- end
- envPrefix = "PKG_CONFIG_PATH='" .. pkg_config_path .. "' "
- else
- -- ICU not found, disable it
- io.stderr:write("Warning: ICU not found. Installing without ICU support.\n")
- io.stderr:write(" To enable ICU: brew install icu4c\n")
- configureOptions = configureOptions .. " --without-icu"
- end
-
- -- Check for UUID library: prefer ossp-uuid, then util-linux (e2fs), otherwise skip
- f = io.open(ossp_uuid_path .. "/lib", "r")
- if f ~= nil then
- f:close()
- configureOptions = configureOptions .. " --with-uuid=ossp"
- table.insert(lib_paths, ossp_uuid_path .. "/lib")
- table.insert(include_paths, ossp_uuid_path .. "/include")
- else
- f = io.open(util_linux_path .. "/lib", "r")
- if f ~= nil then
- f:close()
- configureOptions = configureOptions .. " --with-uuid=e2fs"
- table.insert(lib_paths, util_linux_path .. "/lib")
- table.insert(include_paths, util_linux_path .. "/include")
- else
- -- Neither UUID library available
- io.stderr:write("Warning: UUID library not found. Installing without UUID support.\n")
- io.stderr:write(" To enable UUID: brew install ossp-uuid\n")
- end
- end
-
- if #lib_paths > 0 then
- configureOptions = configureOptions .. " --with-libraries='" .. table.concat(lib_paths, ":") .. "'"
- end
- if #include_paths > 0 then
- configureOptions = configureOptions .. " --with-includes='" .. table.concat(include_paths, ":") .. "'"
- end
- else
- -- Linux: use e2fs UUID
- configureOptions = configureOptions .. " --with-uuid=e2fs"
-
- -- Check if ICU is available on Linux
- local icu_check = os.execute("pkg-config --exists icu-uc 2>/dev/null")
- if icu_check ~= 0 and icu_check ~= true then
- -- ICU not found, disable it
- io.stderr:write("Warning: ICU not found. Installing without ICU support.\n")
- io.stderr:write(" To enable ICU: sudo apt install libicu-dev (Debian/Ubuntu)\n")
- configureOptions = configureOptions .. " --without-icu"
- end
- end
-
- -- Allow user to override or extend configure options
- local extraOptions = os.getenv("POSTGRES_EXTRA_CONFIGURE_OPTIONS")
- if extraOptions ~= nil and extraOptions ~= "" then
- configureOptions = configureOptions .. " " .. extraOptions
- end
-
- local userOptions = os.getenv("POSTGRES_CONFIGURE_OPTIONS")
- if userOptions ~= nil and userOptions ~= "" then
- -- User provided full options, use those instead (but keep prefix)
- configureOptions = "--prefix='" .. sdkPath .. "' " .. userOptions
- end
-
- -- Run configure
- print("Configuring PostgreSQL with: " .. configureOptions)
- local configureCmd = string.format("cd '%s' && %s./configure %s", sdkPath, envPrefix, configureOptions)
- local status = os.execute(configureCmd)
- if status ~= 0 and status ~= true then
- error("Failed to configure PostgreSQL")
- end
-
- -- Build PostgreSQL
- print("Building PostgreSQL (this may take several minutes)...")
- local makeCmd =
- string.format("cd '%s' && make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)", sdkPath)
- status = os.execute(makeCmd)
- if status ~= 0 and status ~= true then
- error("Failed to build PostgreSQL")
- end
-
- -- Install PostgreSQL
- print("Installing PostgreSQL...")
- local installCmd = string.format("cd '%s' && make install", sdkPath)
- status = os.execute(installCmd)
- if status ~= 0 and status ~= true then
- error("Failed to install PostgreSQL")
- end
-
- -- Build and install contrib modules
- print("Building contrib modules...")
- local contribCmd = string.format(
- "cd '%s/contrib' && make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2) && make install",
- sdkPath
- )
- status = os.execute(contribCmd)
- if status ~= 0 and status ~= true then
- -- Contrib failure is not fatal
- print("Warning: Failed to build some contrib modules")
- end
-
- -- Create data directory
- local dataDir = sdkPath .. "/data"
- os.execute(string.format("mkdir -p '%s'", dataDir))
-
- -- Run initdb unless skipped
- local skipInitdb = os.getenv("POSTGRES_SKIP_INITDB")
- if skipInitdb ~= "1" and skipInitdb ~= "true" then
- print("Initializing database cluster...")
- local initdbCmd = string.format("'%s/bin/initdb' -D '%s' -U postgres", sdkPath, dataDir)
- status = os.execute(initdbCmd)
- if status ~= 0 and status ~= true then
- print("Warning: initdb failed. You may need to run it manually.")
- end
- else
- print("Skipping initdb (POSTGRES_SKIP_INITDB is set)")
- end
-
- -- Clean up source files to save space
- print("Cleaning up source files...")
- local cleanCmd = string.format(
- "cd '%s' && rm -rf src doc contrib config Makefile GNUmakefile configure* aclocal* 2>/dev/null",
- sdkPath
- )
- os.execute(cleanCmd)
-
- print("PostgreSQL installation complete!")
+ local sdkInfo = ctx.sdkInfo["postgres"]
+ local version = sdkInfo.version
+ local sdkPath = sdkInfo.path
+
+ -- mise extracts tarball and strips top-level directory, so sdkPath IS the source directory
+
+ -- Build configure options
+ local configureOptions = "--prefix='" .. sdkPath .. "'"
+ local envPrefix = "" -- Environment variables to prepend to configure command
+
+ -- Add common options
+ configureOptions = configureOptions .. " --with-openssl --with-zlib"
+
+ -- Try to add UUID support (e2fs on Linux, BSD on macOS)
+ local os_type = RUNTIME.osType
+ local homebrew_prefix = os.getenv("HOMEBREW_PREFIX") or "/opt/homebrew"
+
+ if os_type == "darwin" then
+ -- Homebrew paths
+ local openssl_path = homebrew_prefix .. "/opt/openssl"
+ local icu_path = homebrew_prefix .. "/opt/icu4c"
+ local ossp_uuid_path = homebrew_prefix .. "/opt/ossp-uuid"
+ local util_linux_path = homebrew_prefix .. "/opt/util-linux"
+
+ -- Build library and include paths
+ local lib_paths = {}
+ local include_paths = {}
+ local f
+
+ -- Check if OpenSSL exists in Homebrew
+ f = io.open(openssl_path .. "/lib", "r")
+ if f ~= nil then
+ f:close()
+ table.insert(lib_paths, openssl_path .. "/lib")
+ table.insert(include_paths, openssl_path .. "/include")
+ end
+
+ -- Check if ICU exists in Homebrew (PostgreSQL 17+ requires ICU by default)
+ f = io.open(icu_path .. "/lib", "r")
+ if f ~= nil then
+ f:close()
+ table.insert(lib_paths, icu_path .. "/lib")
+ table.insert(include_paths, icu_path .. "/include")
+ -- Set PKG_CONFIG_PATH for ICU (prepend to configure command)
+ local pkg_config_path = os.getenv("PKG_CONFIG_PATH") or ""
+ if pkg_config_path ~= "" then
+ pkg_config_path = icu_path .. "/lib/pkgconfig:" .. pkg_config_path
+ else
+ pkg_config_path = icu_path .. "/lib/pkgconfig"
+ end
+ envPrefix = "PKG_CONFIG_PATH='" .. pkg_config_path .. "' "
+ else
+ -- ICU not found, disable it
+ io.stderr:write("Warning: ICU not found. Installing without ICU support.\n")
+ io.stderr:write(" To enable ICU: brew install icu4c\n")
+ configureOptions = configureOptions .. " --without-icu"
+ end
+
+ -- Check for UUID library: prefer ossp-uuid, then util-linux (e2fs), otherwise skip
+ f = io.open(ossp_uuid_path .. "/lib", "r")
+ if f ~= nil then
+ f:close()
+ configureOptions = configureOptions .. " --with-uuid=ossp"
+ table.insert(lib_paths, ossp_uuid_path .. "/lib")
+ table.insert(include_paths, ossp_uuid_path .. "/include")
+ else
+ f = io.open(util_linux_path .. "/lib", "r")
+ if f ~= nil then
+ f:close()
+ configureOptions = configureOptions .. " --with-uuid=e2fs"
+ table.insert(lib_paths, util_linux_path .. "/lib")
+ table.insert(include_paths, util_linux_path .. "/include")
+ else
+ -- Neither UUID library available
+ io.stderr:write("Warning: UUID library not found. Installing without UUID support.\n")
+ io.stderr:write(" To enable UUID: brew install ossp-uuid\n")
+ end
+ end
+
+ if #lib_paths > 0 then
+ configureOptions = configureOptions .. " --with-libraries='" .. table.concat(lib_paths, ":") .. "'"
+ end
+ if #include_paths > 0 then
+ configureOptions = configureOptions .. " --with-includes='" .. table.concat(include_paths, ":") .. "'"
+ end
+ else
+ -- Linux: use e2fs UUID
+ configureOptions = configureOptions .. " --with-uuid=e2fs"
+
+ -- Check if ICU is available on Linux
+ local icu_check = os.execute("pkg-config --exists icu-uc 2>/dev/null")
+ if icu_check ~= 0 and icu_check ~= true then
+ -- ICU not found, disable it
+ io.stderr:write("Warning: ICU not found. Installing without ICU support.\n")
+ io.stderr:write(" To enable ICU: sudo apt install libicu-dev (Debian/Ubuntu)\n")
+ configureOptions = configureOptions .. " --without-icu"
+ end
+ end
+
+ -- Allow user to override or extend configure options
+ local extraOptions = os.getenv("POSTGRES_EXTRA_CONFIGURE_OPTIONS")
+ if extraOptions ~= nil and extraOptions ~= "" then
+ configureOptions = configureOptions .. " " .. extraOptions
+ end
+
+ local userOptions = os.getenv("POSTGRES_CONFIGURE_OPTIONS")
+ if userOptions ~= nil and userOptions ~= "" then
+ -- User provided full options, use those instead (but keep prefix)
+ configureOptions = "--prefix='" .. sdkPath .. "' " .. userOptions
+ end
+
+ -- Run configure
+ print("Configuring PostgreSQL with: " .. configureOptions)
+ local configureCmd = string.format("cd '%s' && %s./configure %s", sdkPath, envPrefix, configureOptions)
+ local status = os.execute(configureCmd)
+ if status ~= 0 and status ~= true then
+ error("Failed to configure PostgreSQL")
+ end
+
+ -- Build PostgreSQL
+ print("Building PostgreSQL (this may take several minutes)...")
+ local makeCmd =
+ string.format("cd '%s' && make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)", sdkPath)
+ status = os.execute(makeCmd)
+ if status ~= 0 and status ~= true then
+ error("Failed to build PostgreSQL")
+ end
+
+ -- Install PostgreSQL
+ print("Installing PostgreSQL...")
+ local installCmd = string.format("cd '%s' && make install", sdkPath)
+ status = os.execute(installCmd)
+ if status ~= 0 and status ~= true then
+ error("Failed to install PostgreSQL")
+ end
+
+ -- Build and install contrib modules
+ print("Building contrib modules...")
+ local contribCmd = string.format(
+ "cd '%s/contrib' && make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2) && make install",
+ sdkPath
+ )
+ status = os.execute(contribCmd)
+ if status ~= 0 and status ~= true then
+ -- Contrib failure is not fatal
+ print("Warning: Failed to build some contrib modules")
+ end
+
+ -- Create data directory
+ local dataDir = sdkPath .. "/data"
+ os.execute(string.format("mkdir -p '%s'", dataDir))
+
+ -- Run initdb unless skipped
+ local skipInitdb = os.getenv("POSTGRES_SKIP_INITDB")
+ if skipInitdb ~= "1" and skipInitdb ~= "true" then
+ print("Initializing database cluster...")
+ local initdbCmd = string.format("'%s/bin/initdb' -D '%s' -U postgres", sdkPath, dataDir)
+ status = os.execute(initdbCmd)
+ if status ~= 0 and status ~= true then
+ print("Warning: initdb failed. You may need to run it manually.")
+ end
+ else
+ print("Skipping initdb (POSTGRES_SKIP_INITDB is set)")
+ end
+
+ -- Clean up source files to save space
+ print("Cleaning up source files...")
+ local cleanCmd = string.format(
+ "cd '%s' && rm -rf src doc contrib config Makefile GNUmakefile configure* aclocal* 2>/dev/null",
+ sdkPath
+ )
+ os.execute(cleanCmd)
+
+ print("PostgreSQL installation complete!")
end
diff --git a/crates/vfox/embedded-plugins/vfox-postgres/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-postgres/hooks/pre_install.lua
index ed048db7a1..e5beef3029 100644
--- a/crates/vfox/embedded-plugins/vfox-postgres/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-postgres/hooks/pre_install.lua
@@ -2,10 +2,10 @@
--- @param ctx table Context provided by vfox
--- @return table Pre-install info
function PLUGIN:PreInstall(ctx)
- local version = ctx.version
+ local version = ctx.version
- return {
- version = version,
- url = "https://ftp.postgresql.org/pub/source/v" .. version .. "/postgresql-" .. version .. ".tar.gz",
- }
+ return {
+ version = version,
+ url = "https://ftp.postgresql.org/pub/source/v" .. version .. "/postgresql-" .. version .. ".tar.gz",
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-postgres/metadata.lua b/crates/vfox/embedded-plugins/vfox-postgres/metadata.lua
index 7eda16be3a..61655f6c04 100644
--- a/crates/vfox/embedded-plugins/vfox-postgres/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-postgres/metadata.lua
@@ -6,6 +6,6 @@ PLUGIN.license = "MIT"
PLUGIN.description = "PostgreSQL database - compiles from source"
PLUGIN.minRuntimeVersion = "0.3.0"
PLUGIN.notes = {
- "Compiles PostgreSQL from source. Requires: C compiler, make, readline, zlib, openssl.",
- "Automatically runs initdb unless POSTGRES_SKIP_INITDB=1 is set.",
+ "Compiles PostgreSQL from source. Requires: C compiler, make, readline, zlib, openssl.",
+ "Automatically runs initdb unless POSTGRES_SKIP_INITDB=1 is set.",
}
diff --git a/crates/vfox/embedded-plugins/vfox-redis/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-redis/hooks/available.lua
index 145e2834ce..b4a7d916c8 100644
--- a/crates/vfox/embedded-plugins/vfox-redis/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-redis/hooks/available.lua
@@ -5,7 +5,7 @@ function PLUGIN:Available(ctx)
local http = require("http")
local resp, err = http.get({
- url = "https://download.redis.io/releases/"
+ url = "https://download.redis.io/releases/",
})
if err ~= nil then
@@ -21,7 +21,7 @@ function PLUGIN:Available(ctx)
seen[version] = true
table.insert(results, {
version = version,
- note = ""
+ note = "",
})
end
end
diff --git a/crates/vfox/embedded-plugins/vfox-redis/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-redis/hooks/env_keys.lua
index 3d85b94d3f..238e38a95c 100644
--- a/crates/vfox/embedded-plugins/vfox-redis/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-redis/hooks/env_keys.lua
@@ -7,7 +7,7 @@ function PLUGIN:EnvKeys(ctx)
return {
{
key = "PATH",
- value = mainPath .. "/bin"
- }
+ value = mainPath .. "/bin",
+ },
}
end
diff --git a/crates/vfox/embedded-plugins/vfox-redis/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-redis/hooks/post_install.lua
index f7853ac675..17832dcc8e 100644
--- a/crates/vfox/embedded-plugins/vfox-redis/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-redis/hooks/post_install.lua
@@ -4,11 +4,7 @@ function PLUGIN:PostInstall(ctx)
local rootPath = ctx.rootPath
-- Redis doesn't need configure, just make with PREFIX
- local build_cmd = string.format(
- 'cd "%s" && make PREFIX="%s" install',
- rootPath,
- rootPath
- )
+ local build_cmd = string.format('cd "%s" && make PREFIX="%s" install', rootPath, rootPath)
print("Compiling Redis from source...")
local result = os.execute(build_cmd)
diff --git a/crates/vfox/embedded-plugins/vfox-redis/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-redis/hooks/pre_install.lua
index 62fba0ceef..58437f6421 100644
--- a/crates/vfox/embedded-plugins/vfox-redis/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-redis/hooks/pre_install.lua
@@ -7,6 +7,6 @@ function PLUGIN:PreInstall(ctx)
return {
version = version,
url = "https://download.redis.io/releases/redis-" .. version .. ".tar.gz",
- note = "Downloading Redis " .. version .. " source..."
+ note = "Downloading Redis " .. version .. " source...",
}
end
diff --git a/crates/vfox/embedded-plugins/vfox-redis/metadata.lua b/crates/vfox/embedded-plugins/vfox-redis/metadata.lua
index f011952266..1454707dd9 100644
--- a/crates/vfox/embedded-plugins/vfox-redis/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-redis/metadata.lua
@@ -7,5 +7,5 @@ PLUGIN.license = "MIT"
PLUGIN.description = "Redis - in-memory data structure store, cache, and message broker"
PLUGIN.minRuntimeVersion = "0.3.0"
PLUGIN.notes = {
- "Compiles from source - requires C compiler (gcc/clang) and make"
+ "Compiles from source - requires C compiler (gcc/clang) and make",
}
diff --git a/crates/vfox/embedded-plugins/vfox-vlang/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-vlang/hooks/available.lua
index d449cc5d51..0b84fe46fb 100644
--- a/crates/vfox/embedded-plugins/vfox-vlang/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-vlang/hooks/available.lua
@@ -4,5 +4,5 @@ local util = require("util")
--- @param ctx table Empty table used as context, for future extension
--- @return table Descriptions of available versions and accompanying tool descriptions
function PLUGIN:Available(ctx)
- return util:getInfo()
+ return util:getInfo()
end
diff --git a/crates/vfox/embedded-plugins/vfox-vlang/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-vlang/hooks/env_keys.lua
index 86acc8e63d..0b40978d07 100644
--- a/crates/vfox/embedded-plugins/vfox-vlang/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-vlang/hooks/env_keys.lua
@@ -3,11 +3,11 @@
--- Note: Be sure to distinguish between environment variable settings for different platforms!
--- @param ctx {path: string} Context information (SDK installation directory)
function PLUGIN:EnvKeys(ctx)
- local mainPath = ctx.path
- return {
- {
- key = "PATH",
- value = mainPath,
- },
- }
+ local mainPath = ctx.path
+ return {
+ {
+ key = "PATH",
+ value = mainPath,
+ },
+ }
end
diff --git a/crates/vfox/embedded-plugins/vfox-vlang/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-vlang/hooks/post_install.lua
index eaf37d6a16..8f23ed3e3f 100644
--- a/crates/vfox/embedded-plugins/vfox-vlang/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-vlang/hooks/post_install.lua
@@ -2,5 +2,5 @@
--- such as file operations for the SDK installation directory or compile source code
--- Currently can be left unimplemented!
function PLUGIN:PostInstall(ctx)
- -- do nothing
+ -- do nothing
end
diff --git a/crates/vfox/embedded-plugins/vfox-vlang/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-vlang/hooks/pre_install.lua
index 3a0a74cf42..7c96068c7a 100644
--- a/crates/vfox/embedded-plugins/vfox-vlang/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-vlang/hooks/pre_install.lua
@@ -4,14 +4,14 @@ local util = require("util")
--- @param ctx {version: string} (User-input version)
--- @return table Version information
function PLUGIN:PreInstall(ctx)
- if #util.RELEASES == 0 then
- self:Available(ctx)
- end
- local releases = util.RELEASES
- for _, release in ipairs(releases) do
- if release.version == ctx.version then
- return release
- end
- end
- return {}
+ if #util.RELEASES == 0 then
+ self:Available(ctx)
+ end
+ local releases = util.RELEASES
+ for _, release in ipairs(releases) do
+ if release.version == ctx.version then
+ return release
+ end
+ end
+ return {}
end
diff --git a/crates/vfox/embedded-plugins/vfox-vlang/hooks/pre_use.lua b/crates/vfox/embedded-plugins/vfox-vlang/hooks/pre_use.lua
index fca899b2c7..de9a81cc83 100644
--- a/crates/vfox/embedded-plugins/vfox-vlang/hooks/pre_use.lua
+++ b/crates/vfox/embedded-plugins/vfox-vlang/hooks/pre_use.lua
@@ -2,5 +2,5 @@
--- valid version information.
--- @param ctx table Context information
function PLUGIN:PreUse(ctx)
- --do nothing
+ --do nothing
end
diff --git a/crates/vfox/embedded-plugins/vfox-vlang/lib/util.lua b/crates/vfox/embedded-plugins/vfox-vlang/lib/util.lua
index 2aff87ba3d..4ceff670a9 100644
--- a/crates/vfox/embedded-plugins/vfox-vlang/lib/util.lua
+++ b/crates/vfox/embedded-plugins/vfox-vlang/lib/util.lua
@@ -5,7 +5,7 @@ local util = {}
util.__index = util
local utilSingleton = setmetatable({}, util)
utilSingleton.SOURCE_URL = "https://raw.githubusercontent.com/ahai-code/sdk-sources/main/v.json"
-utilSingleton.RELEASES ={}
+utilSingleton.RELEASES = {}
function util:compare_versions(v1o, v2o)
local v1 = v1o.version
@@ -36,7 +36,7 @@ end
function util:getInfo()
local result = {}
local resp, err = http.get({
- url = utilSingleton.SOURCE_URL
+ url = utilSingleton.SOURCE_URL,
})
if err ~= nil then
error("Failed to get information: " .. err)
@@ -47,25 +47,25 @@ function util:getInfo()
local respInfo = json.decode(resp.body)[RUNTIME.osType]
for version, array in pairs(respInfo) do
local url = ""
- if string.sub(version, 1, #("weekly.")) == "weekly." then
+ if string.sub(version, 1, #"weekly.") == "weekly." then
version = string.gsub(version, "^weekly.", "")
end
for _, obj in ipairs(array) do
- if obj.Arch=="" then
+ if obj.Arch == "" then
url = obj.Url
elseif obj.Arch == RUNTIME.archType then
- url = obj.Url
+ url = obj.Url
end
end
- table.insert(result, {version = version,note=""})
- table.insert(utilSingleton.RELEASES,{version = version,url=url})
+ table.insert(result, { version = version, note = "" })
+ table.insert(utilSingleton.RELEASES, { version = version, url = url })
end
table.sort(result, function(a, b)
- return util:compare_versions(a,b)
+ return util:compare_versions(a, b)
end)
return result
end
-return utilSingleton
\ No newline at end of file
+return utilSingleton
diff --git a/crates/vfox/embedded-plugins/vfox-yarn/hooks/available.lua b/crates/vfox/embedded-plugins/vfox-yarn/hooks/available.lua
index a75f25a351..419f0da8a4 100644
--- a/crates/vfox/embedded-plugins/vfox-yarn/hooks/available.lua
+++ b/crates/vfox/embedded-plugins/vfox-yarn/hooks/available.lua
@@ -3,30 +3,30 @@
local function fetch_github_tags(repo_url)
-- Use git ls-remote to get tags
local cmd = 'git ls-remote --refs --tags "' .. repo_url .. '"'
-
+
-- Detect Windows
- local is_windows = package.config:sub(1,1) == '\\'
-
+ local is_windows = package.config:sub(1, 1) == "\\"
+
-- Redirect stderr appropriately for the platform
if is_windows then
cmd = cmd .. " 2>NUL"
else
cmd = cmd .. " 2>/dev/null"
end
-
+
local handle = io.popen(cmd)
if not handle then
return {}
end
-
+
local result = handle:read("*a")
handle:close()
-
+
-- If result is empty or nil, return empty table
if not result or result == "" then
return {}
end
-
+
local tags = {}
for line in result:gmatch("[^\r\n]+") do
-- Extract tag name from refs/tags/...
@@ -35,7 +35,7 @@ local function fetch_github_tags(repo_url)
table.insert(tags, tag)
end
end
-
+
return tags
end
@@ -48,28 +48,28 @@ local function version_compare(a, b)
end
return parts
end
-
+
local a_parts = parse_version(a)
local b_parts = parse_version(b)
-
+
for i = 1, math.max(#a_parts, #b_parts) do
local a_val = a_parts[i] or 0
local b_val = b_parts[i] or 0
if a_val ~= b_val then
- return a_val > b_val -- Descending order
+ return a_val > b_val -- Descending order
end
end
-
+
return false
end
function PLUGIN:Available(ctx)
local versions = {}
-
+
-- Get Yarn Berry versions (v2.x+)
local berry_tags = fetch_github_tags("https://github.com/yarnpkg/berry.git")
local berry_versions = {}
-
+
for _, tag in ipairs(berry_tags) do
-- Extract version from @yarnpkg/cli/X.X.X format
local version = tag:match("@yarnpkg/cli/(.+)$")
@@ -77,21 +77,21 @@ function PLUGIN:Available(ctx)
table.insert(berry_versions, version)
end
end
-
+
-- Sort Berry versions in descending order
table.sort(berry_versions, version_compare)
-
+
-- Add Berry versions to the list
for _, version in ipairs(berry_versions) do
table.insert(versions, {
- version = version
+ version = version,
})
end
-
+
-- Get Yarn Classic versions (v1.x)
local classic_tags = fetch_github_tags("https://github.com/yarnpkg/yarn.git")
local classic_versions = {}
-
+
for _, tag in ipairs(classic_tags) do
-- Remove 'v' prefix if present
local version = tag:match("^v(.+)$") or tag
@@ -100,18 +100,18 @@ function PLUGIN:Available(ctx)
table.insert(classic_versions, version)
end
end
-
+
-- Sort Classic versions in descending order
table.sort(classic_versions, version_compare)
-
+
-- Add Classic versions to the list
for _, version in ipairs(classic_versions) do
table.insert(versions, {
- version = version
+ version = version,
})
end
-
+
return versions
end
-return PLUGIN
\ No newline at end of file
+return PLUGIN
diff --git a/crates/vfox/embedded-plugins/vfox-yarn/hooks/env_keys.lua b/crates/vfox/embedded-plugins/vfox-yarn/hooks/env_keys.lua
index e2b7a713d3..5af608efa1 100644
--- a/crates/vfox/embedded-plugins/vfox-yarn/hooks/env_keys.lua
+++ b/crates/vfox/embedded-plugins/vfox-yarn/hooks/env_keys.lua
@@ -3,14 +3,14 @@
function PLUGIN:EnvKeys(ctx)
-- Get the SDK installation path
local version_path = ctx.path
-
+
-- Return the PATH configuration for yarn binaries
return {
{
key = "PATH",
- value = version_path .. "/bin"
- }
+ value = version_path .. "/bin",
+ },
}
end
-return PLUGIN
\ No newline at end of file
+return PLUGIN
diff --git a/crates/vfox/embedded-plugins/vfox-yarn/hooks/legacy_filenames.lua b/crates/vfox/embedded-plugins/vfox-yarn/hooks/legacy_filenames.lua
index 2a89cd54e1..024ab11bce 100644
--- a/crates/vfox/embedded-plugins/vfox-yarn/hooks/legacy_filenames.lua
+++ b/crates/vfox/embedded-plugins/vfox-yarn/hooks/legacy_filenames.lua
@@ -1,6 +1,6 @@
--- Get list of legacy filenames
return function(ctx)
return {
- ".yvmrc"
+ ".yvmrc",
}
-end
\ No newline at end of file
+end
diff --git a/crates/vfox/embedded-plugins/vfox-yarn/hooks/parse_legacy_file.lua b/crates/vfox/embedded-plugins/vfox-yarn/hooks/parse_legacy_file.lua
index f37df52c9e..7d45cea55b 100644
--- a/crates/vfox/embedded-plugins/vfox-yarn/hooks/parse_legacy_file.lua
+++ b/crates/vfox/embedded-plugins/vfox-yarn/hooks/parse_legacy_file.lua
@@ -9,11 +9,11 @@ function PLUGIN:ParseLegacyFile(ctx)
if version then
version = version:gsub("^v", ""):gsub("%s+", "")
return {
- version = version
+ version = version,
}
end
end
return {}
end
-return PLUGIN
\ No newline at end of file
+return PLUGIN
diff --git a/crates/vfox/embedded-plugins/vfox-yarn/hooks/post_install.lua b/crates/vfox/embedded-plugins/vfox-yarn/hooks/post_install.lua
index 425efdb3a2..b1bf9e12ac 100644
--- a/crates/vfox/embedded-plugins/vfox-yarn/hooks/post_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-yarn/hooks/post_install.lua
@@ -7,7 +7,7 @@ end
local function download_file(url, output_path)
-- Detect Windows
- local is_windows = package.config:sub(1,1) == '\\'
+ local is_windows = package.config:sub(1, 1) == "\\"
local stderr_redirect = is_windows and " 2>NUL" or " 2>/dev/null"
-- Try curl first (more likely to be available on Windows via Git Bash)
@@ -26,13 +26,13 @@ function PLUGIN:PostInstall(ctx)
-- Get install path - it should be in sdkInfo
local install_path = nil
local version = nil
-
+
-- Try to get path from sdkInfo
if ctx.sdkInfo and ctx.sdkInfo.yarn then
install_path = ctx.sdkInfo.yarn.path
version = ctx.sdkInfo.yarn.version
end
-
+
-- Fallback to environment variable
if not install_path then
install_path = os.getenv("MISE_INSTALL_PATH")
@@ -40,21 +40,21 @@ function PLUGIN:PostInstall(ctx)
if not version then
version = os.getenv("MISE_INSTALL_VERSION") or ctx.version
end
-
+
if not install_path or not version then
-- For v1, mise handles everything, so this is OK
return {}
end
-
+
local major_version = string.sub(version, 1, 1)
-
+
if major_version ~= "1" then
-- Yarn Berry (v2.x+) - download single JS file
local yarn_url = "https://repo.yarnpkg.com/" .. version .. "/packages/yarnpkg-cli/bin/yarn.js"
-
+
-- Detect Windows
- local is_windows = package.config:sub(1,1) == '\\'
-
+ local is_windows = package.config:sub(1, 1) == "\\"
+
-- Create bin directory (cross-platform)
local bin_dir = install_path .. "/bin"
if is_windows then
@@ -62,13 +62,13 @@ function PLUGIN:PostInstall(ctx)
else
os.execute("mkdir -p " .. bin_dir)
end
-
+
-- Download yarn.js
local yarn_js_file = bin_dir .. "/yarn.js"
if not download_file(yarn_url, yarn_js_file) then
error("Failed to download Yarn v2+")
end
-
+
-- Create wrapper script
if is_windows then
-- Create yarn.cmd wrapper for Windows
@@ -79,7 +79,7 @@ function PLUGIN:PostInstall(ctx)
cmd_file:write('node "%~dp0yarn.js" %*\n')
cmd_file:close()
end
-
+
-- Also create yarn without extension for Git Bash
local yarn_sh = bin_dir .. "/yarn"
local sh_file = io.open(yarn_sh, "w")
@@ -101,8 +101,8 @@ function PLUGIN:PostInstall(ctx)
os.execute("chmod +x " .. yarn_file)
end
end
-
+
return {}
end
-return PLUGIN
\ No newline at end of file
+return PLUGIN
diff --git a/crates/vfox/embedded-plugins/vfox-yarn/hooks/pre_install.lua b/crates/vfox/embedded-plugins/vfox-yarn/hooks/pre_install.lua
index cfe31916b1..336eae8409 100644
--- a/crates/vfox/embedded-plugins/vfox-yarn/hooks/pre_install.lua
+++ b/crates/vfox/embedded-plugins/vfox-yarn/hooks/pre_install.lua
@@ -3,38 +3,42 @@
function PLUGIN:PreInstall(ctx)
local version = ctx.version
local major_version = string.sub(version, 1, 1)
-
+
if major_version == "1" then
-- Yarn Classic (v1.x) - return tarball URL for mise to handle
local archive_url = "https://classic.yarnpkg.com/downloads/" .. version .. "/yarn-v" .. version .. ".tar.gz"
-
+
-- Note about GPG verification (skip on Windows)
- local is_windows = package.config:sub(1,1) == '\\'
+ local is_windows = package.config:sub(1, 1) == "\\"
if os.getenv("MISE_YARN_SKIP_GPG") == nil and not is_windows then
local stderr_redirect = " 2>/dev/null"
-
+
local gpg_check = io.popen("command -v gpg" .. stderr_redirect)
local has_gpg = gpg_check and gpg_check:read("*a"):match("%S")
- if gpg_check then gpg_check:close() end
-
+ if gpg_check then
+ gpg_check:close()
+ end
+
if not has_gpg then
- print("⚠️ Note: GPG verification skipped (gpg not found). Set MISE_YARN_SKIP_GPG=1 to suppress this message")
+ print(
+ "⚠️ Note: GPG verification skipped (gpg not found). Set MISE_YARN_SKIP_GPG=1 to suppress this message"
+ )
end
-- Note: We can't do GPG verification when mise handles the download
-- This is a tradeoff for simpler code
end
-
+
-- Return URL for mise to download and extract
return {
version = version,
- url = archive_url
+ url = archive_url,
}
else
-- Yarn Berry (v2.x+) - single JS file, handled in post-install
return {
- version = version
+ version = version,
}
end
end
-return PLUGIN
\ No newline at end of file
+return PLUGIN
diff --git a/crates/vfox/embedded-plugins/vfox-yarn/metadata.lua b/crates/vfox/embedded-plugins/vfox-yarn/metadata.lua
index 70822f907e..989905c9ae 100644
--- a/crates/vfox/embedded-plugins/vfox-yarn/metadata.lua
+++ b/crates/vfox/embedded-plugins/vfox-yarn/metadata.lua
@@ -12,7 +12,7 @@ PLUGIN = {
This plugin installs Yarn package manager.
Supports both Yarn Classic (v1.x) and Yarn Berry (v2.x+).
]],
- minRuntimeVersion = "0.5.0"
+ minRuntimeVersion = "0.5.0",
}
-return PLUGIN
\ No newline at end of file
+return PLUGIN
diff --git a/default.nix b/default.nix
index c94762b5cd..31ade2d39c 100644
--- a/default.nix
+++ b/default.nix
@@ -2,7 +2,7 @@
rustPlatform.buildRustPackage {
pname = "mise";
- version = "2026.2.1";
+ version = "2026.2.2";
src = lib.cleanSource ./.;
diff --git a/docs/.vitepress/stars.data.ts b/docs/.vitepress/stars.data.ts
index 96c0284e2f..27f1d7e184 100644
--- a/docs/.vitepress/stars.data.ts
+++ b/docs/.vitepress/stars.data.ts
@@ -3,7 +3,7 @@
export default {
load() {
return {
- stars: "24k",
+ stars: "24.1k",
};
},
};
diff --git a/mise.lock b/mise.lock
index 67c0d6427f..2bb1bb212c 100644
--- a/mise.lock
+++ b/mise.lock
@@ -61,7 +61,7 @@ version = "0.13.8"
backend = "cargo:cargo-edit"
[[tools."cargo:cargo-insta"]]
-version = "1.46.2"
+version = "1.46.3"
backend = "cargo:cargo-insta"
[[tools."cargo:cargo-release"]]
diff --git a/packaging/rpm/mise.spec b/packaging/rpm/mise.spec
index 70f1f7529f..816a872d47 100644
--- a/packaging/rpm/mise.spec
+++ b/packaging/rpm/mise.spec
@@ -1,6 +1,6 @@
Summary: The front-end to your dev env
Name: mise
-Version: 2026.2.1
+Version: 2026.2.2
Release: 1
URL: https://github.com/jdx/mise/
Group: System
diff --git a/snapcraft.yaml b/snapcraft.yaml
index d74f3ad4a0..5ae89aa564 100644
--- a/snapcraft.yaml
+++ b/snapcraft.yaml
@@ -9,7 +9,7 @@
name: mise
title: mise-en-place
-version: "2026.2.1"
+version: "2026.2.2"
summary: The front-end to your dev env
description: |
mise-en-place is a command line tool to manage your development environment.