Skip to documentation
SLOP

tiny.smg.command.about.render

Reference tiny.smg command about render

Defined in command.about.

API (4)

Actions

Public operations.

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

Source

Called byCallsNo direct callscommand.about.commandrunprivate; no linktools.smg.src.command.about.commandstoredtest; no linktools.smg.src.command.about.rendertest: about text renders coupling con...command.about.renderincoming
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallsNo direct callscommand.about.commandrunprivate; no linktools.smg.src.help.click.top.explorewritecommand.about.renderneighbors
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallsNo direct callscommand.about.commandrunprivate; no linktools.smg.src.command.about.commandstoredtest; no linktools.smg.src.command.about.rendertest: about text renders coupling con...command.about.renderoutgoing
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallstest; no linktools.smg.src.command.about.rendertest: about text renders coupling con...private; no linktools.smg.src.command.about.renderfirstLinecommand.about.renderwriteText
Static calls · unresolved targets: 6 · external targets: 5.

Source: tools/smg/src/command/about/render.zig

zig
const std = @import("std");const smg = @import("../../root.zig");const exports = smg.exports;const graph_mod = smg.graph;const model = smg.model;const node_cli = smg.command.node;const query = smg.query;const view = smg.view;pub fn incoming(allocator: std.mem.Allocator, edges: []const model.Edge, coupling_only: bool) ![]const model.Edge {    var out: std.ArrayList(model.Edge) = .empty;    for (edges) |edge| {        if (coupling_only and !exports.isCoupling(edge.rel)) continue;        try out.append(allocator, edge);    }    std.mem.sort(model.Edge, out.items, {}, incomingLess);    return try out.toOwnedSlice(allocator);}pub fn outgoing(allocator: std.mem.Allocator, edges: []const model.Edge, coupling_only: bool) ![]const model.Edge {    var out: std.ArrayList(model.Edge) = .empty;    for (edges) |edge| {        if (coupling_only and !exports.isCoupling(edge.rel)) continue;        try out.append(allocator, edge);    }    std.mem.sort(model.Edge, out.items, {}, outgoingLess);    return try out.toOwnedSlice(allocator);}fn incomingLess(_: void, a: model.Edge, b: model.Edge) bool {    const rel_order = std.mem.order(u8, a.rel, b.rel);    if (rel_order != .eq) return rel_order == .lt;    return std.mem.lessThan(u8, a.source, b.source);}fn outgoingLess(_: void, a: model.Edge, b: model.Edge) bool {    const rel_order = std.mem.order(u8, a.rel, b.rel);    if (rel_order != .eq) return rel_order == .lt;    return std.mem.lessThan(u8, a.target, b.target);}pub fn neighbors(allocator: std.mem.Allocator, graph: graph_mod.Graph, name: []const u8, coupling_only: bool) ![]const []const u8 {    const sub = try query.subgraph(allocator, graph, name, 2, coupling_only);    var out: std.ArrayList([]const u8) = .empty;    for (sub.nodes.items) |item| {        if (!std.mem.eql(u8, item.name, name)) try out.append(allocator, item.name);    }    std.mem.sort([]const u8, out.items, {}, stringLess);    return try out.toOwnedSlice(allocator);}fn stringLess(_: void, a: []const u8, b: []const u8) bool {    return std.mem.lessThan(u8, a, b);}pub fn writeText(allocator: std.mem.Allocator, writer: *std.Io.Writer, graph: graph_mod.Graph, node: model.Node, depth: usize, full: bool, coupling_only: bool, incoming_all: usize, outgoing_all: usize, filtered_incoming: []const model.Edge, filtered_outgoing: []const model.Edge, path: []const []const u8, neighborhood: []const []const u8) !void {    try writer.print("{s}  [{s}]\n", .{ node.name, node.type });    const loc = try node_cli.location(allocator, node);    if (loc.len != 0) try writer.print("file:  {s}\n", .{loc});    if (node.docstring) |doc| try writer.print("doc:   {s}\n", .{firstLine(doc)});    try node_cli.writeMetadata(allocator, writer, node.metadata);    if (depth >= 1) {        if (path.len > 1) {            try writer.writeAll("\nPath: ");            for (path, 0..) |item, index| {                if (index != 0) try writer.writeAll(" > ");                try writer.writeAll(item);            }            try writer.writeByte('\n');        }        const edge_cap = if (full) @as(usize, 0) else @as(usize, 10);        if (filtered_incoming.len != 0) {            try writer.print("\nIncoming ({d})\n", .{filtered_incoming.len});            for (filtered_incoming, 0..) |edge, index| {                if (edge_cap != 0 and index >= edge_cap) {                    try writer.print("  ... and {d} more (use --full)\n", .{filtered_incoming.len - edge_cap});                    break;                }                try writer.print("  {s} --{s}-->\n", .{ edge.source, edge.rel });            }        }        if (filtered_outgoing.len != 0) {            try writer.print("\nOutgoing ({d})\n", .{filtered_outgoing.len});            for (filtered_outgoing, 0..) |edge, index| {                if (edge_cap != 0 and index >= edge_cap) {                    try writer.print("  ... and {d} more (use --full)\n", .{filtered_outgoing.len - edge_cap});                    break;                }                try writer.print("  --{s}--> {s}\n", .{ edge.rel, edge.target });            }        }        if (coupling_only) {            const hidden_total = incoming_all - filtered_incoming.len + outgoing_all - filtered_outgoing.len;            if (hidden_total != 0) try writer.print("\n{d} hidden non-coupling edge(s); rerun with --all-rels to include them\n", .{hidden_total});        }    }    if (depth >= 2 and neighborhood.len != 0) {        const neighbor_cap = if (full) @as(usize, 0) else @as(usize, 10);        try writer.print("\nNeighborhood ({d} nodes within 2 hops)\n", .{neighborhood.len});        for (neighborhood, 0..) |neighbor, index| {            if (neighbor_cap != 0 and index >= neighbor_cap) {                try writer.print("  ... and {d} more (use --full)\n", .{neighborhood.len - neighbor_cap});                break;            }            const neighbor_node = graph_mod.getNode(&graph, neighbor);            const neighbor_type = if (neighbor_node) |item| item.type else "?";            try writer.print("  [{s}] {s}\n", .{ neighbor_type, neighbor });        }    }}fn firstLine(value: []const u8) []const u8 {    return value[0..(std.mem.indexOfScalar(u8, value, '\n') orelse value.len)];}test "about text renders coupling context and hidden edge count" {    var arena = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena.deinit();    const allocator = arena.allocator();    var graph = graph_mod.init(allocator);    try graph_mod.addNode(&graph, .{ .name = "app", .type = model.NodeType.module, .file = "src/app.py" });    try graph_mod.addNode(&graph, .{ .name = "app.main", .type = model.NodeType.function, .file = "src/app.py", .line = 1, .docstring = "main doc\nmore" });    try graph_mod.addNode(&graph, .{ .name = "app.helper", .type = model.NodeType.function, .file = "src/app.py", .line = 5 });    try graph_mod.addEdge(&graph, .{ .source = "app", .rel = model.RelType.contains, .target = "app.main" });    try graph_mod.addEdge(&graph, .{ .source = "app.main", .rel = model.RelType.calls, .target = "app.helper" });    const node = graph_mod.getNode(&graph, "app.main").?;    const incoming_all = try view.incoming(graph, allocator, "app.main", null);    const outgoing_all = try view.outgoing(graph, allocator, "app.main", null);    const filtered_incoming = try incoming(allocator, incoming_all, true);    const filtered_outgoing = try outgoing(allocator, outgoing_all, true);    const path = try query.containmentPath(allocator, graph, "app.main");    var out: std.Io.Writer.Allocating = .init(allocator);    try writeText(allocator, &out.writer, graph, node, 1, false, true, incoming_all.len, outgoing_all.len, filtered_incoming, filtered_outgoing, path, &.{});    try std.testing.expectEqualStrings(        \\app.main  [function]        \\file:  src/app.py:1        \\doc:   main doc        \\        \\Path: app > app.main        \\        \\Outgoing (1)        \\  --calls--> app.helper        \\        \\1 hidden non-coupling edge(s); rerun with --all-rels to include them        \\    , out.written());}

Source: tools/smg/src/command/about/root.zig:2

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

Audit

Definitions5
Public names9
Members0
Version26.7.0
Revisiondaab053ee433