suma 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +3 -0
- data/.github/workflows/release.yml +5 -1
- data/.rubocop_todo.yml +78 -26
- data/CLAUDE.md +76 -0
- data/Gemfile +3 -1
- data/README.adoc +131 -0
- data/lib/suma/cli/build.rb +2 -3
- data/lib/suma/cli/check_svg_quality.rb +178 -0
- data/lib/suma/cli/compare.rb +7 -158
- data/lib/suma/cli/export.rb +1 -7
- data/lib/suma/cli/extract_terms.rb +7 -648
- data/lib/suma/cli/generate_schemas.rb +9 -123
- data/lib/suma/cli/validate_links.rb +15 -290
- data/lib/suma/cli.rb +39 -0
- data/lib/suma/collection_manifest.rb +3 -4
- data/lib/suma/express_schema.rb +43 -30
- data/lib/suma/jsdai/figure_xml.rb +12 -9
- data/lib/suma/jsdai.rb +0 -6
- data/lib/suma/link_validator.rb +203 -0
- data/lib/suma/processor.rb +75 -101
- data/lib/suma/schema_attachment.rb +2 -29
- data/lib/suma/schema_collection.rb +1 -32
- data/lib/suma/schema_comparer.rb +116 -0
- data/lib/suma/schema_document.rb +0 -14
- data/lib/suma/schema_exporter.rb +16 -28
- data/lib/suma/schema_index.rb +53 -0
- data/lib/suma/schema_manifest_generator.rb +105 -0
- data/lib/suma/svg_quality/batch_report.rb +80 -0
- data/lib/suma/svg_quality/formatters/json_formatter.rb +30 -0
- data/lib/suma/svg_quality/formatters/terminal_formatter.rb +168 -0
- data/lib/suma/svg_quality/formatters/yaml_formatter.rb +32 -0
- data/lib/suma/svg_quality/report.rb +52 -0
- data/lib/suma/svg_quality.rb +28 -0
- data/lib/suma/term_extractor.rb +393 -0
- data/lib/suma/utils.rb +10 -2
- data/lib/suma/version.rb +1 -1
- data/lib/suma.rb +3 -2
- data/suma.gemspec +3 -2
- metadata +33 -7
- data/lib/suma/export_standalone_schema.rb +0 -14
data/lib/suma/cli/compare.rb
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "thor"
|
|
4
|
-
require_relative "../
|
|
5
|
-
require_relative "../eengine_converter"
|
|
4
|
+
require_relative "../schema_comparer"
|
|
6
5
|
|
|
7
6
|
module Suma
|
|
8
7
|
module Cli
|
|
9
|
-
# Command to compare EXPRESS schemas using eengine
|
|
10
8
|
class Compare < Thor
|
|
11
9
|
desc "compare TRIAL_SCHEMA REFERENCE_SCHEMA",
|
|
12
10
|
"Compare EXPRESS schemas using eengine and generate Change YAML"
|
|
@@ -44,166 +42,17 @@ module Suma
|
|
|
44
42
|
desc: "Enable verbose output"
|
|
45
43
|
|
|
46
44
|
def compare(trial_schema, reference_schema)
|
|
47
|
-
|
|
48
|
-
unless File.exist?(trial_schema)
|
|
49
|
-
say "Error: Trial schema not found: #{trial_schema}", :red
|
|
50
|
-
exit 1
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
unless File.exist?(reference_schema)
|
|
54
|
-
say "Error: Reference schema not found: #{reference_schema}", :red
|
|
55
|
-
exit 1
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Check eengine availability
|
|
59
|
-
unless Eengine::Wrapper.available?
|
|
60
|
-
say "Error: eengine not found in PATH", :red
|
|
61
|
-
say "Install eengine following instructions at:"
|
|
62
|
-
say " macOS: https://github.com/expresslang/homebrew-eengine"
|
|
63
|
-
say " Linux: https://github.com/expresslang/eengine-releases"
|
|
64
|
-
exit 1
|
|
65
|
-
end
|
|
45
|
+
comparer = SchemaComparer.new(trial_schema, reference_schema, options)
|
|
66
46
|
|
|
67
|
-
|
|
68
|
-
trial_stepmod = options[:trial_stepmod] ||
|
|
69
|
-
detect_repo_root(trial_schema)
|
|
70
|
-
reference_stepmod = options[:reference_stepmod] ||
|
|
71
|
-
detect_repo_root(reference_schema)
|
|
47
|
+
result = comparer.compare
|
|
72
48
|
|
|
73
|
-
if
|
|
74
|
-
say "Using eengine version: #{Eengine::Wrapper.version}", :green
|
|
75
|
-
say "Trial repo root: #{trial_stepmod}", :cyan
|
|
76
|
-
say "Reference repo root: #{reference_stepmod}", :cyan
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Create a temporary directory for eengine output
|
|
80
|
-
require "tmpdir"
|
|
81
|
-
out_dir = nil
|
|
82
|
-
out_dir = Dir.mktmpdir("eengine-compare-")
|
|
83
|
-
|
|
84
|
-
# Run comparison
|
|
85
|
-
result = Eengine::Wrapper.compare(
|
|
86
|
-
trial_schema,
|
|
87
|
-
reference_schema,
|
|
88
|
-
mode: options[:mode],
|
|
89
|
-
trial_stepmod: trial_stepmod,
|
|
90
|
-
reference_stepmod: reference_stepmod,
|
|
91
|
-
out_dir: out_dir,
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
unless result[:has_changes]
|
|
49
|
+
if result.nil?
|
|
95
50
|
say "No changes detected between schemas", :yellow
|
|
96
|
-
# Clean up temp directory
|
|
97
|
-
FileUtils.rm_rf(out_dir) if out_dir && File.directory?(out_dir)
|
|
98
|
-
return
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
unless result[:xml_path]
|
|
102
|
-
say "Error: XML output not found", :red
|
|
103
|
-
exit 1
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
if options[:verbose]
|
|
107
|
-
say "Comparison XML generated: #{result[:xml_path]}", :green
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# Convert to Change YAML
|
|
111
|
-
convert_to_change_yaml(result[:xml_path], trial_schema, out_dir)
|
|
112
|
-
rescue Eengine::EengineError => e
|
|
113
|
-
# Clean up temp directory
|
|
114
|
-
FileUtils.rm_rf(out_dir) if out_dir && File.directory?(out_dir)
|
|
115
|
-
say "Error: #{e.message}", :red
|
|
116
|
-
say e.stderr if e.respond_to?(:stderr) && options[:verbose]
|
|
117
|
-
exit 1
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
private
|
|
121
|
-
|
|
122
|
-
def detect_repo_root(schema_path)
|
|
123
|
-
# Walk up from schema path to find .git directory
|
|
124
|
-
current = File.expand_path(File.dirname(schema_path))
|
|
125
|
-
|
|
126
|
-
loop do
|
|
127
|
-
if File.directory?(File.join(current, ".git"))
|
|
128
|
-
return current
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
parent = File.dirname(current)
|
|
132
|
-
break if parent == current # reached root
|
|
133
|
-
|
|
134
|
-
current = parent
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# If no .git found, use the directory containing the schema
|
|
138
|
-
# (for non-git workflows)
|
|
139
|
-
File.dirname(schema_path)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def convert_to_change_yaml(xml_path, trial_schema, out_dir)
|
|
143
|
-
schema_name = extract_schema_name(trial_schema)
|
|
144
|
-
output_path = determine_output_path(trial_schema)
|
|
145
|
-
|
|
146
|
-
# Load existing ChangeSchema if it exists
|
|
147
|
-
existing_schema = if File.exist?(output_path)
|
|
148
|
-
if options[:verbose]
|
|
149
|
-
say "Loading existing change schema: " \
|
|
150
|
-
"#{output_path}", :cyan
|
|
151
|
-
end
|
|
152
|
-
require "expressir/changes"
|
|
153
|
-
Expressir::Changes::SchemaChange.from_file(output_path)
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
# Convert using Suma's converter
|
|
157
|
-
converter = EengineConverter.new(xml_path, schema_name)
|
|
158
|
-
change_schema = converter.convert(
|
|
159
|
-
version: options[:version],
|
|
160
|
-
existing_change_schema: existing_schema,
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
# Save using Expressir model
|
|
164
|
-
change_schema.to_file(output_path)
|
|
165
|
-
|
|
166
|
-
# Determine what action was taken
|
|
167
|
-
if existing_schema
|
|
168
|
-
existing_version = existing_schema.versions.find do |ed|
|
|
169
|
-
ed.version == options[:version]
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
say "Change YAML file updated: #{output_path}", :green
|
|
173
|
-
if existing_version
|
|
174
|
-
say " Replaced existing version #{options[:version]}", :green
|
|
175
|
-
else
|
|
176
|
-
say " Added version #{options[:version]} to change versions",
|
|
177
|
-
:green
|
|
178
|
-
end
|
|
179
|
-
else
|
|
180
|
-
say "Change YAML file created: #{output_path}", :green
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
if options[:verbose]
|
|
184
|
-
say "\nGenerated change schema content:", :cyan
|
|
185
|
-
say File.read(output_path)
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
# Clean up temp directory and XML file
|
|
189
|
-
FileUtils.rm_rf(out_dir) if out_dir && File.directory?(out_dir)
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def extract_schema_name(path)
|
|
193
|
-
# Remove version suffix if present (e.g., schema_1.exp -> schema)
|
|
194
|
-
basename = File.basename(path, ".exp")
|
|
195
|
-
basename.sub(/_\d+$/, "")
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
def determine_output_path(trial_schema)
|
|
199
|
-
if options[:output]
|
|
200
|
-
options[:output]
|
|
201
51
|
else
|
|
202
|
-
|
|
203
|
-
base = extract_schema_name(trial_schema)
|
|
204
|
-
dir = File.dirname(trial_schema)
|
|
205
|
-
File.join(dir, "#{base}.changes.yaml")
|
|
52
|
+
say "Change YAML file: #{result}", :green
|
|
206
53
|
end
|
|
54
|
+
rescue Suma::Error => e
|
|
55
|
+
raise Thor::Error, e.message
|
|
207
56
|
end
|
|
208
57
|
end
|
|
209
58
|
end
|
data/lib/suma/cli/export.rb
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
require "thor"
|
|
4
4
|
require_relative "../thor_ext"
|
|
5
|
-
require_relative "../export_standalone_schema"
|
|
6
5
|
|
|
7
6
|
module Suma
|
|
8
7
|
module Cli
|
|
@@ -85,12 +84,7 @@ module Suma
|
|
|
85
84
|
end
|
|
86
85
|
|
|
87
86
|
def create_schema_from_exp_file(exp_file)
|
|
88
|
-
|
|
89
|
-
# The id will be determined during parsing
|
|
90
|
-
ExportStandaloneSchema.new(
|
|
91
|
-
id: nil,
|
|
92
|
-
path: File.expand_path(exp_file),
|
|
93
|
-
)
|
|
87
|
+
Struct.new(:id, :path).new(nil, File.expand_path(exp_file))
|
|
94
88
|
end
|
|
95
89
|
|
|
96
90
|
def self.exit_on_failure?
|