Skip to documentation
SLOP

tiny.smg.command.between

Reference tiny.smg command between

Defined in command.

API (3)

Actions

Public operations.

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

Source

Called byCallscommand.betweenruntest; no linktools.smg.src.command.betweentest: between renders python text con...viewallEdgescommand.betweendirectEdges
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsNo direct callerscommand.betweendirectEdgescommand.betweenwriteTextqueryshortestPathcommand.betweenrun
Static calls · unresolved targets: 0 · external targets: 13.
Called byCallscommand.betweenruntest; no linktools.smg.src.command.betweentest: between renders python text con...private; no linktools.smg.src.command.betweenwriteWrappedPlainLinecommand.betweenwriteText
Static calls · unresolved targets: 2 · external targets: 4.

Source: tools/smg/src/command/between.zig

zig
const std = @import("std");const smg = @import("../root.zig");const graph_mod = smg.graph;const model = smg.model;const query = smg.query;const cli_json = smg.cli.json;const cli_options = smg.cli.options;const cli_output = smg.cli.output;const cli_resolve = smg.cli.resolve;const cli_session = smg.command.session;const cli_validation = smg.cli.validation;const view = smg.view;pub fn run(allocator: std.mem.Allocator, phases: std.mem.Allocator, args: []const []const u8, limits: smg.Limits, boundary: cli_session.PhaseBoundary) !u8 {    if (try cli_validation.rejectMissingOptionValues(allocator, args, &.{"--format"})) return 2;    if (try cli_validation.rejectUnexpectedOptionsPlain(allocator, "between", "[OPTIONS] A B", args, &.{"--format"})) return 2;    if (try cli_validation.rejectInvalidChoiceOption(allocator, "between", "[OPTIONS] A B", args, "--format", &.{ "text", "json" })) return 2;    const pos = try cli_options.positional(allocator, args);    if (pos.len == 0) {        try cli_output.writeClickUsageError(allocator, "between", "[OPTIONS] A B", "Missing argument 'A'.");        return 2;    }    if (pos.len == 1) {        try cli_output.writeClickUsageError(allocator, "between", "[OPTIONS] A B", "Missing argument 'B'.");        return 2;    }    if (pos.len > 2) {        try cli_output.writeClickUsageError(allocator, "between", "[OPTIONS] A B", try cli_validation.unexpectedArgumentMessage(allocator, pos[2..]));        return 2;    }    const loaded = try cli_session.loadRead(allocator, phases, limits, boundary);    defer boundary.beginTeardown();    const graph = loaded[1];    const source = try cli_resolve.graphNode(allocator, graph, pos[0], limits.suggestions);    const target = try cli_resolve.graphNode(allocator, graph, pos[1], limits.suggestions);    const path = try query.shortestPath(allocator, graph, source, target);    const direct = try directEdges(allocator, graph, source, target);    var out: std.Io.Writer.Allocating = .init(allocator);    if (std.mem.eql(u8, cli_options.flagValue(args, "--format") orelse "", "json")) {        try cli_json.writeBetween(&out.writer, source, target, path, direct);        return try cli_output.writeOut(out.written());    }    try writeText(allocator, &out.writer, source, target, path, direct);    return try cli_output.writeOut(out.written());}pub fn directEdges(allocator: std.mem.Allocator, graph: graph_mod.Graph, source: []const u8, target: []const u8) ![]const model.Edge {    var out: std.ArrayList(model.Edge) = .empty;    for (try view.allEdges(graph, allocator)) |edge| {        const forward = std.mem.eql(u8, edge.source, source) and std.mem.eql(u8, edge.target, target);        const backward = std.mem.eql(u8, edge.source, target) and std.mem.eql(u8, edge.target, source);        if (forward or backward) try out.append(allocator, edge);    }    return try out.toOwnedSlice(allocator);}pub fn writeText(allocator: std.mem.Allocator, writer: *std.Io.Writer, source: []const u8, target: []const u8, path: ?[]const []const u8, direct: []const model.Edge) !void {    if (path) |items| {        var line: std.Io.Writer.Allocating = .init(allocator);        defer line.deinit();        try line.writer.writeAll("Path: ");        for (items, 0..) |item, index| {            if (index != 0) try line.writer.writeAll(" -> ");            try line.writer.writeAll(item);        }        try writeWrappedPlainLine(writer, line.written(), 80);    } else {        try writer.print("No path between {s} and {s}\n", .{ source, target });    }    if (direct.len != 0) {        try writer.writeAll("\nDirect edges:\n");        for (direct) |edge| {            var line: std.Io.Writer.Allocating = .init(allocator);            defer line.deinit();            try line.writer.print("  {s} --{s}--> {s}", .{ edge.source, edge.rel, edge.target });            try writeWrappedPlainLine(writer, line.written(), 80);        }    }}fn writeWrappedPlainLine(writer: *std.Io.Writer, line: []const u8, width: usize) !void {    var start: usize = 0;    while (line.len - start > width) {        var split = start + width;        while (split > start and line[split] != ' ') split -= 1;        if (split == start) {            split = start + width;            try writer.writeAll(line[start..split]);            try writer.writeByte('\n');            start = split;        } else {            try writer.writeAll(line[start .. split + 1]);            try writer.writeByte('\n');            start = split + 1;            while (start < line.len and line[start] == ' ') start += 1;        }    }    try writer.writeAll(line[start..]);    try writer.writeByte('\n');}test "between renders python text contracts" {    var arena = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena.deinit();    const allocator = arena.allocator();    var graph = graph_mod.init(allocator);    for ([_][]const u8{        "a",        "b",        "c",        "d",        "app.api.handler",        "app.service.Service",        "app.service.Service.load",        "app.db.query",        "really.long.source.module.component.Handler",        "really.long.target.module.component.ServiceMethod",    }) |name| try graph_mod.addNode(&graph, .{ .name = name, .type = model.NodeType.module });    try graph_mod.addEdge(&graph, .{ .source = "a", .rel = model.RelType.calls, .target = "b" });    try graph_mod.addEdge(&graph, .{ .source = "b", .rel = model.RelType.imports, .target = "c" });    try graph_mod.addEdge(&graph, .{ .source = "app.api.handler", .rel = model.RelType.calls, .target = "app.service.Service" });    try graph_mod.addEdge(&graph, .{ .source = "app.service.Service", .rel = model.RelType.calls, .target = "app.service.Service.load" });    try graph_mod.addEdge(&graph, .{ .source = "app.service.Service.load", .rel = model.RelType.calls, .target = "app.db.query" });    try graph_mod.addEdge(&graph, .{ .source = "really.long.source.module.component.Handler", .rel = model.RelType.calls, .target = "really.long.target.module.component.ServiceMethod" });    const path = try query.shortestPath(allocator, graph, "a", "c");    const long_path = try query.shortestPath(allocator, graph, "app.api.handler", "app.db.query");    const long_direct = try directEdges(allocator, graph, "really.long.source.module.component.Handler", "really.long.target.module.component.ServiceMethod");    var out: std.Io.Writer.Allocating = .init(allocator);    try writeText(allocator, &out.writer, "a", "c", path, &.{});    try writeText(allocator, &out.writer, "app.api.handler", "app.db.query", long_path, &.{});    try writeText(allocator, &out.writer, "really.long.source.module.component.Handler", "really.long.target.module.component.ServiceMethod", try query.shortestPath(allocator, graph, "really.long.source.module.component.Handler", "really.long.target.module.component.ServiceMethod"), long_direct);    try std.testing.expectEqualStrings("Path: a -> b -> c\n" ++        "Path: app.api.handler -> app.service.Service -> app.service.Service.load -> \n" ++        "app.db.query\n" ++        "Path: really.long.source.module.component.Handler -> \n" ++        "really.long.target.module.component.ServiceMethod\n" ++        "\n" ++        "Direct edges:\n" ++        "  really.long.source.module.component.Handler --calls--> \n" ++        "really.long.target.module.component.ServiceMethod\n", out.written());}

Source: tools/smg/src/command/root.zig:4

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

Audit

Definitions4
Public names4
Members0
Version26.7.0
Revisiondaab053ee433