Add named local build variants

This commit is contained in:
slhx agent
2026-06-21 05:19:56 +02:00
parent fb68747848
commit b10cb8fdc4
3 changed files with 108 additions and 19 deletions
+90 -12
View File
@@ -1,21 +1,84 @@
const std = @import("std"); const std = @import("std");
const Profile = struct {
name: []const u8,
exe_name: []const u8,
local_socket: bool,
remote_transport: bool,
plugin_host: bool,
bundled_pi: bool,
background_agent: bool,
tool_mutation: []const u8,
};
pub fn build(b: *std.Build) void { pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{}); const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{}); const optimize = b.standardOptimizeOption(.{});
const mod = b.createModule(.{ const profiles = [_]Profile{
.root_source_file = b.path("src/main.zig"), .{
.target = target, .name = "dev-local",
.optimize = optimize, .exe_name = "mim",
}); .local_socket = true,
.remote_transport = false,
.plugin_host = false,
.bundled_pi = false,
.background_agent = false,
.tool_mutation = "protocol_logged",
},
.{
.name = "minimal",
.exe_name = "mim-min",
.local_socket = false,
.remote_transport = false,
.plugin_host = false,
.bundled_pi = false,
.background_agent = false,
.tool_mutation = "not_built",
},
.{
.name = "coding",
.exe_name = "mim-code",
.local_socket = true,
.remote_transport = false,
.plugin_host = false,
.bundled_pi = false,
.background_agent = false,
.tool_mutation = "protocol_logged",
},
.{
.name = "full-local",
.exe_name = "mim-full",
.local_socket = true,
.remote_transport = false,
.plugin_host = false,
.bundled_pi = false,
.background_agent = false,
.tool_mutation = "protocol_logged",
},
};
const main_mod = profileModule(b, target, optimize, profiles[0]);
const exe = b.addExecutable(.{ const exe = b.addExecutable(.{
.name = "mim", .name = profiles[0].exe_name,
.root_module = mod, .root_module = main_mod,
}); });
b.installArtifact(exe); b.installArtifact(exe);
inline for (profiles[1..]) |profile| {
const profile_exe = b.addExecutable(.{
.name = profile.exe_name,
.root_module = profileModule(b, target, optimize, profile),
});
b.installArtifact(profile_exe);
const run_profile = b.addRunArtifact(profile_exe);
run_profile.step.dependOn(b.getInstallStep());
if (b.args) |args| run_profile.addArgs(args);
const step_name = if (std.mem.eql(u8, profile.exe_name, "mim-min")) "run-min" else if (std.mem.eql(u8, profile.exe_name, "mim-code")) "run-code" else "run-full";
const run_profile_step = b.step(step_name, "Run profile variant");
run_profile_step.dependOn(&run_profile.step);
}
const run_cmd = b.addRunArtifact(exe); const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep()); run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| { if (b.args) |args| {
@@ -25,13 +88,28 @@ pub fn build(b: *std.Build) void {
run_step.dependOn(&run_cmd.step); run_step.dependOn(&run_cmd.step);
const tests = b.addTest(.{ const tests = b.addTest(.{
.root_module = b.createModule(.{ .root_module = profileModule(b, target, optimize, profiles[0]),
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
}),
}); });
const test_cmd = b.addRunArtifact(tests); const test_cmd = b.addRunArtifact(tests);
const test_step = b.step("test", "Run unit tests"); const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&test_cmd.step); test_step.dependOn(&test_cmd.step);
} }
fn profileModule(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, profile: Profile) *std.Build.Module {
const options = b.addOptions();
options.addOption([]const u8, "active_profile", profile.name);
options.addOption(bool, "local_socket", profile.local_socket);
options.addOption(bool, "remote_transport_built", profile.remote_transport);
options.addOption(bool, "plugin_host_built", profile.plugin_host);
options.addOption(bool, "bundled_pi_built", profile.bundled_pi);
options.addOption(bool, "background_agent_built", profile.background_agent);
options.addOption([]const u8, "tool_mutation", profile.tool_mutation);
const mod = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
mod.addOptions("build_options", options);
return mod;
}
+10
View File
@@ -82,6 +82,10 @@ pub fn main(init: std.process.Init) !u8 {
return 69; return 69;
} }
if (std.mem.eql(u8, arg, "mimctl")) { if (std.mem.eql(u8, arg, "mimctl")) {
if (!profile.local_socket) {
try printProfileStub(init.io, stderr, "mimctl");
return 69;
}
const sub = args.next() orelse { const sub = args.next() orelse {
try stderr.writeStreamingAll(init.io, "mim: mimctl requires a subcommand\n"); try stderr.writeStreamingAll(init.io, "mim: mimctl requires a subcommand\n");
return 64; return 64;
@@ -101,6 +105,10 @@ pub fn main(init: std.process.Init) !u8 {
} }
if (std.mem.eql(u8, arg, "--mimctl")) { if (std.mem.eql(u8, arg, "--mimctl")) {
if (!profile.local_socket) {
try printProfileStub(init.io, stderr, "mimctl");
return 69;
}
const socket_path = args.next() orelse { const socket_path = args.next() orelse {
try stderr.writeStreamingAll(init.io, "mim: --mimctl requires a socket path\n"); try stderr.writeStreamingAll(init.io, "mim: --mimctl requires a socket path\n");
return 64; return 64;
@@ -152,6 +160,7 @@ fn printProfile(allocator: std.mem.Allocator, io: std.Io, stdout: std.Io.File) !
fn isProfileStub(arg: []const u8) bool { fn isProfileStub(arg: []const u8) bool {
return std.mem.eql(u8, arg, "remote") or return std.mem.eql(u8, arg, "remote") or
std.mem.eql(u8, arg, "mimctl") or
std.mem.eql(u8, arg, "plugin") or std.mem.eql(u8, arg, "plugin") or
std.mem.eql(u8, arg, "plugins") or std.mem.eql(u8, arg, "plugins") or
std.mem.eql(u8, arg, "background-agent") or std.mem.eql(u8, arg, "background-agent") or
@@ -243,6 +252,7 @@ test "regular: help text names the binary and smoke boundary" {
test "regular: excluded profile capabilities have explicit stubs" { test "regular: excluded profile capabilities have explicit stubs" {
try std.testing.expect(isProfileStub("remote")); try std.testing.expect(isProfileStub("remote"));
try std.testing.expect(isProfileStub("mimctl"));
try std.testing.expect(isProfileStub("plugin")); try std.testing.expect(isProfileStub("plugin"));
try std.testing.expect(isProfileStub("background-agent")); try std.testing.expect(isProfileStub("background-agent"));
try std.testing.expect(!isProfileStub("context")); try std.testing.expect(!isProfileStub("context"));
+8 -7
View File
@@ -1,4 +1,5 @@
const std = @import("std"); const std = @import("std");
const build_options = @import("build_options");
// Explicit v1 build/profile fences. // Explicit v1 build/profile fences.
// req: governance/002, governance/003, testing/001, testing/002 // req: governance/002, governance/003, testing/001, testing/002
@@ -7,12 +8,12 @@ test {
_ = statusAlloc; _ = statusAlloc;
} }
pub const active_profile = "dev-local"; pub const active_profile = build_options.active_profile;
pub const local_socket = true; pub const local_socket = build_options.local_socket;
pub const remote_transport_built = false; pub const remote_transport_built = build_options.remote_transport_built;
pub const plugin_host_built = false; pub const plugin_host_built = build_options.plugin_host_built;
pub const bundled_pi_built = false; pub const bundled_pi_built = build_options.bundled_pi_built;
pub const background_agent_built = false; pub const background_agent_built = build_options.background_agent_built;
pub fn statusAlloc(allocator: std.mem.Allocator) ![]u8 { pub fn statusAlloc(allocator: std.mem.Allocator) ![]u8 {
var out = std.ArrayList(u8).empty; var out = std.ArrayList(u8).empty;
@@ -24,7 +25,7 @@ pub fn statusAlloc(allocator: std.mem.Allocator) ![]u8 {
try appendKV(allocator, &out, "plugin_host", if (plugin_host_built) "built" else "not_built"); try appendKV(allocator, &out, "plugin_host", if (plugin_host_built) "built" else "not_built");
try appendKV(allocator, &out, "bundled_pi", if (bundled_pi_built) "built" else "not_built"); try appendKV(allocator, &out, "bundled_pi", if (bundled_pi_built) "built" else "not_built");
try appendKV(allocator, &out, "background_agent", if (background_agent_built) "built" else "not_built"); try appendKV(allocator, &out, "background_agent", if (background_agent_built) "built" else "not_built");
try appendKV(allocator, &out, "tool_mutation", "protocol_logged"); try appendKV(allocator, &out, "tool_mutation", build_options.tool_mutation);
return out.toOwnedSlice(allocator); return out.toOwnedSlice(allocator);
} }