nxt_registry 0.3.0 → 0.3.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84faa74573904a66ff0f574195ef5ab7e74508d097f04d1e7f43afcfe4867432
4
- data.tar.gz: 8f5c04f6eef2f3b7328567d2b1e49fe9e862d915b572e18fdefd32cb71c24fc2
3
+ metadata.gz: e3c1e56b8913dea9833ea5fac4b1b837389de5df7aa269f3b2f04977f2ddceb3
4
+ data.tar.gz: 782bcb6ecce2753f77b488c29806bf1b2127714fe82aeed8ab2564297a43b95b
5
5
  SHA512:
6
- metadata.gz: 293d5d1d418152c704ea04aaff4dd392b901c40a9460f1858e5cf6581a0c6fe58041bbe163b8aff3fbcdd9848638f7715e87046b14666f5111677c5241d67eea
7
- data.tar.gz: 0475b0d48a589d90ff548d2c7f414bab38e5360fb46cafee35a29e83203a72fcd8fbce4870fbd7862b182ac38558f48567417808c5d400f4a728ff7dbf353a53
6
+ metadata.gz: 1e512d832f3d40ae60ffcfad8578589138c1f00479c2d2dab797c7e9faa6a37cec77da419d671715af55629e0efeac09ef5761bf39afcafe077c0d6f6af740a0
7
+ data.tar.gz: 3f17bfcc73233107e2daa4db54905115aea50e6f926b8e7ed10aea6d098ff418a4f39ced0e688b02a0a207e0562f02274bdfd9f59d568734485454afe7e1f06d
@@ -1,3 +1,24 @@
1
+ # v0.3.5 2020-12-04
2
+
3
+ - Allow patterns as keys
4
+
5
+ # v0.3.4 2020-12-04
6
+
7
+ - Bring back Singleton
8
+ - Fix mistakes in readme
9
+
10
+ # v0.3.3 2020-11-24
11
+
12
+ - Fix: Pass key to resolver instead of value
13
+
14
+ # v0.3.2 2020-09-29
15
+
16
+ - Fix interface definition
17
+
18
+ # v0.3.1 2020-09-23
19
+
20
+ - Allow to define custom accessors for registries
21
+
1
22
  # v0.3.0 2020-09-10
2
23
 
3
24
  ### Breaking Changes
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nxt_registry (0.3.0)
4
+ nxt_registry (0.3.5)
5
5
  activesupport
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activesupport (6.0.3.3)
10
+ activesupport (6.0.3.4)
11
11
  concurrent-ruby (~> 1.0, >= 1.0.2)
12
12
  i18n (>= 0.7, < 2)
13
13
  minitest (~> 5.1)
@@ -24,25 +24,25 @@ GEM
24
24
  coderay (~> 1.1)
25
25
  method_source (~> 1.0)
26
26
  rake (12.3.3)
27
- rspec (3.9.0)
28
- rspec-core (~> 3.9.0)
29
- rspec-expectations (~> 3.9.0)
30
- rspec-mocks (~> 3.9.0)
31
- rspec-core (3.9.2)
32
- rspec-support (~> 3.9.3)
33
- rspec-expectations (3.9.2)
27
+ rspec (3.10.0)
28
+ rspec-core (~> 3.10.0)
29
+ rspec-expectations (~> 3.10.0)
30
+ rspec-mocks (~> 3.10.0)
31
+ rspec-core (3.10.0)
32
+ rspec-support (~> 3.10.0)
33
+ rspec-expectations (3.10.0)
34
34
  diff-lcs (>= 1.2.0, < 2.0)
35
- rspec-support (~> 3.9.0)
36
- rspec-mocks (3.9.1)
35
+ rspec-support (~> 3.10.0)
36
+ rspec-mocks (3.10.0)
37
37
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.9.0)
39
- rspec-support (3.9.3)
38
+ rspec-support (~> 3.10.0)
39
+ rspec-support (3.10.0)
40
40
  rspec_junit_formatter (0.4.1)
41
41
  rspec-core (>= 2, < 4, != 2.12.0)
42
42
  thread_safe (0.3.6)
43
- tzinfo (1.2.7)
43
+ tzinfo (1.2.8)
44
44
  thread_safe (~> 0.1)
45
- zeitwerk (2.4.0)
45
+ zeitwerk (2.4.2)
46
46
 
47
47
  PLATFORMS
48
48
  ruby
data/README.md CHANGED
@@ -27,24 +27,23 @@ Or install it yourself as:
27
27
 
28
28
  ## Instance Level
29
29
 
30
- To use `NxtRegistry` on an instance level simply include it and build registries like so:
30
+ If you simply need a single global instance of a registry include `NxtRegistry::Singleton`:
31
31
 
32
32
  ```ruby
33
33
  class Example
34
- include NxtRegistry
34
+ include NxtRegistry::Singleton
35
35
 
36
- registry :languages do
36
+ registry do
37
37
  register(:ruby, 'Stone')
38
38
  register(:python, 'Snake')
39
39
  register(:javascript, 'undefined')
40
40
  end
41
41
  end
42
42
 
43
- example = Example.new
44
- example.registry(:languages).resolve(:ruby) # => 'Stone'
43
+ Example.resolve(:ruby) # => 'Stone'
45
44
  ```
46
45
 
47
- Alternatively you can also create instances of `NxtRegistry::Registry`
46
+ Alternatively you can simply create instances of `NxtRegistry::Registry`:
48
47
 
49
48
  ```ruby
50
49
  registry = NxtRegistry::Registry.new do
@@ -59,7 +58,7 @@ registry.resolve(:aki) # => 'Aki'
59
58
 
60
59
  ## Class Level
61
60
 
62
- You can register registries on the class level simply by extending your class with `NxtRegistry`
61
+ You can also add registries on the class level simply by extending your class with `NxtRegistry`
63
62
 
64
63
  ```ruby
65
64
  class OtherExample
@@ -83,6 +82,30 @@ OtherExample.registry(:errors).resolve(KeyError)
83
82
  OtherExample.registry(:country_codes).resolve(:germany)
84
83
  # => :de
85
84
  ```
85
+
86
+ ## Register Patterns
87
+
88
+ You can also register values with patterns as keys. Non pattern keys are always evaluated first and then patterns
89
+ will be tried to match by definition sequence.
90
+
91
+ ```ruby
92
+ class Example
93
+ extend NxtRegistry
94
+
95
+ registry :status_codes do
96
+ register(/\A4\d{2}\z/, 'Client errors')
97
+ register(/\A5.*\z/, 'Server errors')
98
+ register('422', 'Unprocessable Entity')
99
+ register(:'503', 'Internal Server Error')
100
+ end
101
+ end
102
+
103
+ Example.registry(:status_codes).resolve('503') # => "Internal Server Error"
104
+ Example.registry(:status_codes).resolve(503) # => "Internal Server Error"
105
+ Example.registry(:status_codes).resolve(422) # => "Unprocessable Entity"
106
+ Example.registry(:status_codes).resolve(404) # => "Client Errors"
107
+ ```
108
+
86
109
  ### Readers
87
110
 
88
111
  Access your defined registries with the `registry(:country_code)` method.
@@ -130,17 +153,41 @@ class Layer
130
153
  end
131
154
  end
132
155
 
156
+ # On every upper level every resolve returns a registry
133
157
  Layer.registry(:from) # => Registry[from]
134
-
135
158
  Layer.registry(:from).resolve(:munich) # => Registry[to] -> {}
136
159
  Layer.registry(:from).resolve(:amsterdam) # => Registry[to] -> {}
137
160
  Layer.registry(:from).resolve(:any_key) # => Registry[to] -> {}
138
-
139
161
  Layer.registry(:from).resolve(:munich, :amsterdam) # => Registry[via] -> {}
162
+
163
+ # Register a value on the bottom level
140
164
  Layer.registry(:from).resolve(:munich, :amsterdam).register(:train, -> { 'train' })
165
+ # Resolve the complete path
141
166
  Layer.registry(:from).resolve(:munich, :amsterdam, :train) # => 'train'
142
167
  ```
143
168
 
169
+ For registries with multiple levels the normal syntax for registering and resolving becomes quite weird and unreadable. This is why
170
+ every registry can be accessed through it's name or a custom accessor. The above example then can be simplified as follows.
171
+
172
+ ```ruby
173
+ class Layer
174
+ extend NxtRegistry
175
+
176
+ registry :path, accessor: :from do # registry named path, can be accessed with .from(...)
177
+ level :to do
178
+ level :via
179
+ end
180
+ end
181
+ end
182
+
183
+ # Register a value
184
+ Layer.registry(:path).from(:munich).to(:amsterdam).via(:train, -> { 'train' })
185
+ # Resolve the complete path
186
+ Layer.registry(:path).from(:munich).to(:amsterdam).via(:train) # => 'train'
187
+ ```
188
+
189
+ *Note that this feature is also available for registries with a single level only.*
190
+
144
191
  ### Restrict attributes to a certain set
145
192
 
146
193
  Use `attrs` to restrict which attributes can be registered on a specific level.
@@ -1,32 +1,44 @@
1
1
  require 'active_support/core_ext'
2
- require "nxt_registry/version"
3
- require "nxt_registry/blank"
4
- require "nxt_registry/attribute"
5
- require "nxt_registry/errors"
6
- require "nxt_registry/registry_builder"
7
- require "nxt_registry/registry"
8
- require "nxt_registry/recursive_registry"
2
+ require 'nxt_registry/version'
3
+ require 'nxt_registry/blank'
4
+ require 'nxt_registry/attribute'
5
+ require 'nxt_registry/errors'
6
+ require 'nxt_registry/registry_builder'
7
+ require 'nxt_registry/registry'
8
+ require 'nxt_registry/recursive_registry'
9
+ require 'nxt_registry/singleton'
9
10
 
10
11
  module NxtRegistry
11
12
  def registry(name, **options, &config)
12
- return registries.fetch(name) if registries.key?(name)
13
-
14
- registry = Registry.new(name, **options, &config)
15
- registries[name] ||= registry
16
- registry
13
+ build_registry(Registry, name, **options, &config)
17
14
  end
18
15
 
19
16
  def recursive_registry(name, **options, &config)
20
- return registries.fetch(name) if registries.key?(name)
21
-
22
- registry = RecursiveRegistry.new(name, **options, &config)
23
- registries[name] ||= registry
24
- registry
17
+ build_registry(RecursiveRegistry, name, **options, &config)
25
18
  end
26
19
 
27
20
  private
28
21
 
22
+ def build_registry(registry_class, name, **options, &config)
23
+ registry = registries.resolve(name)
24
+
25
+ if registry.present?
26
+ if registry.configured
27
+ return registry
28
+ else
29
+ raise_unconfigured_registry_accessed(name)
30
+ end
31
+ else
32
+ registry = registry_class.new(name, **options, &config)
33
+ registries.register(name, registry)
34
+ end
35
+ end
36
+
37
+ def raise_unconfigured_registry_accessed(name)
38
+ raise ArgumentError, "The registry #{name} must be configured before accessed!"
39
+ end
40
+
29
41
  def registries
30
- @registries ||= {}
42
+ @registries ||= Registry.new(:registries)
31
43
  end
32
44
  end
@@ -1,25 +1,28 @@
1
1
  module NxtRegistry
2
2
  class Registry
3
3
  def initialize(name = object_id.to_s, **options, &config)
4
+ @options = options
4
5
  @name = name
5
6
  @parent = options[:parent]
6
7
  @is_leaf = true
7
8
  @namespace = build_namespace
8
9
  @config = config
9
- @options = options
10
10
  @store = {}
11
11
  @attrs = nil
12
+ @configured = false
13
+ @patterns = []
12
14
 
13
15
  setup_defaults(options)
14
16
  configure(&config)
15
17
  end
16
18
 
17
19
  attr_reader :name
20
+ attr_accessor :configured
18
21
 
19
22
  def level(name, **options, &config)
20
23
  options = options.merge(parent: self)
21
24
 
22
- if default.is_a?(Blank)
25
+ if is_a_blank?(default)
23
26
  self.is_leaf = false
24
27
 
25
28
  self.default = RegistryBuilder.new do
@@ -36,13 +39,13 @@ module NxtRegistry
36
39
  end
37
40
 
38
41
  def registry(name, **options, &config)
39
- options = options.merge(parent: self)
40
- register(name, Registry.new(name, **options, &config))
42
+ opts = options.merge(parent: self)
43
+ register(name, Registry.new(name, **opts, &config))
41
44
  end
42
45
 
43
46
  def registry!(name, **options, &config)
44
- options = options.merge(parent: self)
45
- register!(name, Registry.new(name, **options, &config))
47
+ opts = options.merge(parent: self)
48
+ register!(name, Registry.new(name, **opts, &config))
46
49
  end
47
50
 
48
51
  def attr(name)
@@ -61,37 +64,37 @@ module NxtRegistry
61
64
 
62
65
  def register(key = Blank.new, value = Blank.new, **options, &block)
63
66
  if block_given?
64
- if value.is_a?(Blank)
67
+ if is_a_blank?(value)
65
68
  registry(key, **options, &block)
66
69
  else
67
70
  raise_register_argument_error
68
71
  end
69
72
  else
70
- __register(key, value, raise: true)
73
+ __register(key, value, raise_on_key_already_registered: true)
71
74
  end
72
75
  end
73
76
 
74
77
  def register!(key = Blank.new, value = Blank.new, **options, &block)
75
78
  if block_given?
76
- if value.is_a?(Blank)
79
+ if is_a_blank?(value)
77
80
  registry!(key, **options, &block)
78
81
  else
79
82
  raise_register_argument_error
80
83
  end
81
84
  else
82
- __register(key, value, raise: false)
85
+ __register(key, value, raise_on_key_already_registered: false)
83
86
  end
84
87
  end
85
88
 
86
89
  def resolve!(*keys)
87
90
  keys.inject(self) do |current_registry, key|
88
- current_registry.send(:__resolve, key, raise: true)
91
+ current_registry.send(:__resolve, key, raise_on_key_not_registered: true)
89
92
  end
90
93
  end
91
94
 
92
95
  def resolve(*keys)
93
96
  keys.inject(self) do |current_registry, key|
94
- current_registry.send(:__resolve, key, raise: false) || break
97
+ current_registry.send(:__resolve, key, raise_on_key_not_registered: false) || break
95
98
  end
96
99
  end
97
100
 
@@ -124,7 +127,8 @@ module NxtRegistry
124
127
  end
125
128
 
126
129
  def fetch(key, *args, &block)
127
- store.fetch(transformed_key(key), *args, &block)
130
+ key = matching_key(key)
131
+ store.fetch(key, *args, &block)
128
132
  end
129
133
 
130
134
  delegate :size, :values, :each, :freeze, to: :store
@@ -141,6 +145,8 @@ module NxtRegistry
141
145
  instance_exec(&block)
142
146
  end
143
147
  end
148
+
149
+ self.configured = true
144
150
  end
145
151
 
146
152
  def to_s
@@ -151,33 +157,40 @@ module NxtRegistry
151
157
 
152
158
  private
153
159
 
154
- attr_reader :namespace, :parent, :config, :store, :options
155
- attr_accessor :is_leaf
160
+ attr_reader :namespace, :parent, :config, :store, :options, :accessor, :patterns
161
+ attr_accessor :is_leaf, :interface_defined
156
162
 
157
163
  def is_leaf?
158
164
  @is_leaf
159
165
  end
160
166
 
161
- def __register(key, value, raise: true)
162
- key = transformed_key(key)
167
+ def __register(key, value, raise_on_key_already_registered: true)
168
+ key = if key.is_a?(Regexp)
169
+ patterns << key
170
+ key
171
+ else
172
+ transformed_key(key)
173
+ end
163
174
 
164
175
  raise ArgumentError, "Not allowed to register values in a registry that contains nested registries" unless is_leaf
165
176
  raise KeyError, "Keys are restricted to #{attrs.keys}" if attribute_not_allowed?(key)
166
177
 
167
- on_key_already_registered && on_key_already_registered.call(key) if store[key] && raise
178
+ on_key_already_registered && on_key_already_registered.call(key) if store[key] && raise_on_key_already_registered
168
179
 
169
180
  store[key] = value
170
181
  end
171
182
 
172
- def __resolve(key, raise: true)
183
+ def __resolve(key, raise_on_key_not_registered: true)
173
184
  key = transformed_key(key)
174
185
 
175
186
  value = if is_leaf?
176
187
  if store.key?(key)
177
188
  store.fetch(key)
189
+ elsif (pattern = matching_pattern(key))
190
+ store.fetch(pattern)
178
191
  else
179
- if default.is_a?(Blank)
180
- return unless raise
192
+ if is_a_blank?(default)
193
+ return unless raise_on_key_not_registered
181
194
 
182
195
  on_key_not_registered && on_key_not_registered.call(key)
183
196
  else
@@ -191,11 +204,7 @@ module NxtRegistry
191
204
  store[key] ||= default.call
192
205
  end
193
206
 
194
- value = if value.respond_to?(:call) && call && !value.is_a?(NxtRegistry::Registry)
195
- value.call(*[value].take(value.arity))
196
- else
197
- value
198
- end
207
+ value = call_or_value(value, key)
199
208
 
200
209
  if resolver
201
210
  resolver.call(value)
@@ -204,30 +213,59 @@ module NxtRegistry
204
213
  end
205
214
  end
206
215
 
216
+ def matching_key(key)
217
+ key = transformed_key(key)
218
+ # if key is present it always wins over patterns
219
+ return key if store.key?(key)
220
+
221
+ matching_pattern(key) || key
222
+ end
223
+
224
+ def call_or_value(value, key)
225
+ return value unless call
226
+ return value if value.is_a?(NxtRegistry::Registry)
227
+ return value unless value.respond_to?(:call)
228
+
229
+ args = [key, value]
230
+ value.call(*args.take(value.arity))
231
+ end
232
+
233
+ def matching_pattern(key)
234
+ patterns.find { |pattern| key.match?(pattern) }
235
+ end
236
+
207
237
  def define_interface
208
- define_singleton_method name do |key = Blank.new, value = Blank.new|
209
- return self if key.is_a?(Blank)
238
+ return if interface_defined
239
+
240
+ raise_invalid_accessor_name(accessor) if respond_to?(accessor.to_s)
241
+ accessor_with_bang = "#{accessor}!"
242
+ raise_invalid_accessor_name(accessor_with_bang) if respond_to?(accessor_with_bang)
243
+
244
+ define_singleton_method accessor.to_s do |key = Blank.new, value = Blank.new|
245
+ return self if is_a_blank?(key)
210
246
 
211
247
  key = transformed_key(key)
212
248
 
213
- if value.is_a?(Blank)
249
+ if is_a_blank?(value)
214
250
  resolve(key)
215
251
  else
216
252
  register(key, value)
217
253
  end
218
254
  end
219
255
 
220
- define_singleton_method "#{name}!" do |key = Blank.new, value = Blank.new|
221
- return self if key.is_a?(Blank)
256
+ define_singleton_method accessor_with_bang do |key = Blank.new, value = Blank.new|
257
+ return self if is_a_blank?(key)
222
258
 
223
259
  key = transformed_key(key)
224
260
 
225
- if value.is_a?(Blank)
261
+ if is_a_blank?(value)
226
262
  resolve!(key)
227
263
  else
228
264
  register!(key, value)
229
265
  end
230
266
  end
267
+
268
+ self.interface_defined = true
231
269
  end
232
270
 
233
271
  def setup_defaults(options)
@@ -235,7 +273,8 @@ module NxtRegistry
235
273
  @memoize = options.fetch(:memoize) { true }
236
274
  @call = options.fetch(:call) { true }
237
275
  @resolver = options.fetch(:resolver, false)
238
- @transform_keys = options.fetch(:transform_keys) { ->(key) { key.to_s } }
276
+ @transform_keys = options.fetch(:transform_keys) { ->(key) { key.is_a?(Regexp) ? key : key.to_s } }
277
+ @accessor = options.fetch(:accessor) { name }
239
278
 
240
279
  @on_key_already_registered = options.fetch(:on_key_already_registered) { ->(key) { raise_key_already_registered_error(key) } }
241
280
  @on_key_not_registered = options.fetch(:on_key_not_registered) { ->(key) { raise_key_not_registered_error(key) } }
@@ -246,7 +285,7 @@ module NxtRegistry
246
285
  define_singleton_method attribute do |value = Blank.new, &block|
247
286
  value = block if block
248
287
 
249
- if value.is_a?(Blank)
288
+ if is_a_blank?(value)
250
289
  instance_variable_get("@#{attribute}")
251
290
  else
252
291
  instance_variable_set("@#{attribute}", value)
@@ -284,7 +323,7 @@ module NxtRegistry
284
323
  def transformed_key(key)
285
324
  @transformed_key ||= {}
286
325
  @transformed_key[key] ||= begin
287
- if transform_keys && !key.is_a?(Blank)
326
+ if transform_keys && !is_a_blank?(key)
288
327
  transform_keys.call(key)
289
328
  else
290
329
  key
@@ -296,6 +335,7 @@ module NxtRegistry
296
335
  super
297
336
  @store = original.send(:store).deep_dup
298
337
  @options = original.send(:options).deep_dup
338
+ @patterns = original.send(:patterns).dup
299
339
  end
300
340
 
301
341
  def build_namespace
@@ -305,5 +345,13 @@ module NxtRegistry
305
345
  def raise_register_argument_error
306
346
  raise ArgumentError, 'Either provide a key value pair or a block to register'
307
347
  end
348
+
349
+ def is_a_blank?(value)
350
+ value.is_a?(Blank)
351
+ end
352
+
353
+ def raise_invalid_accessor_name(name)
354
+ raise ArgumentError, "#{self} already implements a method named: #{name}. Please choose a different accessor name"
355
+ end
308
356
  end
309
357
  end
@@ -0,0 +1,15 @@
1
+ module NxtRegistry
2
+ module Singleton
3
+ include NxtRegistry
4
+
5
+ def self.included(base)
6
+ base.extend(self)
7
+ end
8
+
9
+ def registry(type = Registry, **options, &config)
10
+ @registry ||= build_registry(type, self.class.name, **options, &config)
11
+ end
12
+
13
+ delegate_missing_to :registry
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module NxtRegistry
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.5"
3
3
  end
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.name = "nxt_registry"
7
7
  spec.version = NxtRegistry::VERSION
8
8
  spec.authors = ["Andreas Robecke", "Nils Sommer", "Raphael Kallensee", "Lütfi Demirci"]
9
- spec.email = ["a.robecke@getsafe.de"]
9
+ spec.email = ['a.robecke@hellogetsafe.com', 'andreas@robecke.de']
10
10
 
11
11
  spec.summary = %q{nxt_registry is a simple implementation of the container pattern}
12
12
  spec.homepage = "https://github.com/nxt-insurance"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nxt_registry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Robecke
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2020-09-17 00:00:00.000000000 Z
14
+ date: 2020-12-04 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
@@ -85,7 +85,8 @@ dependencies:
85
85
  version: '0'
86
86
  description:
87
87
  email:
88
- - a.robecke@getsafe.de
88
+ - a.robecke@hellogetsafe.com
89
+ - andreas@robecke.de
89
90
  executables: []
90
91
  extensions: []
91
92
  extra_rdoc_files: []
@@ -111,6 +112,7 @@ files:
111
112
  - lib/nxt_registry/recursive_registry.rb
112
113
  - lib/nxt_registry/registry.rb
113
114
  - lib/nxt_registry/registry_builder.rb
115
+ - lib/nxt_registry/singleton.rb
114
116
  - lib/nxt_registry/version.rb
115
117
  - nxt_registry.gemspec
116
118
  homepage: https://github.com/nxt-insurance