unitsdb 2.1.1 → 2.2.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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +8 -1
  3. data/.gitignore +2 -0
  4. data/.gitmodules +4 -3
  5. data/.rubocop.yml +13 -8
  6. data/.rubocop_todo.yml +217 -100
  7. data/CLAUDE.md +55 -0
  8. data/Gemfile +4 -1
  9. data/README.adoc +283 -16
  10. data/data/dimensions.yaml +1864 -0
  11. data/data/prefixes.yaml +874 -0
  12. data/data/quantities.yaml +3715 -0
  13. data/data/scales.yaml +97 -0
  14. data/data/schemas/dimensions-schema.yaml +153 -0
  15. data/data/schemas/prefixes-schema.yaml +155 -0
  16. data/data/schemas/quantities-schema.yaml +117 -0
  17. data/data/schemas/scales-schema.yaml +106 -0
  18. data/data/schemas/unit_systems-schema.yaml +116 -0
  19. data/data/schemas/units-schema.yaml +215 -0
  20. data/data/unit_systems.yaml +78 -0
  21. data/data/units.yaml +14052 -0
  22. data/exe/unitsdb +7 -1
  23. data/lib/unitsdb/cli.rb +42 -15
  24. data/lib/unitsdb/commands/_modify.rb +40 -4
  25. data/lib/unitsdb/commands/base.rb +6 -2
  26. data/lib/unitsdb/commands/check_si/si_formatter.rb +488 -0
  27. data/lib/unitsdb/commands/check_si/si_matcher.rb +487 -0
  28. data/lib/unitsdb/commands/check_si/si_ttl_parser.rb +103 -0
  29. data/lib/unitsdb/commands/check_si/si_updater.rb +254 -0
  30. data/lib/unitsdb/commands/check_si.rb +54 -35
  31. data/lib/unitsdb/commands/get.rb +11 -10
  32. data/lib/unitsdb/commands/normalize.rb +21 -7
  33. data/lib/unitsdb/commands/qudt/check.rb +150 -0
  34. data/lib/unitsdb/commands/qudt/formatter.rb +194 -0
  35. data/lib/unitsdb/commands/qudt/matcher.rb +746 -0
  36. data/lib/unitsdb/commands/qudt/ttl_parser.rb +403 -0
  37. data/lib/unitsdb/commands/qudt/update.rb +126 -0
  38. data/lib/unitsdb/commands/qudt/updater.rb +189 -0
  39. data/lib/unitsdb/commands/qudt.rb +82 -0
  40. data/lib/unitsdb/commands/release.rb +12 -9
  41. data/lib/unitsdb/commands/search.rb +12 -11
  42. data/lib/unitsdb/commands/ucum/check.rb +42 -29
  43. data/lib/unitsdb/commands/ucum/formatter.rb +2 -1
  44. data/lib/unitsdb/commands/ucum/matcher.rb +23 -9
  45. data/lib/unitsdb/commands/ucum/update.rb +14 -13
  46. data/lib/unitsdb/commands/ucum/updater.rb +40 -6
  47. data/lib/unitsdb/commands/ucum/xml_parser.rb +0 -2
  48. data/lib/unitsdb/commands/ucum.rb +44 -4
  49. data/lib/unitsdb/commands/validate/identifiers.rb +2 -4
  50. data/lib/unitsdb/commands/validate/qudt_references.rb +111 -0
  51. data/lib/unitsdb/commands/validate/references.rb +36 -19
  52. data/lib/unitsdb/commands/validate/si_references.rb +3 -5
  53. data/lib/unitsdb/commands/validate/ucum_references.rb +105 -0
  54. data/lib/unitsdb/commands/validate.rb +67 -11
  55. data/lib/unitsdb/commands.rb +20 -0
  56. data/lib/unitsdb/database.rb +90 -52
  57. data/lib/unitsdb/dimension.rb +1 -4
  58. data/lib/unitsdb/dimension_details.rb +0 -1
  59. data/lib/unitsdb/dimensions.rb +0 -2
  60. data/lib/unitsdb/errors.rb +7 -0
  61. data/lib/unitsdb/prefix.rb +0 -4
  62. data/lib/unitsdb/prefix_reference.rb +0 -2
  63. data/lib/unitsdb/prefixes.rb +0 -1
  64. data/lib/unitsdb/quantities.rb +0 -2
  65. data/lib/unitsdb/quantity.rb +0 -6
  66. data/lib/unitsdb/qudt.rb +100 -0
  67. data/lib/unitsdb/root_unit_reference.rb +0 -3
  68. data/lib/unitsdb/scale.rb +0 -4
  69. data/lib/unitsdb/scale_reference.rb +0 -2
  70. data/lib/unitsdb/scales.rb +0 -2
  71. data/lib/unitsdb/si_derived_base.rb +0 -2
  72. data/lib/unitsdb/ucum.rb +14 -10
  73. data/lib/unitsdb/unit.rb +0 -10
  74. data/lib/unitsdb/unit_reference.rb +0 -2
  75. data/lib/unitsdb/unit_system.rb +1 -3
  76. data/lib/unitsdb/unit_system_reference.rb +0 -2
  77. data/lib/unitsdb/unit_systems.rb +0 -2
  78. data/lib/unitsdb/units.rb +0 -2
  79. data/lib/unitsdb/utils.rb +32 -21
  80. data/lib/unitsdb/version.rb +5 -1
  81. data/lib/unitsdb.rb +62 -14
  82. data/unitsdb.gemspec +6 -3
  83. metadata +52 -13
  84. data/lib/unitsdb/commands/si_formatter.rb +0 -485
  85. data/lib/unitsdb/commands/si_matcher.rb +0 -470
  86. data/lib/unitsdb/commands/si_ttl_parser.rb +0 -100
  87. data/lib/unitsdb/commands/si_updater.rb +0 -212
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unitsdb
4
+ # QUDT Unit from units vocabulary
5
+ # Example: http://qudt.org/vocab/unit/M (meter)
6
+ class QudtUnit < Lutaml::Model::Serializable
7
+ attribute :uri, :string
8
+ attribute :label, :string
9
+ attribute :symbol, :string
10
+ attribute :has_quantity_kind, :string
11
+ attribute :has_dimension_vector, :string
12
+ attribute :conversion_multiplier, :float
13
+ attribute :conversion_offset, :float
14
+ attribute :description, :string
15
+ attribute :si_exact_match, :string
16
+
17
+ def identifier
18
+ "qudt:unit:#{uri}"
19
+ end
20
+ end
21
+
22
+ # QUDT QuantityKind from quantitykinds vocabulary
23
+ # Example: http://qudt.org/vocab/quantitykind/Length
24
+ class QudtQuantityKind < Lutaml::Model::Serializable
25
+ attribute :uri, :string
26
+ attribute :label, :string
27
+ attribute :has_dimension_vector, :string
28
+ attribute :description, :string
29
+ attribute :symbol, :string
30
+ attribute :si_exact_match, :string
31
+
32
+ def identifier
33
+ "qudt:quantitykind:#{uri}"
34
+ end
35
+ end
36
+
37
+ # QUDT DimensionVector from dimensionvectors vocabulary
38
+ # Example: http://qudt.org/vocab/dimensionvector/A0E0L1I0M0H0T0D0
39
+ class QudtDimensionVector < Lutaml::Model::Serializable
40
+ attribute :uri, :string
41
+ attribute :label, :string
42
+ attribute :dimension_exponent_for_length, :integer
43
+ attribute :dimension_exponent_for_mass, :integer
44
+ attribute :dimension_exponent_for_time, :integer
45
+ attribute :dimension_exponent_for_electric_current, :integer
46
+ attribute :dimension_exponent_for_thermodynamic_temperature, :integer
47
+ attribute :dimension_exponent_for_amount_of_substance, :integer
48
+ attribute :dimension_exponent_for_luminous_intensity, :integer
49
+ attribute :description, :string
50
+
51
+ def identifier
52
+ "qudt:dimensionvector:#{uri}"
53
+ end
54
+ end
55
+
56
+ # QUDT SystemOfUnits from sou vocabulary
57
+ # Example: http://qudt.org/vocab/sou/SI
58
+ class QudtSystemOfUnits < Lutaml::Model::Serializable
59
+ attribute :uri, :string
60
+ attribute :label, :string
61
+ attribute :abbreviation, :string
62
+ attribute :description, :string
63
+
64
+ def identifier
65
+ "qudt:sou:#{uri}"
66
+ end
67
+ end
68
+
69
+ # QUDT Prefix from prefixes vocabulary
70
+ # Example: http://qudt.org/vocab/prefix/Kilo
71
+ class QudtPrefix < Lutaml::Model::Serializable
72
+ attribute :uri, :string
73
+ attribute :label, :string
74
+ attribute :symbol, :string
75
+ attribute :prefix_multiplier, :float
76
+ attribute :prefix_multiplier_sn, :string
77
+ attribute :ucum_code, :string
78
+ attribute :si_exact_match, :string
79
+ attribute :description, :string
80
+ attribute :prefix_type, :string # "DecimalPrefix" or "BinaryPrefix"
81
+
82
+ def identifier
83
+ "qudt:prefix:#{uri}"
84
+ end
85
+ end
86
+
87
+ # Container for all QUDT vocabularies
88
+ class QudtVocabularies
89
+ attr_accessor :units, :quantity_kinds, :dimension_vectors,
90
+ :systems_of_units, :prefixes
91
+
92
+ def initialize
93
+ @units = []
94
+ @quantity_kinds = []
95
+ @dimension_vectors = []
96
+ @systems_of_units = []
97
+ @prefixes = []
98
+ end
99
+ end
100
+ end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "unit_reference"
4
- require_relative "prefix_reference"
5
-
6
3
  module Unitsdb
7
4
  class RootUnitReference < Lutaml::Model::Serializable
8
5
  # model Config.model_for(:root_unit)
data/lib/unitsdb/scale.rb CHANGED
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "identifier"
4
- require_relative "localized_string"
5
- require_relative "scale_properties"
6
-
7
3
  module Unitsdb
8
4
  class Scale < Lutaml::Model::Serializable
9
5
  # model Config.model_for(:quantity)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "identifier"
4
-
5
3
  module Unitsdb
6
4
  class ScaleReference < Identifier
7
5
  attribute :id, :string
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "scale"
4
-
5
3
  module Unitsdb
6
4
  class Scales < Lutaml::Model::Serializable
7
5
  # model Config.model_for(:Scale)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "root_unit_reference"
4
-
5
3
  # si_derived_bases:
6
4
  # - power: 2
7
5
  # unit_reference:
data/lib/unitsdb/ucum.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "lutaml/model"
4
-
5
3
  module Unitsdb
6
4
  # <base-unit Code="s" CODE="S" dim="T">
7
5
  # <name>second</name>
@@ -17,7 +15,7 @@ module Unitsdb
17
15
  attribute :property, :string
18
16
 
19
17
  xml do
20
- root "base-unit"
18
+ element "base-unit"
21
19
  map_attribute "Code", to: :code_sensitive
22
20
  map_attribute "CODE", to: :code
23
21
  map_attribute "dim", to: :dimension
@@ -43,7 +41,7 @@ module Unitsdb
43
41
  attribute :content, :string
44
42
 
45
43
  xml do
46
- root "value"
44
+ element "value"
47
45
  map_attribute "value", to: :value
48
46
  map_content to: :content
49
47
  end
@@ -57,7 +55,7 @@ module Unitsdb
57
55
  attribute :value, UcumPrefixValue
58
56
 
59
57
  xml do
60
- root "prefix"
58
+ element "prefix"
61
59
  map_attribute "Code", to: :code_sensitive
62
60
  map_attribute "CODE", to: :code
63
61
  map_element "name", to: :name
@@ -110,7 +108,7 @@ module Unitsdb
110
108
  attribute :unit_sensitive, :string
111
109
 
112
110
  xml do
113
- root "function"
111
+ element "function"
114
112
  map_attribute "name", to: :name
115
113
  map_attribute "value", to: :value
116
114
  map_attribute "Unit", to: :unit_sensitive
@@ -125,7 +123,7 @@ module Unitsdb
125
123
  attribute :content, :string
126
124
 
127
125
  xml do
128
- root "value"
126
+ element "value"
129
127
  map_attribute "Unit", to: :unit_sensitive
130
128
  map_attribute "UNIT", to: :unit
131
129
  map_attribute "value", to: :value
@@ -147,7 +145,7 @@ module Unitsdb
147
145
  attribute :value, UcumUnitValue
148
146
 
149
147
  xml do
150
- root "unit"
148
+ element "unit"
151
149
  map_attribute "Code", to: :code_sensitive
152
150
  map_attribute "CODE", to: :code
153
151
  map_attribute "isMetric", to: :is_metric
@@ -168,6 +166,11 @@ module Unitsdb
168
166
  end
169
167
  end
170
168
 
169
+ class UcumNamespace < Lutaml::Xml::Namespace
170
+ uri "http://unitsofmeasure.org/ucum-essence"
171
+ prefix_default "ucum"
172
+ end
173
+
171
174
  # This is the root element of the UCUM XML "ucum-essence.xml" file.
172
175
  #
173
176
  # <root xmlns="http://unitsofmeasure.org/ucum-essence" version="2.2" revision="N/A"
@@ -182,8 +185,9 @@ module Unitsdb
182
185
  attribute :units, UcumUnit, collection: true
183
186
 
184
187
  xml do
185
- root "root"
186
- namespace "http://unitsofmeasure.org/ucum-essence"
188
+ element "root"
189
+ namespace UcumNamespace
190
+
187
191
  map_attribute "version", to: :version
188
192
  map_attribute "revision", to: :revision
189
193
  map_attribute "revision-date", to: :revision_date
data/lib/unitsdb/unit.rb CHANGED
@@ -1,15 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "symbol_presentations"
4
- require_relative "unit_system_reference"
5
- require_relative "root_unit_reference"
6
- require_relative "si_derived_base"
7
- require_relative "quantity_reference"
8
- require_relative "dimension_reference"
9
- require_relative "external_reference"
10
- require_relative "localized_string"
11
- require_relative "scale_reference"
12
-
13
3
  # "NISTu10":
14
4
  # dimension_url: "#NISTd9"
15
5
  # short: steradian
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "identifier"
4
-
5
3
  module Unitsdb
6
4
  class UnitReference < Identifier
7
5
  attribute :id, :string
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "identifier"
4
- require_relative "localized_string"
5
-
6
3
  module Unitsdb
7
4
  class UnitSystem < Lutaml::Model::Serializable
8
5
  # model Config.model_for(:unit_system)
@@ -11,5 +8,6 @@ module Unitsdb
11
8
  attribute :names, LocalizedString, collection: true
12
9
  attribute :short, :string
13
10
  attribute :acceptable, :boolean
11
+ attribute :references, ExternalReference, collection: true
14
12
  end
15
13
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "identifier"
4
-
5
3
  module Unitsdb
6
4
  class UnitSystemReference < Identifier
7
5
  attribute :id, :string
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "unit_system"
4
-
5
3
  module Unitsdb
6
4
  class UnitSystems < Lutaml::Model::Serializable
7
5
  # model Config.model_for(:unit_systems)
data/lib/unitsdb/units.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "unit"
4
-
5
3
  module Unitsdb
6
4
  class Units < Lutaml::Model::Serializable
7
5
  # model Config.model_for(:units)
data/lib/unitsdb/utils.rb CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  module Unitsdb
4
4
  module Utils
5
- DEFAULT_YAML_FILES = %w[dimensions prefixes quantities unit_systems units].map { |f| "#{f}.yaml" }
5
+ DEFAULT_YAML_FILES = %w[dimensions prefixes quantities unit_systems
6
+ units].map do |f|
7
+ "#{f}.yaml"
8
+ end
6
9
 
7
10
  def self.levenshtein_distance(s, t)
8
11
  m = s.length
@@ -32,7 +35,10 @@ module Unitsdb
32
35
  def self.find_similar_ids(id, valid_ids, max_results = 5)
33
36
  # Simple similarity measure based on Levenshtein distance
34
37
  valid_ids
35
- .map { |valid_id| [valid_id, levenshtein_distance(id.to_s, valid_id.to_s)] }
38
+ .map do |valid_id|
39
+ [valid_id,
40
+ levenshtein_distance(id.to_s, valid_id.to_s)]
41
+ end
36
42
  .sort_by { |_, distance| distance }
37
43
  .take(max_results)
38
44
  .select { |_, distance| distance < [id.to_s.length, 10].min }
@@ -44,32 +50,37 @@ module Unitsdb
44
50
  when Hash
45
51
  # Transform values first, then sort keys
46
52
  obj.transform_values { |v| sort_yaml_keys(v) }
47
- .sort_by do |key, _|
48
- key_str = key.to_s
53
+ .sort_by do |key, _|
54
+ key_str = key.to_s
49
55
 
50
- # Handle NIST IDs with proper category-based sorting
51
- case key_str
52
- when /\ANIST([a-z])(\d+)_(-?\d+)\Z/ # Prefixes with power (NISTp2_10)
53
- [0, ::Regexp.last_match(1), ::Regexp.last_match(2).to_i, ::Regexp.last_match(3).to_i]
54
- when /\ANIST([a-z])(\d+)\Z/ # Prefixes without power
55
- [0, ::Regexp.last_match(1), ::Regexp.last_match(2).to_i, 0]
56
- when %r{[/e]} # Composite IDs with '/' or 'e' to the end
57
- [2, key_str]
58
- when /\ANISTu(\d+)\.(.+)\Z/ # Simple unit IDs (NISTu10.1)
59
- [1, "u", ::Regexp.last_match(1).to_i, ::Regexp.last_match(2)]
60
- else
61
- [3, key_str] # Everything else
62
- end
63
- end.to_h
56
+ # Handle NIST IDs with proper category-based sorting
57
+ case key_str
58
+ when /\ANIST([a-z])(\d+)_(-?\d+)\Z/ # Prefixes with power (NISTp2_10)
59
+ [0, ::Regexp.last_match(1), ::Regexp.last_match(2).to_i,
60
+ ::Regexp.last_match(3).to_i]
61
+ when /\ANIST([a-z])(\d+)\Z/ # Prefixes without power
62
+ [0, ::Regexp.last_match(1), ::Regexp.last_match(2).to_i, 0]
63
+ when %r{[/e]} # Composite IDs with '/' or 'e' to the end
64
+ [2, key_str]
65
+ when /\ANISTu(\d+)\.(.+)\Z/ # Simple unit IDs (NISTu10.1)
66
+ [1, "u", ::Regexp.last_match(1).to_i, ::Regexp.last_match(2)]
67
+ else
68
+ [3, key_str] # Everything else
69
+ end
70
+ end.to_h
64
71
  when Array
65
72
  # For arrays in the new structure, sort them if they're arrays of hashes with 'id' or 'short' keys
66
- if !obj.empty? && obj.all? { |item| item.is_a?(Hash) }
73
+ if !obj.empty? && obj.all?(Hash)
67
74
  # Sort by 'id' within identifiers array
68
75
  if obj.first.key?("id") && obj.first.key?("type")
69
- obj.sort_by { |item| item["id"].to_s }.map { |item| sort_yaml_keys(item) }
76
+ obj.sort_by do |item|
77
+ item["id"].to_s
78
+ end.map { |item| sort_yaml_keys(item) }
70
79
  # Sort by 'short' for other arrays (like main unit arrays)
71
80
  elsif obj.first.key?("short")
72
- obj.sort_by { |item| item["short"].to_s }.map { |item| sort_yaml_keys(item) }
81
+ obj.sort_by do |item|
82
+ item["short"].to_s
83
+ end.map { |item| sort_yaml_keys(item) }
73
84
  else
74
85
  obj.map { |item| sort_yaml_keys(item) }
75
86
  end
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Unitsdb
4
- VERSION = "2.1.1"
4
+ VERSION = "2.2.1"
5
+
6
+ # The version of the bundled UnitsDB data (from the data/ submodule).
7
+ # This version corresponds to a tag/commit in https://github.com/unitsml/unitsdb.
8
+ UNITS_DATA_VERSION = "2.0.0"
5
9
  end
data/lib/unitsdb.rb CHANGED
@@ -2,20 +2,68 @@
2
2
 
3
3
  require "lutaml/model"
4
4
 
5
- require_relative "unitsdb/version"
6
- require_relative "unitsdb/config"
7
- require_relative "unitsdb/errors"
8
- require_relative "unitsdb/database"
9
- require_relative "unitsdb/dimensions"
10
- require_relative "unitsdb/prefixes"
11
- require_relative "unitsdb/quantities"
12
- require_relative "unitsdb/unit_systems"
13
- require_relative "unitsdb/scales"
14
- require_relative "unitsdb/units"
15
- require_relative "unitsdb/utils"
5
+ module Unitsdb
6
+ autoload :Cli, "unitsdb/cli"
7
+ autoload :Config, "unitsdb/config"
8
+ autoload :Commands, "unitsdb/commands"
9
+ autoload :Database, "unitsdb/database"
10
+ autoload :Dimension, "unitsdb/dimension"
11
+ autoload :DimensionDetails, "unitsdb/dimension_details"
12
+ autoload :DimensionReference, "unitsdb/dimension_reference"
13
+ autoload :Dimensions, "unitsdb/dimensions"
14
+ autoload :Errors, "unitsdb/errors"
15
+ autoload :ExternalReference, "unitsdb/external_reference"
16
+ autoload :Identifier, "unitsdb/identifier"
17
+ autoload :LocalizedString, "unitsdb/localized_string"
18
+ autoload :Prefix, "unitsdb/prefix"
19
+ autoload :PrefixReference, "unitsdb/prefix_reference"
20
+ autoload :Prefixes, "unitsdb/prefixes"
21
+ autoload :Quantities, "unitsdb/quantities"
22
+ autoload :Quantity, "unitsdb/quantity"
23
+ autoload :QuantityReference, "unitsdb/quantity_reference"
24
+ autoload :QudtUnit, "unitsdb/qudt"
25
+ autoload :QudtQuantityKind, "unitsdb/qudt"
26
+ autoload :QudtDimensionVector, "unitsdb/qudt"
27
+ autoload :QudtSystemOfUnits, "unitsdb/qudt"
28
+ autoload :QudtPrefix, "unitsdb/qudt"
29
+ autoload :QudtVocabularies, "unitsdb/qudt"
30
+ autoload :RootUnitReference, "unitsdb/root_unit_reference"
31
+ autoload :Scale, "unitsdb/scale"
32
+ autoload :ScaleProperties, "unitsdb/scale_properties"
33
+ autoload :ScaleReference, "unitsdb/scale_reference"
34
+ autoload :Scales, "unitsdb/scales"
35
+ autoload :SiDerivedBase, "unitsdb/si_derived_base"
36
+ autoload :SymbolPresentations, "unitsdb/symbol_presentations"
37
+ autoload :UcumBaseUnit, "unitsdb/ucum"
38
+ autoload :UcumPrefixValue, "unitsdb/ucum"
39
+ autoload :UcumPrefix, "unitsdb/ucum"
40
+ autoload :UcumUnitValueFunction, "unitsdb/ucum"
41
+ autoload :UcumUnitValue, "unitsdb/ucum"
42
+ autoload :UcumUnit, "unitsdb/ucum"
43
+ autoload :UcumFile, "unitsdb/ucum"
44
+ autoload :Unit, "unitsdb/unit"
45
+ autoload :UnitReference, "unitsdb/unit_reference"
46
+ autoload :UnitSystem, "unitsdb/unit_system"
47
+ autoload :UnitSystemReference, "unitsdb/unit_system_reference"
48
+ autoload :UnitSystems, "unitsdb/unit_systems"
49
+ autoload :Units, "unitsdb/units"
50
+ autoload :Utils, "unitsdb/utils"
16
51
 
17
- # CLI-related requires
18
- require_relative "unitsdb/cli" if defined?(Thor)
52
+ class << self
53
+ # Returns the path to the bundled data directory containing YAML files
54
+ def data_dir
55
+ @data_dir ||= File.join(gem_dir, "data")
56
+ end
19
57
 
20
- module Unitsdb
58
+ # Returns a pre-loaded Database instance from the bundled data
59
+ def database
60
+ @database ||= Database.from_db(data_dir)
61
+ end
62
+
63
+ private
64
+
65
+ def gem_dir
66
+ @gem_dir ||= File.dirname(__dir__)
67
+ end
68
+ end
21
69
  end
data/unitsdb.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.metadata["homepage_uri"] = spec.homepage
19
19
  spec.metadata["source_code_uri"] = spec.homepage
20
20
  spec.metadata["changelog_uri"] = "https://github.com/unitsml/unitsdb-ruby/releases"
21
+ spec.metadata["rubygems_mfa_required"] = "true"
21
22
 
22
23
  # Specify which files should be added to the gem when it is released.
23
24
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -26,15 +27,17 @@ Gem::Specification.new do |spec|
26
27
  f.match(%r{^(test|spec|features)/})
27
28
  end
28
29
  end
30
+ # Include YAML data files in the gem
31
+ spec.files += Dir.glob("data/**/*.yaml")
29
32
  spec.bindir = "exe"
30
33
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
- spec.test_files = `git ls-files -- {spec}/*`.split("\n")
32
34
  spec.require_paths = ["lib"]
33
35
 
34
- spec.add_dependency "lutaml-model", "~>0.7"
36
+ spec.add_dependency "fuzzy_match"
37
+ spec.add_dependency "lutaml-model", "~> 0.8.0"
35
38
  spec.add_dependency "rdf", "~> 3.1"
36
39
  spec.add_dependency "rdf-turtle", "~> 3.1"
37
40
  spec.add_dependency "rubyzip", "~> 2.3"
38
- spec.add_dependency "terminal-table"
41
+ spec.add_dependency "table_tennis", "~> 0.0.7"
39
42
  spec.add_dependency "thor", "~> 1.0"
40
43
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unitsdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-07-11 00:00:00.000000000 Z
11
+ date: 2026-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fuzzy_match
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: lutaml-model
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: '0.7'
33
+ version: 0.8.0
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: '0.7'
40
+ version: 0.8.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rdf
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -67,19 +81,19 @@ dependencies:
67
81
  - !ruby/object:Gem::Version
68
82
  version: '2.3'
69
83
  - !ruby/object:Gem::Dependency
70
- name: terminal-table
84
+ name: table_tennis
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ">="
87
+ - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '0'
89
+ version: 0.0.7
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ">="
94
+ - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '0'
96
+ version: 0.0.7
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: thor
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -111,6 +125,7 @@ files:
111
125
  - ".rspec"
112
126
  - ".rubocop.yml"
113
127
  - ".rubocop_todo.yml"
128
+ - CLAUDE.md
114
129
  - CODE_OF_CONDUCT.md
115
130
  - Gemfile
116
131
  - LICENSE.txt
@@ -118,20 +133,40 @@ files:
118
133
  - Rakefile
119
134
  - bin/console
120
135
  - bin/setup
136
+ - data/dimensions.yaml
137
+ - data/prefixes.yaml
138
+ - data/quantities.yaml
139
+ - data/scales.yaml
140
+ - data/schemas/dimensions-schema.yaml
141
+ - data/schemas/prefixes-schema.yaml
142
+ - data/schemas/quantities-schema.yaml
143
+ - data/schemas/scales-schema.yaml
144
+ - data/schemas/unit_systems-schema.yaml
145
+ - data/schemas/units-schema.yaml
146
+ - data/unit_systems.yaml
147
+ - data/units.yaml
121
148
  - exe/unitsdb
122
149
  - lib/unitsdb.rb
123
150
  - lib/unitsdb/cli.rb
151
+ - lib/unitsdb/commands.rb
124
152
  - lib/unitsdb/commands/_modify.rb
125
153
  - lib/unitsdb/commands/base.rb
126
154
  - lib/unitsdb/commands/check_si.rb
155
+ - lib/unitsdb/commands/check_si/si_formatter.rb
156
+ - lib/unitsdb/commands/check_si/si_matcher.rb
157
+ - lib/unitsdb/commands/check_si/si_ttl_parser.rb
158
+ - lib/unitsdb/commands/check_si/si_updater.rb
127
159
  - lib/unitsdb/commands/get.rb
128
160
  - lib/unitsdb/commands/normalize.rb
161
+ - lib/unitsdb/commands/qudt.rb
162
+ - lib/unitsdb/commands/qudt/check.rb
163
+ - lib/unitsdb/commands/qudt/formatter.rb
164
+ - lib/unitsdb/commands/qudt/matcher.rb
165
+ - lib/unitsdb/commands/qudt/ttl_parser.rb
166
+ - lib/unitsdb/commands/qudt/update.rb
167
+ - lib/unitsdb/commands/qudt/updater.rb
129
168
  - lib/unitsdb/commands/release.rb
130
169
  - lib/unitsdb/commands/search.rb
131
- - lib/unitsdb/commands/si_formatter.rb
132
- - lib/unitsdb/commands/si_matcher.rb
133
- - lib/unitsdb/commands/si_ttl_parser.rb
134
- - lib/unitsdb/commands/si_updater.rb
135
170
  - lib/unitsdb/commands/ucum.rb
136
171
  - lib/unitsdb/commands/ucum/check.rb
137
172
  - lib/unitsdb/commands/ucum/formatter.rb
@@ -141,8 +176,10 @@ files:
141
176
  - lib/unitsdb/commands/ucum/xml_parser.rb
142
177
  - lib/unitsdb/commands/validate.rb
143
178
  - lib/unitsdb/commands/validate/identifiers.rb
179
+ - lib/unitsdb/commands/validate/qudt_references.rb
144
180
  - lib/unitsdb/commands/validate/references.rb
145
181
  - lib/unitsdb/commands/validate/si_references.rb
182
+ - lib/unitsdb/commands/validate/ucum_references.rb
146
183
  - lib/unitsdb/config.rb
147
184
  - lib/unitsdb/database.rb
148
185
  - lib/unitsdb/dimension.rb
@@ -159,6 +196,7 @@ files:
159
196
  - lib/unitsdb/quantities.rb
160
197
  - lib/unitsdb/quantity.rb
161
198
  - lib/unitsdb/quantity_reference.rb
199
+ - lib/unitsdb/qudt.rb
162
200
  - lib/unitsdb/root_unit_reference.rb
163
201
  - lib/unitsdb/scale.rb
164
202
  - lib/unitsdb/scale_properties.rb
@@ -184,6 +222,7 @@ metadata:
184
222
  homepage_uri: https://github.com/unitsml/unitsdb-ruby
185
223
  source_code_uri: https://github.com/unitsml/unitsdb-ruby
186
224
  changelog_uri: https://github.com/unitsml/unitsdb-ruby/releases
225
+ rubygems_mfa_required: 'true'
187
226
  post_install_message:
188
227
  rdoc_options: []
189
228
  require_paths: