Skip to documentation
SLOP

tiny.smg.cli.dispatch

Reference tiny.smg cli dispatch

Defined in cli.

API (3)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callsclidispatch
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callstest; no linktools.smg.src.cli.dispatchtest: diagnosed resolver errors exit ...cli.dispatchdiagnosedErrorExitCode
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersprivate; no linktools.smg.src.cli.dispatchcommandEntryprivate; no linktools.smg.src.cli.dispatchrunCommandprivate; no linktools.smg.src.cli.dispatchwriteCommandHelpprivate; no linktools.smg.src.cli.dispatchwriteVersioncli.dispatchrun
Static calls · unresolved targets: 0 · external targets: 5.

Source: tools/smg/src/cli/dispatch.zig

zig
const std = @import("std");const pretty_usage = @import("pretty_usage");const smg = @import("../root.zig");const cli_about = smg.command.about;const cli_analyze = smg.command.analyze;const cli_batch = smg.command.batch;const cli_between = smg.command.between;const cli_blame = smg.command.blame;const cli_calls = smg.command.calls;const cli_check = smg.command.check;const cli_concepts = smg.command.concepts;const cli_context = smg.command.context;const cli_diff = smg.command.diff;const cli_exports = smg.command.exports;const cli_impact = smg.command.impact;const cli_init = smg.command.init;const cli_mutate = smg.command.mutate;const cli_node = smg.command.node;const cli_output = smg.cli.output;const cli_options = smg.cli.options;const cli_query = smg.command.query;const cli_rules = smg.command.rules;const cli_scan = smg.command.scan;const cli_search = smg.command.search;const cli_session = smg.command.session;const cli_status = smg.command.status;const cli_usages = smg.command.usages;const cli_validate = smg.command.validate;const cli_watch = smg.command.watch;const help_data = @import("../help/root.zig");const click_help = help_data.click;const help = help_data.help;const CommandRun = *const fn (std.mem.Allocator, std.mem.Allocator, []const []const u8, smg.Limits) anyerror!u8;const PhasedCommandRun = *const fn (std.mem.Allocator, std.mem.Allocator, []const []const u8, smg.Limits, cli_session.PhaseBoundary) anyerror!u8;const BatchCommandRun = *const fn (std.mem.Allocator, std.mem.Allocator, []const []const u8, smg.Limits) anyerror!u8;const CommandAction = union(enum) {    regular: CommandRun,    phased: PhasedCommandRun,    batch: BatchCommandRun,};pub const Build = struct {    version: []const u8,};pub fn diagnosedErrorExitCode(err: anyerror) ?u8 {    if (err == error.NodeNotFound or err == error.AmbiguousName) return 1;    return null;}const EmptyHelp = enum {    none,    query,    export_root,    concept,};const Command = struct {    name: []const u8,    action: CommandAction,    empty_help: EmptyHelp = .none,};const commands = [_]Command{    .{ .name = "init", .action = .{ .regular = cli_init.run } },    .{ .name = "scan", .action = .{ .regular = cli_scan.run } },    .{ .name = "add", .action = .{ .regular = cli_mutate.add } },    .{ .name = "link", .action = .{ .regular = cli_mutate.link } },    .{ .name = "rm", .action = .{ .regular = cli_mutate.remove } },    .{ .name = "unlink", .action = .{ .regular = cli_mutate.unlink } },    .{ .name = "update", .action = .{ .regular = cli_mutate.update } },    .{ .name = "status", .action = .{ .phased = cli_status.run } },    .{ .name = "list", .action = .{ .phased = cli_node.list } },    .{ .name = "show", .action = .{ .phased = cli_node.show } },    .{ .name = "about", .action = .{ .phased = cli_about.run } },    .{ .name = "calls", .action = .{ .phased = cli_calls.run } },    .{ .name = "usages", .action = .{ .phased = cli_usages.run } },    .{ .name = "impact", .action = .{ .phased = cli_impact.run } },    .{ .name = "between", .action = .{ .phased = cli_between.run } },    .{ .name = "query", .action = .{ .phased = cli_query.run }, .empty_help = .query },    .{ .name = "export", .action = .{ .phased = cli_exports.run }, .empty_help = .export_root },    .{ .name = "analyze", .action = .{ .phased = cli_analyze.run } },    .{ .name = "overview", .action = .{ .phased = cli_analyze.overview } },    .{ .name = "search", .action = .{ .phased = cli_search.run } },    .{ .name = "index", .action = .{ .regular = cli_search.index } },    .{ .name = "validate", .action = .{ .phased = cli_validate.run } },    .{ .name = "rule", .action = .{ .phased = cli_rules.run } },    .{ .name = "check", .action = .{ .phased = cli_check.command.run } },    .{ .name = "refresh-check", .action = .{ .regular = cli_check.refresh.run } },    .{ .name = "concept", .action = .{ .phased = cli_concepts.run }, .empty_help = .concept },    .{ .name = "context", .action = .{ .phased = cli_context.run } },    .{ .name = "blame", .action = .{ .phased = cli_blame.run } },    .{ .name = "diff", .action = .{ .phased = cli_diff.run } },    .{ .name = "watch", .action = .{ .regular = cli_watch.run } },    .{ .name = "batch", .action = .{ .batch = cli_batch.run } },};pub fn run(    allocator: std.mem.Allocator,    phases: std.mem.Allocator,    args: []const []const u8,    command_name: []const u8,    build: Build,    limits: smg.Limits,    boundary: cli_session.PhaseBoundary,) !u8 {    if (args.len < 1) {        try click_help.writeRoot(allocator, command_name);        return 2;    }    if (std.mem.eql(u8, args[0], "--help")) {        try click_help.writeRoot(allocator, command_name);        return 0;    }    if (std.mem.eql(u8, args[0], "--version")) return try writeVersion(allocator, args, command_name, build.version);    if (std.mem.startsWith(u8, args[0], "-")) {        try cli_output.writeRootUsageError(allocator, command_name, try std.fmt.allocPrint(allocator, "No such option: {s}", .{cli_options.optionName(args[0])}));        return 2;    }    const command = args[0];    const rest = args[1..];    const entry = commandEntry(command) orelse {        try cli_output.writeRootUsageError(allocator, command_name, try std.fmt.allocPrint(allocator, "No such command '{s}'.", .{command}));        return 2;    };    if (click_help.hasLongArg(rest)) {        if (try click_help.writeForCommandPath(allocator, args)) |code| return code;        return try writeCommandHelp(allocator, args);    }    return try runCommand(        allocator,        phases,        entry,        rest,        limits,        boundary,    );}fn commandEntry(command: []const u8) ?Command {    for (commands) |entry| if (std.mem.eql(u8, entry.name, command)) return entry;    return null;}fn runCommand(    allocator: std.mem.Allocator,    phases: std.mem.Allocator,    command: Command,    args: []const []const u8,    limits: smg.Limits,    boundary: cli_session.PhaseBoundary,) !u8 {    if (args.len == 0) {        if (try writeEmptyHelp(allocator, command.empty_help)) |code| return code;    }    return switch (command.action) {        .regular => |run_regular| try run_regular(allocator, phases, args, limits),        .phased => |run_phased| try run_phased(allocator, phases, args, limits, boundary),        .batch => |run_batch| try run_batch(allocator, phases, args, limits),    };}fn writeEmptyHelp(allocator: std.mem.Allocator, empty_help: EmptyHelp) !?u8 {    switch (empty_help) {        .none => return null,        .query => try click_help.writeQueryRoot(allocator),        .export_root => try click_help.writeExportRoot(allocator),        .concept => try click_help.writeConceptRoot(allocator),    }    return 2;}fn writeVersion(allocator: std.mem.Allocator, args: []const []const u8, command_name: []const u8, version: []const u8) !u8 {    for (args[1..]) |arg| {        if (!std.mem.startsWith(u8, arg, "-")) break;        if (std.mem.eql(u8, arg, "--help")) continue;        try cli_output.writeRootUsageError(allocator, command_name, try std.fmt.allocPrint(allocator, "No such option: {s}", .{cli_options.optionName(arg)}));        return 2;    }    return try cli_output.writeOutFmt(allocator, "smg, version {s}\n", .{version});}fn writeCommandHelp(allocator: std.mem.Allocator, args: []const []const u8) !u8 {    var stdout_buffer: [8192]u8 = undefined;    var stdout_writer = std.Io.File.stdout().writer(std.Options.debug_io, &stdout_buffer);    defer stdout_writer.interface.flush() catch {};    var stderr_buffer: [8192]u8 = undefined;    var stderr_writer = std.Io.File.stderr().writer(std.Options.debug_io, &stderr_buffer);    defer stderr_writer.interface.flush() catch {};    return try pretty_usage.writeCommandPathHelpOrError(        allocator,        &stdout_writer.interface,        &stderr_writer.interface,        help,        args,        .{            .layout = .{ .width = 88 },            .suggestions = .{ .enabled = true },            .parent_fallback_help = true,        },    );}test "top usage includes historical python command surface" {    const rendered = try pretty_usage.renderHelpAlloc(std.testing.allocator, help, .{ .layout = .{ .width = 120 } });    defer std.testing.allocator.free(rendered);    for ([_][]const u8{        "calls NAME",        "diff [REF]",        "context NAME",        "blame NAME",        "index",        "batch",    }) |needle| {        try std.testing.expect(std.mem.indexOf(u8, rendered, needle) != null);    }}test "diagnosed resolver errors exit without process label" {    try std.testing.expectEqual(        @as(?u8, 1),        diagnosedErrorExitCode(error.NodeNotFound),    );    try std.testing.expectEqual(        @as(?u8, 1),        diagnosedErrorExitCode(error.AmbiguousName),    );    try std.testing.expect(        diagnosedErrorExitCode(error.MissingArgument) == null,    );}test "command usage resolves before project loading" {    const diff_detail = help.commandHelp("diff").?;    const diff_rendered = try pretty_usage.renderHelpAlloc(std.testing.allocator, diff_detail.*, .{ .layout = .{ .width = 120 } });    defer std.testing.allocator.free(diff_rendered);    try std.testing.expect(std.mem.indexOf(u8, diff_rendered, "usage: smg diff [REF] [--json]") != null);    try std.testing.expect(std.mem.indexOf(u8, diff_rendered, "Compare the current graph against a git ref.") != null);    const batch_detail = help.commandHelp("batch").?;    const batch_rendered = try pretty_usage.renderHelpAlloc(std.testing.allocator, batch_detail.*, .{ .layout = .{ .width = 120 } });    defer std.testing.allocator.free(batch_rendered);    try std.testing.expect(std.mem.indexOf(u8, batch_rendered, "usage: smg batch [--format text|json]") != null);    try std.testing.expect(std.mem.indexOf(u8, batch_rendered, "Execute JSONL graph mutations from stdin.") != null);    try std.testing.expect(std.mem.indexOf(u8, batch_rendered, "Read up to 64 MiB inclusive from stdin.") != null);    try std.testing.expect(help.commandHelp("unknown") == null);}test "scan usage omits removed jobs option" {    const scan_detail = help.commandHelp("scan").?;    const scan_rendered = try pretty_usage.renderHelpAlloc(        std.testing.allocator,        scan_detail.*,        .{ .layout = .{ .width = 120 } },    );    defer std.testing.allocator.free(scan_rendered);    try std.testing.expect(std.mem.indexOf(u8, scan_rendered, "--jobs") == null);}test "one-shot queries and mutations have distinct phase actions" {    for ([_][]const u8{        "status",        "list",        "show",        "about",        "calls",        "usages",        "impact",        "between",        "query",        "export",        "analyze",        "overview",        "search",        "validate",        "rule",        "check",        "concept",        "context",        "blame",        "diff",    }) |name| {        const entry = commandEntry(name).?;        try std.testing.expectEqual(@as(std.meta.Tag(CommandAction), .phased), std.meta.activeTag(entry.action));    }    for ([_][]const u8{        "init",        "scan",        "add",        "link",        "rm",        "unlink",        "update",        "index",        "refresh-check",        "watch",    }) |name| {        const entry = commandEntry(name).?;        try std.testing.expectEqual(@as(std.meta.Tag(CommandAction), .regular), std.meta.activeTag(entry.action));    }}test "batch is the sole SMG command action with input storage" {    comptime {        @stardustClaim(            @import("alloc_phase").capacity.witness(@import("../batch/input/root.zig").Storage, "smg_batch_input_cli_composition"),            null,            null,            null,            null,            null,            null,        );    }    for (commands) |entry| {        try std.testing.expectEqual(            std.mem.eql(u8, entry.name, "batch"),            std.meta.activeTag(entry.action) == .batch,        );    }}

Source: tools/smg/src/cli/root.zig:1

zig
pub const dispatch = @import("dispatch.zig");

Audit

Definitions4
Public names4
Members1
Version26.7.0
Revisiondaab053ee433