浏览代码

finalize changes

Jonathan Marler 3 年之前
父节点
当前提交
9cb83cbd63
共有 3 个文件被更改,包括 36 次插入6 次删除
  1. 3 0
      README.md
  2. 6 1
      test.zig
  3. 27 5
      zigup.zig

+ 3 - 0
README.md

@@ -28,6 +28,9 @@ zigup clean [<version>]
 
 # mark a compiler to keep
 zigup keep <version>
+
+# run a specific version of the copmiler
+zigup run <version> <args>...
 ```
 
 # How the compilers are managed

+ 6 - 1
test.zig

@@ -136,7 +136,12 @@ pub fn main() !u8 {
     {
         const result = try runCaptureOuts(allocator, zigup_args ++ &[_][]const u8 {"run", "0.6.0", "version"});
         defer { allocator.free(result.stdout); allocator.free(result.stderr); }
-        try testing.expect(std.mem.containsAtLeast(u8, result.stdout, 1, "0.6.0"));
+        try testing.expectEqualSlices(u8, "0.6.0\n", result.stdout);
+    }
+    {
+        const result = try runCaptureOuts(allocator, zigup_args ++ &[_][]const u8 {"run", "doesnotexist", "version"});
+        defer { allocator.free(result.stdout); allocator.free(result.stderr); }
+        try testing.expectEqualSlices(u8, "error: compiler 'doesnotexist' does not exist, fetch it first with: zigup fetch doesnotexist\n", result.stderr);
     }
     try runNoCapture(zigup_args ++ &[_][]const u8 {"keep", "0.6.0"});
     // doesn't delete anything because we have keepfile and master doens't get deleted

+ 27 - 5
zigup.zig

@@ -30,8 +30,11 @@ const archive_ext = if (builtin.os.tag == .windows) "zip" else "tar.xz";
 var global_optional_install_dir: ?[]const u8 = null;
 var global_optional_path_link: ?[]const u8 = null;
 
+var global_enable_log = true;
 fn loginfo(comptime fmt: []const u8, args: anytype) void {
-    std.debug.print(fmt ++ "\n", args);
+    if (global_enable_log) {
+        std.debug.print(fmt ++ "\n", args);
+    }
 }
 
 fn download(allocator: Allocator, url: []const u8, writer: anytype) !void {
@@ -142,6 +145,7 @@ fn help() void {
         \\  zigup clean   [VERSION]       deletes the given compiler version, otherwise, cleans all compilers
         \\                                that aren't the default, master, or marked to keep.
         \\  zigup keep VERSION            mark a compiler to be kept during clean
+        \\  zigup run VERSION ARGS...     run the given VERSION of the compiler with the given ARGS...
         \\
         \\Uncommon Usage:
         \\
@@ -206,7 +210,7 @@ pub fn main2() !u8 {
                 return 0;
             } else {
                 if (newlen == 0 and std.mem.eql(u8, "run", arg)) {
-                    return try runCompiler(allocator, args[i + 1], args[i + 2 ..]);
+                    return try runCompiler(allocator, args[i+1..]);
                 }
                 args[newlen] = args[i];
                 newlen += 1;
@@ -310,21 +314,39 @@ pub fn main2() !u8 {
     //const optionalInstallPath = try find_zigs(allocator);
 }
 
-pub fn runCompiler(allocator: Allocator, version_string: []const u8, args: []const []const u8) !u8 {
+pub fn runCompiler(allocator: Allocator, args: []const []const u8) !u8 {
+    // disable log so we don't add extra output to whatever the compiler will output
+    global_enable_log = false;
+    if (args.len <= 1) {
+        std.log.err("zigup run requires at least 2 arguments: zigup run VERSION PROG ARGS...", .{});
+        return 1;
+    }
+    const version_string = args[0];
     const install_dir_string = try getInstallDir(allocator, .{ .create = true });
     defer allocator.free(install_dir_string);
 
     const compiler_dir = try std.fs.path.join(allocator, &[_][]const u8{ install_dir_string, version_string });
     defer allocator.free(compiler_dir);
+    if (!try existsAbsolute(compiler_dir)) {
+        std.log.err("compiler '{s}' does not exist, fetch it first with: zigup fetch {0s}", .{version_string});
+        return 1;
+    }
 
     var argv = std.ArrayList([]const u8).init(allocator);
     try argv.append(try std.fs.path.join(allocator, &.{ compiler_dir, "files", "zig" ++ builtin.target.exeFileExt() }));
-    try argv.appendSlice(args);
+    try argv.appendSlice(args[1..]);
 
+    // TODO: use "execve" if on linux
     const proc = try std.ChildProcess.init(argv.items, allocator);
     defer proc.deinit();
     const ret_val = try proc.spawnAndWait();
-    return ret_val.Exited;
+    switch (ret_val) {
+        .Exited => |code| return code,
+        else => |result| {
+            std.log.err("compiler exited with {}", .{result});
+            return 0xff;
+        },
+    }
 }
 
 const SetDefault = enum { set_default, leave_default };