Skip to documentation
SLOP

tiny.smg.cli.options

Reference tiny.smg cli options

Defined in cli.

API (25)

Actions

Public operations.

Types and contracts

Public types and contracts.

Values and defaults

Public values and defaults.

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

Source

Called byCallstest; no linktools.smg.src.cli.optionstest: configured limits map human opt...cli.validationconfiguredLimitsOrRejectcli.optionsflagValuecli.optionsparseByteSizecli.optionsconfiguredLimits
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest; no linktools.smg.src.cli.optionstest: depth and relationship options ...cli.optionscouplingOnlyValue
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest; no linktools.smg.src.cli.optionstest: depth and relationship options ...cli.optionsflagValuecli.optionssignedOptionValuecli.optionsunsignedTraversalDepthcli.optionsdepthValue
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallscli.optionsconfiguredLimitscli.optionsdepthValuecli.optionshasJsoncli.optionssearchLimitValuecli.optionssignedOptionValue+14 morecli.optionsinlineOptionValuecli.optionsoptionNamecli.optionsflagValue
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerscli.optionsinlineOptionValuecli.optionsoptionNamecli.optionsflagValues
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsNo direct callscli.optionshasJsoncommand.checkruncommand.inspectionruncommand.nodeshowprivate; no linktools.smg.src.command.rules.addaddKind+2 morecli.optionshasFlag
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallscommand.checkruncommand.nodelistcommand.nodeshowcommand.searchruncommand.statusruncli.optionsflagValuecli.optionshasFlagcli.optionshasJson
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callscli.optionsflagValuecli.optionsflagValuescli.optionspositionalcli.validationoptionWithForbiddenValuecli.validationrejectMissingOptionValuescli.optionsinlineOptionValue
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callscli.optionsflagValuecli.optionsflagValuesprivate; no linktools.smg.src.cli.optionstakesValuecli.validationrejectUnexpectedOptionscli.validationrejectUnexpectedOptionsPlain+3 morecli.optionsoptionName
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callscli.optionsconfiguredLimitstest; no linktools.smg.src.cli.optionstest: byte size parser accepts binary...cli.optionsparseByteSize
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest; no linktools.smg.src.cli.optionstest: positional skips valued flagscli.validationvalidateQueryNameCommandcommand.checkruncommand.nodelistcommand.nodeshow+4 morecli.optionsinlineOptionValueprivate; no linktools.smg.src.cli.optionstakesValuecli.optionspositional
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallscommand.searchruncli.optionsflagValuecli.optionssearchLimitValue
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest; no linktools.smg.src.cli.optionstest: signed option helpers preserve ...command.nodelistcommand.usagesruncli.optionssignedOptionValuecli.optionssignedLimitValue
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallscli.optionsdepthValuecli.optionssignedLimitValuecli.optionsflagValuecli.optionssignedOptionValue
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest; no linktools.smg.src.cli.optionstest: slice and storage limits preser...command.blame.renderfileTextcommand.nodelistcommand.usagesruncli.optionsslicedLen
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest; no linktools.smg.src.cli.optionstest: slice and storage limits preser...command.nodelistcli.optionsstorageLimit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callscli.optionsdepthValuecli.optionsunsignedTraversalDepth
Static calls · unresolved targets: 0 · external targets: 0.

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

zig
const std = @import("std");const smg = @import("../root.zig");const text = smg.text;pub const max_source_file_bytes_option = "--max-source-file-bytes";pub const max_fragment_bytes_option = "--max-fragment-bytes";pub const max_git_file_list_bytes_option = "--max-git-file-list-bytes";pub const wal_recovery_limit_bytes_option = "--wal-recovery-limit-bytes";pub const byte_limit_options = [_][]const u8{    max_source_file_bytes_option,    max_fragment_bytes_option,    max_git_file_list_bytes_option,    wal_recovery_limit_bytes_option,};pub const ByteLimitFailure = struct {    option: []const u8,    value: []const u8,    reason: Reason,    pub const Reason = enum {        invalid_size,        capacity_overflow,        fragment_header,    };};pub const LimitsResult = union(enum) {    limits: smg.Limits,    invalid: ByteLimitFailure,};pub fn positional(allocator: std.mem.Allocator, args: []const []const u8) ![]const []const u8 {    var out: std.ArrayList([]const u8) = .empty;    var i: usize = 0;    while (i < args.len) : (i += 1) {        const arg = args[i];        if (std.mem.startsWith(u8, arg, "--")) {            if (takesValue(arg) and inlineOptionValue(arg) == null and i + 1 < args.len) i += 1;            continue;        }        try out.append(allocator, arg);    }    return try out.toOwnedSlice(allocator);}fn takesValue(flag: []const u8) bool {    const valued = [_][]const u8{        "--file",        "--line",        "--doc",        "--meta",        "--type",        "--rel",        "--format",        "--limit",        "--depth",        "--top",        "--module",        "--kind",        "--level",        "--since",        "--churn-days",        "--deny",        "--exclude-source",        "--invariant",        "--forall",        "--assert",        "--scope",        "--prefix",        "--sync-point",        "--tokens",        "--entry-points",        "--baseline",        "--debounce",        "--exclude",        max_source_file_bytes_option,        max_fragment_bytes_option,        max_git_file_list_bytes_option,        wal_recovery_limit_bytes_option,    };    const name = optionName(flag);    for (valued) |item| if (std.mem.eql(u8, name, item)) return true;    return false;}pub fn optionName(arg: []const u8) []const u8 {    if (!std.mem.startsWith(u8, arg, "--")) return arg;    const equals = std.mem.indexOfScalar(u8, arg, '=') orelse return arg;    return arg[0..equals];}pub fn inlineOptionValue(arg: []const u8) ?[]const u8 {    if (!std.mem.startsWith(u8, arg, "--")) return null;    const equals = std.mem.indexOfScalar(u8, arg, '=') orelse return null;    return arg[equals + 1 ..];}pub fn hasFlag(args: []const []const u8, flag: []const u8) bool {    for (args) |arg| if (std.mem.eql(u8, arg, flag)) return true;    return false;}pub fn flagValue(args: []const []const u8, flag: []const u8) ?[]const u8 {    var i: usize = 0;    while (i + 1 < args.len) : (i += 1) {        if (std.mem.eql(u8, optionName(args[i]), flag)) {            if (inlineOptionValue(args[i])) |value| return value;        }        if (std.mem.eql(u8, args[i], flag)) return args[i + 1];    }    if (args.len != 0 and std.mem.eql(u8, optionName(args[args.len - 1]), flag)) {        if (inlineOptionValue(args[args.len - 1])) |value| return value;    }    return null;}pub fn flagValues(allocator: std.mem.Allocator, args: []const []const u8, flag: []const u8) ![]const []const u8 {    var out: std.ArrayList([]const u8) = .empty;    var i: usize = 0;    while (i + 1 < args.len) : (i += 1) {        if (std.mem.eql(u8, optionName(args[i]), flag)) {            if (inlineOptionValue(args[i])) |value| {                try out.append(allocator, value);                continue;            }        }        if (std.mem.eql(u8, args[i], flag)) {            try out.append(allocator, args[i + 1]);            i += 1;        }    }    if (args.len != 0 and std.mem.eql(u8, optionName(args[args.len - 1]), flag)) {        if (inlineOptionValue(args[args.len - 1])) |value| try out.append(allocator, value);    }    return try out.toOwnedSlice(allocator);}pub fn hasJson(args: []const []const u8) bool {    return hasFlag(args, "--json") or std.mem.eql(u8, flagValue(args, "--format") orelse "", "json");}pub fn signedLimitValue(args: []const []const u8) i64 {    return signedOptionValue(args, "--limit", 20);}pub fn signedOptionValue(args: []const []const u8, option: []const u8, default: i64) i64 {    return if (flagValue(args, option)) |raw| std.fmt.parseInt(i64, raw, 10) catch default else default;}pub fn storageLimit(limit: i64) usize {    return if (limit > 0) @intCast(limit) else 0;}pub fn slicedLen(total: usize, limit: i64) usize {    if (limit == 0) return total;    if (limit > 0) return @min(total, @as(usize, @intCast(limit)));    const magnitude = if (limit == std.math.minInt(i64)) std.math.maxInt(u64) else @as(u64, @intCast(-limit));    const total_u64 = @as(u64, @intCast(total));    if (magnitude >= total_u64) return 0;    return @intCast(total_u64 - magnitude);}pub fn searchLimitValue(args: []const []const u8) i64 {    return text.parseInt(flagValue(args, "--limit") orelse "10", 10);}pub fn depthValue(args: []const []const u8) ?usize {    _ = flagValue(args, "--depth") orelse return null;    return unsignedTraversalDepth(signedOptionValue(args, "--depth", 0));}pub fn unsignedTraversalDepth(depth: i64) usize {    return if (depth > 0) @intCast(depth) else 0;}pub fn couplingOnlyValue(args: []const []const u8) bool {    var value = true;    for (args) |arg| {        if (std.mem.eql(u8, arg, "--coupling-only")) value = true;        if (std.mem.eql(u8, arg, "--all-rels")) value = false;    }    return value;}pub fn parseByteSize(raw: []const u8) error{ InvalidByteSize, CapacityOverflow }!usize {    const Unit = struct {        suffix: []const u8,        multiplier: usize,    };    const units = [_]Unit{        .{ .suffix = "GiB", .multiplier = 1024 * 1024 * 1024 },        .{ .suffix = "MiB", .multiplier = 1024 * 1024 },        .{ .suffix = "KiB", .multiplier = 1024 },        .{ .suffix = "B", .multiplier = 1 },    };    var digits = raw;    var multiplier: usize = 1;    for (units) |unit| {        if (!std.mem.endsWith(u8, raw, unit.suffix)) continue;        digits = raw[0 .. raw.len - unit.suffix.len];        multiplier = unit.multiplier;        break;    }    if (digits.len == 0) return error.InvalidByteSize;    const value = std.fmt.parseUnsigned(usize, digits, 10) catch |err| switch (err) {        error.InvalidCharacter => return error.InvalidByteSize,        error.Overflow => return error.CapacityOverflow,    };    if (value == 0) return error.InvalidByteSize;    return std.math.mul(usize, value, multiplier) catch error.CapacityOverflow;}pub fn configuredLimits(args: []const []const u8, base: smg.Limits) LimitsResult {    var limits = base;    for (byte_limit_options) |option| {        const raw = flagValue(args, option) orelse continue;        const value = parseByteSize(raw) catch |err| return .{ .invalid = .{            .option = option,            .value = raw,            .reason = switch (err) {                error.InvalidByteSize => .invalid_size,                error.CapacityOverflow => .capacity_overflow,            },        } };        if (std.mem.eql(u8, option, max_source_file_bytes_option)) {            limits.scan.max_source_file_bytes = value;        } else if (std.mem.eql(u8, option, max_fragment_bytes_option)) {            if (value <= std.crypto.hash.sha2.Sha256.digest_length) return .{ .invalid = .{                .option = option,                .value = raw,                .reason = .fragment_header,            } };            limits.scan.max_fragment_bytes = value;        } else if (std.mem.eql(u8, option, max_git_file_list_bytes_option)) {            limits.scan.max_git_file_list_bytes = value;        } else if (std.mem.eql(u8, option, wal_recovery_limit_bytes_option)) {            limits.storage.wal_recovery_limit_bytes = value;        } else unreachable;    }    _ = limits.derive() catch unreachable;    return .{ .limits = limits };}test "positional skips valued flags" {    const args = [_][]const u8{ "name", "--limit", "3", "--json", "tail", "--top", "4", "--exclude", ".zig-cache", "--module", "app", "--baseline", "1:digest" };    const pos = try positional(std.testing.allocator, &args);    defer std.testing.allocator.free(pos);    try std.testing.expectEqual(@as(usize, 2), pos.len);    try std.testing.expectEqualStrings("name", pos[0]);    try std.testing.expectEqualStrings("tail", pos[1]);}test "signed option helpers preserve click-shaped values" {    const limit = [_][]const u8{ "--limit", "-1" };    try std.testing.expectEqual(@as(i64, -1), signedLimitValue(&limit));    const inline_limit = [_][]const u8{"--limit=-2"};    try std.testing.expectEqual(@as(i64, -2), signedLimitValue(&inline_limit));    const inline_format = [_][]const u8{"--format=json"};    try std.testing.expectEqualStrings("json", flagValue(&inline_format, "--format").?);}test "slice and storage limits preserve signed semantics" {    try std.testing.expectEqual(@as(usize, 7), slicedLen(7, 0));    try std.testing.expectEqual(@as(usize, 2), slicedLen(7, 2));    try std.testing.expectEqual(@as(usize, 6), slicedLen(7, -1));    try std.testing.expectEqual(@as(usize, 0), slicedLen(7, -20));    try std.testing.expectEqual(@as(usize, 0), storageLimit(-1));    try std.testing.expectEqual(@as(usize, 4), storageLimit(4));}test "depth and relationship options preserve python semantics" {    const deps_depth = [_][]const u8{ "--depth", "-1" };    try std.testing.expectEqual(@as(?usize, 0), depthValue(&deps_depth));    const all_then_coupling = [_][]const u8{ "--all-rels", "--coupling-only" };    try std.testing.expect(couplingOnlyValue(&all_then_coupling));    const coupling_then_all = [_][]const u8{ "--coupling-only", "--all-rels" };    try std.testing.expect(!couplingOnlyValue(&coupling_then_all));}test "byte size parser accepts binary units and rejects invalid capacities" {    try std.testing.expectEqual(@as(usize, 32 * 1024 * 1024), try parseByteSize("32MiB"));    try std.testing.expectEqual(@as(usize, 4096), try parseByteSize("4KiB"));    try std.testing.expectEqual(@as(usize, 17), try parseByteSize("17"));    try std.testing.expectEqual(@as(usize, 17), try parseByteSize("17B"));    try std.testing.expectError(error.InvalidByteSize, parseByteSize("0"));    try std.testing.expectError(error.InvalidByteSize, parseByteSize("32MB"));    try std.testing.expectError(error.CapacityOverflow, parseByteSize("999999999999999999999999GiB"));}test "configured limits map human options to their owners" {    const args = [_][]const u8{        "--max-source-file-bytes=48MiB",        "--max-fragment-bytes",        "384MiB",        "--max-git-file-list-bytes=96MiB",        "--wal-recovery-limit-bytes",        "512MiB",    };    const configured = configuredLimits(&args, smg.default_limits).limits;    try std.testing.expectEqual(@as(usize, 48 * 1024 * 1024), configured.scan.max_source_file_bytes);    try std.testing.expectEqual(@as(usize, 384 * 1024 * 1024), configured.scan.max_fragment_bytes);    try std.testing.expectEqual(@as(usize, 96 * 1024 * 1024), configured.scan.max_git_file_list_bytes);    try std.testing.expectEqual(@as(usize, 512 * 1024 * 1024), configured.storage.wal_recovery_limit_bytes);}

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

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

Complete caller list for cli.options.flagValue

19 direct callers.

Complete caller list for cli.options.hasFlag

7 direct callers.

Complete caller list for cli.options.optionName

8 direct callers.

Complete caller list for cli.options.positional

9 direct callers.

Audit

Definitions26
Public names26
Members8
Version26.7.0
Revisiondaab053ee433