unitsdb 1.0.0 → 2.0.1
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/.gitmodules +3 -0
- data/.rspec +2 -1
- data/.rubocop_todo.yml +168 -15
- data/Gemfile +3 -2
- data/README.adoc +803 -1
- data/exe/unitsdb +7 -0
- data/lib/unitsdb/cli.rb +88 -0
- data/lib/unitsdb/commands/_modify.rb +22 -0
- data/lib/unitsdb/commands/base.rb +26 -0
- data/lib/unitsdb/commands/check_si.rb +124 -0
- data/lib/unitsdb/commands/get.rb +133 -0
- data/lib/unitsdb/commands/normalize.rb +81 -0
- data/lib/unitsdb/commands/release.rb +73 -0
- data/lib/unitsdb/commands/search.rb +219 -0
- data/lib/unitsdb/commands/si_formatter.rb +485 -0
- data/lib/unitsdb/commands/si_matcher.rb +470 -0
- data/lib/unitsdb/commands/si_ttl_parser.rb +100 -0
- data/lib/unitsdb/commands/si_updater.rb +212 -0
- data/lib/unitsdb/commands/ucum/check.rb +126 -0
- data/lib/unitsdb/commands/ucum/formatter.rb +141 -0
- data/lib/unitsdb/commands/ucum/matcher.rb +301 -0
- data/lib/unitsdb/commands/ucum/update.rb +84 -0
- data/lib/unitsdb/commands/ucum/updater.rb +98 -0
- data/lib/unitsdb/commands/ucum/xml_parser.rb +34 -0
- data/lib/unitsdb/commands/ucum.rb +43 -0
- data/lib/unitsdb/commands/validate/identifiers.rb +42 -0
- data/lib/unitsdb/commands/validate/references.rb +318 -0
- data/lib/unitsdb/commands/validate/si_references.rb +109 -0
- data/lib/unitsdb/commands/validate.rb +40 -0
- data/lib/unitsdb/database.rb +662 -0
- data/lib/unitsdb/dimension.rb +49 -0
- data/lib/unitsdb/dimension_details.rb +20 -0
- data/lib/unitsdb/dimension_reference.rb +8 -0
- data/lib/unitsdb/dimensions.rb +5 -10
- data/lib/unitsdb/errors.rb +13 -0
- data/lib/unitsdb/external_reference.rb +14 -0
- data/lib/unitsdb/identifier.rb +8 -0
- data/lib/unitsdb/localized_string.rb +17 -0
- data/lib/unitsdb/prefix.rb +30 -0
- data/lib/unitsdb/prefix_reference.rb +10 -0
- data/lib/unitsdb/prefixes.rb +5 -11
- data/lib/unitsdb/quantities.rb +5 -31
- data/lib/unitsdb/quantity.rb +21 -0
- data/lib/unitsdb/quantity_reference.rb +10 -0
- data/lib/unitsdb/root_unit_reference.rb +14 -0
- data/lib/unitsdb/scale.rb +17 -0
- data/lib/unitsdb/scale_properties.rb +12 -0
- data/lib/unitsdb/scale_reference.rb +10 -0
- data/lib/unitsdb/scales.rb +12 -0
- data/lib/unitsdb/si_derived_base.rb +19 -0
- data/lib/unitsdb/symbol_presentations.rb +3 -8
- data/lib/unitsdb/ucum.rb +198 -0
- data/lib/unitsdb/unit.rb +63 -0
- data/lib/unitsdb/unit_reference.rb +10 -0
- data/lib/unitsdb/unit_system.rb +15 -0
- data/lib/unitsdb/unit_system_reference.rb +10 -0
- data/lib/unitsdb/unit_systems.rb +5 -10
- data/lib/unitsdb/units.rb +5 -10
- data/lib/unitsdb/utils.rb +84 -0
- data/lib/unitsdb/version.rb +1 -1
- data/lib/unitsdb.rb +12 -2
- data/unitsdb.gemspec +6 -3
- metadata +124 -20
- data/lib/unitsdb/dimensions/dimension.rb +0 -59
- data/lib/unitsdb/dimensions/quantity.rb +0 -32
- data/lib/unitsdb/dimensions/symbol.rb +0 -26
- data/lib/unitsdb/prefixes/prefix.rb +0 -35
- data/lib/unitsdb/prefixes/symbol.rb +0 -17
- data/lib/unitsdb/quantities/quantity.rb +0 -37
- data/lib/unitsdb/quantities/unit_reference.rb +0 -15
- data/lib/unitsdb/unit_systems/unit_system.rb +0 -19
- data/lib/unitsdb/units/quantity_reference.rb +0 -17
- data/lib/unitsdb/units/root_unit.rb +0 -21
- data/lib/unitsdb/units/root_units.rb +0 -18
- data/lib/unitsdb/units/si_derived_base.rb +0 -26
- data/lib/unitsdb/units/symbol.rb +0 -19
- data/lib/unitsdb/units/system.rb +0 -17
- data/lib/unitsdb/units/unit.rb +0 -73
- data/lib/unitsdb/unitsdb.rb +0 -6
@@ -0,0 +1,318 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Unitsdb
|
6
|
+
module Commands
|
7
|
+
module Validate
|
8
|
+
class References < Unitsdb::Commands::Base
|
9
|
+
def run
|
10
|
+
# Load the database
|
11
|
+
db = load_database(@options[:database])
|
12
|
+
|
13
|
+
# Build registry of all valid IDs
|
14
|
+
registry = build_id_registry(db)
|
15
|
+
|
16
|
+
# Check all references
|
17
|
+
invalid_refs = check_references(db, registry)
|
18
|
+
|
19
|
+
# Display results
|
20
|
+
display_reference_results(invalid_refs, registry)
|
21
|
+
rescue Unitsdb::Errors::DatabaseError => e
|
22
|
+
puts "Error: #{e.message}"
|
23
|
+
exit(1)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def build_id_registry(db)
|
29
|
+
registry = {}
|
30
|
+
|
31
|
+
# Add all unit identifiers to the registry
|
32
|
+
registry["units"] = {}
|
33
|
+
db.units.each_with_index do |unit, index|
|
34
|
+
unit.identifiers.each do |identifier|
|
35
|
+
next unless identifier.id && identifier.type
|
36
|
+
|
37
|
+
# Add the composite key (type:id)
|
38
|
+
composite_key = "#{identifier.type}:#{identifier.id}"
|
39
|
+
registry["units"][composite_key] = "index:#{index}"
|
40
|
+
|
41
|
+
# Also add just the ID for backward compatibility
|
42
|
+
registry["units"][identifier.id] = "index:#{index}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Add dimension identifiers
|
47
|
+
registry["dimensions"] = {}
|
48
|
+
db.dimensions.each_with_index do |dimension, index|
|
49
|
+
dimension.identifiers.each do |identifier|
|
50
|
+
next unless identifier.id && identifier.type
|
51
|
+
|
52
|
+
composite_key = "#{identifier.type}:#{identifier.id}"
|
53
|
+
registry["dimensions"][composite_key] = "index:#{index}"
|
54
|
+
registry["dimensions"][identifier.id] = "index:#{index}"
|
55
|
+
end
|
56
|
+
|
57
|
+
# Also track dimensions by short name
|
58
|
+
if dimension.respond_to?(:short) && dimension.short
|
59
|
+
registry["dimensions_short"] ||= {}
|
60
|
+
registry["dimensions_short"][dimension.short] = "index:#{index}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Add quantity identifiers
|
65
|
+
registry["quantities"] = {}
|
66
|
+
db.quantities.each_with_index do |quantity, index|
|
67
|
+
quantity.identifiers.each do |identifier|
|
68
|
+
next unless identifier.id && identifier.type
|
69
|
+
|
70
|
+
composite_key = "#{identifier.type}:#{identifier.id}"
|
71
|
+
registry["quantities"][composite_key] = "index:#{index}"
|
72
|
+
registry["quantities"][identifier.id] = "index:#{index}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Add prefix identifiers
|
77
|
+
registry["prefixes"] = {}
|
78
|
+
db.prefixes.each_with_index do |prefix, index|
|
79
|
+
prefix.identifiers.each do |identifier|
|
80
|
+
next unless identifier.id && identifier.type
|
81
|
+
|
82
|
+
composite_key = "#{identifier.type}:#{identifier.id}"
|
83
|
+
registry["prefixes"][composite_key] = "index:#{index}"
|
84
|
+
registry["prefixes"][identifier.id] = "index:#{index}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Add unit system identifiers
|
89
|
+
registry["unit_systems"] = {}
|
90
|
+
db.unit_systems.each_with_index do |unit_system, index|
|
91
|
+
unit_system.identifiers.each do |identifier|
|
92
|
+
next unless identifier.id && identifier.type
|
93
|
+
|
94
|
+
composite_key = "#{identifier.type}:#{identifier.id}"
|
95
|
+
registry["unit_systems"][composite_key] = "index:#{index}"
|
96
|
+
registry["unit_systems"][identifier.id] = "index:#{index}"
|
97
|
+
end
|
98
|
+
|
99
|
+
# Also track unit systems by short name
|
100
|
+
if unit_system.respond_to?(:short) && unit_system.short
|
101
|
+
registry["unit_systems_short"] ||= {}
|
102
|
+
registry["unit_systems_short"][unit_system.short] = "index:#{index}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Debug registry if requested
|
107
|
+
if @options[:debug_registry]
|
108
|
+
puts "Registry contents:"
|
109
|
+
registry.each do |type, ids|
|
110
|
+
puts " #{type}:"
|
111
|
+
ids.each do |id, location|
|
112
|
+
puts " #{id} => #{location}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
registry
|
118
|
+
end
|
119
|
+
|
120
|
+
def check_references(db, registry)
|
121
|
+
invalid_refs = {}
|
122
|
+
|
123
|
+
# Check unit references in dimensions
|
124
|
+
check_dimension_references(db, registry, invalid_refs)
|
125
|
+
|
126
|
+
# Check unit_system references
|
127
|
+
check_unit_system_references(db, registry, invalid_refs)
|
128
|
+
|
129
|
+
# Check quantity references
|
130
|
+
check_quantity_references(db, registry, invalid_refs)
|
131
|
+
|
132
|
+
# Check root unit references in units
|
133
|
+
check_root_unit_references(db, registry, invalid_refs)
|
134
|
+
|
135
|
+
invalid_refs
|
136
|
+
end
|
137
|
+
|
138
|
+
def check_dimension_references(db, registry, invalid_refs)
|
139
|
+
db.dimensions.each_with_index do |dimension, index|
|
140
|
+
next unless dimension.respond_to?(:dimension_reference) && dimension.dimension_reference
|
141
|
+
|
142
|
+
ref_id = dimension.dimension_reference
|
143
|
+
ref_type = "dimensions"
|
144
|
+
ref_path = "dimensions:index:#{index}:dimension_reference"
|
145
|
+
|
146
|
+
validate_reference(ref_id, ref_type, ref_path, registry, invalid_refs, "dimensions")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def check_unit_system_references(db, registry, invalid_refs)
|
151
|
+
db.units.each_with_index do |unit, index|
|
152
|
+
next unless unit.respond_to?(:unit_system_reference) && unit.unit_system_reference
|
153
|
+
|
154
|
+
unit.unit_system_reference.each_with_index do |ref_id, idx|
|
155
|
+
ref_type = "unit_systems"
|
156
|
+
ref_path = "units:index:#{index}:unit_system_reference[#{idx}]"
|
157
|
+
|
158
|
+
validate_reference(ref_id, ref_type, ref_path, registry, invalid_refs, "units")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def check_quantity_references(db, registry, invalid_refs)
|
164
|
+
db.units.each_with_index do |unit, index|
|
165
|
+
next unless unit.respond_to?(:quantity_references) && unit.quantity_references
|
166
|
+
|
167
|
+
unit.quantity_references.each_with_index do |ref_id, idx|
|
168
|
+
ref_type = "quantities"
|
169
|
+
ref_path = "units:index:#{index}:quantity_references[#{idx}]"
|
170
|
+
|
171
|
+
validate_reference(ref_id, ref_type, ref_path, registry, invalid_refs, "units")
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def check_root_unit_references(db, registry, invalid_refs)
|
177
|
+
db.units.each_with_index do |unit, index|
|
178
|
+
next unless unit.respond_to?(:root_units) && unit.root_units
|
179
|
+
|
180
|
+
unit.root_units.each_with_index do |root_unit, idx|
|
181
|
+
next unless root_unit.respond_to?(:unit_reference) && root_unit.unit_reference
|
182
|
+
|
183
|
+
# Check unit reference
|
184
|
+
ref_id = root_unit.unit_reference
|
185
|
+
ref_type = "units"
|
186
|
+
ref_path = "units:index:#{index}:root_units.#{idx}.unit_reference"
|
187
|
+
|
188
|
+
validate_reference(ref_id, ref_type, ref_path, registry, invalid_refs, "units")
|
189
|
+
|
190
|
+
# Check prefix reference if present
|
191
|
+
next unless root_unit.respond_to?(:prefix_reference) && root_unit.prefix_reference
|
192
|
+
|
193
|
+
ref_id = root_unit.prefix_reference
|
194
|
+
ref_type = "prefixes"
|
195
|
+
ref_path = "units:index:#{index}:root_units.#{idx}.prefix_reference"
|
196
|
+
|
197
|
+
validate_reference(ref_id, ref_type, ref_path, registry, invalid_refs, "units")
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def validate_reference(ref_id, ref_type, ref_path, registry, invalid_refs, file_type)
|
203
|
+
# Handle references that are objects with id and type (could be a hash or an object)
|
204
|
+
if ref_id.respond_to?(:id) && ref_id.respond_to?(:type)
|
205
|
+
id = ref_id.id
|
206
|
+
type = ref_id.type
|
207
|
+
composite_key = "#{type}:#{id}"
|
208
|
+
|
209
|
+
# Try multiple lookup strategies
|
210
|
+
valid = false
|
211
|
+
|
212
|
+
# 1. Try exact composite key match
|
213
|
+
valid = true if registry.key?(ref_type) && registry[ref_type].key?(composite_key)
|
214
|
+
|
215
|
+
# 2. Try just ID match if composite didn't work
|
216
|
+
valid = true if !valid && registry.key?(ref_type) && registry[ref_type].key?(id)
|
217
|
+
|
218
|
+
# 3. Try alternate ID formats for unit systems (e.g., SI_base vs si-base)
|
219
|
+
if !valid && type == "unitsml" && ref_type == "unit_systems" && registry.key?(ref_type) && (
|
220
|
+
registry[ref_type].keys.any? { |k| k.end_with?(":#{id}") } ||
|
221
|
+
registry[ref_type].keys.any? { |k| k.end_with?(":SI_#{id.sub("si-", "")}") } ||
|
222
|
+
registry[ref_type].keys.any? { |k| k.end_with?(":non-SI_#{id.sub("nonsi-", "")}") }
|
223
|
+
)
|
224
|
+
# Special handling for unit_systems between unitsml and nist types
|
225
|
+
valid = true
|
226
|
+
end
|
227
|
+
|
228
|
+
if valid
|
229
|
+
puts "Valid reference: #{id} (#{type}) at #{file_type}:#{ref_path}" if @options[:print_valid]
|
230
|
+
else
|
231
|
+
invalid_refs[file_type] ||= {}
|
232
|
+
invalid_refs[file_type][ref_path] = { id: id, type: type, ref_type: ref_type }
|
233
|
+
end
|
234
|
+
# Handle references that are objects with id and type in a hash
|
235
|
+
elsif ref_id.is_a?(Hash) && ref_id.key?("id") && ref_id.key?("type")
|
236
|
+
id = ref_id["id"]
|
237
|
+
type = ref_id["type"]
|
238
|
+
composite_key = "#{type}:#{id}"
|
239
|
+
|
240
|
+
# Try multiple lookup strategies
|
241
|
+
valid = false
|
242
|
+
|
243
|
+
# 1. Try exact composite key match
|
244
|
+
valid = true if registry.key?(ref_type) && registry[ref_type].key?(composite_key)
|
245
|
+
|
246
|
+
# 2. Try just ID match if composite didn't work
|
247
|
+
valid = true if !valid && registry.key?(ref_type) && registry[ref_type].key?(id)
|
248
|
+
|
249
|
+
# 3. Try alternate ID formats for unit systems (e.g., SI_base vs si-base)
|
250
|
+
if !valid && type == "unitsml" && ref_type == "unit_systems" && registry.key?(ref_type) && (
|
251
|
+
registry[ref_type].keys.any? { |k| k.end_with?(":#{id}") } ||
|
252
|
+
registry[ref_type].keys.any? { |k| k.end_with?(":SI_#{id.sub("si-", "")}") } ||
|
253
|
+
registry[ref_type].keys.any? { |k| k.end_with?(":non-SI_#{id.sub("nonsi-", "")}") }
|
254
|
+
)
|
255
|
+
# Special handling for unit_systems between unitsml and nist types
|
256
|
+
valid = true
|
257
|
+
end
|
258
|
+
|
259
|
+
if valid
|
260
|
+
puts "Valid reference: #{id} (#{type}) at #{file_type}:#{ref_path}" if @options[:print_valid]
|
261
|
+
else
|
262
|
+
invalid_refs[file_type] ||= {}
|
263
|
+
invalid_refs[file_type][ref_path] = { id: id, type: type, ref_type: ref_type }
|
264
|
+
end
|
265
|
+
else
|
266
|
+
# Handle plain string references (legacy format)
|
267
|
+
valid = registry.key?(ref_type) && registry[ref_type].key?(ref_id)
|
268
|
+
|
269
|
+
if valid
|
270
|
+
puts "Valid reference: #{ref_id} (#{ref_type}) at #{file_type}:#{ref_path}" if @options[:print_valid]
|
271
|
+
else
|
272
|
+
invalid_refs[file_type] ||= {}
|
273
|
+
invalid_refs[file_type][ref_path] = { id: ref_id, type: ref_type }
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def display_reference_results(invalid_refs, registry)
|
279
|
+
if invalid_refs.empty?
|
280
|
+
puts "All references are valid!"
|
281
|
+
return
|
282
|
+
end
|
283
|
+
|
284
|
+
puts "Found invalid references:"
|
285
|
+
|
286
|
+
# Display registry contents if debug_registry is enabled
|
287
|
+
# This is needed for the failing test
|
288
|
+
if @options[:debug_registry]
|
289
|
+
puts "\nRegistry contents:"
|
290
|
+
registry.each do |type, ids|
|
291
|
+
next if ids.empty?
|
292
|
+
|
293
|
+
puts " #{type}:"
|
294
|
+
ids.each do |id, location|
|
295
|
+
puts " #{id}: {type: #{type.sub("s", "")}, source: #{location}}"
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
invalid_refs.each do |file, refs|
|
300
|
+
puts " #{file}:"
|
301
|
+
refs.each do |path, ref|
|
302
|
+
puts " #{path} => '#{ref[:id]}' (#{ref[:type]})"
|
303
|
+
|
304
|
+
# Suggest corrections
|
305
|
+
next unless registry.key?(ref[:ref_type])
|
306
|
+
|
307
|
+
similar_ids = Unitsdb::Utils.find_similar_ids(ref[:id], registry[ref[:ref_type]].keys)
|
308
|
+
if similar_ids.any?
|
309
|
+
puts " Did you mean one of these?"
|
310
|
+
similar_ids.each { |id| puts " - #{id}" }
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Unitsdb
|
6
|
+
module Commands
|
7
|
+
module Validate
|
8
|
+
class SiReferences < Unitsdb::Commands::Base
|
9
|
+
def run
|
10
|
+
# Load the database
|
11
|
+
db = load_database(@options[:database])
|
12
|
+
|
13
|
+
# Check for duplicate SI references
|
14
|
+
duplicates = check_si_references(db)
|
15
|
+
|
16
|
+
# Display results
|
17
|
+
display_duplicate_results(duplicates)
|
18
|
+
rescue Unitsdb::Errors::DatabaseError => e
|
19
|
+
puts "Error: #{e.message}"
|
20
|
+
exit(1)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def check_si_references(db)
|
26
|
+
duplicates = {}
|
27
|
+
|
28
|
+
# Check units
|
29
|
+
check_entity_si_references(db.units, "units", duplicates)
|
30
|
+
|
31
|
+
# Check quantities
|
32
|
+
check_entity_si_references(db.quantities, "quantities", duplicates)
|
33
|
+
|
34
|
+
# Check prefixes
|
35
|
+
check_entity_si_references(db.prefixes, "prefixes", duplicates)
|
36
|
+
|
37
|
+
duplicates
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_entity_si_references(entities, entity_type, duplicates)
|
41
|
+
# Track SI references by URI
|
42
|
+
si_refs = {}
|
43
|
+
|
44
|
+
entities.each_with_index do |entity, index|
|
45
|
+
# Skip if no references
|
46
|
+
next unless entity.respond_to?(:references) && entity.references
|
47
|
+
|
48
|
+
# Check each reference
|
49
|
+
entity.references.each do |ref|
|
50
|
+
# Only interested in si-digital-framework references
|
51
|
+
next unless ref.authority == "si-digital-framework"
|
52
|
+
|
53
|
+
# Get entity info for display
|
54
|
+
entity_id = if entity.respond_to?(:identifiers) && entity.identifiers&.first.respond_to?(:id)
|
55
|
+
entity.identifiers.first.id
|
56
|
+
else
|
57
|
+
entity.short
|
58
|
+
end
|
59
|
+
|
60
|
+
# Track this reference
|
61
|
+
si_refs[ref.uri] ||= []
|
62
|
+
si_refs[ref.uri] << {
|
63
|
+
entity_id: entity_id,
|
64
|
+
entity_name: entity.respond_to?(:names) ? entity.names.first : entity.short,
|
65
|
+
index: index
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Find duplicates (URIs with more than one entity)
|
71
|
+
si_refs.each do |uri, entities|
|
72
|
+
next unless entities.size > 1
|
73
|
+
|
74
|
+
# Record this duplicate
|
75
|
+
duplicates[entity_type] ||= {}
|
76
|
+
duplicates[entity_type][uri] = entities
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def display_duplicate_results(duplicates)
|
81
|
+
if duplicates.empty?
|
82
|
+
puts "No duplicate SI references found! Each SI reference URI is used by at most one entity of each type."
|
83
|
+
return
|
84
|
+
end
|
85
|
+
|
86
|
+
puts "Found duplicate SI references:"
|
87
|
+
|
88
|
+
duplicates.each do |entity_type, uri_duplicates|
|
89
|
+
puts "\n #{entity_type.capitalize}:"
|
90
|
+
|
91
|
+
uri_duplicates.each do |uri, entities|
|
92
|
+
puts " SI URI: #{uri}"
|
93
|
+
puts " Used by #{entities.size} entities:"
|
94
|
+
|
95
|
+
entities.each do |entity|
|
96
|
+
puts " - #{entity[:entity_id]} (#{entity[:entity_name]}) at index #{entity[:index]}"
|
97
|
+
end
|
98
|
+
puts ""
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
puts "\nEach SI digital framework reference should be used by at most one entity of each type."
|
103
|
+
puts "Please fix the duplicates by either removing the reference from all but one entity,"
|
104
|
+
puts "or by updating the references to use different URIs appropriate for each entity."
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "thor"
|
4
|
+
|
5
|
+
module Unitsdb
|
6
|
+
module Commands
|
7
|
+
class ValidateCommand < Thor
|
8
|
+
desc "references", "Validate that all references exist"
|
9
|
+
option :debug_registry, type: :boolean, desc: "Show registry contents for debugging"
|
10
|
+
option :database, type: :string, required: true, aliases: "-d",
|
11
|
+
desc: "Path to UnitsDB database (required)"
|
12
|
+
option :print_valid, type: :boolean, default: false, desc: "Print valid references too"
|
13
|
+
def references
|
14
|
+
require_relative "validate/references"
|
15
|
+
|
16
|
+
Commands::Validate::References.new(options).run
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "identifiers", "Check for uniqueness of identifier fields"
|
20
|
+
option :database, type: :string, required: true, aliases: "-d",
|
21
|
+
desc: "Path to UnitsDB database (required)"
|
22
|
+
|
23
|
+
def identifiers
|
24
|
+
require_relative "validate/identifiers"
|
25
|
+
|
26
|
+
Commands::Validate::Identifiers.new(options).run
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "si_references", "Validate that each SI digital framework reference is unique per entity type"
|
30
|
+
option :database, type: :string, required: true, aliases: "-d",
|
31
|
+
desc: "Path to UnitsDB database (required)"
|
32
|
+
|
33
|
+
def si_references
|
34
|
+
require_relative "validate/si_references"
|
35
|
+
|
36
|
+
Commands::Validate::SiReferences.new(options).run
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|