suma 0.5.7 → 0.5.8
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/nightly-benchmark.yml +25 -0
- data/.github/workflows/release-provenance.yml +38 -0
- data/.rubocop_todo.yml +84 -0
- data/CLAUDE.md +44 -0
- data/Rakefile +13 -1
- data/bin/benchmark_corpus +138 -0
- data/bin/release_provenance +40 -0
- data/lib/suma/build_plan.rb +71 -0
- data/lib/suma/change_classification.rb +37 -0
- data/lib/suma/change_impact.rb +61 -0
- data/lib/suma/change_manifest.rb +147 -0
- data/lib/suma/cli/build.rb +23 -0
- data/lib/suma/cli/compare.rb +49 -2
- data/lib/suma/cli/core.rb +83 -0
- data/lib/suma/cli/export.rb +140 -10
- data/lib/suma/cli/extract_terms.rb +11 -0
- data/lib/suma/cli/generate_register.rb +12 -0
- data/lib/suma/cli/resolve.rb +45 -0
- data/lib/suma/cli/validate.rb +90 -0
- data/lib/suma/cli.rb +1 -0
- data/lib/suma/closure_validator.rb +317 -0
- data/lib/suma/corpus_graph.rb +141 -0
- data/lib/suma/express_schema.rb +22 -28
- data/lib/suma/null_cache.rb +4 -0
- data/lib/suma/owl_projection.rb +611 -0
- data/lib/suma/processor.rb +55 -6
- data/lib/suma/provenance.rb +159 -0
- data/lib/suma/publication.rb +108 -0
- data/lib/suma/register_manifest_generator.rb +76 -8
- data/lib/suma/schema_cache.rb +72 -13
- data/lib/suma/schema_category.rb +31 -2
- data/lib/suma/schema_collection.rb +58 -5
- data/lib/suma/schema_exporter.rb +5 -5
- data/lib/suma/schema_naming.rb +29 -33
- data/lib/suma/schema_profile.rb +134 -0
- data/lib/suma/term_classification.rb +9 -2
- data/lib/suma/term_extractor.rb +76 -35
- data/lib/suma/urn_resolver.rb +318 -0
- data/lib/suma/version.rb +1 -1
- data/lib/suma/worker_pool.rb +62 -0
- data/lib/suma.rb +12 -0
- metadata +19 -2
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
require "expressir"
|
|
6
|
+
require "glossarist"
|
|
7
|
+
# Expressir::SchemaManifest references Pathname without requiring it.
|
|
8
|
+
require "pathname"
|
|
9
|
+
|
|
10
|
+
module Suma
|
|
11
|
+
# Resolves URNs to canonical JSON + HTML artifacts.
|
|
12
|
+
#
|
|
13
|
+
# Sources:
|
|
14
|
+
# - schema manifest: schema and declared-element URNs
|
|
15
|
+
# - Glossarist concept documents: term URNs
|
|
16
|
+
# - register.yaml: the dataset URN
|
|
17
|
+
#
|
|
18
|
+
# Artifacts are written under the output directory by URN path, so every
|
|
19
|
+
# URN emitted by a register (and every entity in the corpus) has a static,
|
|
20
|
+
# dereferenceable document without a server.
|
|
21
|
+
class UrnResolver
|
|
22
|
+
class NotFoundError < Error; end
|
|
23
|
+
|
|
24
|
+
attr_reader :urn
|
|
25
|
+
|
|
26
|
+
# @param manifest_file [String] schema manifest path
|
|
27
|
+
# @param urn [String, nil] corpus URN base; required unless a register
|
|
28
|
+
# supplies one
|
|
29
|
+
# @param concepts_dir [String, nil] directory of Glossarist concept YAML
|
|
30
|
+
# @param register_file [String, nil] Glossarist register.yaml
|
|
31
|
+
def initialize(manifest_file:, urn: nil, concepts_dir: nil,
|
|
32
|
+
register_file: nil)
|
|
33
|
+
@manifest_file = File.expand_path(manifest_file)
|
|
34
|
+
@register_file = register_file && File.expand_path(register_file)
|
|
35
|
+
@concepts_dir = concepts_dir && File.expand_path(concepts_dir)
|
|
36
|
+
@urn = urn && Urn.new(urn)
|
|
37
|
+
load_register if @register_file
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @return [Hash{String=>Hash}] URN → artifact payload
|
|
41
|
+
def artifacts
|
|
42
|
+
@artifacts ||= schema_artifacts
|
|
43
|
+
.merge(concept_artifacts)
|
|
44
|
+
.merge(dataset_artifacts)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @param urn [String]
|
|
48
|
+
# @return [Hash] artifact payload
|
|
49
|
+
# @raise [NotFoundError]
|
|
50
|
+
def resolve(urn)
|
|
51
|
+
artifacts[normalize(urn)] || raise(
|
|
52
|
+
NotFoundError, "urn does not resolve: #{urn}"
|
|
53
|
+
)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Write JSON and HTML for every artifact.
|
|
57
|
+
def write(output_directory)
|
|
58
|
+
artifacts.each_key { |key| write_urn(key, output_directory) }
|
|
59
|
+
Utils.log "Wrote #{artifacts.length} URN artifacts to #{output_directory}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Write JSON and HTML for one URN.
|
|
63
|
+
def write_urn(urn, output_directory)
|
|
64
|
+
payload = resolve(urn)
|
|
65
|
+
json = canonical_json(payload)
|
|
66
|
+
write_file(output_directory, urn, "json", json)
|
|
67
|
+
write_file(output_directory, urn, "html", html_document(urn, json))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def normalize(value)
|
|
73
|
+
value.to_s.delete_suffix(":*")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def base_urn
|
|
77
|
+
@urn&.to_s || @register_urn
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def compose(component, leaf)
|
|
81
|
+
"#{base_urn}:#{component}:#{leaf}"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def load_register
|
|
85
|
+
@register = Glossarist::DatasetRegister.from_file(@register_file)
|
|
86
|
+
@register_urn = @register.urn
|
|
87
|
+
@urn ||= Urn.new(@register_urn) if @register_urn
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def schema_artifacts
|
|
91
|
+
return {} unless base_urn
|
|
92
|
+
|
|
93
|
+
artifacts = {}
|
|
94
|
+
schemas.each do |schema|
|
|
95
|
+
artifacts[compose(:tech, schema.id)] = schema_payload(schema)
|
|
96
|
+
schema.children.each do |element|
|
|
97
|
+
payload = element_payload(schema, element)
|
|
98
|
+
artifacts[compose(:tech, "#{schema.id}.#{element.id}")] = payload if
|
|
99
|
+
payload
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
artifacts
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def schemas
|
|
106
|
+
@schemas ||= begin
|
|
107
|
+
manifest = Expressir::SchemaManifest.from_file(@manifest_file)
|
|
108
|
+
manifest.schemas.flat_map do |entry|
|
|
109
|
+
Expressir::Express::Parser.from_file(entry.path.to_s).schemas
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def schema_payload(schema)
|
|
115
|
+
{
|
|
116
|
+
"urn" => compose(:tech, schema.id),
|
|
117
|
+
"kind" => "schema",
|
|
118
|
+
"id" => schema.id,
|
|
119
|
+
"source" => relative_source(schema),
|
|
120
|
+
"interface" => Array(schema.interfaces).filter_map do |interface|
|
|
121
|
+
interface.schema&.id
|
|
122
|
+
end,
|
|
123
|
+
"elements" => schema.children.filter_map do |element|
|
|
124
|
+
element.id if declared_element?(element)
|
|
125
|
+
end.sort,
|
|
126
|
+
}
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def element_payload(schema, element)
|
|
130
|
+
case element
|
|
131
|
+
when Expressir::Model::Declarations::Entity
|
|
132
|
+
entity_payload(schema, element)
|
|
133
|
+
when Expressir::Model::Declarations::Type
|
|
134
|
+
type_payload(schema, element)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def entity_payload(schema, entity)
|
|
139
|
+
{
|
|
140
|
+
"urn" => compose(:tech, "#{schema.id}.#{entity.id}"),
|
|
141
|
+
"kind" => "entity",
|
|
142
|
+
"schema" => schema.id,
|
|
143
|
+
"id" => entity.id,
|
|
144
|
+
"abstract" => entity.abstract,
|
|
145
|
+
"source" => relative_source(schema),
|
|
146
|
+
"subtype_of" => Array(entity.subtype_of).filter_map(&:id),
|
|
147
|
+
"attributes" => Array(entity.attributes).map do |attribute|
|
|
148
|
+
attribute_payload(attribute)
|
|
149
|
+
end,
|
|
150
|
+
"where_rules" => Array(entity.where_rules).map(&:id),
|
|
151
|
+
}
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def type_payload(schema, type)
|
|
155
|
+
{
|
|
156
|
+
"urn" => compose(:tech, "#{schema.id}.#{type.id}"),
|
|
157
|
+
"kind" => "type",
|
|
158
|
+
"schema" => schema.id,
|
|
159
|
+
"id" => type.id,
|
|
160
|
+
"source" => relative_source(schema),
|
|
161
|
+
"underlying" => type.underlying_type.class.name.split("::").last,
|
|
162
|
+
"where_rules" => Array(type.where_rules).map(&:id),
|
|
163
|
+
}
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def attribute_payload(attribute)
|
|
167
|
+
{
|
|
168
|
+
"id" => attribute.id,
|
|
169
|
+
"kind" => attribute.kind,
|
|
170
|
+
"optional" => attribute.optional == true,
|
|
171
|
+
"type" => attribute.type&.source,
|
|
172
|
+
}
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def declared_element?(element)
|
|
176
|
+
element.is_a?(Expressir::Model::Declarations::Entity) ||
|
|
177
|
+
element.is_a?(Expressir::Model::Declarations::Type)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def relative_source(schema)
|
|
181
|
+
return nil unless schema.file
|
|
182
|
+
|
|
183
|
+
Pathname.new(schema.file.to_s)
|
|
184
|
+
.relative_path_from(Pathname.new(File.dirname(@manifest_file)))
|
|
185
|
+
.to_s
|
|
186
|
+
rescue ArgumentError
|
|
187
|
+
schema.file.to_s
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def concept_artifacts
|
|
191
|
+
return {} unless @concepts_dir && base_urn
|
|
192
|
+
return {} unless Dir.exist?(@concepts_dir)
|
|
193
|
+
|
|
194
|
+
Dir[File.join(@concepts_dir,
|
|
195
|
+
"*.yaml")].each_with_object({}) do |path, map|
|
|
196
|
+
document = Glossarist::V3::ConceptDocument.from_yamls(File.read(path))
|
|
197
|
+
concept = document.concept
|
|
198
|
+
next unless concept
|
|
199
|
+
|
|
200
|
+
key = compose(:term, concept.data.id)
|
|
201
|
+
map[key] = concept_payload(concept, document)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def concept_payload(concept, document)
|
|
206
|
+
{
|
|
207
|
+
"urn" => compose(:term, concept.data.id),
|
|
208
|
+
"kind" => "concept",
|
|
209
|
+
"id" => concept.data.id,
|
|
210
|
+
"uuid" => concept.uuid,
|
|
211
|
+
"domain" => concept.data.domains&.first&.concept_id,
|
|
212
|
+
"localizations" => document.localizations.map do |localized|
|
|
213
|
+
localization_payload(localized)
|
|
214
|
+
end,
|
|
215
|
+
}
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def localization_payload(localized)
|
|
219
|
+
data = localized.data
|
|
220
|
+
{
|
|
221
|
+
"language" => data.language_code,
|
|
222
|
+
"terms" => Array(data.terms).map(&:designation),
|
|
223
|
+
"definitions" => Array(data.definition).map(&:content),
|
|
224
|
+
"notes" => Array(data.notes).map(&:content),
|
|
225
|
+
"sources" => Array(data.sources).map do |source|
|
|
226
|
+
source_payload(source)
|
|
227
|
+
end,
|
|
228
|
+
}
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def source_payload(source)
|
|
232
|
+
{
|
|
233
|
+
"id" => source.id,
|
|
234
|
+
"type" => source.type,
|
|
235
|
+
"source" => source.origin&.ref&.source,
|
|
236
|
+
"version" => source.origin&.ref&.version,
|
|
237
|
+
"sourced_from" => Array(source.sourced_from).map do |citation|
|
|
238
|
+
citation.ref&.source
|
|
239
|
+
end,
|
|
240
|
+
}
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def dataset_artifacts
|
|
244
|
+
return {} unless @register
|
|
245
|
+
|
|
246
|
+
{
|
|
247
|
+
normalize(@register.urn) => {
|
|
248
|
+
"urn" => @register.urn,
|
|
249
|
+
"kind" => "dataset",
|
|
250
|
+
"id" => @register.id,
|
|
251
|
+
"ref" => @register.ref,
|
|
252
|
+
"year" => @register.year,
|
|
253
|
+
"supersedes" => @register.supersedes,
|
|
254
|
+
"tags" => @register.tags,
|
|
255
|
+
"sections" => Array(@register.sections).map do |s|
|
|
256
|
+
section_payload(s)
|
|
257
|
+
end,
|
|
258
|
+
},
|
|
259
|
+
}
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def section_payload(section)
|
|
263
|
+
{
|
|
264
|
+
"id" => section.id,
|
|
265
|
+
"name" => section.name("eng"),
|
|
266
|
+
"children" => Array(section.children).map { |s| section_payload(s) },
|
|
267
|
+
}
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# Deterministic documents: sorted object keys, trailing newline.
|
|
271
|
+
def canonical_json(value)
|
|
272
|
+
"#{JSON.pretty_generate(canonicalize(value))}\n"
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def canonicalize(value)
|
|
276
|
+
case value
|
|
277
|
+
when Hash
|
|
278
|
+
value.keys.sort.to_h { |key| [key, canonicalize(value[key])] }
|
|
279
|
+
when Array
|
|
280
|
+
value.map { |item| canonicalize(item) }
|
|
281
|
+
else
|
|
282
|
+
value
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def write_file(output_directory, urn, extension, content)
|
|
287
|
+
path = File.join(output_directory, artifact_path(urn, extension))
|
|
288
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
289
|
+
File.write(path, content, encoding: "utf-8")
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def artifact_path(urn, extension)
|
|
293
|
+
segments = normalize(urn).split(":").map do |segment|
|
|
294
|
+
segment.gsub(/[^A-Za-z0-9._-]/, "_")
|
|
295
|
+
end
|
|
296
|
+
"#{segments.join('/')}.#{extension}"
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def html_document(urn, json)
|
|
300
|
+
title = escape_html(urn)
|
|
301
|
+
<<~HTML
|
|
302
|
+
<!doctype html>
|
|
303
|
+
<html lang="en">
|
|
304
|
+
<head><meta charset="utf-8"><title>#{title}</title></head>
|
|
305
|
+
<body>
|
|
306
|
+
<h1>#{title}</h1>
|
|
307
|
+
<pre>#{escape_html(json)}</pre>
|
|
308
|
+
</body>
|
|
309
|
+
</html>
|
|
310
|
+
HTML
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def escape_html(value)
|
|
314
|
+
value.gsub("&", "&").gsub("<", "<").gsub(">", ">")
|
|
315
|
+
.gsub('"', """)
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
data/lib/suma/version.rb
CHANGED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Suma
|
|
4
|
+
# A bounded worker pool for independent per-schema work.
|
|
5
|
+
#
|
|
6
|
+
# Document compilation is deliberately excluded: Metanorma rendering is not
|
|
7
|
+
# thread-safe and memory-hungry, so it stays sequential and composes with
|
|
8
|
+
# StagedCollectionBuilder's process isolation. Parsing and file export are
|
|
9
|
+
# independent per schema and safe to overlap.
|
|
10
|
+
class WorkerPool
|
|
11
|
+
attr_reader :size
|
|
12
|
+
|
|
13
|
+
def initialize(size: 1)
|
|
14
|
+
@size = Integer(size)
|
|
15
|
+
raise ArgumentError, "worker pool size must be at least 1" if @size < 1
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Map +items+ in order, running at most +size+ blocks concurrently.
|
|
19
|
+
#
|
|
20
|
+
# @return [Array] results in input order
|
|
21
|
+
def map(items, &block)
|
|
22
|
+
return items.map(&block) if size == 1 || items.length <= 1
|
|
23
|
+
|
|
24
|
+
queue = Queue.new
|
|
25
|
+
items.each_with_index { |item, index| queue << [item, index] }
|
|
26
|
+
results = Array.new(items.length)
|
|
27
|
+
errors = Queue.new
|
|
28
|
+
workers = Array.new([size, items.length].min) do
|
|
29
|
+
worker(queue, results, errors, block)
|
|
30
|
+
end
|
|
31
|
+
workers.each(&:join)
|
|
32
|
+
raise errors.pop unless errors.empty?
|
|
33
|
+
|
|
34
|
+
results
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def worker(queue, results, errors, block)
|
|
40
|
+
Thread.new do
|
|
41
|
+
loop do
|
|
42
|
+
pair = next_item(queue)
|
|
43
|
+
break unless pair
|
|
44
|
+
|
|
45
|
+
item, index = pair
|
|
46
|
+
begin
|
|
47
|
+
results[index] = block.call(item)
|
|
48
|
+
rescue StandardError => e
|
|
49
|
+
errors << e
|
|
50
|
+
break
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def next_item(queue)
|
|
57
|
+
queue.pop(true)
|
|
58
|
+
rescue ThreadError
|
|
59
|
+
nil
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
data/lib/suma.rb
CHANGED
|
@@ -7,8 +7,17 @@ require "fileutils"
|
|
|
7
7
|
module Suma
|
|
8
8
|
autoload :VERSION, "suma/version"
|
|
9
9
|
|
|
10
|
+
autoload :SchemaProfile, "suma/schema_profile"
|
|
11
|
+
autoload :BuildPlan, "suma/build_plan"
|
|
10
12
|
autoload :Processor, "suma/processor"
|
|
13
|
+
autoload :Provenance, "suma/provenance"
|
|
14
|
+
autoload :Publication, "suma/publication"
|
|
15
|
+
autoload :ChangeClassification, "suma/change_classification"
|
|
16
|
+
autoload :ChangeImpact, "suma/change_impact"
|
|
17
|
+
autoload :ChangeManifest, "suma/change_manifest"
|
|
18
|
+
autoload :ClosureValidator, "suma/closure_validator"
|
|
11
19
|
autoload :CollectionConfig, "suma/collection_config"
|
|
20
|
+
autoload :CorpusGraph, "suma/corpus_graph"
|
|
12
21
|
autoload :CollectionManifest, "suma/collection_manifest"
|
|
13
22
|
autoload :EengineConverter, "suma/eengine_converter"
|
|
14
23
|
autoload :ExpressReformatter, "suma/express_reformatter"
|
|
@@ -19,6 +28,7 @@ module Suma
|
|
|
19
28
|
autoload :MappingDrift, "suma/mapping_drift"
|
|
20
29
|
autoload :NoteProcessor, "suma/note_processor"
|
|
21
30
|
autoload :NullCache, "suma/null_cache"
|
|
31
|
+
autoload :OwlProjection, "suma/owl_projection"
|
|
22
32
|
autoload :RegisterManifestGenerator, "suma/register_manifest_generator"
|
|
23
33
|
autoload :SchemaCache, "suma/schema_cache"
|
|
24
34
|
autoload :SchemaCategory, "suma/schema_category"
|
|
@@ -38,7 +48,9 @@ module Suma
|
|
|
38
48
|
autoload :TermExtractor, "suma/term_extractor"
|
|
39
49
|
autoload :ThorExt, "suma/thor_ext"
|
|
40
50
|
autoload :Urn, "suma/urn"
|
|
51
|
+
autoload :UrnResolver, "suma/urn_resolver"
|
|
41
52
|
autoload :Utils, "suma/utils"
|
|
53
|
+
autoload :WorkerPool, "suma/worker_pool"
|
|
42
54
|
|
|
43
55
|
autoload :Cli, "suma/cli"
|
|
44
56
|
autoload :Eengine, "suma/eengine"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: suma
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: expressir
|
|
@@ -166,7 +166,9 @@ executables:
|
|
|
166
166
|
extensions: []
|
|
167
167
|
extra_rdoc_files: []
|
|
168
168
|
files:
|
|
169
|
+
- ".github/workflows/nightly-benchmark.yml"
|
|
169
170
|
- ".github/workflows/rake.yml"
|
|
171
|
+
- ".github/workflows/release-provenance.yml"
|
|
170
172
|
- ".github/workflows/release.yml"
|
|
171
173
|
- ".gitignore"
|
|
172
174
|
- ".rspec"
|
|
@@ -177,10 +179,16 @@ files:
|
|
|
177
179
|
- Gemfile
|
|
178
180
|
- README.adoc
|
|
179
181
|
- Rakefile
|
|
182
|
+
- bin/benchmark_corpus
|
|
180
183
|
- bin/console
|
|
184
|
+
- bin/release_provenance
|
|
181
185
|
- bin/setup
|
|
182
186
|
- exe/suma
|
|
183
187
|
- lib/suma.rb
|
|
188
|
+
- lib/suma/build_plan.rb
|
|
189
|
+
- lib/suma/change_classification.rb
|
|
190
|
+
- lib/suma/change_impact.rb
|
|
191
|
+
- lib/suma/change_manifest.rb
|
|
184
192
|
- lib/suma/cli.rb
|
|
185
193
|
- lib/suma/cli/build.rb
|
|
186
194
|
- lib/suma/cli/check_svg_quality.rb
|
|
@@ -192,10 +200,13 @@ files:
|
|
|
192
200
|
- lib/suma/cli/generate_register.rb
|
|
193
201
|
- lib/suma/cli/generate_schemas.rb
|
|
194
202
|
- lib/suma/cli/reformat.rb
|
|
203
|
+
- lib/suma/cli/resolve.rb
|
|
195
204
|
- lib/suma/cli/validate.rb
|
|
196
205
|
- lib/suma/cli/validate_links.rb
|
|
206
|
+
- lib/suma/closure_validator.rb
|
|
197
207
|
- lib/suma/collection_config.rb
|
|
198
208
|
- lib/suma/collection_manifest.rb
|
|
209
|
+
- lib/suma/corpus_graph.rb
|
|
199
210
|
- lib/suma/eengine.rb
|
|
200
211
|
- lib/suma/eengine/errors.rb
|
|
201
212
|
- lib/suma/eengine/wrapper.rb
|
|
@@ -213,7 +224,10 @@ files:
|
|
|
213
224
|
- lib/suma/mapping_drift.rb
|
|
214
225
|
- lib/suma/note_processor.rb
|
|
215
226
|
- lib/suma/null_cache.rb
|
|
227
|
+
- lib/suma/owl_projection.rb
|
|
216
228
|
- lib/suma/processor.rb
|
|
229
|
+
- lib/suma/provenance.rb
|
|
230
|
+
- lib/suma/publication.rb
|
|
217
231
|
- lib/suma/register_manifest_generator.rb
|
|
218
232
|
- lib/suma/schema_cache.rb
|
|
219
233
|
- lib/suma/schema_category.rb
|
|
@@ -225,6 +239,7 @@ files:
|
|
|
225
239
|
- lib/suma/schema_index.rb
|
|
226
240
|
- lib/suma/schema_manifest_generator.rb
|
|
227
241
|
- lib/suma/schema_naming.rb
|
|
242
|
+
- lib/suma/schema_profile.rb
|
|
228
243
|
- lib/suma/schema_template.rb
|
|
229
244
|
- lib/suma/schema_template/document.rb
|
|
230
245
|
- lib/suma/schema_template/plain.rb
|
|
@@ -242,8 +257,10 @@ files:
|
|
|
242
257
|
- lib/suma/term_extractor.rb
|
|
243
258
|
- lib/suma/thor_ext.rb
|
|
244
259
|
- lib/suma/urn.rb
|
|
260
|
+
- lib/suma/urn_resolver.rb
|
|
245
261
|
- lib/suma/utils.rb
|
|
246
262
|
- lib/suma/version.rb
|
|
263
|
+
- lib/suma/worker_pool.rb
|
|
247
264
|
- sig/suma.rbs
|
|
248
265
|
- suma.gemspec
|
|
249
266
|
homepage: https://github.com/metanorma/suma
|