lib/sandbox/src/macos.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const builtin = @import("builtin");
3 const sys = @import("sys");
4 const audit_data = @import("audit.zig");
5 const change = @import("change.zig");
6 const copied = @import("copied.zig");
7 const plan_data = @import("plan.zig");
8 const result_data = @import("result.zig");
9
10 const Allocator = std.mem.Allocator;
11 const fs_io = sys.fs.debugIo();
12
13 pub fn available() bool {
14 return builtin.os.tag == .macos;
15 }
16
17 pub fn audit(plan: plan_data.Plan) audit_data.Audit {
18 return .{
19 .runner = .macos_staging,
20 .filesystem = .copied,
21 .process = .host,
22 .network = .inherited,
23 .environment = if (plan.environ_map == null) .inherited else .replaced,
24 };
25 }
26
27 pub fn execute(allocator: Allocator, plan: plan_data.Plan) !result_data.Result {
28 if (!available()) return error.UnsupportedRunner;
29 return try copied.execute(allocator, plan, audit(plan));
30 }
31
32 test "macos backend is unavailable away from macos" {
33 if (comptime builtin.os.tag == .macos) return error.SkipZigTest;
34
35 var scratch = std.testing.tmpDir(.{});
36 defer scratch.cleanup();
37
38 const argv = [_][]const u8{ "bash", "-c", ":" };
39 try std.testing.expectError(error.UnsupportedRunner, execute(std.testing.allocator, .{
40 .scratch = scratch.dir,
41 .argv = argv[0..],
42 .runner = .macos_staging,
43 .prefix = "macos-unavailable",
44 .max_file_bytes = 1024,
45 }));
46 }
47
48 test "macos backend keeps Plan Result contract on macos" {
49 if (comptime builtin.os.tag != .macos) return error.SkipZigTest;
50
51 var source = std.testing.tmpDir(.{});
52 defer source.cleanup();
53 var scratch = std.testing.tmpDir(.{});
54 defer scratch.cleanup();
55
56 try source.dir.writeFile(fs_io, .{ .sub_path = "a.txt", .data = "old" });
57 const argv = [_][]const u8{ "bash", "-c", "printf changed > a.txt; printf new > new.txt" };
58 var result = try execute(std.testing.allocator, .{
59 .scratch = scratch.dir,
60 .source = source.dir,
61 .argv = argv[0..],
62 .runner = .macos_staging,
63 .prefix = "macos-contract",
64 .max_file_bytes = 1024,
65 });
66 defer result.deinit();
67
68 try std.testing.expectEqual(audit_data.Runner.macos_staging, result.audit.runner);
69 try std.testing.expectEqual(audit_data.Filesystem.copied, result.audit.filesystem);
70 try std.testing.expectEqual(audit_data.Process.host, result.audit.process);
71 try std.testing.expectEqual(change.Operation.put, result.changes.find("a.txt").?.operation);
72 try std.testing.expectEqual(change.Operation.put, result.changes.find("new.txt").?.operation);
73 }