csv2hash 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 043c4be4542235e09772f8ca2249288158f7230f
4
- data.tar.gz: 2eb0e8d2a0e13854f103b21b34d4a54fbb55e64f
3
+ metadata.gz: 12502614a6a2f8d3243b4b35152bc6dc33cc3f60
4
+ data.tar.gz: 235432257ee6d4e907aaa900f5090fc284fc80db
5
5
  SHA512:
6
- metadata.gz: 43c070b76ca768925631f70c3e95750b5ec7edf9438e856ee58160c288f04a9c6d2215bc04c01af7a464ef80a991c1adb88797b5f4183d7c53922b1d09ca893b
7
- data.tar.gz: 62050c84397a144b712a592cc9e39d28d1bec6965fdbe31d35263016cf31a4b4a35b2450538088da239583ed76a0d9ce7e8ec0c3e129176792ed39e5a6c06715
6
+ metadata.gz: 5f597444c037b909413309e3570374c074a18e96463c40c1c7979cd5aeec5f96f6203ade714959c4ca930341e90d4b67a39f2b3718f02c57e85cf4882b6594d5
7
+ data.tar.gz: e9488827e829ecdc086791c8beadc0afcf5dd868327fbf0c78a479f963d19608a50e581d6974366dacbac9fed4ce289741c8c9971098dddbf90f7e374e0f8bb2
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- csv2hash (0.5.0)
4
+ csv2hash (0.6.0)
5
5
  activesupport (~> 4.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -28,6 +28,19 @@ Or install it yourself as:
28
28
 
29
29
  Parsing is based on rules, you must defined rules of parsing
30
30
 
31
+ ### DSL
32
+
33
+ Csv2hash::Main.generate_definition :name do
34
+ set_type { Definition::MAPPING }
35
+ set_header_size { 2 } # 0 by default
36
+ set_structure_rules {{ 'MaxColumns' => 2 }}
37
+ mapping do
38
+ cell position: [0,0], key: 'gender'
39
+ cell position: [1,0], key: 'name'
40
+ end
41
+ end
42
+ Csv2hash::Main[:name] # Access anywhere
43
+
31
44
  ### Rules
32
45
 
33
46
  You should declared a definition for you CSV, and then define for each cell what you would expect.
@@ -37,31 +50,31 @@ Example :
37
50
  If you want the very first cell, located on the first line and on the first column to be a string with values are either 'yes' either 'no', you can write the following validation rule:
38
51
 
39
52
  ```
40
- { name: 'aswering', type: 'string', values: ['yes', 'no'], position: [0,0] }
53
+ cell name: 'aswering', type: 'string', values: ['yes', 'no'], position: [0,0]
41
54
  ```
42
55
 
43
56
  :type attribute has 'string' for default value, therefore you can just write this:
44
57
 
45
58
  ```
46
- { name: 'aswering', values: ['yes', 'no'], position: [0,0] }
59
+ cell name: 'aswering', values: ['yes', 'no'], position: [0,0]
47
60
  ```
48
61
 
49
62
  You can define you own message but default message is 'undefined :key on :position'
50
63
 
51
64
  ```
52
- { name: 'aswering', values: ['yes', 'no'], position: [0,0], message: 'this value is not supported' }
65
+ cell name: 'aswering', values: ['yes', 'no'], position: [0,0], message: 'this value is not supported'
53
66
  ```
54
67
 
55
68
  You can also define Range of values
56
69
 
57
70
  ```
58
- { name: 'score', values: 0..5, position: [0,0] }
71
+ cell name: 'score', values: 0..5, position: [0,0]
59
72
  ```
60
73
 
61
74
  The message is parsed:
62
75
 
63
76
  ```
64
- { ..., message: 'value of :name is not supported, please you one of :values' }
77
+ cell ..., message: 'value of :name is not supported, please you one of :values'
65
78
  ```
66
79
 
67
80
  It produces :
@@ -119,20 +132,21 @@ Precise position validation sample:
119
132
  end
120
133
 
121
134
  def data
122
- @data_wrapper ||= Csv2hash::Main.new(definition, file_path_or_data).parse
135
+ @data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:<definition_name>], file_path_or_data).parse
123
136
  end
124
137
 
125
138
  private
126
139
 
127
- def rules
128
- [].tap do |mapping|
129
- mapping << { position: [2,1], key: 'first_name' }
130
- mapping << { position: [3,1], key: 'last_name' }
131
- end
132
- end
133
-
134
140
  def definition
135
- Csv2Hash::Definition.new(rules, type = Csv2Hash::Definition::MAPPING, header_size: 1)
141
+ Main.generate_definition :my_defintion do
142
+ set_type { Definition::MAPPING }
143
+ set_header_size { 1 }
144
+ mapping do
145
+ cell position: [2,1], key: 'first_name'
146
+ cell position: [3,1], key: 'last_name'
147
+ end
148
+ end
149
+ end
136
150
  end
137
151
 
138
152
  end
@@ -159,23 +173,28 @@ Collection validation sample:
159
173
  end
160
174
 
161
175
  def data
162
- @data_wrapper ||= Csv2hash::Main.new(definition, file_path_or_data).parse
176
+ @data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:<definition_name>], file_path_or_data).parse
163
177
  end
164
178
 
165
179
  private
166
180
 
167
- def rules
168
- [].tap do |mapping|
169
- mapping << { position: 0, key: 'nickname' }
170
- mapping << { position: 1, key: 'first_name' }
171
- mapping << { position: 2, key: 'last_name' }
172
- end
173
- end
174
-
175
181
  def definition
176
182
  Csv2Hash::Definition.new(rules, type = Csv2Hash::Definition::COLLECTION, header_size: 1)
177
183
  end
178
184
 
185
+ def definition
186
+ Main.generate_definition :my_defintion do
187
+ set_type { Definition::COLLECTION }
188
+ set_header_size { 1 }
189
+ mapping do
190
+ cell position: 0, key: 'nickname'
191
+ cell position: 1, key: 'first_name'
192
+ cell position: 2, key: 'last_name'
193
+ end
194
+ end
195
+ end
196
+ end
197
+
179
198
  end
180
199
  ```
181
200
 
@@ -194,22 +213,23 @@ Current validations are: MinColumn, MaxColumn
194
213
  end
195
214
 
196
215
  def data
197
- @data_wrapper ||= Csv2hash::Main.new(definition, file_path_or_data).parse
216
+ @data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:<definition_name>], file_path_or_data).parse
198
217
  end
199
218
 
200
219
  private
201
220
 
202
- def rules
203
- [].tap do |mapping|
204
- mapping << { position: 0, key: 'nickname' }
205
- mapping << { position: 1, key: 'first_name' }
206
- mapping << { position: 2, key: 'last_name' }
207
- end
208
- end
209
-
210
221
  def definition
211
- Csv2Hash::Definition.new(rules, type = Csv2Hash::Definition::COLLECTION,
212
- structure_rules: { 'MinColumns' => 2, 'MaxColumns' => 3 })
222
+ Main.generate_definition :my_defintion do
223
+ set_type { Definition::COLLECTION }
224
+ set_header_size { 1 }
225
+ set_structure_rules {{ 'MinColumns' => 2, 'MaxColumns' => 3 }}
226
+ mapping do
227
+ cell position: 0, key: 'nickname'
228
+ cell position: 1, key: 'first_name'
229
+ cell position: 2, key: 'last_name'
230
+ end
231
+ end
232
+ end
213
233
  end
214
234
  end
215
235
  ```
@@ -219,7 +239,7 @@ Current validations are: MinColumn, MaxColumn
219
239
  You can define the number of rows to skip in the header of the CSV.
220
240
 
221
241
  ```
222
- Definition.new(rules, type, header_size: 0)
242
+ set_header_size { 1 }
223
243
  ```
224
244
 
225
245
  ### Parser and configuration
@@ -343,8 +363,8 @@ For downcase validation
343
363
  in your rule
344
364
 
345
365
  ```
346
- { position: [0,0], key: 'name', extra_validator: DowncaseValidator.new,
347
- message: 'your data should be written in lowercase only.' }
366
+ cell position: [0,0], key: 'name', extra_validator: DowncaseValidator.new,
367
+ message: 'your data should be written in lowercase only.'
348
368
  ```
349
369
 
350
370
  Csv data
@@ -353,6 +373,30 @@ Csv data
353
373
  [ [ 'Foo' ] ]
354
374
  ```
355
375
 
376
+ # Upgrading
377
+
378
+ # Upgrading from 0.5 to 0.6
379
+
380
+ Introduce DSL
381
+
382
+ Prior to 0.6 :
383
+
384
+ ```
385
+ rules = [{ position: [0,0], key: 'name' }]
386
+ Csv2hash::Definition.new(rules, Definition::MAPPING, options={})
387
+
388
+ ```
389
+
390
+ Starting from 0.6 :
391
+
392
+ ```
393
+ Csv2hash::Main.generate_definition :foo do
394
+ set_type { Definition::MAPPING }
395
+ mapping { cell position: [0,0], key: 'name' }
396
+ end
397
+ Csv2hash::Main[:foo] # Access anywhere
398
+ ```
399
+
356
400
  # Upgrading from 0.4 to 0.5
357
401
 
358
402
  Signature of ```Csv2hash::Main#new``` has changed too
data/ReleaseNotes.md CHANGED
@@ -1,10 +1,18 @@
1
+ ### VERSION 0.6.0
2
+
3
+ * backwards incompatible changes
4
+ * Introduce DSL for definition
5
+
6
+ * refactoring
7
+ * replace arguments for rules by DSL of cells
8
+
1
9
  ### VERSION 0.5.0
2
10
 
3
11
  * backwards incompatible changes
4
12
  * The signature of Csv2hash::Main#new has changed.
5
13
 
6
14
  * refactoring
7
- * remove params ``` ignore_blank_line ``` to benefit of options of Hash
15
+ * remove params ``` ignore_blank_line ``` to benefit of options of Hash
8
16
 
9
17
  ### VERSION 0.4.0
10
18
 
data/bin/launch_irb ADDED
@@ -0,0 +1 @@
1
+ irb -r csv2hash -I ./lib
@@ -5,7 +5,6 @@ module Csv2hash
5
5
  class UnsupportedAdapter < StandardError ; end
6
6
 
7
7
  def self.create adapter_name, file_path_or_data
8
- # binding.pry
9
8
  load "csv2hash/adapters/#{adapter_name}_adapter.rb"
10
9
  class_eval("Csv2hash::Adapter::#{klass_adapter(adapter_name)}").new file_path_or_data
11
10
  end
@@ -0,0 +1,11 @@
1
+ require 'active_support/core_ext/array/extract_options'
2
+
3
+ class Cell
4
+
5
+ attr_accessor :rules
6
+
7
+ def initialize *args
8
+ self.rules = args.extract_options!
9
+ end
10
+
11
+ end
@@ -4,52 +4,81 @@ module Csv2hash
4
4
  MAPPING = 'mapping'.freeze
5
5
  COLLECTION = 'collection'.freeze
6
6
 
7
- TYPES = [MAPPING, COLLECTION]
7
+ TYPES = [ MAPPING, COLLECTION ]
8
8
 
9
- attr_accessor :rules, :type, :header_size, :structure_rules
9
+ attr_accessor :cells, :structure_rules, :header_size
10
+ attr_reader :type, :name
10
11
 
11
- def initialize rules, type, options = {}
12
- self.rules, self.type = rules, type
13
- self.header_size, self.structure_rules = options.fetch(:header_size) { 0 }, options.fetch(:structure_rules) { {} }
12
+ def initialize name, &blk
13
+ @name = name
14
+ self.cells = []
15
+ self.header_size = 0
16
+ self.structure_rules = {}
17
+ instance_eval(&blk) if block_given?
18
+ end
19
+
20
+ def mapping &blk
21
+ instance_eval(&blk) if block_given?
22
+ end
23
+
24
+ def cell *args
25
+ self.cells << Cell.new(*args)
26
+ end
27
+
28
+ def set_header_size &blk
29
+ self.header_size = yield if block_given?
30
+ end
31
+
32
+ def set_type &blk
33
+ @type = yield if block_given?
34
+ end
35
+
36
+ def set_structure_rules &blk
37
+ self.structure_rules = yield if block_given?
14
38
  end
15
39
 
16
40
  def validate!
17
- unless TYPES.include?(type)
41
+ # binding.pry
42
+ unless TYPES.include?(@type)
18
43
  raise "not suitable type, please use '#{MAPPING}' or '#{COLLECTION}'"
19
44
  end
20
- raise 'rules must be an Array of rules' unless rules.class == Array
21
- raise 'structure rules must be a Hash of rules' unless structure_rules.class == Hash
45
+ raise 'cells must be an Array of cell' unless self.cells.class == Array
46
+ raise 'structure rules must be a Hash of rules' unless self.structure_rules.class == Hash
22
47
  end
23
48
 
24
49
  def default!
25
- rules.each do |rule|
26
- default_position rule
27
- unless rule.has_key? :message
28
- if rule.has_key? :values
29
- rule.merge! message: ':key not supported, please use one of :values'
50
+ # binding.pry
51
+ cells.each do |cell|
52
+ cell.rules.fetch(:position)
53
+
54
+ default_position cell
55
+ unless cell.rules.has_key? :message
56
+ if cell.rules.has_key? :values
57
+ cell.rules.merge! message: ':key not supported, please use one of :values'
30
58
  else
31
- rule.merge! message: 'undefined :key on :position'
59
+ cell.rules.merge! message: 'undefined :key on :position'
32
60
  end
33
61
  end
34
- rule.merge! mappable: true unless rule.has_key? :mappable
35
- rule.merge! type: 'string' unless rule.has_key? :type
36
- rule.merge! values: nil unless rule.has_key? :values
37
- rule.merge! nested: nil unless rule.has_key? :nested
38
- rule.merge! allow_blank: false unless rule.has_key? :allow_blank
39
- rule.merge! extra_validator: nil unless rule.has_key? :extra_validator
62
+ cell.rules.merge! mappable: true unless cell.rules.has_key? :mappable
63
+ cell.rules.merge! type: 'string' unless cell.rules.has_key? :type
64
+ cell.rules.merge! values: nil unless cell.rules.has_key? :values
65
+ cell.rules.merge! nested: nil unless cell.rules.has_key? :nested
66
+ cell.rules.merge! allow_blank: false unless cell.rules.has_key? :allow_blank
67
+ cell.rules.merge! extra_validator: nil unless cell.rules.has_key? :extra_validator
40
68
  end
69
+ # binding.pry
41
70
  end
42
71
 
43
72
  private
44
73
 
45
- def default_position rule
74
+ def default_position cell
46
75
  case type
47
76
  when MAPPING
48
- y, x = rule.fetch(:position, ['undefined', 'undefined'])
49
- rule.merge! key: "key_#{y}_#{x}" unless rule.has_key? :key
77
+ y, x = cell.rules.fetch(:position, ['undefined', 'undefined'])
78
+ cell.rules.merge! key: "key_#{y}_#{x}" unless cell.rules.has_key? :key
50
79
  when COLLECTION
51
- x = rule.fetch :position
52
- rule.merge! key: "key_undefined_#{x}" unless rule.has_key? :key
80
+ x = cell.rules.fetch :position
81
+ cell.rules.merge! key: "key_undefined_#{x}" unless cell.rules.has_key? :key
53
82
  end
54
83
  end
55
84
 
@@ -0,0 +1,10 @@
1
+ module Csv2hash
2
+ module Expectation
3
+
4
+ def unexpected_line? line, y
5
+ return true if y < definition.header_size
6
+ return true if self.options.fetch(:ignore_blank_line){false} and line.compact.empty?
7
+ end
8
+
9
+ end
10
+ end
@@ -1,31 +1,37 @@
1
- module Csv2hash::Parser::Collection
2
- include Csv2hash::Parser
1
+ require_relative '../expectation'
3
2
 
4
- def fill!
5
- self.data = {}.tap do |data_computed|
6
- data_computed[:data] ||= []
7
- self.data_source.each_with_index do |line, y|
8
- next if y < definition.header_size
9
- next if self.options.fetch(:ignore_blank_line) and line.compact.empty?
10
- data_computed[:data] << {}.tap do |data_parsed|
11
- fill_it data_parsed, line
3
+ module Csv2hash
4
+ module Parser
5
+ module Collection
6
+ include Parser
7
+ include Expectation
8
+
9
+ def fill!
10
+ self.data = {}.tap do |data_computed|
11
+ data_computed[:data] ||= []
12
+ self.data_source.each_with_index do |line, y|
13
+ next if unexpected_line?(line, y)
14
+ data_computed[:data] << {}.tap do |data_parsed|
15
+ fill_it data_parsed, line
16
+ end
17
+ end
12
18
  end
13
19
  end
14
- end
15
- end
16
20
 
17
- def fill_it parsed_data, source_data
18
- definition.rules.each do |rule|
19
- if rule.fetch :mappable
20
- x = rule.fetch :position
21
- if (nested = rule.fetch :nested)
22
- parsed_data[nested] ||= {}
23
- parsed_data[nested][rule.fetch(:key)] = source_data[x]
24
- else
25
- parsed_data[rule.fetch(:key)] = source_data[x]
21
+ def fill_it parsed_data, source_data
22
+ definition.cells.each do |cell|
23
+ if cell.rules.fetch :mappable
24
+ x = cell.rules.fetch :position
25
+ if (nested = cell.rules.fetch :nested)
26
+ parsed_data[nested] ||= {}
27
+ parsed_data[nested][cell.rules.fetch(:key)] = source_data[x]
28
+ else
29
+ parsed_data[cell.rules.fetch(:key)] = source_data[x]
30
+ end
31
+ end
26
32
  end
27
33
  end
34
+
28
35
  end
29
36
  end
30
-
31
37
  end
@@ -11,14 +11,14 @@ module Csv2hash::Parser::Mapping
11
11
  end
12
12
 
13
13
  def fill_it parsed_data, source_data
14
- definition.rules.each do |rule|
15
- if rule.fetch :mappable
16
- y, x = rule.fetch :position
17
- if (nested = rule.fetch :nested)
14
+ definition.cells.each do |cell|
15
+ if cell.rules.fetch :mappable
16
+ y, x = cell.rules.fetch :position
17
+ if (nested = cell.rules.fetch :nested)
18
18
  parsed_data[nested] ||= {}
19
- parsed_data[nested][rule.fetch(:key)] = source_data[y][x]
19
+ parsed_data[nested][cell.rules.fetch(:key)] = source_data[y][x]
20
20
  else
21
- parsed_data[rule.fetch(:key)] = source_data[y][x]
21
+ parsed_data[cell.rules.fetch(:key)] = source_data[y][x]
22
22
  end
23
23
  end
24
24
  end
@@ -0,0 +1,13 @@
1
+ class Registry
2
+ def initialize
3
+ @definitions = Hash.new
4
+ end
5
+
6
+ def [] name
7
+ @definitions[name]
8
+ end
9
+
10
+ def []= name, definition
11
+ @definitions[name] = definition
12
+ end
13
+ end
@@ -4,6 +4,7 @@ module Csv2hash::StructureValidator
4
4
  class ValidationError < StandardError ; end
5
5
 
6
6
  def validate_structure!
7
+ # binding.pry
7
8
  definition.structure_rules.each do |rule, options|
8
9
  begin
9
10
  rule_instance(rule, options).validate! data_source
@@ -1,18 +1,24 @@
1
- module Csv2hash::Validator::Collection
2
- include Csv2hash::Validator
1
+ require_relative '../expectation'
3
2
 
4
- def validate_data!
5
- self.data_source.each_with_index do |line, y|
6
- next if y < definition.header_size
7
- next if self.options.fetch(:ignore_blank_line) and line.compact.empty?
8
- validate_rules y
9
- end
10
- end
3
+ module Csv2hash
4
+ module Validator
5
+ module Collection
6
+ include Validator
7
+ include Expectation
11
8
 
12
- protected
9
+ def validate_data!
10
+ self.data_source.each_with_index do |line, y|
11
+ next if unexpected_line?(line, y)
12
+ validate_rules y
13
+ end
14
+ end
13
15
 
14
- def position _position
15
- [nil, _position]
16
- end
16
+ protected
17
17
 
18
+ def position _position
19
+ [nil, _position]
20
+ end
21
+
22
+ end
23
+ end
18
24
  end
@@ -1,14 +1,18 @@
1
- module Csv2hash::Validator::Mapping
2
- include Csv2hash::Validator
1
+ module Csv2hash
2
+ module Validator
3
+ module Mapping
4
+ include Validator
3
5
 
4
- def validate_data!
5
- validate_rules data_source
6
- end
6
+ def validate_data!
7
+ validate_rules data_source
8
+ end
7
9
 
8
- protected
10
+ protected
9
11
 
10
- def position _position
11
- _position
12
- end
12
+ def position _position
13
+ _position
14
+ end
13
15
 
16
+ end
17
+ end
14
18
  end
@@ -2,12 +2,13 @@ module Csv2hash
2
2
  module Validator
3
3
 
4
4
  def validate_rules y=nil
5
- definition.rules.each do |rule|
6
- _y, x = position rule.fetch(:position)
5
+ # binding.pry
6
+ definition.cells.each do |cell|
7
+ _y, x = position cell.rules.fetch(:position)
7
8
  begin
8
- validate_cell (_y||y), x, rule
9
+ validate_cell (_y||y), x, cell
9
10
  rescue => e
10
- self.errors << { y: (_y||y), x: x, message: e.message, key: rule.fetch(:key) }
11
+ self.errors << { y: (_y||y), x: x, message: e.message, key: cell.rules.fetch(:key) }
11
12
  raise if break_on_failure
12
13
  end
13
14
  end
@@ -17,14 +18,14 @@ module Csv2hash
17
18
 
18
19
  protected
19
20
 
20
- def validate_cell y, x, rule
21
+ def validate_cell y, x, cell
21
22
  value = data_source[y][x] rescue nil
22
23
  begin
23
- raise unless value unless rule.fetch :allow_blank
24
- if (extra_validator = rule.fetch :extra_validator) && extra_validator.kind_of?(Csv2hash::ExtraValidator)
25
- raise unless extra_validator.valid? rule, value
24
+ raise unless value unless cell.rules.fetch :allow_blank
25
+ if (extra_validator = cell.rules.fetch :extra_validator) && extra_validator.kind_of?(Csv2hash::ExtraValidator)
26
+ raise unless extra_validator.valid? cell.rules, value
26
27
  else
27
- if value && (values = rule.fetch :values)
28
+ if value && (values = cell.rules.fetch :values)
28
29
  if values.class == Range
29
30
  raise unless values.include?(value.to_f)
30
31
  else
@@ -33,13 +34,13 @@ module Csv2hash
33
34
  end
34
35
  end
35
36
  rescue => e
36
- raise message(rule, y, x)
37
+ raise message(cell, y, x)
37
38
  end
38
39
  end
39
40
 
40
- def message rule, y, x
41
- msg = rule.fetch(:message).tap do |msg|
42
- rule.each { |key, value| msg.gsub!(":#{key.to_s}", value.to_s) unless key == :position }
41
+ def message cell, y, x
42
+ msg = cell.rules.fetch(:message).tap do |msg|
43
+ cell.rules.each { |key, value| msg.gsub!(":#{key.to_s}", value.to_s) unless key == :position }
43
44
  end
44
45
  msg.gsub ':position', "[#{y}, #{x}]"
45
46
  end
@@ -1,3 +1,3 @@
1
1
  module Csv2hash
2
- VERSION = '0.5.0'
2
+ VERSION = '0.6.0'
3
3
  end
data/lib/csv2hash.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require_relative 'csv2hash/version'
2
+ require_relative 'csv2hash/registry'
3
+ require_relative 'csv2hash/cell'
2
4
  require_relative 'csv2hash/definition'
3
5
  require_relative 'csv2hash/validator'
4
6
  require_relative 'csv2hash/validator/mapping'
@@ -26,6 +28,24 @@ module Csv2hash
26
28
  class Main
27
29
  include Csv2hash::StructureValidator
28
30
 
31
+ class << self
32
+
33
+ def generate_definition name, &block
34
+ definition = Definition.new name, &block
35
+ Main[name] = definition
36
+ end
37
+
38
+ def [] definition_name
39
+ @@registry[definition_name]
40
+ end
41
+
42
+ def []= definition_name, role
43
+ @@registry[definition_name] = role
44
+ end
45
+ end
46
+
47
+ @@registry = Registry.new
48
+
29
49
  attr_accessor :definition, :file_path_or_data, :data, :notifier, :break_on_failure, :errors, :options
30
50
 
31
51
  def initialize definition, file_path_or_data, *args