class Rigor::ModuleGraph::CLI::RigorRunner
Encapsulates the actual rigor check --format json shell-out and the diagnostic → Edge / Node transformation. Reused by both Collect (write JSONL) and View (render HTML).
Public Class Methods
Source
# File lib/rigor/module_graph/cli.rb, line 161 def initialize(rigor_cmd: ENV.fetch("RIGOR_CMD", "rigor"), cache: false) @rigor_cmd = rigor_cmd @cache = cache end
Public Instance Methods
Source
# File lib/rigor/module_graph/cli.rb, line 172 def analyse(paths) diagnostics = run_rigor(paths) [diagnostics_to_edges(diagnostics), diagnostics_to_nodes(diagnostics)] end
Returns both edges and nodes from one rigor invocation.
Source
# File lib/rigor/module_graph/cli.rb, line 202 def diagnostics_to_edges(diagnostics) diagnostics.filter_map do |row| next unless row["rule"] == EDGE_RULE next unless row["source_family"] == SOURCE_FAMILY payload = JSON.parse(row.fetch("message")) Edge.build( from: payload.fetch("from"), to: payload.fetch("to"), kind: payload.fetch("kind"), path: row["path"], line: row["line"], column: row["column"], confidence: payload.fetch("confidence", "syntax"), raw: payload["raw"] ) rescue JSON::ParserError, KeyError nil end end
Source
# File lib/rigor/module_graph/cli.rb, line 223 def diagnostics_to_nodes(diagnostics) diagnostics.filter_map do |row| next unless row["rule"] == NODE_RULE next unless row["source_family"] == SOURCE_FAMILY payload = JSON.parse(row.fetch("message")) Node.build( kind: payload.fetch("kind"), name: payload.fetch("name"), owner: payload["owner"], path: row["path"], line: row["line"], column: row["column"], visibility: payload["visibility"], access: payload["access"] ) rescue JSON::ParserError, KeyError nil end end
Source
# File lib/rigor/module_graph/cli.rb, line 166 def edges_for(paths) diagnostics = run_rigor(paths) diagnostics_to_edges(diagnostics) end
Source
# File lib/rigor/module_graph/cli.rb, line 177 def run_rigor(paths) cmd = [@rigor_cmd, "check", "--format", "json"] cmd << (@cache ? "--cache" : "--no-cache") cmd << "--no-stats" cmd.concat(paths) unless paths.empty? stdout_str, stderr_str, status = Open3.capture3(*cmd) unless status.success? # `rigor check` exits non-zero when it finds any error # diagnostic — our edges live inside that same output, # so we still parse the JSON. We only escalate when no # JSON was emitted at all (e.g. binary missing). if stdout_str.empty? raise CollectError, "rigor exited #{status.exitstatus} with no output\n#{stderr_str}" end end payload = JSON.parse(stdout_str) payload.fetch("diagnostics", []) rescue Errno::ENOENT raise CollectError, "rigor binary not found: #{cmd.first.inspect}. " \ "Install rigortype or set RIGOR_CMD." rescue JSON::ParserError => e raise CollectError, "rigor produced invalid JSON: #{e.message}\n#{stdout_str}" end