const std = @import("std"); /// Build-plan types for the `manifest.rg` project file (Phase 3 of the v2 /// toolchain). A manifest is a RinneScript source that drives the `std.build` /// VM namespace; the recognized calls accumulate here and main.zig consumes /// the plan to make `rinne run/build/check` project-aware. /// /// All strings and lists live in the caller's arena; `BuildPlan.create` must /// be fed that arena's allocator. pub const MAX_TARGETS: usize = 8; pub const BuildTarget = struct { name: []const u8, source: ?[]const u8 = null, native: bool = false, opt: []const u8 = "2", link_libs: std.ArrayListUnmanaged([]const u8) = .empty, lib_dirs: std.ArrayListUnmanaged([]const u8) = .empty, }; pub const UseRow = struct { /// Import namespace the package is exposed under in the target source /// (`std.build.use(pkg, src, .{ .as = "ray" })` -> `ray.draw_sprite(...)`). ns: []const u8, /// Local module path (relative to the manifest dir) or fetch-record name. module: []const u8, /// When the input was a fetched package, the fetch record's name. package_name: ?[]const u8 = null, }; pub const FetchRow = struct { /// Plain URL sugar: fetch("https://.../x.rg"). url: ?[]const u8 = null, /// Git transport: fetch(.{ .git = "...", .git_tag = "v1.0.0" }). git: ?[]const u8 = null, git_ref: ?[]const u8 = null, }; pub const IncludeRow = struct { name: []const u8, path: []const u8, }; /// A typed option declared by `std.build.option(name, type, default)`. Options /// are read from CLI arguments (`--name=value`) and injected as constants into /// the target source. pub const OptionDecl = struct { name: []const u8, opt_type: []const u8, // "str", "int", "float", "bool" default: []const u8, // rendered string form of the default value }; /// An overlay registered by `std.build.overlay(name, fn)`: a post-processing /// function in manifest.rg that receives the resolved module and may rewrite /// its top-level declarations. pub const OverlayFn = struct { name: []const u8, fn_name: []const u8, }; pub const BuildPlan = struct { allocator: std.mem.Allocator, targets: std.ArrayListUnmanaged(BuildTarget) = .empty, uses: std.ArrayListUnmanaged(UseRow) = .empty, fetches: std.ArrayListUnmanaged(FetchRow) = .empty, includes: std.ArrayListUnmanaged(IncludeRow) = .empty, include_aliases: std.ArrayListUnmanaged(IncludeRow) = .empty, options: std.ArrayListUnmanaged(OptionDecl) = .empty, imports: std.ArrayListUnmanaged([]const u8) = .empty, overlays: std.ArrayListUnmanaged(OverlayFn) = .empty, auto_target: ?bool = null, target_arch: ?[]const u8 = null, locked: bool = false, pub fn create(allocator: std.mem.Allocator) !*BuildPlan { const p = try allocator.create(BuildPlan); p.* = .{ .allocator = allocator }; return p; } /// The default build target: the first one registered, preferring one /// named "app". pub fn primary(self: *const BuildPlan) ?*const BuildTarget { if (self.targets.items.len == 0) return null; for (self.targets.items) |*t| { if (std.mem.eql(u8, t.name, "app")) return t; } return &self.targets.items[0]; } /// Resolve a fetch-record target index back to its row (used by `use`). pub fn fetchBy(self: *const BuildPlan, idx: usize) ?*const FetchRow { if (idx >= self.fetches.items.len) return null; return &self.fetches.items[idx]; } };