| 1 | const std = @import("std"); |
| 2 | const string = []const u8; |
| 3 | const gpa = std.heap.c_allocator; |
| 4 | const knownfolders = @import("known-folders"); |
| 5 | const extras = @import("extras"); |
| 6 | const nio = @import("nio"); |
| 7 | const nfs = @import("nfs"); |
| 8 | const root = @import("root"); |
| 9 | |
| 10 | const zigmod = @import("./../lib.zig"); |
| 11 | const u = @import("./../util/funcs.zig"); |
| 12 | const common = @import("./../common.zig"); |
| 13 | |
| 14 | pub fn execute(self_name: []const u8, args: []const [:0]const u8) !void { |
| 15 | _ = self_name; |
| 16 | |
| 17 | if (args.len < 2) u.fail("usage: zigmod install [git|hg|http] [url]", .{}); |
| 18 | |
| 19 | const io = root.io; |
| 20 | const homepath = try knownfolders.getPath(io, gpa, root.environ, .home) orelse u.fail("failed to read HOME", .{}); |
| 21 | const cache = try knownfolders.getPath(io, gpa, root.environ, .cache) orelse u.fail("failed to read XDG_CACHE_HOME", .{}); |
| 22 | const datapath = try knownfolders.getPath(io, gpa, root.environ, .data) orelse u.fail("failed to read XDG_DATA_HOME", .{}); |
| 23 | |
| 24 | const RemoteType = enum { |
| 25 | git, |
| 26 | hg, |
| 27 | http, |
| 28 | }; |
| 29 | const rty_s = args[0]; |
| 30 | const rty = std.meta.stringToEnum(RemoteType, rty_s) orelse u.fail("usage: zigmod install [git|hg|http] [url]", .{}); |
| 31 | const ty: zigmod.Dep.Type = switch (rty) { |
| 32 | .git => .git, |
| 33 | .hg => .hg, |
| 34 | .http => .http, |
| 35 | }; |
| 36 | const dep: zigmod.Dep = .{ |
| 37 | .type = ty, |
| 38 | .path = args[1], |
| 39 | .id = u.random_string(48), |
| 40 | .name = "(name)", |
| 41 | .main = "", |
| 42 | .version = "", |
| 43 | .c_include_dirs = &.{}, |
| 44 | .c_source_flags = &.{}, |
| 45 | .c_source_files = &.{}, |
| 46 | .only_os = &.{}, |
| 47 | .except_os = &.{}, |
| 48 | .yaml = null, |
| 49 | .deps = &.{}, |
| 50 | .keep = false, |
| 51 | .for_build = false, |
| 52 | }; |
| 53 | const clean_path = try dep.clean_path(gpa); |
| 54 | const cachepath = try std.fs.path.joinZ(gpa, &.{ cache, "zigmod", "deps" }); |
| 55 | const modpath = try std.fs.path.joinZ(gpa, &.{ cachepath, clean_path }); |
| 56 | std.log.debug("modpath: {s}", .{modpath}); |
| 57 | |
| 58 | if (!try nfs.cwd().existsDir(modpath)) { |
| 59 | try dep.type.pull(gpa, dep.path, modpath); |
| 60 | } else { |
| 61 | try dep.type.update(gpa, modpath, ""); |
| 62 | } |
| 63 | |
| 64 | const moddir = try nfs.cwd().openDir(modpath, .{}); |
| 65 | const ci = @import("./ci.zig"); |
| 66 | try ci.do(gpa, cachepath, moddir); |
| 67 | |
| 68 | const modfile = try zigmod.ModFile.from_dir(gpa, moddir, modpath); |
| 69 | const zigversion_sv = modfile.min_zig_version orelse u.fail("zigmod manifest requires min_zig_version field", .{}); |
| 70 | const zigversion = try nio.fmt.allocPrint(gpa, "{s}", .{u.altSemanticVersion(zigversion_sv)}); |
| 71 | const zigpath = try std.fs.path.joinZ(gpa, &.{ datapath, "zig", zigversion, "zig" }); |
| 72 | |
| 73 | // regen deps.zig with the repo's zig version |
| 74 | var fetch_options = common.CollectOptions{ |
| 75 | .log = true, |
| 76 | .update = false, |
| 77 | .lock = try common.parse_lockfile(gpa, moddir), |
| 78 | .alloc = gpa, |
| 79 | }; |
| 80 | const fetch_top_module = try common.collect_deps_deep(cachepath, moddir, &fetch_options); |
| 81 | var fetch_list = std.array_list.Managed(zigmod.Module).init(gpa); |
| 82 | try common.collect_pkgs(fetch_top_module, &fetch_list); |
| 83 | const V = struct { major: u32, minor: u32 }; |
| 84 | const version_sct: V = .{ .major = @intCast(zigversion_sv.major), .minor = @intCast(zigversion_sv.minor) }; |
| 85 | const version_int: u32 = (version_sct.major << 2) | version_sct.minor; |
| 86 | switch (version_int) { |
| 87 | 0x0000_000b => try @import("./fetch.0.11.zig").create_depszig(gpa, cachepath, moddir, fetch_top_module, &fetch_list), |
| 88 | 0x0000_000c => try @import("./fetch.0.12.zig").create_depszig(gpa, cachepath, moddir, fetch_top_module, &fetch_list), |
| 89 | 0x0000_000d => try @import("./fetch.0.13.zig").create_depszig(gpa, cachepath, moddir, fetch_top_module, &fetch_list), |
| 90 | 0x0000_000e => try @import("./fetch.0.14.zig").create_depszig(gpa, cachepath, moddir, fetch_top_module, &fetch_list), |
| 91 | 0x0000_000f => try @import("./fetch.0.15.zig").create_depszig(gpa, cachepath, moddir, fetch_top_module, &fetch_list), |
| 92 | 0x0000_0010 => {}, // that's us, zigmod is already 0.16.0 |
| 93 | else => u.fail("zig {d}.{d} unimplemented", .{ version_sct.major, version_sct.minor }), |
| 94 | } |
| 95 | |
| 96 | // zig build |
| 97 | const argv: []const string = &.{ |
| 98 | zigpath, "build", |
| 99 | "--prefix", try std.fs.path.join(gpa, &.{ homepath, ".zigmod" }), |
| 100 | }; |
| 101 | logargv(argv) catch return; |
| 102 | var proc = try std.process.spawn(io, .{ |
| 103 | .argv = argv, |
| 104 | .cwd = .{ .path = modpath }, |
| 105 | }); |
| 106 | const term = try proc.wait(io); |
| 107 | switch (term) { |
| 108 | .exited => |v| u.assert(v == 0, "zig build failed with exit code: {d}", .{v}), |
| 109 | .signal => |v| u.fail("zig build was stopped with signal: {d}", .{v}), |
| 110 | .stopped => |v| u.fail("zig build was stopped with code: {d}", .{v}), |
| 111 | .unknown => |v| u.fail("zig build encountered unknown: {d}", .{v}), |
| 112 | } |
| 113 | std.log.info("success!", .{}); |
| 114 | } |
| 115 | |
| 116 | // needed this after moving to zig 0.15 |
| 117 | // /zig/0.15.2/lib/std/Io/Writer.zig:1122:51: error: expected type '[]const u8', found '[]const []const u8' |
| 118 | fn logargv(argv: []const []const u8) !void { |
| 119 | const io = std.Options.debug_io; |
| 120 | const prev = io.swapCancelProtection(.blocked); |
| 121 | defer _ = io.swapCancelProtection(prev); |
| 122 | var buffer: [64]u8 = undefined; |
| 123 | const stderrterm = std.debug.lockStderr(&buffer).terminal(); |
| 124 | defer std.debug.unlockStderr(); |
| 125 | const stderr = stderrterm.writer; |
| 126 | try stderr.writeAll("debug: argv: {"); |
| 127 | for (argv, 0..) |v, i| { |
| 128 | if (i > 0) try stderr.writeAll(","); |
| 129 | try stderr.writeAll(" "); |
| 130 | try stderr.writeAll(v); |
| 131 | } |
| 132 | try stderr.writeAll(" }\n"); |
| 133 | } |