tiny.smg.command.status
Defined in command.
API (3)
Actions
Public operations.
Source
Source: tools/smg/src/command/root.zig:22
zig
pub const status = @import("status.zig");Source: tools/smg/src/command/status.zig
zig
const std = @import("std");const pretty_json = @import("pretty").json;const smg = @import("../root.zig");const options = smg.cli.options;const output = smg.cli.output;const session = smg.command.session;const storage = smg.storage;const table = smg.cli.table;const validation = smg.cli.validation;pub fn run(allocator: std.mem.Allocator, _: std.mem.Allocator, args: []const []const u8, limits: smg.Limits, boundary: session.PhaseBoundary) !u8 { if (try validation.rejectMissingOptionValues(allocator, args, &.{"--format"})) return 2; if (try validation.rejectUnexpectedOptionsPlain(allocator, "status", "[OPTIONS]", args, &.{ "--format", "--json", "--full" })) return 2; if (try validation.rejectInvalidChoiceOption(allocator, "status", "[OPTIONS]", args, "--format", &.{ "text", "json" })) return 2; const pos = try options.positional(allocator, args); if (pos.len != 0) { try output.writeClickUsageError(allocator, "status", "[OPTIONS]", try validation.unexpectedArgumentMessage(allocator, pos)); return 2; } const root = try storage.requireRoot(allocator); try session.noteGraphAge(allocator, root); const graph_summary = try storage.summary.load(allocator, root, limits.storage); boundary.seal(); defer boundary.beginTeardown(); if (options.hasJson(args)) return try output.writeOut(try renderJson(allocator, graph_summary)); var out: std.Io.Writer.Allocating = .init(allocator); try writeText(allocator, &out.writer, graph_summary); return try output.writeOut(out.written());}pub fn renderJson(allocator: std.mem.Allocator, graph_summary: storage.summary.Graph) ![]const u8 { var out: std.Io.Writer.Allocating = .init(allocator); errdefer out.deinit(); var writer = pretty_json.Writer.init(&out.writer, .minified); try writer.beginObject(); try writer.objectField("nodes"); try writer.write(graph_summary.nodes); try writer.objectField("edges"); try writer.write(graph_summary.edges); try writer.objectField("node_types"); try countJson(&writer, graph_summary.node_types); try writer.objectField("rel_types"); try countJson(&writer, graph_summary.rel_types); try writer.endObject(); try out.writer.writeByte('\n'); return try out.toOwnedSlice();}pub fn writeText(allocator: std.mem.Allocator, writer: *std.Io.Writer, graph_summary: storage.summary.Graph) !void { try writer.print("Nodes ({d})\n", .{graph_summary.nodes}); try countText(allocator, writer, graph_summary.node_types, "type"); try writer.print("\nEdges ({d})\n", .{graph_summary.edges}); try countText(allocator, writer, graph_summary.rel_types, "relationship");}fn countJson(writer: *pretty_json.Writer, counts: []const storage.summary.Count) !void { try writer.beginObject(); for (counts) |item| { try writer.objectField(item.name); try writer.write(item.count); } try writer.endObject();}fn countText(allocator: std.mem.Allocator, writer: *std.Io.Writer, counts: []const storage.summary.Count, header: []const u8) !void { const sorted = try allocator.dupe(storage.summary.Count, counts); std.mem.sort(storage.summary.Count, sorted, {}, countRowLess); try writeStatusCountTable(allocator, writer, sorted, header);}fn countRowLess(_: void, a: storage.summary.Count, b: storage.summary.Count) bool { return std.mem.lessThan(u8, a.name, b.name);}fn writeStatusCountTable(allocator: std.mem.Allocator, writer: *std.Io.Writer, count_rows: []const storage.summary.Count, name_header: []const u8) !void { const columns = [_]table.Column{ .{ .header = name_header, .max_width = 40 }, .{ .header = "count", .alignment = .right, .max_width = 12 }, }; var scratch_state = std.heap.ArenaAllocator.init(allocator); defer scratch_state.deinit(); const scratch = scratch_state.allocator(); var rows: std.ArrayList([]const []const u8) = .empty; for (count_rows) |row| { try table.appendRow(scratch, &rows, &.{ row.name, try std.fmt.allocPrint(scratch, "{d}", .{row.count}), }); } try table.write(allocator, writer, &columns, rows.items, null);}test "status count table matches compact oracle shape" { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const allocator = arena.allocator(); const counts = [_]storage.summary.Count{ .{ .name = "function", .count = 2, .first = "app.helper" }, .{ .name = "module", .count = 1, .first = "app" }, .{ .name = "class", .count = 1, .first = "app.Engine" }, }; var out: std.Io.Writer.Allocating = .init(allocator); try countText(allocator, &out.writer, &counts, "type"); try std.testing.expectEqualStrings( \\type count \\-------- ----- \\class 1 \\function 2 \\module 1 \\ , out.written());}test "status json counts preserve graph traversal order" { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const allocator = arena.allocator(); const graph_summary = storage.summary.Graph{ .nodes = 4, .edges = 3, .node_types = &.{ .{ .name = "module", .count = 2, .first = "app" }, .{ .name = "function", .count = 2, .first = "app.main" }, }, .rel_types = &.{ .{ .name = "contains", .count = 2, .first = "app\x00contains\x00app.main" }, .{ .name = "calls", .count = 1, .first = "app.main\x00calls\x00lib.util" }, }, }; try std.testing.expectEqualStrings( \\{"nodes":4,"edges":3,"node_types":{"module":2,"function":2},"rel_types":{"contains":2,"calls":1}} \\ , try renderJson(allocator, graph_summary));}Complete call list for command.status.run
8 direct calls.
tiny.smg.cli.options.hasJson[function] attools/smg/src/cli/options.zig:141tiny.smg.cli.options.positional[function] attools/smg/src/cli/options.zig:35tiny.smg.cli.output.writeClickUsageError[function] attools/smg/src/cli/output.zig:85tiny.smg.cli.output.writeOut[function] attools/smg/src/cli/output.zig:8tiny.smg.command.session.noteGraphAge[function] attools/smg/src/command/session.zig:104tiny.smg.command.status.renderJson[function] attools/smg/src/command/status.zig:32tiny.smg.command.status.writeText[function] attools/smg/src/command/status.zig:50tiny.smg.storage.summary.load[function] attools/smg/src/storage/summary.zig:31
Audit
| Definitions | 4 |
|---|---|
| Public names | 4 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |