unitsdb 2.1.1 → 2.2.2
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/release.yml +8 -1
- data/.gitignore +2 -0
- data/.gitmodules +4 -3
- data/.rubocop.yml +13 -8
- data/.rubocop_todo.yml +217 -100
- data/CLAUDE.md +55 -0
- data/Gemfile +4 -1
- data/README.adoc +283 -16
- data/data/dimensions.yaml +1864 -0
- data/data/prefixes.yaml +874 -0
- data/data/quantities.yaml +3715 -0
- data/data/scales.yaml +97 -0
- data/data/schemas/dimensions-schema.yaml +153 -0
- data/data/schemas/prefixes-schema.yaml +155 -0
- data/data/schemas/quantities-schema.yaml +117 -0
- data/data/schemas/scales-schema.yaml +106 -0
- data/data/schemas/unit_systems-schema.yaml +116 -0
- data/data/schemas/units-schema.yaml +215 -0
- data/data/unit_systems.yaml +78 -0
- data/data/units.yaml +14052 -0
- data/exe/unitsdb +7 -1
- data/lib/unitsdb/cli.rb +42 -15
- data/lib/unitsdb/commands/_modify.rb +40 -4
- data/lib/unitsdb/commands/base.rb +6 -2
- data/lib/unitsdb/commands/check_si/si_formatter.rb +488 -0
- data/lib/unitsdb/commands/check_si/si_matcher.rb +487 -0
- data/lib/unitsdb/commands/check_si/si_ttl_parser.rb +103 -0
- data/lib/unitsdb/commands/check_si/si_updater.rb +254 -0
- data/lib/unitsdb/commands/check_si.rb +54 -35
- data/lib/unitsdb/commands/get.rb +11 -10
- data/lib/unitsdb/commands/normalize.rb +21 -7
- data/lib/unitsdb/commands/qudt/check.rb +150 -0
- data/lib/unitsdb/commands/qudt/formatter.rb +194 -0
- data/lib/unitsdb/commands/qudt/matcher.rb +746 -0
- data/lib/unitsdb/commands/qudt/ttl_parser.rb +403 -0
- data/lib/unitsdb/commands/qudt/update.rb +126 -0
- data/lib/unitsdb/commands/qudt/updater.rb +189 -0
- data/lib/unitsdb/commands/qudt.rb +82 -0
- data/lib/unitsdb/commands/release.rb +12 -9
- data/lib/unitsdb/commands/search.rb +12 -11
- data/lib/unitsdb/commands/ucum/check.rb +42 -29
- data/lib/unitsdb/commands/ucum/formatter.rb +2 -1
- data/lib/unitsdb/commands/ucum/matcher.rb +23 -9
- data/lib/unitsdb/commands/ucum/update.rb +14 -13
- data/lib/unitsdb/commands/ucum/updater.rb +40 -6
- data/lib/unitsdb/commands/ucum/xml_parser.rb +0 -2
- data/lib/unitsdb/commands/ucum.rb +44 -4
- data/lib/unitsdb/commands/validate/identifiers.rb +2 -4
- data/lib/unitsdb/commands/validate/qudt_references.rb +111 -0
- data/lib/unitsdb/commands/validate/references.rb +36 -19
- data/lib/unitsdb/commands/validate/si_references.rb +3 -5
- data/lib/unitsdb/commands/validate/ucum_references.rb +105 -0
- data/lib/unitsdb/commands/validate.rb +67 -11
- data/lib/unitsdb/commands.rb +20 -0
- data/lib/unitsdb/config.rb +114 -2
- data/lib/unitsdb/database.rb +160 -123
- data/lib/unitsdb/dimension.rb +3 -4
- data/lib/unitsdb/dimension_details.rb +2 -1
- data/lib/unitsdb/dimension_reference.rb +2 -0
- data/lib/unitsdb/dimensions.rb +2 -2
- data/lib/unitsdb/errors.rb +7 -0
- data/lib/unitsdb/external_reference.rb +2 -0
- data/lib/unitsdb/identifier.rb +2 -0
- data/lib/unitsdb/localized_string.rb +2 -0
- data/lib/unitsdb/prefix.rb +2 -4
- data/lib/unitsdb/prefix_reference.rb +2 -2
- data/lib/unitsdb/prefixes.rb +2 -1
- data/lib/unitsdb/quantities.rb +2 -2
- data/lib/unitsdb/quantity.rb +2 -6
- data/lib/unitsdb/quantity_reference.rb +2 -0
- data/lib/unitsdb/qudt.rb +105 -0
- data/lib/unitsdb/root_unit_reference.rb +2 -3
- data/lib/unitsdb/scale.rb +2 -4
- data/lib/unitsdb/scale_properties.rb +2 -0
- data/lib/unitsdb/scale_reference.rb +2 -2
- data/lib/unitsdb/scales.rb +2 -2
- data/lib/unitsdb/si_derived_base.rb +2 -2
- data/lib/unitsdb/symbol_presentations.rb +2 -0
- data/lib/unitsdb/ucum.rb +21 -10
- data/lib/unitsdb/unit.rb +2 -10
- data/lib/unitsdb/unit_reference.rb +2 -2
- data/lib/unitsdb/unit_system.rb +3 -3
- data/lib/unitsdb/unit_system_reference.rb +2 -2
- data/lib/unitsdb/unit_systems.rb +2 -2
- data/lib/unitsdb/units.rb +2 -2
- data/lib/unitsdb/utils.rb +32 -21
- data/lib/unitsdb/version.rb +5 -1
- data/lib/unitsdb.rb +62 -14
- data/unitsdb.gemspec +6 -3
- metadata +52 -13
- data/lib/unitsdb/commands/si_formatter.rb +0 -485
- data/lib/unitsdb/commands/si_matcher.rb +0 -470
- data/lib/unitsdb/commands/si_ttl_parser.rb +0 -100
- data/lib/unitsdb/commands/si_updater.rb +0 -212
|
@@ -4,16 +4,28 @@ require "thor"
|
|
|
4
4
|
|
|
5
5
|
module Unitsdb
|
|
6
6
|
module Commands
|
|
7
|
+
module Validate
|
|
8
|
+
autoload :Identifiers, "unitsdb/commands/validate/identifiers"
|
|
9
|
+
autoload :QudtReferences, "unitsdb/commands/validate/qudt_references"
|
|
10
|
+
autoload :References, "unitsdb/commands/validate/references"
|
|
11
|
+
autoload :SiReferences, "unitsdb/commands/validate/si_references"
|
|
12
|
+
autoload :UcumReferences, "unitsdb/commands/validate/ucum_references"
|
|
13
|
+
end
|
|
14
|
+
|
|
7
15
|
class ValidateCommand < Thor
|
|
16
|
+
# Inherit trace option from parent CLI
|
|
17
|
+
class_option :trace, type: :boolean, default: false,
|
|
18
|
+
desc: "Show full backtrace on error"
|
|
19
|
+
|
|
8
20
|
desc "references", "Validate that all references exist"
|
|
9
|
-
option :debug_registry, type: :boolean,
|
|
21
|
+
option :debug_registry, type: :boolean,
|
|
22
|
+
desc: "Show registry contents for debugging"
|
|
10
23
|
option :database, type: :string, required: true, aliases: "-d",
|
|
11
24
|
desc: "Path to UnitsDB database (required)"
|
|
12
|
-
option :print_valid, type: :boolean, default: false,
|
|
25
|
+
option :print_valid, type: :boolean, default: false,
|
|
26
|
+
desc: "Print valid references too"
|
|
13
27
|
def references
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Commands::Validate::References.new(options).run
|
|
28
|
+
run_command(Commands::Validate::References, options)
|
|
17
29
|
end
|
|
18
30
|
|
|
19
31
|
desc "identifiers", "Check for uniqueness of identifier fields"
|
|
@@ -21,19 +33,63 @@ module Unitsdb
|
|
|
21
33
|
desc: "Path to UnitsDB database (required)"
|
|
22
34
|
|
|
23
35
|
def identifiers
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Commands::Validate::Identifiers.new(options).run
|
|
36
|
+
run_command(Commands::Validate::Identifiers, options)
|
|
27
37
|
end
|
|
28
38
|
|
|
29
|
-
desc "si_references",
|
|
39
|
+
desc "si_references",
|
|
40
|
+
"Validate that each SI digital framework reference is unique per entity type"
|
|
30
41
|
option :database, type: :string, required: true, aliases: "-d",
|
|
31
42
|
desc: "Path to UnitsDB database (required)"
|
|
32
43
|
|
|
33
44
|
def si_references
|
|
34
|
-
|
|
45
|
+
run_command(Commands::Validate::SiReferences, options)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
desc "qudt_references",
|
|
49
|
+
"Validate that each QUDT reference is unique per entity type"
|
|
50
|
+
option :database, type: :string, required: true, aliases: "-d",
|
|
51
|
+
desc: "Path to UnitsDB database (required)"
|
|
52
|
+
|
|
53
|
+
def qudt_references
|
|
54
|
+
run_command(Commands::Validate::QudtReferences, options)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
desc "ucum_references",
|
|
58
|
+
"Validate that each UCUM reference is unique per entity type"
|
|
59
|
+
option :database, type: :string, required: true, aliases: "-d",
|
|
60
|
+
desc: "Path to UnitsDB database (required)"
|
|
61
|
+
|
|
62
|
+
def ucum_references
|
|
63
|
+
run_command(Commands::Validate::UcumReferences, options)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def run_command(command_class, options)
|
|
69
|
+
command = command_class.new(options)
|
|
70
|
+
command.run
|
|
71
|
+
rescue Unitsdb::Errors::CLIRuntimeError => e
|
|
72
|
+
handle_cli_error(e)
|
|
73
|
+
rescue StandardError => e
|
|
74
|
+
handle_error(e)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def handle_cli_error(error)
|
|
78
|
+
if options[:trace]
|
|
79
|
+
raise error
|
|
80
|
+
else
|
|
81
|
+
warn "Error: #{error.message}"
|
|
82
|
+
exit 1
|
|
83
|
+
end
|
|
84
|
+
end
|
|
35
85
|
|
|
36
|
-
|
|
86
|
+
def handle_error(error)
|
|
87
|
+
if options[:trace]
|
|
88
|
+
raise error
|
|
89
|
+
else
|
|
90
|
+
warn "Error: #{error.message}"
|
|
91
|
+
exit 1
|
|
92
|
+
end
|
|
37
93
|
end
|
|
38
94
|
end
|
|
39
95
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unitsdb
|
|
4
|
+
module Commands
|
|
5
|
+
autoload :ModifyCommand, "unitsdb/commands/_modify"
|
|
6
|
+
autoload :Base, "unitsdb/commands/base"
|
|
7
|
+
autoload :CheckSi, "unitsdb/commands/check_si"
|
|
8
|
+
autoload :CheckSiCommand, "unitsdb/commands/check_si"
|
|
9
|
+
autoload :Get, "unitsdb/commands/get"
|
|
10
|
+
autoload :Normalize, "unitsdb/commands/normalize"
|
|
11
|
+
autoload :Qudt, "unitsdb/commands/qudt"
|
|
12
|
+
autoload :QudtCommand, "unitsdb/commands/qudt"
|
|
13
|
+
autoload :Release, "unitsdb/commands/release"
|
|
14
|
+
autoload :Search, "unitsdb/commands/search"
|
|
15
|
+
autoload :Ucum, "unitsdb/commands/ucum"
|
|
16
|
+
autoload :UcumCommand, "unitsdb/commands/ucum"
|
|
17
|
+
autoload :Validate, "unitsdb/commands/validate"
|
|
18
|
+
autoload :ValidateCommand, "unitsdb/commands/validate"
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/unitsdb/config.rb
CHANGED
|
@@ -2,17 +2,129 @@
|
|
|
2
2
|
|
|
3
3
|
module Unitsdb
|
|
4
4
|
class Config
|
|
5
|
+
CONTEXT_ID = :unitsdb_v2
|
|
6
|
+
|
|
5
7
|
class << self
|
|
8
|
+
def context_id
|
|
9
|
+
@context_id ||= CONTEXT_ID
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def register_model(klass, id:)
|
|
13
|
+
registered_models[id.to_sym] = klass
|
|
14
|
+
klass
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def registered_models
|
|
18
|
+
@registered_models ||= {}
|
|
19
|
+
end
|
|
20
|
+
|
|
6
21
|
def models
|
|
7
22
|
@models ||= {}
|
|
8
23
|
end
|
|
9
24
|
|
|
10
25
|
def models=(user_models)
|
|
11
|
-
|
|
26
|
+
normalized_models = user_models.each_with_object({}) do |(id, klass), result|
|
|
27
|
+
model_id = id.to_sym
|
|
28
|
+
result[model_id] = register_model(klass, id: model_id)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
models.merge!(normalized_models)
|
|
12
32
|
end
|
|
13
33
|
|
|
14
34
|
def model_for(model_name)
|
|
15
|
-
|
|
35
|
+
model_id = model_name.to_sym
|
|
36
|
+
models[model_id] || registered_models[model_id]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def register(id = context_id)
|
|
40
|
+
explicit_registers[id.to_sym]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def populate_register(id: context_id, fallback_to: [:default], substitutions: [])
|
|
44
|
+
register_id = id.to_sym
|
|
45
|
+
context(register_id)
|
|
46
|
+
|
|
47
|
+
model_register = Lutaml::Model::Register.new(register_id, fallback: fallback_to)
|
|
48
|
+
resolve_substitutions(
|
|
49
|
+
substitutions,
|
|
50
|
+
registry: build_registry,
|
|
51
|
+
fallback_to: fallback_to,
|
|
52
|
+
id: "#{register_id}_register",
|
|
53
|
+
).each do |substitution|
|
|
54
|
+
model_register.register_global_type_substitution(**substitution)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
explicit_registers[register_id] = Lutaml::Model::GlobalRegister.register(model_register)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def find_context(id)
|
|
61
|
+
Lutaml::Model::GlobalContext.context(id.to_sym)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def resolve_type(type_name, context: context_id)
|
|
65
|
+
Lutaml::Model::GlobalContext.resolve_type(type_name, context.to_sym)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def context(id = context_id, force_populate: false)
|
|
69
|
+
existing = find_context(id)
|
|
70
|
+
return existing if existing && !force_populate && populated?(id)
|
|
71
|
+
|
|
72
|
+
populate_context(id: id)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def populate_context(id: context_id, fallback_to: [:default], substitutions: [])
|
|
76
|
+
Lutaml::Model::GlobalContext.unregister_context(id) if find_context(id)
|
|
77
|
+
|
|
78
|
+
opts = { registry: build_registry, fallback_to: fallback_to, id: id }
|
|
79
|
+
context = Lutaml::Model::GlobalContext.create_context(
|
|
80
|
+
substitutions: resolve_substitutions(substitutions, **opts),
|
|
81
|
+
**opts,
|
|
82
|
+
)
|
|
83
|
+
mark_populated!(id)
|
|
84
|
+
context
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def resolve_substitutions(substitutions, registry:, fallback_to:, id:)
|
|
88
|
+
resolution_context = Lutaml::Model::TypeContext.derived(
|
|
89
|
+
id: "#{id}_substitution_resolution",
|
|
90
|
+
registry: registry,
|
|
91
|
+
fallback_to: fallback_to,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
Array(substitutions).map do |substitution|
|
|
95
|
+
from_key = substitution[:from_type] || substitution[:from]
|
|
96
|
+
to_key = substitution[:to_type] || substitution[:to]
|
|
97
|
+
|
|
98
|
+
{
|
|
99
|
+
from_type: resolve_substitution_type(from_key, resolution_context),
|
|
100
|
+
to_type: resolve_substitution_type(to_key, resolution_context),
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def resolve_substitution_type(value, resolution_context)
|
|
106
|
+
return value if value.is_a?(Class)
|
|
107
|
+
|
|
108
|
+
Lutaml::Model::TypeResolver.resolve(value, resolution_context)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def build_registry
|
|
112
|
+
registry = Lutaml::Model::TypeRegistry.new
|
|
113
|
+
registered_models.each { |model_id, klass| registry.register(model_id, klass) }
|
|
114
|
+
registry
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def populated?(context_id)
|
|
118
|
+
@populated_for&.[](context_id.to_sym)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def mark_populated!(context_id)
|
|
122
|
+
@populated_for ||= {}
|
|
123
|
+
@populated_for[context_id.to_sym] = true
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def explicit_registers
|
|
127
|
+
@explicit_registers ||= {}
|
|
16
128
|
end
|
|
17
129
|
end
|
|
18
130
|
end
|