Module: Archsight::Helpers

Extended by:
AnalysisRenderer, Formatting
Defined in:
lib/archsight/helpers.rb,
lib/archsight/helpers/formatting.rb,
lib/archsight/helpers/analysis_renderer.rb

Overview

Helpers provides utility functions for the architecture tool

Defined Under Namespace

Modules: AnalysisRenderer, Formatting

Constant Summary

Constants included from Formatting

Formatting::AI_ESTIMATE_CONFIG

Class Method Summary collapse

Methods included from AnalysisRenderer

render_code, render_heading, render_list, render_message, render_table, render_text

Class Method Details

.ai_adjusted_estimate(type, value) ⇒ Object



196
# File 'lib/archsight/helpers.rb', line 196

def ai_adjusted_estimate(type, value) = Formatting.ai_adjusted_estimate(type, value)

.category_for_url(url) ⇒ Object

Get category for a URL based on domain patterns



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/archsight/helpers.rb', line 127

def category_for_url(url)
  case url
  when %r{docs\.google\.com/(document|spreadsheets|presentation)}
    "Documentation"
  when /github\.com|gitlab/
    "Code Repository"
  when /confluence\.|atlassian\.net/
    "Documentation"
  when /jira\.|atlassian\.net.*jira/
    "Project Management"
  when /grafana/
    "Monitoring"
  when /prometheus/
    "Monitoring"
  when /api\./
    "API"
  when /docs\./
    "Documentation"
  else
    "Other"
  end
end

.classify(val) ⇒ Object

Delegate formatting methods



194
# File 'lib/archsight/helpers.rb', line 194

def classify(val) = Formatting.classify(val)

.compare_values(val_a, val_b) ⇒ Object

Compare two values, using numeric comparison when both are integers



185
186
187
188
189
190
191
# File 'lib/archsight/helpers.rb', line 185

def compare_values(val_a, val_b)
  if val_a.to_s.match?(/\A-?\d+\z/) && val_b.to_s.match?(/\A-?\d+\z/)
    val_a.to_i <=> val_b.to_i
  else
    (val_a || "").to_s.downcase <=> (val_b || "").to_s.downcase
  end
end

.deep_merge(hash1, hash2) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/archsight/helpers.rb', line 55

def deep_merge(hash1, hash2)
  hash1.dup.merge(hash2) do |_, old_value, new_value|
    if old_value.is_a?(Hash) && new_value.is_a?(Hash)
      deep_merge(old_value, new_value)
    elsif old_value.is_a?(Array) && new_value.is_a?(Array)
      (old_value + new_value).uniq
    else
      new_value
    end
  end
end

.error_context_lines(path, error_line_no, context_lines: 5) ⇒ Object

Extract context lines around a YAML document containing an error Returns array of hashes with :line_no, :content, :selected keys



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/archsight/helpers.rb', line 27

def error_context_lines(path, error_line_no, context_lines: 5)
  return [] unless File.exist?(path)

  lines = File.readlines(path, chomp: true)
  error_idx = error_line_no - 1 # Convert to 0-indexed

  # Find the start of the YAML document (--- separator at or before error line)
  doc_start = error_idx
  doc_start -= 1 while doc_start.positive? && lines[doc_start] != "---"

  # Find the end of the YAML document (next --- or end of file)
  doc_end = error_idx + 1
  doc_end += 1 while doc_end < lines.length && lines[doc_end] != "---"
  doc_end -= 1 # Don't include the next ---

  # Show context_lines before doc start, full document, and context_lines after doc end
  context_start = [doc_start - context_lines, 0].max
  context_end = [doc_end + context_lines, lines.length - 1].min

  (context_start..context_end).map do |i|
    {
      line_no: i + 1,
      content: lines[i],
      selected: (i + 1) == error_line_no
    }
  end
end

.escape_html(text) ⇒ Object

Delegate analysis renderer methods



202
# File 'lib/archsight/helpers.rb', line 202

def escape_html(text) = AnalysisRenderer.escape_html(text)

.github_raw_base_url(git_url, branch: "main") ⇒ String?

Convert a GitHub git URL to a raw.githubusercontent.com base URL

Parameters:

  • git_url (String)

    Git URL like “git@github.com:owner/repo.git” or “github.com/owner/repo

  • branch (String) (defaults to: "main")

    Branch name, defaults to “main”

Returns:

  • (String, nil)

    Base URL for raw content, or nil if not a GitHub URL



97
98
99
100
101
102
103
104
105
106
107
# File 'lib/archsight/helpers.rb', line 97

def github_raw_base_url(git_url, branch: "main")
  return nil unless git_url

  # Extract owner/repo from various GitHub URL formats
  match = git_url.match(%r{github\.com[:/]([^/]+)/([^/.]+)})
  return nil unless match

  owner = match[1]
  repo = match[2]
  "https://raw.githubusercontent.com/#{owner}/#{repo}/#{branch}"
end

.http_git(repo_url) ⇒ Object



197
# File 'lib/archsight/helpers.rb', line 197

def http_git(repo_url) = Formatting.http_git(repo_url)

.icon_for_url(url) ⇒ Object

Get icon class for a URL based on domain patterns



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/archsight/helpers.rb', line 68

def icon_for_url(url)
  case url
  when %r{docs\.google\.com/(document|spreadsheets|presentation)}
    "iconoir-google-docs"
  when /github\.com/
    "iconoir-github"
  when /gitlab/
    "iconoir-git-fork"
  when /confluence\.|atlassian\.net/
    "iconoir-page-edit"
  when /jira\.|atlassian\.net.*jira/
    "iconoir-list"
  when /grafana/
    "iconoir-graph-up"
  when /prometheus/
    "iconoir-database"
  when /api\./
    "iconoir-code"
  when /docs\./
    "iconoir-book"
  else
    "iconoir-internet"
  end
end

.instance_sort_value(instance, field) ⇒ Object

Get the value of a field from an instance for sorting



176
177
178
179
180
181
182
# File 'lib/archsight/helpers.rb', line 176

def instance_sort_value(instance, field)
  case field
  when "name" then instance.name.to_s
  when "kind" then instance.klass.to_s
  else instance.annotations[field]
  end
end

.number_with_delimiter(num) ⇒ Object



198
# File 'lib/archsight/helpers.rb', line 198

def number_with_delimiter(num) = Formatting.number_with_delimiter(num)

.relative_error_path(path) ⇒ Object

Make path relative to resources directory



16
17
18
19
20
21
22
23
# File 'lib/archsight/helpers.rb', line 16

def relative_error_path(path)
  # Find 'resources/' in path and return from there
  if (idx = path.index("resources/"))
    path[idx..]
  else
    File.basename(path)
  end
end

.render_analysis_section(section) ⇒ Object



203
# File 'lib/archsight/helpers.rb', line 203

def render_analysis_section(section, **) = AnalysisRenderer.render_analysis_section(section, **)

.render_analysis_table(section) ⇒ Object



204
# File 'lib/archsight/helpers.rb', line 204

def render_analysis_table(section) = AnalysisRenderer.render_analysis_table(section)

.resolve_relative_urls(content, base_url) ⇒ String

Resolve relative paths in HTML/Markdown content to absolute URLs

Parameters:

  • content (String)

    HTML content with potential relative paths

  • base_url (String)

    Base URL to prepend to relative paths

Returns:

  • (String)

    Content with resolved URLs



113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/archsight/helpers.rb', line 113

def resolve_relative_urls(content, base_url)
  return content unless base_url

  # Match src="./path" or src="path" (not starting with http/https/data//)
  content.gsub(%r{(\ssrc=["'])(\./)?((?!https?:|data:|//)[^"']+)(["'])}) do
    prefix = ::Regexp.last_match(1)
    _dot_slash = ::Regexp.last_match(2)
    path = ::Regexp.last_match(3)
    suffix = ::Regexp.last_match(4)
    "#{prefix}#{base_url}/#{path}#{suffix}"
  end
end

.sort_instances(instances, sort_fields) ⇒ Array

Sort instances by multiple fields

Parameters:

  • instances (Array)

    Array of resource instances to sort

  • sort_fields (Array<String>)

    Fields to sort by, prefix with ‘-’ for descending

Returns:

  • (Array)

    Sorted instances



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/archsight/helpers.rb', line 154

def sort_instances(instances, sort_fields)
  return instances if sort_fields.empty?

  instances.sort do |a, b|
    cmp = 0
    sort_fields.each do |sort_spec|
      break if cmp != 0

      desc = sort_spec.start_with?("-")
      field = desc ? sort_spec[1..] : sort_spec

      val_a = instance_sort_value(a, field)
      val_b = instance_sort_value(b, field)

      cmp = compare_values(val_a, val_b)
      cmp = -cmp if desc
    end
    cmp
  end
end

.time_ago(timestamp) ⇒ Object



199
# File 'lib/archsight/helpers.rb', line 199

def time_ago(timestamp) = Formatting.time_ago(timestamp)

.to_euro(num) ⇒ Object



195
# File 'lib/archsight/helpers.rb', line 195

def to_euro(num) = Formatting.to_euro(num)