1
Fork 0
mirror of https://github.com/RGBCube/nu_scripts synced 2025-08-01 06:37:46 +00:00
nu_scripts/modules/zvm/zvm.nu

191 lines
5.8 KiB
Text

# Zig version manager
# - list available Zig versions
# - install tagged and/or nightly versions
# - point symlink to current active version
# - remove versions
# List all available versions of Zig
export def "zvm list" [
--system (-s) # List locally installed versions
] {
if $system == true {
let path_prefix = get_or_create_path_prefix
let current_version = get_current_version $path_prefix
ls --short-names $path_prefix
| where type == dir
| get name
| sort --reverse
| each { |it| { version: $it active: ($it == $current_version) }}
} else {
http get https://ziglang.org/download/index.json | columns
}
}
# Fetch info about specified version
export def "zvm info" [version: string] {
http get https://ziglang.org/download/index.json
| get $version
| select version? date docs stdDocs notes?
}
# Install Zig for the specified version
export def "zvm install" [version: string] {
let version_data = http get https://ziglang.org/download/index.json | get $version
let version_to_install = if $version_data.version? != null { $version_data.version } else { $version }
let local_versions = zvm list --system | get version
if $version_to_install in $local_versions {
error make {
msg: $"Version ($version_to_install) is already installed."
label: {
text: $"Version ($version) is already installed locally"
span: (metadata $version).span
}
}
}
let tarball = $version_data | get $"($nu.os-info.arch)-($nu.os-info.name)" | get tarball
let temp_dir = mktemp --directory --suffix "-zvm"
http get $tarball | save --progress $"($temp_dir)/($tarball | path basename)"
verify_signature $temp_dir $tarball
ouch decompress --dir $temp_dir --quiet $"($temp_dir)/($tarball | path basename)"
let path_prefix = get_or_create_path_prefix
let decompressed_dir_path = ls $temp_dir | where type == dir | get 0.name
cp --recursive $decompressed_dir_path $"($path_prefix)/($version_to_install)"
rm --recursive --permanent $temp_dir
echo $"Successfully installed Zig ($version)"
}
# Make the zig symlink point to the specified version
export def "zvm use" [
version: string # Version to use. Nightly version is expressed using one of these terms: master, dev or nightly.
] {
let actual_version = get_actual_version $version
mut zig_to_use = find_installed_version $actual_version
if $zig_to_use == null {
print $"Version ($actual_version) is not currently installed. Would you like to install it first?"
let install_first = [yes no] | input list
if $install_first == no { return }
zvm install $version
$zig_to_use = { version: $actual_version active: false }
}
if $zig_to_use.active {
error make {
msg: $"Version ($zig_to_use.version) is already in use."
label: {
text: $"Version ($version) is already targeted by symlink"
span: (metadata $version).span
}
}
}
let path_prefix = get_or_create_path_prefix
let symlink = $"($path_prefix)/zig"
let bin = $"($path_prefix)/($zig_to_use.version)/zig"
if $nu.os-info.name == "windows" {
if ($symlink | path exists) { rm --permanent $symlink }
mklink $symlink $bin
} else {
ln -sf $bin $symlink
}
echo $"Successfully switched to Zig ($version)"
}
# Remove the specified version
export def "zvm remove" [
version: string # Version to remove. Nightly version is expressed using one of these terms: master, dev or nightly.
] {
let actual_version = get_actual_version $version
let zig_to_remove = find_installed_version $actual_version
if $zig_to_remove == null {
error make {
msg: $"Version ($actual_version) is not installed."
label: {
text: $"Version ($version) not found on system"
span: (metadata $version).span
}
}
}
let path_prefix = get_or_create_path_prefix
rm --recursive --permanent $"($path_prefix)/($zig_to_remove.version)"
if $zig_to_remove.active {
rm --permanent $"($path_prefix)/zig"
}
echo $"Successfully removed Zig ($zig_to_remove.version)"
}
# Remove unused versions
export def "zvm clean" [] {
let versions_to_remove = zvm list --system | where active == false | get version
if ($versions_to_remove | is-empty) {
print "No unused version to remove"
return
}
let path_prefix = get_or_create_path_prefix
for v in $versions_to_remove {
rm --recursive --permanent $"($path_prefix)/($v)"
}
echo $"Successfully removed the following unused versions:\n($versions_to_remove)"
}
def verify_signature [temp_dir: string, tarball: string] {
http get $"($tarball).minisig" | save $"($temp_dir)/($tarball | path basename).minisig"
let minisign_result = minisign -Vm $"($temp_dir)/($tarball | path basename)" -P "RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U" | complete
if $minisign_result.exit_code != 0 {
error make {
msg: $"Failed to verify archive signature. Temporary data left as is in ($temp_dir)."
label: {
text: "Received error from minisign verification"
span: (metadata $minisign_result).span
}
}
}
}
def get_or_create_path_prefix [] {
let path_prefix = $"($nu.home-path)/.local/share/zvm"
if not ($path_prefix | path exists) { mkdir $path_prefix }
$path_prefix
}
def get_current_version [path_prefix: string] {
let zig_path = $"($path_prefix)/zig"
if ($zig_path | path exists) {
ls -l $zig_path
| where type == symlink
| get 0.target
| parse $"($path_prefix)/{current_version}/zig"
| get 0.current_version
} else {
null
}
}
def find_installed_version [version: string] {
let version_search_result = zvm list --system | where version == $version
if $version_search_result == [] {
null
} else {
$version_search_result | first
}
}
def get_actual_version [version: string] {
match $version {
"master" | "dev" | "nightly" => (zvm info master | get version)
_ => $version
}
}