1const std = @import("std");
2const nio = @import("nio");
3const nfs = @import("nfs");
4const root = @import("root");
5
6const zigmod = @import("../lib.zig");
7const u = @import("./../util/funcs.zig");
8const common = @import("./../common.zig");
9
10//
11//
12
13pub fn execute(self_name: []const u8, args: []const [:0]const u8) !void {
14 _ = self_name;
15 if (!std.process.can_replace) u.fail("The target OS does not support execv", .{});
16
17 const gpa = std.heap.c_allocator;
18 const cachepath = try u.find_cachepath();
19 const dir = nfs.cwd();
20 const should_lock = args.len >= 1 and std.mem.eql(u8, args[0], "--locked");
21
22 var options = common.CollectOptions{
23 .log = false,
24 .update = false,
25 .alloc = gpa,
26 .lock = if (should_lock) try common.parse_lockfile(gpa, dir) else null,
27 };
28 const top_module = try common.collect_deps_deep(cachepath, dir, &options);
29
30 var argv = std.array_list.Managed([]const u8).init(gpa);
31 defer argv.deinit();
32
33 var seencache = std.array_list.Managed([48]u8).init(gpa);
34 defer seencache.deinit();
35
36 try argv.append(root.environ.get("ZIG") orelse "zig");
37 try argv.append("test");
38 try argv.append("--name");
39 try argv.append("test");
40 try argv.append("--test-execve"); // requires >= https://codeberg.org/ziglang/zig/pulls/30811 or 0.16
41 try argv.append("-lc");
42 try addArgv(gpa, &argv, cachepath, top_module, &seencache);
43
44 const io = root.io;
45 return std.process.replace(io, .{ .argv = argv.items });
46}
47
48fn addArgv(allocator: std.mem.Allocator, argv: *std.array_list.Managed([]const u8), cachepath: []const u8, module: zigmod.Module, seencache: *std.array_list.Managed([48]u8)) !void {
49 for (seencache.items) |item| {
50 if (std.mem.eql(u8, &module.id, &item)) {
51 return;
52 }
53 }
54 try seencache.append(module.id);
55
56 for (module.deps) |d| {
57 if (d.type == .system_lib) {
58 try argv.append(try nio.fmt.allocPrint(allocator, "-l{s}", .{d.name}));
59 continue;
60 }
61 if (d.main.len == 0) {
62 continue;
63 }
64 try argv.append("--dep");
65 try argv.append(d.name);
66 }
67 if (module.type == .system_lib or module.main.len == 0) {
68 //
69 } else if (std.mem.eql(u8, module.name, "root")) {
70 try argv.append(try nio.fmt.allocPrint(allocator, "-M{s}=test.zig", .{module.name}));
71 } else if (module.clean_path.len == 0 or std.mem.eql(u8, module.clean_path, "../..")) {
72 try argv.append(try nio.fmt.allocPrint(allocator, "-M{s}={s}", .{ module.name, module.main }));
73 } else {
74 try argv.append(try nio.fmt.allocPrint(allocator, "-M{s}={s}/{s}/{s}", .{ module.name, cachepath, module.clean_path, module.main }));
75 }
76 for (module.deps) |dep| {
77 try addArgv(allocator, argv, cachepath, dep, seencache);
78 }
79}