Skip to documentation
SLOP

tiny.smg.command.scan.text

Reference tiny.smg command scan text

Defined in command.scan.

API (1)

Actions

Public operations.

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

Source

Called byCallsprivate; no linktools.smg.src.command.scan.commandsaveAndRendertest; no linktools.smg.src.command.scan.texttest: scan text renders rich table or...private sourcelib.chant.src.profiling.versus.rowskippedcommand.scan.changedfilescommand.scan.countspartscommand.scan.countssortedcommand.scan.hintstextprivate; no linktools.smg.src.command.scan.textwriteRowscommand.scan.textrender
Static calls · unresolved targets: 3 · external targets: 2.

Source: tools/smg/src/command/scan/root.zig:8

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

Source: tools/smg/src/command/scan/text.zig

zig
const std = @import("std");const smg = @import("../../root.zig");const counts = smg.command.scan.counts;const hints = smg.command.scan.hints;const model = smg.model;const output = smg.cli.output;const scan = smg.scan;pub fn render(allocator: std.mem.Allocator, stats: scan.Stats, full: bool) ![]const u8 {    var rows: std.ArrayList(ScanTextRow) = .empty;    const languages = try counts.parts(allocator, stats.lang_counts.items);    const types = try counts.parts(allocator, stats.type_counts.items);    const node_value = if (stats.nodes_removed != 0)        try std.fmt.allocPrint(allocator, "+{d} -{d}", .{ stats.nodes_added, stats.nodes_removed })    else        types;    try rows.append(allocator, .{ .label = "Nodes", .value = node_value });    const edge_value = if (stats.edges_removed != 0)        try std.fmt.allocPrint(allocator, "+{d} -{d}", .{ stats.edges_added, stats.edges_removed })    else        try std.fmt.allocPrint(allocator, "{d}", .{stats.edges_added});    try rows.append(allocator, .{ .label = "Edges", .value = edge_value });    if (stats.skipped_edges != 0) {        try rows.append(allocator, .{ .label = "Skipped", .value = try std.fmt.allocPrint(allocator, "{d} unresolved", .{stats.skipped_edges}) });        try rows.append(allocator, .{ .label = "Skipped by kind", .value = try counts.parts(allocator, stats.skipped_edge_categories.items) });        const advice = try counts.sorted(allocator, stats.skipped_edge_categories.items);        const cap = @min(advice.len, @as(usize, 3));        for (advice[0..cap]) |item| {            try rows.append(allocator, .{                .label = try std.fmt.allocPrint(allocator, "Hint: {s}", .{item.name}),                .value = hints.text(item.name),            });        }    }    var out: std.Io.Writer.Allocating = .init(allocator);    try out.writer.print("Scanned {d} files ({s})\n", .{ stats.files, languages });    try writeRows(allocator, &out.writer, rows.items);    const total_edges = stats.edges_added + stats.skipped_edges;    if (stats.skipped_edges > 0 and total_edges > 0 and stats.skipped_edges * 2 > total_edges) {        try out.writer.print("\nHint: {d}/{d} edges were skipped (targets outside the scanned scope). Try scanning a wider directory to resolve cross-module edges.\n", .{ stats.skipped_edges, total_edges });    }    if (full and stats.skipped_edge_samples.items.len != 0) {        try out.writer.writeAll("Skipped edge examples:\n");        const cap = @min(stats.skipped_edge_samples.items.len, @as(usize, 5));        for (stats.skipped_edge_samples.items[0..cap]) |sample| {            try out.writer.print("  {s} --{s}--> {s} ({s}: {s})\n", .{ sample.source, sample.rel, sample.target, sample.category, sample.reason });        }    } else if (stats.skipped_edge_samples.items.len != 0) {        try out.writer.writeAll("Skipped edge examples hidden; use --full to show samples.\n");    }    if (full and stats.orphaned_manual_edges.items.len != 0) {        try out.writer.print("\nWarning: {d} manual edge(s) orphaned:\n", .{stats.orphaned_manual_edges.items.len});        for (stats.orphaned_manual_edges.items) |edge| {            try out.writer.print("  {s} --{s}--> {s} ({s})\n", .{ edge.source, edge.rel, edge.target, edge.reason });        }    }    return try out.toOwnedSlice();}const ScanTextRow = struct {    label: []const u8,    value: []const u8,};fn writeRows(allocator: std.mem.Allocator, writer: *std.Io.Writer, rows: []const ScanTextRow) !void {    var label_width: usize = 0;    for (rows) |row| label_width = @max(label_width, row.label.len);    const value_width = if (label_width + 2 >= 80) @as(usize, 1) else 80 - label_width - 2;    for (rows) |row| try writeRow(allocator, writer, row, label_width, value_width);}fn writeRow(allocator: std.mem.Allocator, writer: *std.Io.Writer, row: ScanTextRow, label_width: usize, value_width: usize) !void {    var rest = row.value;    var first = true;    while (first or rest.len != 0) {        const chunk_len = wrapLength(rest, value_width);        var line: std.Io.Writer.Allocating = .init(allocator);        if (first) {            try output.writeDocText(&line.writer, row.label);            try output.writeSpacesDoc(&line.writer, label_width -| row.label.len);        } else {            try output.writeSpacesDoc(&line.writer, label_width);        }        try output.writeDocText(&line.writer, "  ");        try output.writeDocText(&line.writer, rest[0..chunk_len]);        try output.writeSpacesDoc(&line.writer, 80 -| line.written().len);        try writeTrimmedLine(writer, line.written());        rest = rest[chunk_len..];        while (rest.len != 0 and rest[0] == ' ') rest = rest[1..];        first = false;    }}fn wrapLength(value: []const u8, width: usize) usize {    if (value.len <= width) return value.len;    var index = width;    while (index > 0) : (index -= 1) {        if (value[index] == ' ') return index;    }    return width;}fn writeTrimmedLine(writer: *std.Io.Writer, line: []const u8) !void {    var end = line.len;    while (end > 0 and line[end - 1] == ' ') end -= 1;    try output.writeDocText(writer, line[0..end]);    try output.writeDocHardline(writer);}test "scan text renders rich table oracle shape" {    var arena = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena.deinit();    const allocator = arena.allocator();    var stats = scan.Stats{        .files = 1,        .nodes_added = 4,        .nodes_removed = 4,        .edges_added = 4,        .skipped_edges = 1,    };    try stats.lang_counts.append(allocator, .{ .name = "Python", .count = 1 });    try stats.skipped_edge_categories.append(allocator, .{ .name = "external_or_generated", .count = 1 });    try stats.skipped_edge_samples.append(allocator, .{        .source = "app",        .rel = model.RelType.imports,        .target = "os",        .reason = "unresolved target",        .category = "external_or_generated",    });    const rendered = try render(allocator, stats, false);    try std.testing.expectEqualStrings(        \\Scanned 1 files (1 Python)        \\Nodes                        +4 -4        \\Edges                        4        \\Skipped                      1 unresolved        \\Skipped by kind              1 external_or_generated        \\Hint: external_or_generated  External or generated dependency; widen scan scope        \\                             only if this target is first-party code.        \\Skipped edge examples hidden; use --full to show samples.        \\    , rendered);}

Audit

Definitions2
Public names3
Members0
Version26.7.0
Revisiondaab053ee433