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.