//! A zig builder step that runs "docker run ..." //! This is primarily meant to do integration tests. const DockerStep = @This(); const std = @import("std"); const Step = std.build.Step; const RunStep = std.build.RunStep; pub const Options = struct { /// Container name name: []const u8, /// The name of the image to run image: []const u8, /// The ports to expose ports: []const []const u8, }; step: *Step, pub fn create(b: *std.Build, opts: Options) *DockerStep { const self = b.allocator.create(DockerStep) catch @panic("OOM"); const run_delete = remove(b, opts.name); const run_create = run: { const run = RunStep.create(b, b.fmt("docker run {s}", .{opts.name})); run.has_side_effects = true; run.addArgs(&.{ "docker", "run", "-d", "--rm", "--name", opts.name, }); for (opts.ports) |p| run.addArgs(&.{ "-p", p }); run.addArg(opts.image); break :run run; }; run_create.step.dependOn(run_delete.step); self.* = .{ .step = &run_create.step, }; return self; } pub fn remove(b: *std.Build, name: []const u8) *DockerStep { const self = b.allocator.create(DockerStep) catch @panic("OOM"); const run_delete = run: { const run = RunStep.create(b, b.fmt("docker rm {s}", .{name})); run.has_side_effects = true; run.addArgs(&.{ "docker", "rm", name, "-f" }); break :run run; }; self.* = .{ .step = &run_delete.step, }; return self; }