// Termux Janitor product registries layered onto the generic engine graph. const std = @import("std"); const engine = @import("engine"); const profile = @import("profile"); pub const limit_count_max = 128; pub const cli_option_count_max = 32; pub const cli_exit_status_count_max = 16; pub const android_package_count_max = 32; pub const classification_value_count_max = 128; pub const threshold_count_max = 16; pub const limits_path = "spec/model/limits.zon"; pub const cli_path = "spec/model/cli.zon"; pub const android_packages_path = "spec/model/android_packages.zon"; pub const classification_path = "spec/model/classification.zon"; pub const thresholds_path = "spec/model/thresholds.zon"; pub const package_path = "build.zig.zon"; /// The complete repository model: the generic relationship graph plus the /// product-domain registries owned by this repository alone. pub const Model = struct { graph: engine.model.Graph, limits: []const Limit, cli: Cli, android_packages: []const AndroidPackage, classification: Classification, thresholds: []const Threshold, package: Package, pub fn load(allocator: std.mem.Allocator, io: std.Io) !Model { return .{ .graph = try engine.model.Graph.load(allocator, io), .limits = try engine.model.parseFile( []const Limit, allocator, io, limits_path, ), .cli = try engine.model.parseFile( Cli, allocator, io, cli_path, ), .android_packages = try engine.model.parseFile( []const AndroidPackage, allocator, io, android_packages_path, ), .classification = try engine.model.parseFile( Classification, allocator, io, classification_path, ), .thresholds = try engine.model.parseFile( []const Threshold, allocator, io, thresholds_path, ), .package = try loadPackage(allocator, io), }; } }; /// The package manifest owns the one canonical version required by /// `spec/ARTIFACT.md`. Unknown manifest fields belong to the Zig toolchain, so /// this parse ignores them instead of duplicating the manifest schema. pub const Package = struct { version: []const u8, }; fn loadPackage(allocator: std.mem.Allocator, io: std.Io) !Package { const bytes = try std.Io.Dir.cwd().readFileAlloc( io, package_path, allocator, .limited(engine.model.file_size_max), ); const source = try allocator.dupeZ(u8, bytes); return std.zon.parse.fromSliceAlloc( Package, allocator, source, null, .{ .ignore_unknown_fields = true, .free_on_error = true }, ); } comptime { std.debug.assert(profile.suiteIsConcrete(.u)); } pub const AndroidPackage = struct { id: []const u8, revision: u32, identifier: []const u8, role: AndroidPackageRole, requirement: engine.model.RequirementReference, }; pub const AndroidPackageRole = enum { base, add_on, }; pub const Classification = struct { source_basenames: ClassificationSet, source_suffixes: ClassificationSet, document_roots: ClassificationSet, }; pub const ClassificationSet = struct { revision: u32, values: []const []const u8, requirement: engine.model.RequirementReference, }; pub const Threshold = struct { id: []const u8, revision: u32, key: []const u8, value: u64, unit: ThresholdUnit, requirement: engine.model.RequirementReference, }; pub const ThresholdUnit = enum { bytes, seconds, }; pub const Limit = struct { id: []const u8, category: LimitCategory, label: []const u8, value: LimitValue, }; pub const LimitCategory = enum { scan, process, queue, terminal, logging, }; pub const LimitValue = union(enum) { scalar: ScalarLimit, dimensions: DimensionsLimit, alternative: AlternativeLimit, }; pub const ScalarLimit = struct { value: u64, unit: LimitUnit, }; pub const DimensionsLimit = struct { columns: u16, rows: u16, }; pub const AlternativeLimit = struct { items: u32, milliseconds: u32, }; pub const LimitUnit = enum { bytes, cells, components, count, milliseconds, minutes, seconds, }; pub const Cli = struct { executable: []const u8, description: []const u8, default_mode: []const u8, long_options_only: bool, option_terminator: bool, operands_allowed: bool, duplicate_options_allowed: bool, unattended_cleanup: bool, informational_stream: OutputStream, usage_stream: OutputStream, diagnostic_stream: OutputStream, options: []const CliOption, argument_rules: []const CliArgumentRule, exit_statuses: []const CliExitStatus, }; pub const OutputStream = enum { stdout, stderr, }; pub const CliOption = struct { id: []const u8, spelling: []const u8, argument: CliArgument, summary: []const u8, must_appear_alone: bool, bypasses_startup: []const StartupSubsystem, requires_terminal: bool, }; pub const StartupSubsystem = enum { configuration, logging, terminal_initialization, scanning, }; pub const CliArgument = enum { none, path, }; pub const CliArgumentRule = struct { option: []const u8, argument: []const u8, arity: u8, syntax: ArgumentSyntax, nonempty: bool, relative_base: RelativeBase, }; pub const ArgumentSyntax = enum { separate, }; pub const RelativeBase = enum { initial_working_directory, }; pub const CliExitStatus = struct { id: []const u8, code: u8, condition: []const u8, };