MetaZig: anyzig-inspired version manager

MetaZig: anyzig-inspired version manager


MetaZig is a single-executable replacement for both zig and zls that works for any project running any version of zig. No more editing editor config files or dotenv to specify zig/zls paths, no more dealing with slow extract dialogs, and no more hunting down of that one zls version that works.

This project was heavily inspired by anyzig and I am grateful for its inspiration, however I felt like parts of the UX were lacking. Enough so that I gave up using it, and I’ve seen first-hand people bouncing off it and instead just following directions on zig’s generally well-written getting started guide.

Features

Here are some of MetaZig’s features:

Download/Extract Progress

Especially on slower internet connections and with slower disks, not having download or extract progress shown in real-time is a bad experience. Without progress shown the version manager could be perceived as “doing nothing” for several minutes even if it is in fact working correctly. Initially I built my own ansi progress bar for doing this but eventually I settled on using the std.Progress API. In my code I abstracted fetch and extract operations to always take a progress parameter which means everything MetaZig does gets displayed to the user, with progress if it is available.

Community Mirrors

Metazig uses zig’s community mirrors system extensively for faster downloads and to reduce load on the zig website. Most community mirrors also host mach-nominated versions, which means MetaZig also reduces load on the hexops package mirror. The only hard-coded urls in MetaZig are the following:

  • The community mirror list from the zig website (Only fetched once per month)
  • index.json from the zig website (Only fetched for resolving stable and master versions)
  • index.json from the hexops package mirror (Only fetched for resolving unknown mach-nominated versions)

Any data found from these URLs is saved into the MetaZig config file.

Initially I would check for the index.json on each mirror before downloading, but since all zig downloads have a predictable filename, I simply build it every time and only use index.json for unpredictable names.

ZLS Support

ZLS has an api for getting a working download link to the correct zls version for any zig version, including mach nominated ones and pre-releases. MetaZig uses this API to always get the correct zls version.

Signature Checking

Following the zig community mirrors system, all zig and zls versions are checked against their respective public keys using the minisig.

Quick-Open Config Directory

At any time, run zig open and the MetaZig config directory will open in your default file manager.

Feedback

Any feedback or bug reports are appreciated, notably any case in which a stack trace is printed instead of an error message.

This project also has no macOS support yet because I don’t have a mac. Read this issue if you want to help out.

Project Links

Source: https://codeberg.org/platypro/metazig

Supported Zig versions

This app was built using 0.16.0 but naturally can also be built using this very project.

1 Like

I compiled this on my M1 macbook, and then compiled it with itself. That works, but the annoying thing is that I know the program downloaded and extracted another copy of zig 0.16.0 somewhere, and it is unclear where this landed.
The location of the config directory could at least be mentioned even if the config directory cannot be opened. Now I have to search my disk for a zig executable that is installed in a non-documented place.

Update: Searched without luck under ~/.cache and ~/.local/share (I have no XDG env vars set), but find ~ -name zig | fgrep metavar did the trick to locate and remove the downloaded stuff.

Thanks for the feedback. I’m ultimately using known-folders to find the config. I’ve pushed a commit which will now show the directory it tries to open no matter if it supports opening it.

I think it would have been nicer to rally behind anyzig, and develop multiple maintainers for it so that marler could have some help. But I understand why you may want to just blitz through something for yourself.

Edit: opened an issue in anyzig: Nominate additional maintainers · Issue #86 · marler8997/anyzig · GitHub

1 Like

On macOS you can spawn open, the following opened the directory with config.json:

const std = @import("std");

pub fn main(init: std.process.Init) !void {
    var child = std.process.spawn(init.io, .{ .argv = &[_][]const u8{"open", "/Users/anthon/Library/Application Support/metazig" }}) catch |err| {
        std.debug.print("could not run open {}\n", .{err});
        return;
    };
    _ = try child.wait(init.io);
}
1 Like