lib/sandbox/src/windows.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 == .windows;
15 }
16 
17 pub fn audit(plan: plan_data.Plan) audit_data.Audit {
18     return .{
19         .runner = .windows_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 "windows backend is unavailable away from windows" {
33     if (comptime builtin.os.tag == .windows) 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 = .windows_staging,
43         .prefix = "windows-unavailable",
44         .max_file_bytes = 1024,
45     }));
46 }
47 
48 test "windows backend keeps Plan Result contract on windows" {
49     if (comptime builtin.os.tag != .windows) 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{ "cmd.exe", "/C", "type a.txt > copy.txt" };
58     var result = try execute(std.testing.allocator, .{
59         .scratch = scratch.dir,
60         .source = source.dir,
61         .argv = argv[0..],
62         .runner = .windows_staging,
63         .prefix = "windows-contract",
64         .max_file_bytes = 1024,
65     });
66     defer result.deinit();
67 
68     try std.testing.expectEqual(audit_data.Runner.windows_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("copy.txt").?.operation);
72 }