expressir 2.1.18 → 2.1.19
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/.rubocop_todo.yml +17 -9
- data/README.adoc +225 -3
- data/expressir.gemspec +2 -0
- data/lib/expressir/cli.rb +28 -193
- data/lib/expressir/commands/base.rb +32 -0
- data/lib/expressir/commands/benchmark.rb +68 -0
- data/lib/expressir/commands/benchmark_cache.rb +88 -0
- data/lib/expressir/commands/clean.rb +20 -0
- data/lib/expressir/commands/coverage.rb +307 -0
- data/lib/expressir/commands/format.rb +13 -0
- data/lib/expressir/commands/validate.rb +53 -0
- data/lib/expressir/commands/version.rb +9 -0
- data/lib/expressir/coverage.rb +249 -0
- data/lib/expressir/express/formatter.rb +4 -2
- data/lib/expressir/express/visitor.rb +10 -6
- data/lib/expressir/model/declarations/derived_attribute.rb +25 -0
- data/lib/expressir/model/declarations/inverse_attribute.rb +25 -0
- data/lib/expressir/model/model_element.rb +2 -0
- data/lib/expressir/version.rb +1 -1
- data/lib/expressir.rb +1 -0
- metadata +41 -2
@@ -0,0 +1,68 @@
|
|
1
|
+
module Expressir
|
2
|
+
module Commands
|
3
|
+
class Benchmark < Base
|
4
|
+
def run(path)
|
5
|
+
configure_benchmarking
|
6
|
+
|
7
|
+
if [".yml", ".yaml"].include?(File.extname(path).downcase)
|
8
|
+
benchmark_from_yaml(path)
|
9
|
+
else
|
10
|
+
benchmark_file(path)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def configure_benchmarking
|
17
|
+
Expressir.configuration.benchmark_enabled = true
|
18
|
+
Expressir.configuration.benchmark_ips = options[:ips]
|
19
|
+
Expressir.configuration.benchmark_verbose = options[:verbose]
|
20
|
+
Expressir.configuration.benchmark_save = options[:save]
|
21
|
+
Expressir.configuration.benchmark_format = options[:format] if options[:format]
|
22
|
+
end
|
23
|
+
|
24
|
+
def benchmark_file(path)
|
25
|
+
say "Express Schema Loading Benchmark"
|
26
|
+
say "--------------------------------"
|
27
|
+
|
28
|
+
repository = Expressir::Benchmark.measure_file(path) do
|
29
|
+
Expressir::Express::Parser.from_file(path)
|
30
|
+
end
|
31
|
+
|
32
|
+
if repository
|
33
|
+
say "Loaded #{repository.schemas.size} schemas"
|
34
|
+
else
|
35
|
+
say "Failed to load schema"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def benchmark_from_yaml(yaml_path)
|
40
|
+
say "Express Schema Loading Benchmark from YAML"
|
41
|
+
say "--------------------------------"
|
42
|
+
|
43
|
+
# Load schema list from YAML
|
44
|
+
schema_list = YAML.load_file(yaml_path)
|
45
|
+
if schema_list.is_a?(Hash) && schema_list["schemas"]
|
46
|
+
# Handle format: { "schemas": ["path1", "path2", ...] }
|
47
|
+
schema_files = schema_list["schemas"]
|
48
|
+
elsif schema_list.is_a?(Array)
|
49
|
+
# Handle format: ["path1", "path2", ...]
|
50
|
+
schema_files = schema_list
|
51
|
+
else
|
52
|
+
say "Invalid YAML format. Expected an array of schema paths or a hash with a 'schemas' key."
|
53
|
+
return
|
54
|
+
end
|
55
|
+
|
56
|
+
say "YAML File: #{yaml_path}"
|
57
|
+
say "Number of schemas in list: #{schema_files.size}"
|
58
|
+
say "--------------------------------"
|
59
|
+
|
60
|
+
# Load the schemas
|
61
|
+
Expressir::Benchmark.measure_collection(schema_files) do |file|
|
62
|
+
repository = Expressir::Express::Parser.from_file(file)
|
63
|
+
repository.schemas
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Expressir
|
2
|
+
module Commands
|
3
|
+
class BenchmarkCache < Base
|
4
|
+
def run(path)
|
5
|
+
configure_benchmarking
|
6
|
+
|
7
|
+
# Run benchmarks with cache
|
8
|
+
cache_path = options[:cache_path] || generate_temp_cache_path
|
9
|
+
|
10
|
+
if [".yml", ".yaml"].include?(File.extname(path).downcase)
|
11
|
+
benchmark_cache_from_yaml(path, cache_path)
|
12
|
+
else
|
13
|
+
benchmark_cache_file(path, cache_path)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def configure_benchmarking
|
20
|
+
Expressir.configuration.benchmark_enabled = true
|
21
|
+
Expressir.configuration.benchmark_ips = options[:ips]
|
22
|
+
Expressir.configuration.benchmark_verbose = options[:verbose]
|
23
|
+
Expressir.configuration.benchmark_save = options[:save]
|
24
|
+
Expressir.configuration.benchmark_format = options[:format] if options[:format]
|
25
|
+
end
|
26
|
+
|
27
|
+
def benchmark_cache_file(path, cache_path)
|
28
|
+
say "Express Schema Loading Benchmark with Caching"
|
29
|
+
say "--------------------------------"
|
30
|
+
say "Schema: #{path}"
|
31
|
+
say "Cache: #{cache_path}"
|
32
|
+
say "--------------------------------"
|
33
|
+
|
34
|
+
# Benchmark with caching
|
35
|
+
results = Expressir::Benchmark.measure_with_cache(path, cache_path) do |file|
|
36
|
+
Expressir::Express::Parser.from_file(file)
|
37
|
+
end
|
38
|
+
|
39
|
+
if results[:repository]
|
40
|
+
schema_count = results[:repository].schemas.size
|
41
|
+
say "Loaded #{schema_count} schemas"
|
42
|
+
else
|
43
|
+
say "Failed to load schema"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def benchmark_cache_from_yaml(yaml_path, cache_path)
|
48
|
+
say "Express Schema Loading Benchmark with Caching from YAML"
|
49
|
+
say "--------------------------------"
|
50
|
+
|
51
|
+
# Load schema list from YAML
|
52
|
+
schema_list = YAML.load_file(yaml_path)
|
53
|
+
if schema_list.is_a?(Hash) && schema_list["schemas"]
|
54
|
+
# Handle format: { "schemas": ["path1", "path2", ...] }
|
55
|
+
schema_files = schema_list["schemas"]
|
56
|
+
elsif schema_list.is_a?(Array)
|
57
|
+
# Handle format: ["path1", "path2", ...]
|
58
|
+
schema_files = schema_list
|
59
|
+
else
|
60
|
+
say "Invalid YAML format. Expected an array of schema paths or a hash with a 'schemas' key."
|
61
|
+
return
|
62
|
+
end
|
63
|
+
|
64
|
+
say "YAML File: #{yaml_path}"
|
65
|
+
say "Number of schemas in list: #{schema_files.size}"
|
66
|
+
say "Cache: #{cache_path}"
|
67
|
+
say "--------------------------------"
|
68
|
+
|
69
|
+
# Process each file with caching
|
70
|
+
schema_files.each_with_index do |file, index|
|
71
|
+
say "Processing file #{index + 1}/#{schema_files.size}: #{file}"
|
72
|
+
|
73
|
+
# Benchmark with caching
|
74
|
+
Expressir::Benchmark.measure_with_cache(file, cache_path) do |path|
|
75
|
+
Expressir::Express::Parser.from_file(path)
|
76
|
+
end
|
77
|
+
|
78
|
+
say "--------------------------------"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def generate_temp_cache_path
|
83
|
+
require "tempfile"
|
84
|
+
Tempfile.new(["expressir_cache", ".bin"]).path
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Expressir
|
2
|
+
module Commands
|
3
|
+
class Clean < Base
|
4
|
+
def run(path)
|
5
|
+
repository = Expressir::Express::Parser.from_file(path)
|
6
|
+
formatted_schemas = repository.schemas.map do |schema|
|
7
|
+
# Format schema without remarks
|
8
|
+
schema.to_s(no_remarks: true)
|
9
|
+
end.join("\n\n")
|
10
|
+
|
11
|
+
if options[:output]
|
12
|
+
File.write(options[:output], formatted_schemas)
|
13
|
+
say "Cleaned schema written to #{options[:output]}"
|
14
|
+
else
|
15
|
+
say formatted_schemas
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,307 @@
|
|
1
|
+
require "terminal-table"
|
2
|
+
require "json"
|
3
|
+
require "yaml"
|
4
|
+
require "ruby-progressbar"
|
5
|
+
|
6
|
+
module Expressir
|
7
|
+
module Commands
|
8
|
+
class Coverage < Base
|
9
|
+
def run(paths)
|
10
|
+
if paths.empty?
|
11
|
+
exit_with_error "No paths specified. Please provide paths to EXPRESS files or directories."
|
12
|
+
end
|
13
|
+
|
14
|
+
reports = collect_reports(paths)
|
15
|
+
|
16
|
+
if reports.empty?
|
17
|
+
exit_with_error "No valid EXPRESS files were processed. Nothing to report."
|
18
|
+
end
|
19
|
+
|
20
|
+
# Generate output based on format
|
21
|
+
case options[:format].downcase
|
22
|
+
when "json"
|
23
|
+
display_json_output(reports)
|
24
|
+
when "yaml"
|
25
|
+
display_yaml_output(reports)
|
26
|
+
else # Default to text
|
27
|
+
display_text_output(reports)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def collect_reports(paths)
|
34
|
+
reports = []
|
35
|
+
|
36
|
+
paths.each do |path|
|
37
|
+
handle_path(path, reports)
|
38
|
+
end
|
39
|
+
|
40
|
+
reports
|
41
|
+
end
|
42
|
+
|
43
|
+
def handle_path(path, reports)
|
44
|
+
if File.directory?(path)
|
45
|
+
handle_directory(path, reports)
|
46
|
+
elsif File.extname(path).downcase == ".exp"
|
47
|
+
handle_express_file(path, reports)
|
48
|
+
elsif [".yml", ".yaml"].include?(File.extname(path).downcase)
|
49
|
+
handle_yaml_manifest(path, reports)
|
50
|
+
else
|
51
|
+
say "Unsupported file type: #{path}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def handle_directory(path, reports)
|
56
|
+
say "Processing directory: #{path}"
|
57
|
+
exp_files = Dir.glob(File.join(path, "**", "*.exp"))
|
58
|
+
if exp_files.empty?
|
59
|
+
say "No EXPRESS files found in directory: #{path}"
|
60
|
+
return
|
61
|
+
end
|
62
|
+
|
63
|
+
say "Found #{exp_files.size} EXPRESS files to process"
|
64
|
+
|
65
|
+
# Initialize progress bar for directory files
|
66
|
+
progress = ProgressBar.create(
|
67
|
+
title: "Processing files",
|
68
|
+
total: exp_files.size,
|
69
|
+
format: "%t: [%B] %p%% %a [%c/%C] %e",
|
70
|
+
output: $stdout,
|
71
|
+
)
|
72
|
+
|
73
|
+
# Parse all files and create a repository with progress tracking
|
74
|
+
begin
|
75
|
+
repository = Expressir::Express::Parser.from_files(exp_files) do |filename, _schemas, error|
|
76
|
+
if error
|
77
|
+
say " Error processing #{File.basename(filename)}: #{error.message}"
|
78
|
+
end
|
79
|
+
progress.increment
|
80
|
+
end
|
81
|
+
skip_types = parse_skip_types
|
82
|
+
report = Expressir::Coverage::Report.from_repository(repository, skip_types)
|
83
|
+
reports << report
|
84
|
+
rescue StandardError => e
|
85
|
+
say "Error processing directory #{path}: #{e.message}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def handle_express_file(path, reports)
|
90
|
+
say "Processing file: #{path}"
|
91
|
+
begin
|
92
|
+
# For a single file, we don't need a progress bar
|
93
|
+
skip_types = parse_skip_types
|
94
|
+
report = Expressir::Coverage::Report.from_file(path, skip_types)
|
95
|
+
reports << report
|
96
|
+
rescue StandardError => e
|
97
|
+
say "Error processing file #{path}: #{e.message}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def handle_yaml_manifest(path, reports)
|
102
|
+
say "Processing YAML manifest: #{path}"
|
103
|
+
begin
|
104
|
+
schema_list = YAML.load_file(path)
|
105
|
+
manifest_dir = File.dirname(path)
|
106
|
+
|
107
|
+
if schema_list.is_a?(Hash) && schema_list["schemas"]
|
108
|
+
schemas_data = schema_list["schemas"]
|
109
|
+
|
110
|
+
# Handle the nested structure with schema name keys and path values
|
111
|
+
if schemas_data.is_a?(Hash)
|
112
|
+
schema_files = schemas_data.values.map do |schema_data|
|
113
|
+
if schema_data.is_a?(Hash) && schema_data["path"]
|
114
|
+
# Make path relative to the manifest location
|
115
|
+
File.expand_path(schema_data["path"], manifest_dir)
|
116
|
+
end
|
117
|
+
end.compact
|
118
|
+
|
119
|
+
say "Found #{schema_files.size} schema files to process"
|
120
|
+
else
|
121
|
+
# If it's a direct array of paths (old format)
|
122
|
+
schema_files = schemas_data
|
123
|
+
end
|
124
|
+
elsif schema_list.is_a?(Array)
|
125
|
+
schema_files = schema_list
|
126
|
+
else
|
127
|
+
say "Invalid YAML format. Expected an array of schema paths or a hash with a 'schemas' key."
|
128
|
+
return
|
129
|
+
end
|
130
|
+
|
131
|
+
# Initialize progress bar
|
132
|
+
if schema_files && !schema_files.empty?
|
133
|
+
say "Processing schemas from manifest file"
|
134
|
+
|
135
|
+
progress = ProgressBar.create(
|
136
|
+
title: "Processing schemas",
|
137
|
+
total: schema_files.size,
|
138
|
+
format: "%t: [%B] %p%% %a [%c/%C] %e",
|
139
|
+
output: $stdout,
|
140
|
+
)
|
141
|
+
|
142
|
+
# Process files with progress tracking
|
143
|
+
repository = Expressir::Express::Parser.from_files(schema_files) do |filename, _schemas, error|
|
144
|
+
if error
|
145
|
+
say " Error processing #{File.basename(filename)}: #{error.message}"
|
146
|
+
end
|
147
|
+
progress.increment
|
148
|
+
end
|
149
|
+
|
150
|
+
# Create and add the report
|
151
|
+
skip_types = parse_skip_types
|
152
|
+
report = Expressir::Coverage::Report.from_repository(repository, skip_types)
|
153
|
+
reports << report
|
154
|
+
end
|
155
|
+
rescue StandardError => e
|
156
|
+
say "Error processing YAML manifest #{path}: #{e.message}"
|
157
|
+
say "Debug: schema_list structure: #{schema_list.class}" if schema_list
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def display_text_output(reports)
|
162
|
+
say "\nEXPRESS Documentation Coverage"
|
163
|
+
say "=============================="
|
164
|
+
|
165
|
+
# If multiple reports, display directory coverage first
|
166
|
+
if reports.size > 1
|
167
|
+
display_directory_coverage(reports)
|
168
|
+
end
|
169
|
+
|
170
|
+
display_file_coverage(reports)
|
171
|
+
display_overall_stats(reports)
|
172
|
+
end
|
173
|
+
|
174
|
+
def display_directory_coverage(reports)
|
175
|
+
say "\nDirectory Coverage:"
|
176
|
+
|
177
|
+
# Collect directory data from all reports
|
178
|
+
dirs = {}
|
179
|
+
reports.each do |report|
|
180
|
+
report.directory_reports.each do |dir_report|
|
181
|
+
dir = dir_report["directory"]
|
182
|
+
dirs[dir] ||= { "total" => 0, "documented" => 0 }
|
183
|
+
dirs[dir]["total"] += dir_report["total"]
|
184
|
+
dirs[dir]["documented"] += dir_report["documented"]
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Create table
|
189
|
+
table = Terminal::Table.new(
|
190
|
+
title: "Directory Coverage",
|
191
|
+
headings: ["Directory", "Total", "Documented", "Coverage %"],
|
192
|
+
style: {
|
193
|
+
border_x: "-",
|
194
|
+
border_y: "|",
|
195
|
+
border_i: "+",
|
196
|
+
},
|
197
|
+
)
|
198
|
+
|
199
|
+
# Add rows
|
200
|
+
dirs.each do |dir, stats|
|
201
|
+
coverage = stats["total"].positive? ? (stats["documented"].to_f / stats["total"] * 100).round(2) : 100.0
|
202
|
+
table.add_row [dir, stats["total"], stats["documented"], "#{coverage}%"]
|
203
|
+
end
|
204
|
+
|
205
|
+
say table
|
206
|
+
end
|
207
|
+
|
208
|
+
def display_file_coverage(reports)
|
209
|
+
say "\nFile Coverage:"
|
210
|
+
|
211
|
+
# Create table
|
212
|
+
table = Terminal::Table.new(
|
213
|
+
title: "File Coverage",
|
214
|
+
headings: ["File", "Undocumented Entities", "Coverage %"],
|
215
|
+
style: {
|
216
|
+
border_x: "-",
|
217
|
+
border_y: "|",
|
218
|
+
border_i: "+",
|
219
|
+
},
|
220
|
+
)
|
221
|
+
|
222
|
+
reports.each do |report|
|
223
|
+
report.file_reports.each do |file_report|
|
224
|
+
file_path = file_report["file"]
|
225
|
+
|
226
|
+
# Format undocumented entities as "TYPE name, TYPE name, ..."
|
227
|
+
undocumented_formatted = file_report["undocumented"].map do |entity_info|
|
228
|
+
"#{entity_info['type']} #{entity_info['name']}"
|
229
|
+
end.join(", ")
|
230
|
+
|
231
|
+
coverage = file_report["coverage"].round(2)
|
232
|
+
table.add_row [file_path, undocumented_formatted, "#{coverage}%"]
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
say table
|
237
|
+
end
|
238
|
+
|
239
|
+
def display_overall_stats(reports)
|
240
|
+
# Get structured report for overall statistics
|
241
|
+
overall = build_structured_report(reports)["overall"]
|
242
|
+
|
243
|
+
table = Terminal::Table.new(
|
244
|
+
title: "Overall Documentation Coverage",
|
245
|
+
style: {
|
246
|
+
border_x: "-",
|
247
|
+
border_y: "|",
|
248
|
+
border_i: "+",
|
249
|
+
},
|
250
|
+
)
|
251
|
+
|
252
|
+
table.add_row ["Coverage Percentage", "#{overall['coverage_percentage']}%"]
|
253
|
+
table.add_row ["Total Entities", overall["total_entities"]]
|
254
|
+
table.add_row ["Documented Entities", overall["documented_entities"]]
|
255
|
+
table.add_row ["Undocumented Entities", overall["undocumented_entities"]]
|
256
|
+
|
257
|
+
say table
|
258
|
+
end
|
259
|
+
|
260
|
+
def build_structured_report(reports)
|
261
|
+
{
|
262
|
+
"overall" => {
|
263
|
+
"total_entities" => reports.sum { |r| r.total_entities.size },
|
264
|
+
"documented_entities" => reports.sum { |r| r.documented_entities.size },
|
265
|
+
"undocumented_entities" => reports.sum { |r| r.undocumented_entities.size },
|
266
|
+
"coverage_percentage" => if reports.sum { |r| r.total_entities.size }.positive?
|
267
|
+
(reports.sum { |r| r.documented_entities.size }.to_f / reports.sum { |r| r.total_entities.size } * 100).round(2)
|
268
|
+
else
|
269
|
+
100.0
|
270
|
+
end,
|
271
|
+
},
|
272
|
+
"files" => reports.flat_map(&:file_reports),
|
273
|
+
"directories" => reports.flat_map(&:directory_reports),
|
274
|
+
}
|
275
|
+
end
|
276
|
+
|
277
|
+
def display_json_output(reports)
|
278
|
+
say JSON.pretty_generate(build_structured_report(reports))
|
279
|
+
end
|
280
|
+
|
281
|
+
def display_yaml_output(reports)
|
282
|
+
say build_structured_report(reports).to_yaml
|
283
|
+
end
|
284
|
+
|
285
|
+
# Parse and validate the skip_types option
|
286
|
+
# @return [Array<String>] Array of validated entity type names
|
287
|
+
def parse_skip_types
|
288
|
+
skip_types_option = options["exclude"]
|
289
|
+
return [] unless skip_types_option
|
290
|
+
|
291
|
+
# Split by comma and clean up whitespace
|
292
|
+
requested_types = skip_types_option.split(",").map(&:strip).map(&:upcase)
|
293
|
+
|
294
|
+
# Validate against known entity types
|
295
|
+
valid_types = Expressir::Coverage::ENTITY_TYPE_MAP.keys
|
296
|
+
invalid_types = requested_types - valid_types
|
297
|
+
|
298
|
+
unless invalid_types.empty?
|
299
|
+
exit_with_error "Invalid entity types: #{invalid_types.join(', ')}. " \
|
300
|
+
"Valid types are: #{valid_types.join(', ')}"
|
301
|
+
end
|
302
|
+
|
303
|
+
requested_types
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Expressir
|
2
|
+
module Commands
|
3
|
+
class Format < Base
|
4
|
+
def run(path)
|
5
|
+
repository = Expressir::Express::Parser.from_file(path)
|
6
|
+
repository.schemas.each do |schema|
|
7
|
+
say "\n(* Expressir formatted schema: #{schema.id} *)\n"
|
8
|
+
say schema.to_s(no_remarks: true)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Expressir
|
2
|
+
module Commands
|
3
|
+
class Validate < Base
|
4
|
+
def run(paths)
|
5
|
+
no_version = []
|
6
|
+
no_valid = []
|
7
|
+
|
8
|
+
paths.each do |path|
|
9
|
+
x = Pathname.new(path).realpath.relative_path_from(Dir.pwd)
|
10
|
+
say "Validating #{x}"
|
11
|
+
ret = validate_schema(path)
|
12
|
+
|
13
|
+
if ret.nil?
|
14
|
+
no_valid << "Failed to parse: #{x}"
|
15
|
+
next
|
16
|
+
end
|
17
|
+
|
18
|
+
ret.each do |schema_id|
|
19
|
+
no_version << "Missing version string: schema `#{schema_id}` | #{x}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
print_validation_errors(:failed_to_parse, no_valid)
|
24
|
+
print_validation_errors(:missing_version_string, no_version)
|
25
|
+
|
26
|
+
exit 1 unless [no_valid, no_version].all?(&:empty?)
|
27
|
+
|
28
|
+
say "Validation passed for all EXPRESS schemas."
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def validate_schema(path)
|
34
|
+
repository = Expressir::Express::Parser.from_file(path)
|
35
|
+
repository.schemas.inject([]) do |acc, schema|
|
36
|
+
acc << schema.id unless schema.version&.value
|
37
|
+
acc
|
38
|
+
end
|
39
|
+
rescue StandardError
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def print_validation_errors(type, array)
|
44
|
+
return if array.empty?
|
45
|
+
|
46
|
+
say "#{'*' * 20} RESULTS: #{type.to_s.upcase.tr('_', ' ')} #{'*' * 20}"
|
47
|
+
array.each do |msg|
|
48
|
+
say msg
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|