Bladeren bron

zig update 0.12.0 (remove ziget dependency)

Jonathan Marler 10 maanden geleden
bovenliggende
commit
24bcacc5be
10 gewijzigde bestanden met toevoegingen van 285 en 565 verwijderingen
  1. 7 7
      .github/workflows/artifact.yml
  2. 0 212
      GitRepoStep.zig
  3. 0 2
      README.md
  4. 118 56
      build.zig
  5. 23 0
      build.zig.zon
  6. 0 213
      build2.zig
  7. 17 7
      test.zig
  8. 2 2
      win32exelink.zig
  9. 0 1
      zigetsha
  10. 118 65
      zigup.zig

+ 7 - 7
.github/workflows/artifact.yml

@@ -12,19 +12,19 @@ jobs:
       - uses: actions/checkout@v2
       - uses: goto-bus-stop/setup-zig@v1
         with:
-          version: 0.11.0
+          version: 0.12.0
       - run: |
-          zig build test -Dfetch -Dci_target=${{matrix.os}}-${{matrix.arch}}
+          zig build test -Dci_target=${{matrix.os}}-${{matrix.arch}}
       - run: |
-          zig build -Dfetch -Dci_target=ubuntu-latest-x86_64 -p zig-out-ubuntu-latest-x86_64
+          zig build -Dci_target=ubuntu-latest-x86_64 -p zig-out-ubuntu-latest-x86_64
       - run: |
-          zig build -Dfetch -Dci_target=ubuntu-latest-aarch64 -p zig-out-ubuntu-latest-aarch64
+          zig build -Dci_target=ubuntu-latest-aarch64 -p zig-out-ubuntu-latest-aarch64
       - run: |
-          zig build -Dfetch -Dci_target=macos-latest-x86_64 -p zig-out-macos-latest-x86_64
+          zig build -Dci_target=macos-latest-x86_64 -p zig-out-macos-latest-x86_64
       - run: |
-          zig build -Dfetch -Dci_target=macos-latest-aarch64 -p zig-out-macos-latest-aarch64
+          zig build -Dci_target=macos-latest-aarch64 -p zig-out-macos-latest-aarch64
       - run: |
-          zig build -Dfetch -Dci_target=windows-latest-x86_64 -p zig-out-windows-latest-x86_64
+          zig build -Dci_target=windows-latest-x86_64 -p zig-out-windows-latest-x86_64
       - uses: actions/upload-artifact@v2
         with:
           name: zigup ${{ matrix.os }}-${{ matrix.arch }}

+ 0 - 212
GitRepoStep.zig

@@ -1,212 +0,0 @@
-//! Publish Date: 2023_03_19
-//! This file is hosted at github.com/marler8997/zig-build-repos and is meant to be copied
-//! to projects that use it.
-const std = @import("std");
-const GitRepoStep = @This();
-
-pub const ShaCheck = enum {
-    none,
-    warn,
-    err,
-
-    pub fn reportFail(self: ShaCheck, comptime fmt: []const u8, args: anytype) void {
-        switch (self) {
-            .none => unreachable,
-            .warn => std.log.warn(fmt, args),
-            .err => {
-                std.log.err(fmt, args);
-                std.os.exit(0xff);
-            },
-        }
-    }
-};
-
-step: std.build.Step,
-url: []const u8,
-name: []const u8,
-branch: ?[]const u8 = null,
-sha: []const u8,
-path: []const u8,
-sha_check: ShaCheck = .warn,
-fetch_enabled: bool,
-
-var cached_default_fetch_option: ?bool = null;
-pub fn defaultFetchOption(b: *std.build.Builder) bool {
-    if (cached_default_fetch_option) |_| {} else {
-        cached_default_fetch_option = if (b.option(bool, "fetch", "automatically fetch network resources")) |o| o else false;
-    }
-    return cached_default_fetch_option.?;
-}
-
-pub fn create(b: *std.build.Builder, opt: struct {
-    url: []const u8,
-    branch: ?[]const u8 = null,
-    sha: []const u8,
-    path: ?[]const u8 = null,
-    sha_check: ShaCheck = .warn,
-    fetch_enabled: ?bool = null,
-    first_ret_addr: ?usize = null,
-}) *GitRepoStep {
-    var result = b.allocator.create(GitRepoStep) catch @panic("memory");
-    const name = std.fs.path.basename(opt.url);
-    result.* = GitRepoStep{
-        .step = std.build.Step.init(.{
-            .id = .custom,
-            .name = b.fmt("clone git repository '{s}'", .{name}),
-            .owner = b,
-            .makeFn = make,
-            .first_ret_addr = opt.first_ret_addr orelse @returnAddress(),
-            .max_rss = 0,
-        }),
-        .url = opt.url,
-        .name = name,
-        .branch = opt.branch,
-        .sha = opt.sha,
-        .path = if (opt.path) |p| b.allocator.dupe(u8, p) catch @panic("OOM") else b.pathFromRoot(b.pathJoin(&.{ "dep", name })),
-        .sha_check = opt.sha_check,
-        .fetch_enabled = if (opt.fetch_enabled) |fe| fe else defaultFetchOption(b),
-    };
-    return result;
-}
-
-// TODO: this should be included in std.build, it helps find bugs in build files
-fn hasDependency(step: *const std.build.Step, dep_candidate: *const std.build.Step) bool {
-    for (step.dependencies.items) |dep| {
-        // TODO: should probably use step.loop_flag to prevent infinite recursion
-        //       when a circular reference is encountered, or maybe keep track of
-        //       the steps encounterd with a hash set
-        if (dep == dep_candidate or hasDependency(dep, dep_candidate))
-            return true;
-    }
-    return false;
-}
-
-fn make(step: *std.Build.Step, prog_node: *std.Progress.Node) !void {
-    _ = prog_node;
-    const self = @fieldParentPtr(GitRepoStep, "step", step);
-
-    std.fs.accessAbsolute(self.path, .{}) catch {
-        const branch_args = if (self.branch) |b| &[2][]const u8{ " -b ", b } else &[2][]const u8{ "", "" };
-        if (!self.fetch_enabled) {
-            std.debug.print("Error: git repository '{s}' does not exist\n", .{self.path});
-            std.debug.print("       Use -Dfetch to download it automatically, or run the following to clone it:\n", .{});
-            std.debug.print("       git clone {s}{s}{s} {s} && git -C {3s} checkout {s} -b fordep\n", .{
-                self.url,
-                branch_args[0],
-                branch_args[1],
-                self.path,
-                self.sha,
-            });
-            std.os.exit(1);
-        }
-
-        {
-            var args = std.ArrayList([]const u8).init(self.step.owner.allocator);
-            defer args.deinit();
-            try args.append("git");
-            try args.append("clone");
-            try args.append(self.url);
-            // TODO: clone it to a temporary location in case of failure
-            //       also, remove that temporary location before running
-            try args.append(self.path);
-            if (self.branch) |branch| {
-                try args.append("-b");
-                try args.append(branch);
-            }
-            try run(self.step.owner, args.items);
-        }
-        try run(self.step.owner, &[_][]const u8{
-            "git",
-            "-C",
-            self.path,
-            "checkout",
-            self.sha,
-            "-b",
-            "fordep",
-        });
-    };
-
-    try self.checkSha();
-}
-
-fn checkSha(self: GitRepoStep) !void {
-    if (self.sha_check == .none)
-        return;
-
-    const result: union(enum) { failed: anyerror, output: []const u8 } = blk: {
-        const result = std.ChildProcess.exec(.{
-            .allocator = self.step.owner.allocator,
-            .argv = &[_][]const u8{
-                "git",
-                "-C",
-                self.path,
-                "rev-parse",
-                "HEAD",
-            },
-            .cwd = self.step.owner.build_root.path,
-            .env_map = self.step.owner.env_map,
-        }) catch |e| break :blk .{ .failed = e };
-        try std.io.getStdErr().writer().writeAll(result.stderr);
-        switch (result.term) {
-            .Exited => |code| {
-                if (code == 0) break :blk .{ .output = result.stdout };
-                break :blk .{ .failed = error.GitProcessNonZeroExit };
-            },
-            .Signal => break :blk .{ .failed = error.GitProcessFailedWithSignal },
-            .Stopped => break :blk .{ .failed = error.GitProcessWasStopped },
-            .Unknown => break :blk .{ .failed = error.GitProcessFailed },
-        }
-    };
-    switch (result) {
-        .failed => |err| {
-            return self.sha_check.reportFail("failed to retreive sha for repository '{s}': {s}", .{ self.name, @errorName(err) });
-        },
-        .output => |output| {
-            if (!std.mem.eql(u8, std.mem.trimRight(u8, output, "\n\r"), self.sha)) {
-                return self.sha_check.reportFail("repository '{s}' sha does not match\nexpected: {s}\nactual  : {s}\n", .{ self.name, self.sha, output });
-            }
-        },
-    }
-}
-
-fn run(builder: *std.build.Builder, argv: []const []const u8) !void {
-    {
-        var msg = std.ArrayList(u8).init(builder.allocator);
-        defer msg.deinit();
-        const writer = msg.writer();
-        var prefix: []const u8 = "";
-        for (argv) |arg| {
-            try writer.print("{s}\"{s}\"", .{ prefix, arg });
-            prefix = " ";
-        }
-        std.log.info("[RUN] {s}", .{msg.items});
-    }
-
-    var child = std.ChildProcess.init(argv, builder.allocator);
-    child.stdin_behavior = .Ignore;
-    child.stdout_behavior = .Inherit;
-    child.stderr_behavior = .Inherit;
-    child.cwd = builder.build_root.path;
-    child.env_map = builder.env_map;
-
-    try child.spawn();
-    const result = try child.wait();
-    switch (result) {
-        .Exited => |code| if (code != 0) {
-            std.log.err("git clone failed with exit code {}", .{code});
-            std.os.exit(0xff);
-        },
-        else => {
-            std.log.err("git clone failed with: {}", .{result});
-            std.os.exit(0xff);
-        },
-    }
-}
-
-// Get's the repository path and also verifies that the step requesting the path
-// is dependent on this step.
-pub fn getPath(self: *const GitRepoStep, who_wants_to_know: *const std.build.Step) []const u8 {
-    if (!hasDependency(who_wants_to_know, &self.step))
-        @panic("a step called GitRepoStep.getPath but has not added it as a dependency");
-    return self.path;
-}

+ 0 - 2
README.md

@@ -58,8 +58,6 @@ Zigup is currently built/tested using zig 0.11.0.
 
 # Dependencies
 
-zigup depends on https://github.com/marler8997/ziget which in turn depends on other projects depending on which SSL backend is selected.  You can provide `-Dfetch` to `zig build` to automatically clone all repository dependencies, otherwise, the build will report a missing dependency error with an explanation of how to clone it.
-
 The windows target depends on https://github.com/SuperAuguste/zarc to extract zip files.  This repo might point to my fork if there are needed changes pending the acceptance of a PR: https://github.com/marler8997/zarc.
 
 On linux and macos, zigup depends on `tar` to extract the compiler archive files (this may change in the future).

+ 118 - 56
build.zig

@@ -1,66 +1,128 @@
-//! This build.zig file boostraps the real build in build2.zig
-
-// NOTE: need to wait on https://github.com/ziglang/zig/pull/9989 before doing this
-//       to make build errors reasonable
 const std = @import("std");
-const Builder = std.build.Builder;
-
-const GitRepoStep = @import("GitRepoStep.zig");
+const builtin = @import("builtin");
+const Pkg = std.build.Pkg;
 
-pub fn build(b: *Builder) !void {
-    buildNoreturn(b);
+fn unwrapOptionalBool(optionalBool: ?bool) bool {
+    if (optionalBool) |b| return b;
+    return false;
 }
-fn buildNoreturn(b: *Builder) noreturn {
-    const err = buildOrFail(b);
-    std.log.err("{s}", .{@errorName(err)});
-    if (@errorReturnTrace()) |trace| {
-        std.debug.dumpStackTrace(trace.*);
+
+pub fn build(b: *std.Build) !void {
+    //var github_release_step = b.step("github-release", "Build the github-release binaries");
+    //try addGithubReleaseExe(b, github_release_step, ziget_repo, "x86_64-linux", .std);
+
+    const target = if (b.option([]const u8, "ci_target", "the CI target being built")) |ci_target|
+        b.resolveTargetQuery(try std.zig.CrossTarget.parse(.{ .arch_os_abi = ci_target_map.get(ci_target) orelse {
+            std.log.err("unknown ci_target '{s}'", .{ci_target});
+            std.process.exit(1);
+        } }))
+    else
+        b.standardTargetOptions(.{});
+
+    const optimize = b.standardOptimizeOption(.{});
+
+    const win32exelink_mod: ?*std.Build.Module = blk: {
+        if (target.result.os.tag == .windows) {
+            const exe = b.addExecutable(.{
+                .name = "win32exelink",
+                .root_source_file = .{ .path = "win32exelink.zig" },
+                .target = target,
+                .optimize = optimize,
+            });
+            break :blk b.createModule(.{
+                .root_source_file = exe.getEmittedBin(),
+            });
+        }
+        break :blk null;
+    };
+
+    const exe = try addZigupExe(
+        b,
+        target,
+        optimize,
+        win32exelink_mod,
+    );
+    b.installArtifact(exe);
+
+    const run_cmd = b.addRunArtifact(exe);
+    run_cmd.step.dependOn(b.getInstallStep());
+
+    const run_step = b.step("run", "Run the app");
+    run_step.dependOn(&run_cmd.step);
+    if (b.args) |args| {
+        run_cmd.addArgs(args);
     }
-    std.os.exit(0xff);
+
+    addTest(b, exe, target, optimize);
 }
-fn buildOrFail(b: *Builder) anyerror {
-    const ziget_repo = GitRepoStep.create(b, .{
-        .url = "https://github.com/marler8997/ziget",
-        .branch = null,
-        .sha = @embedFile("zigetsha"),
-        .fetch_enabled = true,
+
+fn addTest(
+    b: *std.Build,
+    exe: *std.Build.Step.Compile,
+    target: std.Build.ResolvedTarget,
+    optimize: std.builtin.Mode,
+) void {
+    const test_exe = b.addExecutable(.{
+        .name = "test",
+        .root_source_file = .{ .path = "test.zig" },
+        .target = target,
+        .optimize = optimize,
     });
-    const build2 = addBuild(b, .{ .path = "build2.zig" }, .{});
-    build2.addArgs(try getBuildArgs(b));
-
-    var progress = std.Progress{};
-    {
-        var prog_node = progress.start("clone ziget", 1);
-        ziget_repo.step.make(prog_node) catch |e| return e;
-        prog_node.end();
-    }
-    {
-        var prog_node = progress.start("run build2.zig", 1);
-        build2.step.make(prog_node) catch |err| switch (err) {
-            error.MakeFailed => std.os.exit(0xff), // error already printed by subprocess, hopefully?
-            error.MakeSkipped => @panic("impossible?"),
-        };
-        prog_node.end();
-    }
-    std.os.exit(0);
+    const run_cmd = b.addRunArtifact(test_exe);
+
+    // TODO: make this work, add exe install path as argument to test
+    //run_cmd.addArg(exe.getInstallPath());
+    _ = exe;
+    run_cmd.step.dependOn(b.getInstallStep());
+
+    const test_step = b.step("test", "test the executable");
+    test_step.dependOn(&run_cmd.step);
 }
 
-// TODO: remove the following if https://github.com/ziglang/zig/pull/9987 is integrated
-fn getBuildArgs(self: *Builder) ![]const [:0]const u8 {
-    const args = try std.process.argsAlloc(self.allocator);
-    return args[5..];
+fn addZigupExe(
+    b: *std.Build,
+    target: std.Build.ResolvedTarget,
+    optimize: std.builtin.Mode,
+    win32exelink_mod: ?*std.Build.Module,
+) !*std.Build.Step.Compile {
+    const exe = b.addExecutable(.{
+        .name = "zigup",
+        .root_source_file = .{ .path = "zigup.zig" },
+        .target = target,
+        .optimize = optimize,
+    });
+
+    if (target.result.os.tag == .windows) {
+        exe.root_module.addImport("win32exelink", win32exelink_mod.?);
+        if (b.lazyDependency("zarc", .{})) |zarc_dep| {
+            exe.root_module.addImport("zarc", zarc_dep.module("zarc"));
+        }
+    }
+
+    return exe;
 }
-pub fn addBuild(self: *Builder, build_file: std.build.FileSource, _: struct {}) *std.build.RunStep {
-    const run_step = std.build.RunStep.create(
-        self,
-        self.fmt("zig build {s}", .{build_file.getDisplayName()}),
-    );
-    run_step.addArg(self.zig_exe);
-    run_step.addArg("build");
-    run_step.addArg("--build-file");
-    run_step.addFileSourceArg(build_file);
-    run_step.addArg("--cache-dir");
-    const cache_root_path = self.cache_root.path orelse @panic("todo");
-    run_step.addArg(self.pathFromRoot(cache_root_path));
-    return run_step;
+
+fn addGithubReleaseExe(
+    b: *std.Build,
+    github_release_step: *std.build.Step,
+    comptime target_triple: []const u8,
+) !void {
+    const small_release = true;
+
+    const target = try std.zig.CrossTarget.parse(.{ .arch_os_abi = target_triple });
+    const mode = if (small_release) .ReleaseSafe else .Debug;
+    const exe = try addZigupExe(b, target, mode);
+    if (small_release) {
+        exe.strip = true;
+    }
+    exe.setOutputDir("github-release" ++ std.fs.path.sep_str ++ target_triple);
+    github_release_step.dependOn(&exe.step);
 }
+
+const ci_target_map = std.ComptimeStringMap([]const u8, .{
+    .{ "ubuntu-latest-x86_64", "x86_64-linux" },
+    .{ "macos-latest-x86_64", "x86_64-macos" },
+    .{ "windows-latest-x86_64", "x86_64-windows" },
+    .{ "ubuntu-latest-aarch64", "aarch64-linux" },
+    .{ "macos-latest-aarch64", "aarch64-macos" },
+});

+ 23 - 0
build.zig.zon

@@ -0,0 +1,23 @@
+.{
+    .name = "zigup",
+    .version = "0.0.1",
+
+    .dependencies = .{
+        .zarc = .{
+            .url = "https://github.com/marler8997/zarc/archive/6ed370681d0e0c5d8ef32ad63e440d0b3effc8a8.tar.gz",
+            .hash = "1220a69ceaac42e5a3593161c3b4ab1ce7dbc574b1a80398a7cb3100fbfa07baf372",
+            .lazy = true,
+        },
+    },
+
+    .paths = .{
+        "LICENSE",
+        "README.md",
+        "build.zig",
+        "build.zig.zon",
+        "fixdeletetree.zig",
+        "test.zig",
+        "win32exelink.zig",
+        "zigup.zig",
+    },
+}

+ 0 - 213
build2.zig

@@ -1,213 +0,0 @@
-const std = @import("std");
-const builtin = @import("builtin");
-const Builder = std.build.Builder;
-const Pkg = std.build.Pkg;
-
-// TODO: make this work with "GitRepoStep.zig", there is a
-//       problem with the -Dfetch option
-const GitRepoStep = @import("dep/ziget/GitRepoStep.zig");
-
-const zigetbuild = @import("dep/ziget/build.zig");
-const SslBackend = zigetbuild.SslBackend;
-
-fn unwrapOptionalBool(optionalBool: ?bool) bool {
-    if (optionalBool) |b| return b;
-    return false;
-}
-
-pub fn build(b: *Builder) !void {
-    const ziget_repo = GitRepoStep.create(b, .{
-        .url = "https://github.com/marler8997/ziget",
-        .branch = null,
-        .sha = @embedFile("zigetsha"),
-    });
-
-    // TODO: implement this if/when we get @tryImport
-    //if (zigetbuild) |_| { } else {
-    //    std.log.err("TODO: add zigetbuild package and recompile/reinvoke build.d", .{});
-    //    return;
-    //}
-
-    //var github_release_step = b.step("github-release", "Build the github-release binaries");
-    //try addGithubReleaseExe(b, github_release_step, ziget_repo, "x86_64-linux", .std);
-
-    const target = if (b.option([]const u8, "ci_target", "the CI target being built")) |ci_target|
-        try std.zig.CrossTarget.parse(.{ .arch_os_abi = ci_target_map.get(ci_target) orelse {
-            std.log.err("unknown ci_target '{s}'", .{ci_target});
-            std.os.exit(1);
-        } })
-    else
-        b.standardTargetOptions(.{});
-
-    const optimize = b.standardOptimizeOption(.{});
-
-    const win32exelink_mod: ?*std.Build.Module = blk: {
-        if (target.getOs().tag == .windows) {
-            const exe = b.addExecutable(.{
-                .name = "win32exelink",
-                .root_source_file = .{ .path = "win32exelink.zig" },
-                .target = target,
-                .optimize = optimize,
-            });
-            break :blk b.createModule(.{
-                .source_file = exe.getEmittedBin(),
-            });
-        }
-        break :blk null;
-    };
-
-    // TODO: Maybe add more executables with different ssl backends
-    const exe = try addZigupExe(
-        b,
-        ziget_repo,
-        target,
-        optimize,
-        win32exelink_mod,
-        .iguana,
-    );
-    b.installArtifact(exe);
-
-    const run_cmd = b.addRunArtifact(exe);
-    run_cmd.step.dependOn(b.getInstallStep());
-
-    const run_step = b.step("run", "Run the app");
-    run_step.dependOn(&run_cmd.step);
-    if (b.args) |args| {
-        run_cmd.addArgs(args);
-    }
-
-    addTest(b, exe, target, optimize);
-}
-
-fn addTest(b: *Builder, exe: *std.build.LibExeObjStep, target: std.zig.CrossTarget, optimize: std.builtin.Mode) void {
-    const test_exe = b.addExecutable(.{
-        .name = "test",
-        .root_source_file = .{ .path = "test.zig" },
-        .target = target,
-        .optimize = optimize,
-    });
-    const run_cmd = b.addRunArtifact(test_exe);
-
-    // TODO: make this work, add exe install path as argument to test
-    //run_cmd.addArg(exe.getInstallPath());
-    _ = exe;
-    run_cmd.step.dependOn(b.getInstallStep());
-
-    const test_step = b.step("test", "test the executable");
-    test_step.dependOn(&run_cmd.step);
-}
-
-fn addZigupExe(
-    b: *Builder,
-    ziget_repo: *GitRepoStep,
-    target: std.zig.CrossTarget,
-    optimize: std.builtin.Mode,
-    win32exelink_mod: ?*std.build.Module,
-    ssl_backend: ?SslBackend,
-) !*std.build.LibExeObjStep {
-    const require_ssl_backend = b.allocator.create(RequireSslBackendStep) catch unreachable;
-    require_ssl_backend.* = RequireSslBackendStep.init(b, "the zigup exe", ssl_backend);
-
-    const exe = b.addExecutable(.{
-        .name = "zigup",
-        .root_source_file = .{ .path = "zigup.zig" },
-        .target = target,
-        .optimize = optimize,
-    });
-
-    exe.step.dependOn(&ziget_repo.step);
-    zigetbuild.addZigetModule(exe, ssl_backend, ziget_repo.getPath(&exe.step));
-
-    if (targetIsWindows(target)) {
-        exe.addModule("win32exelink", win32exelink_mod.?);
-        const zarc_repo = GitRepoStep.create(b, .{
-            .url = "https://github.com/marler8997/zarc",
-            .branch = "protected",
-            .sha = "2e5256624d7871180badc9784b96dd66d927d604",
-            .fetch_enabled = true,
-        });
-        exe.step.dependOn(&zarc_repo.step);
-        const zarc_repo_path = zarc_repo.getPath(&exe.step);
-        const zarc_mod = b.addModule("zarc", .{
-            .source_file = .{ .path = b.pathJoin(&.{ zarc_repo_path, "src", "main.zig" }) },
-        });
-        exe.addModule("zarc", zarc_mod);
-    }
-
-    exe.step.dependOn(&require_ssl_backend.step);
-    return exe;
-}
-
-fn targetIsWindows(target: std.zig.CrossTarget) bool {
-    if (target.os_tag) |tag|
-        return tag == .windows;
-    return builtin.target.os.tag == .windows;
-}
-
-const SslBackendFailedStep = struct {
-    step: std.build.Step,
-    context: []const u8,
-    backend: SslBackend,
-    pub fn init(b: *Builder, context: []const u8, backend: SslBackend) SslBackendFailedStep {
-        return .{
-            .step = std.build.Step.init(.custom, "SslBackendFailedStep", b.allocator, make),
-            .context = context,
-            .backend = backend,
-        };
-    }
-    fn make(step: *std.build.Step) !void {
-        const self = @fieldParentPtr(RequireSslBackendStep, "step", step);
-        std.debug.print("error: the {s} failed to add the {s} SSL backend\n", .{ self.context, self.backend });
-        std.os.exit(1);
-    }
-};
-
-const RequireSslBackendStep = struct {
-    step: std.build.Step,
-    context: []const u8,
-    backend: ?SslBackend,
-    pub fn init(b: *Builder, context: []const u8, backend: ?SslBackend) RequireSslBackendStep {
-        return .{
-            .step = std.build.Step.init(.{
-                .id = .custom,
-                .name = "RequireSslBackend",
-                .owner = b,
-                .makeFn = make,
-            }),
-            .context = context,
-            .backend = backend,
-        };
-    }
-    fn make(step: *std.build.Step, prog_node: *std.Progress.Node) !void {
-        _ = prog_node;
-        const self = @fieldParentPtr(RequireSslBackendStep, "step", step);
-        if (self.backend) |_| {} else {
-            std.debug.print("error: {s} requires an SSL backend:\n", .{self.context});
-            inline for (zigetbuild.ssl_backends) |field| {
-                std.debug.print("    -D{s}\n", .{field.name});
-            }
-            std.os.exit(1);
-        }
-    }
-};
-
-fn addGithubReleaseExe(b: *Builder, github_release_step: *std.build.Step, ziget_repo: []const u8, comptime target_triple: []const u8, comptime ssl_backend: SslBackend) !void {
-    const small_release = true;
-
-    const target = try std.zig.CrossTarget.parse(.{ .arch_os_abi = target_triple });
-    const mode = if (small_release) .ReleaseSafe else .Debug;
-    const exe = try addZigupExe(b, ziget_repo, target, mode, ssl_backend);
-    if (small_release) {
-        exe.strip = true;
-    }
-    exe.setOutputDir("github-release" ++ std.fs.path.sep_str ++ target_triple ++ std.fs.path.sep_str ++ @tagName(ssl_backend));
-    github_release_step.dependOn(&exe.step);
-}
-
-const ci_target_map = std.ComptimeStringMap([]const u8, .{
-    .{ "ubuntu-latest-x86_64", "x86_64-linux" },
-    .{ "macos-latest-x86_64", "x86_64-macos" },
-    .{ "windows-latest-x86_64", "x86_64-windows" },
-    .{ "ubuntu-latest-aarch64", "aarch64-linux" },
-    .{ "macos-latest-aarch64", "aarch64-macos" },
-});

+ 17 - 7
test.zig

@@ -34,6 +34,15 @@ pub fn main() !u8 {
         zigup,
         .{},
     );
+    if (builtin.os.tag == .windows) {
+        const zigup_pdb = comptime "." ++ sep ++ bin_dir ++ sep ++ "zigup.pdb";
+        try std.fs.cwd().copyFile(
+            comptime "zig-out" ++ sep ++ "bin" ++ sep ++ "zigup.pdb",
+            std.fs.cwd(),
+            zigup_pdb,
+            .{},
+        );
+    }
 
     const install_args = if (builtin.os.tag == .windows) [_][]const u8{} else [_][]const u8{ "--install-dir", install_dir };
     const zigup_args = &[_][]const u8{zigup} ++ install_args;
@@ -265,7 +274,8 @@ pub fn main() !u8 {
             allocator.free(result.stdout);
             allocator.free(result.stderr);
         }
-        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "HTTP request failed"));
+        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "download"));
+        try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, "failed"));
     }
     try testing.expectEqual(@as(u32, 2), try getCompilerCount(install_dir));
 
@@ -310,7 +320,7 @@ pub fn main() !u8 {
     // NOTE: this test will eventually break when these builds are cleaned up,
     //       we should support downloading from bazel and use that instead since
     //       it should be more permanent
-    try runNoCapture(zigup_args ++ &[_][]const u8{"0.11.0-dev.4263+f821543e4"});
+    try runNoCapture(zigup_args ++ &[_][]const u8{ "0.12.0-dev.3639+9cfac4718" });
 
     std.log.info("Success", .{});
     return 0;
@@ -338,7 +348,7 @@ fn checkZigVersion(allocator: std.mem.Allocator, zig: []const u8, compare: []con
 }
 
 fn getCompilerCount(install_dir: []const u8) !u32 {
-    var dir = try std.fs.cwd().openIterableDir(install_dir, .{});
+    var dir = try std.fs.cwd().openDir(install_dir, .{ .iterate = true });
     defer dir.close();
     var it = dir.iterate();
     var count: u32 = 0;
@@ -360,7 +370,7 @@ fn trailNl(s: []const u8) []const u8 {
     return if (s.len == 0 or s[s.len - 1] != '\n') "\n" else "";
 }
 
-fn dumpExecResult(result: std.ChildProcess.ExecResult) void {
+fn dumpExecResult(result: std.ChildProcess.RunResult) void {
     if (result.stdout.len > 0) {
         std.debug.print("--- STDOUT ---\n{s}{s}--------------\n", .{ result.stdout, trailNl(result.stdout) });
     }
@@ -376,13 +386,13 @@ fn runNoCapture(argv: []const []const u8) !void {
     dumpExecResult(result);
     try passOrThrow(result.term);
 }
-fn runCaptureOuts(allocator: std.mem.Allocator, argv: []const []const u8) !std.ChildProcess.ExecResult {
+fn runCaptureOuts(allocator: std.mem.Allocator, argv: []const []const u8) !std.ChildProcess.RunResult {
     {
         const cmd = try std.mem.join(allocator, " ", argv);
         defer allocator.free(cmd);
         std.log.info("RUN: {s}", .{cmd});
     }
-    return try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv, .env_map = &child_env_map });
+    return try std.ChildProcess.run(.{ .allocator = allocator, .argv = argv, .env_map = &child_env_map });
 }
 fn passOrThrow(term: std.ChildProcess.Term) error{ChildProcessFailed}!void {
     if (!execResultPassed(term)) {
@@ -390,7 +400,7 @@ fn passOrThrow(term: std.ChildProcess.Term) error{ChildProcessFailed}!void {
         return error.ChildProcessFailed;
     }
 }
-fn passOrDumpAndThrow(result: std.ChildProcess.ExecResult) error{ChildProcessFailed}!void {
+fn passOrDumpAndThrow(result: std.ChildProcess.RunResult) error{ChildProcessFailed}!void {
     if (!execResultPassed(result.term)) {
         dumpExecResult(result);
         std.log.err("child process failed with {}", .{result.term});

+ 2 - 2
win32exelink.zig

@@ -75,14 +75,14 @@ fn consoleCtrlHandler(ctrl_type: u32) callconv(@import("std").os.windows.WINAPI)
     log.info("caught ctrl signal {d} ({s}), stopping process...", .{ ctrl_type, name });
     const exit_code = switch (global.child.kill() catch |err| {
         log.err("failed to kill process, error={s}", .{@errorName(err)});
-        std.os.exit(0xff);
+        std.process.exit(0xff);
     }) {
         .Exited => |e| e,
         .Signal => 0xff,
         .Stopped => 0xff,
         .Unknown => 0xff,
     };
-    std.os.exit(exit_code);
+    std.process.exit(exit_code);
     unreachable;
 }
 

+ 0 - 1
zigetsha

@@ -1 +0,0 @@
-9020437522f092860c513b1e96dcc250c7dea0aa

+ 118 - 65
zigup.zig

@@ -5,7 +5,6 @@ const mem = std.mem;
 const ArrayList = std.ArrayList;
 const Allocator = mem.Allocator;
 
-const ziget = @import("ziget");
 const zarc = @import("zarc");
 
 const fixdeletetree = @import("fixdeletetree.zig");
@@ -36,36 +35,82 @@ fn loginfo(comptime fmt: []const u8, args: anytype) void {
     }
 }
 
-fn download(allocator: Allocator, url: []const u8, writer: anytype) !void {
-    var download_options = ziget.request.DownloadOptions{
-        .flags = 0,
-        .allocator = allocator,
-        .maxRedirects = 10,
-        .forwardBufferSize = 4096,
-        .maxHttpResponseHeaders = 8192,
-        .onHttpRequest = ignoreHttpCallback,
-        .onHttpResponse = ignoreHttpCallback,
-    };
-    var dowload_state = ziget.request.DownloadState.init();
-    try ziget.request.download(
-        ziget.url.parseUrl(url) catch unreachable,
-        writer,
-        download_options,
-        &dowload_state,
-    );
+pub fn oom(e: error{OutOfMemory}) noreturn {
+    @panic(@errorName(e));
 }
 
-fn downloadToFileAbsolute(allocator: Allocator, url: []const u8, file_absolute: []const u8) !void {
-    const file = try std.fs.createFileAbsolute(file_absolute, .{});
-    defer file.close();
-    try download(allocator, url, file.writer());
+const DownloadResult = union(enum) {
+    ok: void,
+    err: []u8,
+    pub fn deinit(self: DownloadResult, allocator: Allocator) void {
+        switch (self) {
+            .ok => {},
+            .err => |e| allocator.free(e),
+        }
+    }
+};
+fn download(allocator: Allocator, url: []const u8, writer: anytype) DownloadResult {
+    const uri = std.Uri.parse(url) catch |err| std.debug.panic(
+        "failed to parse url '{s}' with {s}", .{url, @errorName(err)}
+    );
+
+    var client = std.http.Client{ .allocator = allocator };
+    defer client.deinit();
+
+    client.initDefaultProxies(allocator) catch |err| return .{ .err = std.fmt.allocPrint(
+        allocator, "failed to query the HTTP proxy settings with {s}", .{ @errorName(err) }
+    ) catch |e| oom(e) };
+
+    var header_buffer: [4096]u8 = undefined;
+    var request = client.open(.GET, uri, .{
+        .server_header_buffer = &header_buffer,
+        .keep_alive = false,
+    }) catch |err| return .{ .err = std.fmt.allocPrint(
+        allocator, "failed to connect to the HTTP server with {s}", .{ @errorName(err) }
+    ) catch |e| oom(e) };
+
+    defer request.deinit();
+
+    request.send() catch |err| return .{ .err = std.fmt.allocPrint(
+        allocator, "failed to send the HTTP request with {s}", .{ @errorName(err) }
+    ) catch |e| oom(e) };
+    request.wait() catch |err| return .{ .err = std.fmt.allocPrint(
+        allocator, "failed to read the HTTP response headers with {s}", .{ @errorName(err) }
+    ) catch |e| oom(e) };
+
+    if (request.response.status != .ok) return .{ .err = std.fmt.allocPrint(
+        allocator,
+        "HTTP server replied with unsuccessful response '{d} {s}'",
+        .{ @intFromEnum(request.response.status), request.response.status.phrase() orelse "" },
+    ) catch |e| oom(e) };
+
+    // TODO: we take advantage of request.response.content_length
+
+    var buf: [std.mem.page_size]u8 = undefined;
+    while (true) {
+        const len = request.reader().read(&buf) catch |err| return .{ .err = std.fmt.allocPrint(
+            allocator, "failed to read the HTTP response body with {s}'", .{ @errorName(err) }
+        ) catch |e| oom(e) };
+        if (len == 0)
+            return .ok;
+        writer.writeAll(buf[0..len]) catch |err| return .{ .err = std.fmt.allocPrint(
+            allocator, "failed to write the HTTP response body with {s}'", .{ @errorName(err) }
+        ) catch |e| oom(e) };
+    }
 }
 
-fn downloadToString(allocator: Allocator, url: []const u8) ![]u8 {
-    var response_array_list = try ArrayList(u8).initCapacity(allocator, 20 * 1024); // 20 KB (modify if response is expected to be bigger)
-    errdefer response_array_list.deinit();
-    try download(allocator, url, response_array_list.writer());
-    return response_array_list.toOwnedSlice();
+const DownloadStringResult = union(enum) {
+    ok: []u8,
+    err: []u8,
+
+};
+fn downloadToString(allocator: Allocator, url: []const u8) DownloadStringResult {
+    var response_array_list = ArrayList(u8).initCapacity(allocator, 20 * 1024) catch |e| oom(e); // 20 KB (modify if response is expected to be bigger)
+    defer response_array_list.deinit();
+    switch (download(allocator, url, response_array_list.writer())) {
+        .ok => return .{ .ok = response_array_list.toOwnedSlice() catch |e| oom(e) },
+        .err => |e| return .{ .err = e },
+    }
 }
 
 fn ignoreHttpCallback(request: []const u8) void {
@@ -73,7 +118,7 @@ fn ignoreHttpCallback(request: []const u8) void {
 }
 
 fn getHomeDir() ![]const u8 {
-    return std.os.getenv("HOME") orelse {
+    return std.posix.getenv("HOME") orelse {
         std.log.err("cannot find install directory, $HOME environment variable is not set", .{});
         return error.MissingHomeEnvironmentVariable;
     };
@@ -282,13 +327,13 @@ pub fn main2() !u8 {
                 if (!std.mem.eql(u8, version_string, "master"))
                     break :init_resolved version_string;
 
-                var optional_master_dir: ?[]const u8 = blk: {
-                    var install_dir = std.fs.openIterableDirAbsolute(install_dir_string, .{}) catch |e| switch (e) {
+                const optional_master_dir: ?[]const u8 = blk: {
+                    var install_dir = std.fs.openDirAbsolute(install_dir_string, .{ .iterate = true }) catch |e| switch (e) {
                         error.FileNotFound => break :blk null,
                         else => return e,
                     };
                     defer install_dir.close();
-                    break :blk try getMasterDir(allocator, &install_dir.dir);
+                    break :blk try getMasterDir(allocator, &install_dir);
                 };
                 // no need to free master_dir, this is a short lived program
                 break :init_resolved optional_master_dir orelse {
@@ -408,10 +453,11 @@ const DownloadIndex = struct {
 };
 
 fn fetchDownloadIndex(allocator: Allocator) !DownloadIndex {
-    const text = downloadToString(allocator, download_index_url) catch |e| switch (e) {
-        else => {
-            std.log.err("failed to download '{s}': {}", .{ download_index_url, e });
-            return e;
+    const text = switch (downloadToString(allocator, download_index_url)) {
+        .ok => |text| text,
+        .err => |err| {
+            std.log.err("download '{s}' failed: {s}", .{download_index_url, err});
+            return error.AlreadyReported;
         },
     };
     errdefer allocator.free(text);
@@ -443,24 +489,24 @@ pub fn loggyRenameAbsolute(old_path: []const u8, new_path: []const u8) !void {
     try std.fs.renameAbsolute(old_path, new_path);
 }
 
-pub fn loggySymlinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags: std.fs.SymLinkFlags) !void {
+pub fn loggySymlinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags: std.fs.Dir.SymLinkFlags) !void {
     loginfo("ln -s '{s}' '{s}'", .{ target_path, sym_link_path });
     // NOTE: can't use symLinkAbsolute because it requires target_path to be absolute but we don't want that
     //       not sure if it is a bug in the standard lib or not
     //try std.fs.symLinkAbsolute(target_path, sym_link_path, flags);
     _ = flags;
-    try std.os.symlink(target_path, sym_link_path);
+    try std.posix.symlink(target_path, sym_link_path);
 }
 
 /// returns: true if the symlink was updated, false if it was already set to the given `target_path`
-pub fn loggyUpdateSymlink(target_path: []const u8, sym_link_path: []const u8, flags: std.fs.SymLinkFlags) !bool {
+pub fn loggyUpdateSymlink(target_path: []const u8, sym_link_path: []const u8, flags: std.fs.Dir.SymLinkFlags) !bool {
     var current_target_path_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
     if (std.fs.readLinkAbsolute(sym_link_path, &current_target_path_buffer)) |current_target_path| {
         if (std.mem.eql(u8, target_path, current_target_path)) {
             loginfo("symlink '{s}' already points to '{s}'", .{ sym_link_path, target_path });
             return false; // already up-to-date
         }
-        try std.os.unlink(sym_link_path);
+        try std.posix.unlink(sym_link_path);
     } else |e| switch (e) {
         error.FileNotFound => {},
         error.NotLink => {
@@ -468,7 +514,7 @@ pub fn loggyUpdateSymlink(target_path: []const u8, sym_link_path: []const u8, fl
                 "unable to update/overwrite the 'zig' PATH symlink, the file '{s}' already exists and is not a symlink\n",
                 .{ sym_link_path},
             );
-            std.os.exit(1);
+            std.process.exit(1);
         },
         else => return e,
     }
@@ -486,7 +532,8 @@ fn existsAbsolute(absolutePath: []const u8) !bool {
         error.SymLinkLoop => return e,
         error.FileBusy => return e,
         error.Unexpected => unreachable,
-        error.InvalidUtf8 => unreachable,
+        error.InvalidUtf8 => return e,
+        error.InvalidWtf8 => return e,
         error.ReadOnlyFileSystem => unreachable,
         error.NameTooLong => unreachable,
         error.BadPathName => unreachable,
@@ -498,7 +545,7 @@ fn listCompilers(allocator: Allocator) !void {
     const install_dir_string = try getInstallDir(allocator, .{ .create = false });
     defer allocator.free(install_dir_string);
 
-    var install_dir = std.fs.openIterableDirAbsolute(install_dir_string, .{}) catch |e| switch (e) {
+    var install_dir = std.fs.openDirAbsolute(install_dir_string, .{ .iterate = true }) catch |e| switch (e) {
         error.FileNotFound => return,
         else => return e,
     };
@@ -521,10 +568,10 @@ fn keepCompiler(allocator: Allocator, compiler_version: []const u8) !void {
     const install_dir_string = try getInstallDir(allocator, .{ .create = true });
     defer allocator.free(install_dir_string);
 
-    var install_dir = try std.fs.openIterableDirAbsolute(install_dir_string, .{});
+    var install_dir = try std.fs.openDirAbsolute(install_dir_string, .{ .iterate = true });
     defer install_dir.close();
 
-    var compiler_dir = install_dir.dir.openDir(compiler_version, .{}) catch |e| switch (e) {
+    var compiler_dir = install_dir.openDir(compiler_version, .{}) catch |e| switch (e) {
         error.FileNotFound => {
             std.log.err("compiler not found: {s}", .{compiler_version});
             return error.AlreadyReported;
@@ -543,12 +590,12 @@ fn cleanCompilers(allocator: Allocator, compiler_name_opt: ?[]const u8) !void {
     const default_comp_opt = try getDefaultCompiler(allocator);
     defer if (default_comp_opt) |default_compiler| allocator.free(default_compiler);
 
-    var install_dir = std.fs.openIterableDirAbsolute(install_dir_string, .{}) catch |e| switch (e) {
+    var install_dir = std.fs.openDirAbsolute(install_dir_string, .{ .iterate = true }) catch |e| switch (e) {
         error.FileNotFound => return,
         else => return e,
     };
     defer install_dir.close();
-    const master_points_to_opt = try getMasterDir(allocator, &install_dir.dir);
+    const master_points_to_opt = try getMasterDir(allocator, &install_dir);
     defer if (master_points_to_opt) |master_points_to| allocator.free(master_points_to);
     if (compiler_name_opt) |compiler_name| {
         if (getKeepReason(master_points_to_opt, default_comp_opt, compiler_name)) |reason| {
@@ -556,7 +603,7 @@ fn cleanCompilers(allocator: Allocator, compiler_name_opt: ?[]const u8) !void {
             return error.AlreadyReported;
         }
         loginfo("deleting '{s}{c}{s}'", .{ install_dir_string, std.fs.path.sep, compiler_name });
-        try fixdeletetree.deleteTree(install_dir.dir, compiler_name);
+        try fixdeletetree.deleteTree(install_dir, compiler_name);
     } else {
         var it = install_dir.iterate();
         while (try it.next()) |entry| {
@@ -568,7 +615,7 @@ fn cleanCompilers(allocator: Allocator, compiler_name_opt: ?[]const u8) !void {
             }
 
             {
-                var compiler_dir = try install_dir.dir.openDir(entry.name, .{});
+                var compiler_dir = try install_dir.openDir(entry.name, .{});
                 defer compiler_dir.close();
                 if (compiler_dir.access("keep", .{})) |_| {
                     loginfo("keeping '{s}' (has keep file)", .{entry.name});
@@ -579,7 +626,7 @@ fn cleanCompilers(allocator: Allocator, compiler_name_opt: ?[]const u8) !void {
                 }
             }
             loginfo("deleting '{s}{c}{s}'", .{ install_dir_string, std.fs.path.sep, entry.name });
-            try fixdeletetree.deleteTree(install_dir.dir, entry.name);
+            try fixdeletetree.deleteTree(install_dir, entry.name);
         }
     }
 }
@@ -632,16 +679,16 @@ fn readMasterDir(buffer: *[std.fs.MAX_PATH_BYTES]u8, install_dir: *std.fs.Dir) !
 fn getDefaultCompiler(allocator: Allocator) !?[]const u8 {
     var buffer: [std.fs.MAX_PATH_BYTES + 1]u8 = undefined;
     const slice_path = (try readDefaultCompiler(allocator, &buffer)) orelse return null;
-    var path_to_return = try allocator.alloc(u8, slice_path.len);
-    std.mem.copy(u8, path_to_return, slice_path);
+    const path_to_return = try allocator.alloc(u8, slice_path.len);
+    @memcpy(path_to_return, slice_path);
     return path_to_return;
 }
 
 fn getMasterDir(allocator: Allocator, install_dir: *std.fs.Dir) !?[]const u8 {
     var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
     const slice_path = (try readMasterDir(&buffer, install_dir)) orelse return null;
-    var path_to_return = try allocator.alloc(u8, slice_path.len);
-    std.mem.copy(u8, path_to_return, slice_path);
+    const path_to_return = try allocator.alloc(u8, slice_path.len);
+    @memcpy(path_to_return, slice_path);
     return path_to_return;
 }
 
@@ -754,7 +801,7 @@ fn verifyPathLink(allocator: Allocator, path_link: []const u8) !void {
             }
         }
     } else {
-        var path_it = std.mem.tokenize(u8, std.os.getenv("PATH") orelse "", ":");
+        var path_it = std.mem.tokenize(u8, std.posix.getenv("PATH") orelse "", ":");
         while (path_it.next()) |path| {
             switch (try compareDir(path_link_dir_id, path)) {
                 .missing => continue,
@@ -798,11 +845,11 @@ fn enforceNoZig(path_link: []const u8, exe: []const u8) !void {
 
 const FileId = struct {
     dev: if (builtin.os.tag == .windows) u32 else blk: {
-        var st: std.os.Stat = undefined;
+        const st: std.posix.Stat = undefined;
         break :blk @TypeOf(st.dev);
     },
     ino: if (builtin.os.tag == .windows) u64 else blk: {
-        var st: std.os.Stat = undefined;
+        const st: std.posix.Stat = undefined;
         break :blk @TypeOf(st.ino);
     },
 
@@ -818,7 +865,7 @@ const FileId = struct {
                 .ino = (@as(u64, @intCast(info.nFileIndexHigh)) << 32) | @as(u64, @intCast(info.nFileIndexLow)),
             };
         }
-        const st = try std.os.fstat(file.handle);
+        const st = try std.posix.fstat(file.handle);
         return FileId{
             .dev = st.dev,
             .ino = st.ino,
@@ -886,7 +933,7 @@ fn createExeLink(link_target: []const u8, path_link: []const u8) !void {
                 "unable to create the exe link, the path '{s}' is a directory\n",
                 .{ path_link},
             );
-            std.os.exit(1);
+            std.process.exit(1);
         },
         else => |e| return e,
     };
@@ -927,16 +974,22 @@ fn installCompiler(allocator: Allocator, compiler_dir: []const u8, url: []const
         const archive_absolute = try std.fs.path.join(allocator, &[_][]const u8{ installing_dir, archive_basename });
         defer allocator.free(archive_absolute);
         loginfo("downloading '{s}' to '{s}'", .{ url, archive_absolute });
-        downloadToFileAbsolute(allocator, url, archive_absolute) catch |e| switch (e) {
-            error.HttpNon200StatusCode => {
-                // TODO: more information would be good
-                std.log.err("HTTP request failed (TODO: improve ziget library to get better error)", .{});
+
+        switch (blk: {
+            const file = try std.fs.createFileAbsolute(archive_absolute, .{});
+            // note: important to close the file before we handle errors below
+            //       since it will delete the parent directory of this file
+            defer file.close();
+            break :blk download(allocator, url, file.writer());
+        }) {
+            .ok => {},
+            .err => |err| {
+                std.log.err("download '{s}' failed: {s}", .{url, err});
                 // this removes the installing dir if the http request fails so we dont have random directories
                 try loggyDeleteTreeAbsolute(installing_dir);
                 return error.AlreadyReported;
             },
-            else => return e,
-        };
+        }
 
         if (std.mem.endsWith(u8, archive_basename, ".tar.xz")) {
             archive_root_dir = archive_basename[0 .. archive_basename.len - ".tar.xz".len];
@@ -1004,7 +1057,7 @@ fn logRun(allocator: Allocator, argv: []const []const u8) !void {
         } else {
             prefix = true;
         }
-        std.mem.copy(u8, buffer[offset .. offset + arg.len], arg);
+        @memcpy(buffer[offset .. offset + arg.len], arg);
         offset += arg.len;
     }
     std.debug.assert(offset == buffer.len);