Class: Archsight::Import::Handlers::Grapher

Inherits:
Archsight::Import::Handler show all
Defined in:
lib/archsight/import/handlers/grapher.rb

Overview

Abstract base class for language-specific code-graph import handlers.

Subclasses implement two discovery methods and inherit all graph layout, clustering, coloring, and DOT generation logic from here.

Required overrides:

discover_modules(repo_root)              → [[rel_dir, mod_name], ...]
collect_packages(repo_root, modules, prefix) → {pkg_path => [dep_path, ...]}

Package paths must use "/" as the separator regardless of language so that all generic helpers (node_id, short_label, rel_parts, etc.) work correctly. Subclasses with "." separators (e.g. Python dotted names) should convert to "/" in collect_packages before returning.

Configuration (inherited by all subclasses):

import/config/path     - Path to the repository root
import/config/ranksep  - Horizontal gap between rank columns (default: 0.6)
import/config/nodesep  - Vertical gap between nodes in a column (default: 0.15)

Constant Summary collapse

PALETTE =
[
  { fill: "#ddeeff", edge: "#2266cc" },
  { fill: "#ddffd8", edge: "#2a8a1e" },
  { fill: "#fff3cc", edge: "#cc8800" },
  { fill: "#fde8e8", edge: "#cc2222" },
  { fill: "#f5e8fd", edge: "#8822cc" },
  { fill: "#fdf5e8", edge: "#cc6600" },
  { fill: "#e8fdfd", edge: "#228888" },
  { fill: "#ffeedd", edge: "#995500" },
  { fill: "#eeeeff", edge: "#4444aa" },
  { fill: "#ffeeff", edge: "#993399" }
].freeze

Instance Attribute Summary

Attributes inherited from Archsight::Import::Handler

#database, #import_resource, #progress, #resources_dir, #shared_writer

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Archsight::Import::Handler

#compute_config_hash, #config, #config_all, #import_yaml, #initialize, #resource_yaml, #resources_to_yaml, #self_marker, #write_generates_meta, #write_yaml

Constructor Details

This class inherits a constructor from Archsight::Import::Handler

Class Method Details

.applicable?(_path) ⇒ Boolean

Subclasses return true when they can handle the given path. Used by Registry.handlers_for to collect all applicable graphers.

Returns:

  • (Boolean)


30
# File 'lib/archsight/import/handlers/grapher.rb', line 30

def self.applicable?(_path) = false

.language_nameObject

Subclasses declare their language name for explicit --language lookup.



26
# File 'lib/archsight/import/handlers/grapher.rb', line 26

def self.language_name = nil

Instance Method Details

#dot_graph(path:, ranksep: 0.6, nodesep: 0.15) ⇒ Object



92
93
94
95
96
97
98
99
100
101
# File 'lib/archsight/import/handlers/grapher.rb', line 92

def dot_graph(path:, ranksep: 0.6, nodesep: 0.15)
  modules = discover_modules(path)
  return nil if modules.empty?

  module_colors, prefix = build_module_colors(modules)
  pkgs = collect_packages(path, modules, prefix)
  return nil if pkgs.empty?

  emit_dot(pkgs, modules, module_colors, prefix, ranksep: ranksep, nodesep: nodesep)
end

#executeObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/archsight/import/handlers/grapher.rb', line 51

def execute
  @path = config("path")
  raise "Missing required config: path" unless @path
  raise "Directory not found: #{@path}" unless File.directory?(@path)

  # Consolidate all grapher output into a single shared file unless an
  # explicit output path is already set (e.g. via grapherOutputPath on the
  # parent Repository import).
  import_resource.annotations["import/outputPath"] ||= "generated/modules.yaml"

  @ranksep = config("ranksep", default: "0.6").to_f
  @nodesep = config("nodesep", default: "0.15").to_f

  progress.update("Discovering modules")
  modules = discover_modules(@path)
  return write_yaml(YAML.dump(self_marker)) if modules.empty?

  module_colors, prefix = build_module_colors(modules)

  progress.update("Collecting packages")
  pkgs = collect_packages(@path, modules, prefix)
  return write_yaml(YAML.dump(self_marker)) if pkgs.empty?

  progress.update("Generating DOT graph")
  dot_content = emit_dot(pkgs, modules, module_colors, prefix,
                         ranksep: @ranksep, nodesep: @nodesep)

  progress.update("Generating resource")
  repo_name = artifact_name(@path)
  resource = resource_yaml(
    kind: "TechnologyArtifact",
    name: repo_name,
    annotations: { annotation_key => dot_content },
    spec: {}
  )

  extra = additional_resources(@path, modules, repo_name)
  write_yaml(YAML.dump(resource) + extra + YAML.dump(self_marker))
  write_generates_meta
end

#safe_glob(pattern) ⇒ Object



32
33
34
35
36
# File 'lib/archsight/import/handlers/grapher.rb', line 32

def safe_glob(pattern)
  Dir.glob(pattern)
rescue Errno::ELOOP, Errno::ENOTDIR
  []
end