Skip to documentation
SLOP

tiny.smg.command.rules.render

Reference tiny.smg command rules render

Defined in command.rules.

API (1)

Actions

Public operations.

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

Source

Called byCallsNo direct callerscli.outputwriteOutprivate; no linktools.smg.src.command.rules.renderwriteTablecommand.rules.renderwriteList
Static calls · unresolved targets: 0 · external targets: 7.

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

zig
const std = @import("std");const pretty_json = @import("pretty").json;const smg = @import("../../root.zig");const output = smg.cli.output;const rich_table = smg.cli.table.rich;const rules_mod = smg.rules;pub fn writeList(allocator: std.mem.Allocator, rule_list: []const rules_mod.Rule, json: bool) !u8 {    if (json) {        var out: std.Io.Writer.Allocating = .init(allocator);        var writer = pretty_json.Writer.init(&out.writer, .minified);        try writer.beginArray();        for (rule_list) |rule| try writer.raw(try rules_mod.render(allocator, rule));        try writer.endArray();        try out.writer.writeByte('\n');        return try output.writeOut(out.written());    }    if (rule_list.len == 0) return try output.writeOut("No rules defined. Add one with smg rule add.\n");    var out: std.Io.Writer.Allocating = .init(allocator);    try writeTable(allocator, &out.writer, rule_list);    return try output.writeOut(out.written());}fn writeTable(allocator: std.mem.Allocator, writer: *std.Io.Writer, rule_list: []const rules_mod.Rule) !void {    var rows: std.ArrayList(rich_table.Row3) = .empty;    for (rule_list) |rule| {        try rows.append(allocator, .{            .a = rule.name,            .b = rule.type,            .c = try constraint(allocator, rule),        });    }    try rich_table.write3(writer, .{ .a = "Name", .b = "Type", .c = "Constraint" }, rows.items);}fn constraint(allocator: std.mem.Allocator, rule: rules_mod.Rule) ![]const u8 {    var value = rule.pattern orelse rule.invariant orelse "";    if (std.mem.eql(u8, rule.type, "quantified")) value = try std.fmt.allocPrint(allocator, "forall {s}: {s}", .{ rule.selector orelse "", rule.assertion orelse "" });    var out: std.Io.Writer.Allocating = .init(allocator);    try out.writer.writeAll(try stripMarkup(allocator, value));    if (rule.params.len != 0) {        try out.writer.writeAll(" (");        for (rule.params, 0..) |param, index| {            if (index != 0) try out.writer.writeAll(", ");            try out.writer.print("{s}={s}", .{ param.key, param.value });        }        try out.writer.writeByte(')');    }    if (rule.allow_empty_target) try out.writer.writeAll(" allow-empty-target");    if (rule.scope) |scope| try out.writer.print(" scope={s}", .{scope});    return try out.toOwnedSlice();}fn stripMarkup(allocator: std.mem.Allocator, value: []const u8) ![]const u8 {    var out: std.ArrayList(u8) = .empty;    var i: usize = 0;    while (i < value.len) : (i += 1) {        if (value[i] == '[') {            while (i < value.len and value[i] != ']') i += 1;            continue;        }        try out.append(allocator, value[i]);    }    return try out.toOwnedSlice(allocator);}test "rule table strips rich markup from constraints" {    var arena = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena.deinit();    const allocator = arena.allocator();    const rule_list = [_]rules_mod.Rule{.{        .name = "no-db",        .type = "deny",        .pattern = "app.* -[calls]-> db.*",    }};    var out: std.Io.Writer.Allocating = .init(allocator);    try writeTable(allocator, &out.writer, &rule_list);    try std.testing.expect(std.mem.indexOf(u8, out.written(), "app.* --> db.*") != null);    try std.testing.expect(std.mem.indexOf(u8, out.written(), "Constraint") != null);}test "rule table exposes empty-target policy" {    var arena = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena.deinit();    const allocator = arena.allocator();    const rule_list = [_]rules_mod.Rule{.{        .name = "no-integration",        .type = "deny",        .pattern = "pkg -[contains]-> *.integration",        .allow_empty_target = true,    }};    var out: std.Io.Writer.Allocating = .init(allocator);    try writeTable(allocator, &out.writer, &rule_list);    try std.testing.expect(std.mem.indexOf(u8, out.written(), "allow-empty-target") != null);}

Source: tools/smg/src/command/rules/root.zig:3

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

Audit

Definitions2
Public names3
Members0
Version26.7.0
Revisiondaab053ee433