bolt 2.37.0 → 2.44.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bolt might be problematic. Click here for more details.

Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/Puppetfile +17 -17
  3. data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +6 -8
  4. data/lib/bolt/analytics.rb +3 -2
  5. data/lib/bolt/applicator.rb +11 -1
  6. data/lib/bolt/bolt_option_parser.rb +20 -13
  7. data/lib/bolt/catalog.rb +10 -29
  8. data/lib/bolt/cli.rb +58 -40
  9. data/lib/bolt/config.rb +134 -119
  10. data/lib/bolt/config/options.rb +142 -77
  11. data/lib/bolt/config/transport/base.rb +2 -2
  12. data/lib/bolt/config/transport/local.rb +1 -0
  13. data/lib/bolt/config/transport/options.rb +18 -68
  14. data/lib/bolt/config/transport/orch.rb +1 -0
  15. data/lib/bolt/config/transport/ssh.rb +0 -5
  16. data/lib/bolt/executor.rb +15 -5
  17. data/lib/bolt/inventory.rb +26 -0
  18. data/lib/bolt/inventory/group.rb +35 -12
  19. data/lib/bolt/inventory/inventory.rb +1 -1
  20. data/lib/bolt/inventory/options.rb +130 -0
  21. data/lib/bolt/inventory/target.rb +10 -11
  22. data/lib/bolt/logger.rb +114 -10
  23. data/lib/bolt/module.rb +10 -2
  24. data/lib/bolt/module_installer.rb +25 -15
  25. data/lib/bolt/module_installer/resolver.rb +65 -12
  26. data/lib/bolt/module_installer/specs/forge_spec.rb +8 -2
  27. data/lib/bolt/module_installer/specs/git_spec.rb +17 -2
  28. data/lib/bolt/outputter.rb +19 -5
  29. data/lib/bolt/outputter/human.rb +24 -1
  30. data/lib/bolt/outputter/json.rb +1 -1
  31. data/lib/bolt/outputter/logger.rb +1 -1
  32. data/lib/bolt/outputter/rainbow.rb +12 -1
  33. data/lib/bolt/pal.rb +93 -14
  34. data/lib/bolt/pal/yaml_plan.rb +8 -2
  35. data/lib/bolt/pal/yaml_plan/evaluator.rb +2 -2
  36. data/lib/bolt/pal/yaml_plan/transpiler.rb +6 -1
  37. data/lib/bolt/plugin.rb +3 -3
  38. data/lib/bolt/plugin/cache.rb +8 -8
  39. data/lib/bolt/plugin/module.rb +1 -1
  40. data/lib/bolt/plugin/puppet_connect_data.rb +35 -0
  41. data/lib/bolt/plugin/puppetdb.rb +2 -2
  42. data/lib/bolt/project.rb +76 -50
  43. data/lib/bolt/project_manager.rb +2 -0
  44. data/lib/bolt/project_manager/config_migrator.rb +9 -1
  45. data/lib/bolt/project_manager/module_migrator.rb +2 -0
  46. data/lib/bolt/puppetdb/client.rb +8 -0
  47. data/lib/bolt/rerun.rb +1 -1
  48. data/lib/bolt/shell/bash.rb +1 -1
  49. data/lib/bolt/shell/bash/tmpdir.rb +4 -1
  50. data/lib/bolt/shell/powershell.rb +7 -5
  51. data/lib/bolt/target.rb +4 -0
  52. data/lib/bolt/task.rb +1 -1
  53. data/lib/bolt/transport/docker/connection.rb +2 -2
  54. data/lib/bolt/transport/local.rb +13 -0
  55. data/lib/bolt/transport/orch/connection.rb +1 -1
  56. data/lib/bolt/transport/ssh.rb +1 -2
  57. data/lib/bolt/transport/ssh/connection.rb +1 -1
  58. data/lib/bolt/validator.rb +227 -0
  59. data/lib/bolt/version.rb +1 -1
  60. data/lib/bolt_server/config.rb +1 -1
  61. data/lib/bolt_server/schemas/partials/task.json +1 -1
  62. data/lib/bolt_server/transport_app.rb +28 -27
  63. data/libexec/bolt_catalog +1 -1
  64. metadata +27 -11
  65. data/lib/bolt/config/validator.rb +0 -231
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bolt
4
- VERSION = '2.37.0'
4
+ VERSION = '2.44.0'
5
5
  end
@@ -9,7 +9,7 @@ module BoltServer
9
9
  def config_keys
10
10
  super + %w[concurrency cache-dir file-server-conn-timeout
11
11
  file-server-uri projects-dir environments-codedir
12
- environmentpath basemodulepath]
12
+ environmentpath basemodulepath builtin-content-dir]
13
13
  end
14
14
 
15
15
  def env_keys
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "input_method": {
39
39
  "type": "string",
40
- "enum": ["stdin", "environment", "powershell"],
40
+ "enum": ["stdin", "environment", "powershell", "both"],
41
41
  "description": "What input method should be used to pass params to the task"
42
42
  }
43
43
  }
@@ -51,8 +51,8 @@ module BoltServer
51
51
  # See the `orchestrator.bolt.codedir` tk config setting.
52
52
  DEFAULT_BOLT_CODEDIR = '/opt/puppetlabs/server/data/orchestration-services/code'
53
53
 
54
- MISSING_PROJECT_REF_RESPONSE = [
55
- 400, Bolt::ValidationError.new('`project_ref` is a required argument').to_json
54
+ MISSING_VERSIONED_PROJECT_RESPONSE = [
55
+ 400, Bolt::ValidationError.new('`versioned_project` is a required argument').to_json
56
56
  ].freeze
57
57
 
58
58
  def initialize(config)
@@ -268,19 +268,20 @@ module BoltServer
268
268
  end
269
269
  end
270
270
 
271
- def config_from_project(project_ref)
272
- project_dir = File.join(@config['projects-dir'], project_ref)
273
- raise Bolt::ValidationError, "`project_ref`: #{project_dir} does not exist" unless Dir.exist?(project_dir)
271
+ def config_from_project(versioned_project)
272
+ project_dir = File.join(@config['projects-dir'], versioned_project)
273
+ raise Bolt::ValidationError, "`versioned_project`: #{project_dir} does not exist" unless Dir.exist?(project_dir)
274
274
  project = Bolt::Project.create_project(project_dir)
275
275
  Bolt::Config.from_project(project, { log: { 'bolt-debug.log' => 'disable' } })
276
276
  end
277
277
 
278
- def in_bolt_project(project_ref)
278
+ def in_bolt_project(versioned_project)
279
279
  @pal_mutex.synchronize do
280
- bolt_config = config_from_project(project_ref)
280
+ bolt_config = config_from_project(versioned_project)
281
281
  modulepath_object = Bolt::Config::Modulepath.new(
282
282
  bolt_config.modulepath,
283
- boltlib_path: [PE_BOLTLIB_PATH, Bolt::Config::Modulepath::BOLTLIB_PATH]
283
+ boltlib_path: [PE_BOLTLIB_PATH, Bolt::Config::Modulepath::BOLTLIB_PATH],
284
+ builtin_content_path: @config['builtin-content-dir']
284
285
  )
285
286
  pal = Bolt::PAL.new(modulepath_object, nil, nil, nil, nil, nil, bolt_config.project)
286
287
  context = {
@@ -514,10 +515,10 @@ module BoltServer
514
515
 
515
516
  # Fetches the metadata for a single plan
516
517
  #
517
- # @param project_ref [String] the project to fetch the plan from
518
+ # @param versioned_project [String] the project to fetch the plan from
518
519
  get '/project_plans/:module_name/:plan_name' do
519
- return MISSING_PROJECT_REF_RESPONSE if params['project_ref'].nil?
520
- in_bolt_project(params['project_ref']) do |context|
520
+ return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
521
+ in_bolt_project(params['versioned_project']) do |context|
521
522
  plan_info = pe_plan_info(context[:pal], params[:module_name], params[:plan_name])
522
523
  plan_info = allowed_helper(plan_info, context[:config].project.plans)
523
524
  [200, plan_info.to_json]
@@ -541,12 +542,12 @@ module BoltServer
541
542
 
542
543
  # Fetches the metadata for a single task
543
544
  #
544
- # @param bolt_project_ref [String] the reference to the bolt-project directory to load task metadata from
545
+ # @param bolt_versioned_project [String] the reference to the bolt-project directory to load task metadata from
545
546
  get '/project_tasks/:module_name/:task_name' do
546
- return MISSING_PROJECT_REF_RESPONSE if params['project_ref'].nil?
547
- in_bolt_project(params['project_ref']) do |context|
547
+ return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
548
+ in_bolt_project(params['versioned_project']) do |context|
548
549
  ps_parameters = {
549
- 'versioned_project' => params['project_ref']
550
+ 'versioned_project' => params['versioned_project']
550
551
  }
551
552
  task_info = pe_task_info(context[:pal], params[:module_name], params[:task_name], ps_parameters)
552
553
  task_info = allowed_helper(task_info, context[:config].project.tasks)
@@ -582,10 +583,10 @@ module BoltServer
582
583
 
583
584
  # Fetches the list of plans for a project
584
585
  #
585
- # @param project_ref [String] the project to fetch the list of plans from
586
+ # @param versioned_project [String] the project to fetch the list of plans from
586
587
  get '/project_plans' do
587
- return MISSING_PROJECT_REF_RESPONSE if params['project_ref'].nil?
588
- in_bolt_project(params['project_ref']) do |context|
588
+ return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
589
+ in_bolt_project(params['versioned_project']) do |context|
589
590
  plans_response = plan_list(context[:pal])
590
591
 
591
592
  # Dig in context for the allowlist of plans from project object
@@ -618,10 +619,10 @@ module BoltServer
618
619
 
619
620
  # Fetches the list of tasks for a bolt-project
620
621
  #
621
- # @param project_ref [String] the project to fetch the list of tasks from
622
+ # @param versioned_project [String] the project to fetch the list of tasks from
622
623
  get '/project_tasks' do
623
- return MISSING_PROJECT_REF_RESPONSE if params['project_ref'].nil?
624
- in_bolt_project(params['project_ref']) do |context|
624
+ return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
625
+ in_bolt_project(params['versioned_project']) do |context|
625
626
  tasks_response = task_list(context[:pal])
626
627
 
627
628
  # Dig in context for the allowlist of tasks from project object
@@ -639,10 +640,10 @@ module BoltServer
639
640
 
640
641
  # Implements puppetserver's file_metadatas endpoint for projects.
641
642
  #
642
- # @param project_ref [String] the project_ref to fetch the file metadatas from
643
+ # @param versioned_project [String] the versioned_project to fetch the file metadatas from
643
644
  get '/project_file_metadatas/:module_name/*' do
644
- return MISSING_PROJECT_REF_RESPONSE if params['project_ref'].nil?
645
- in_bolt_project(params['project_ref']) do |context|
645
+ return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
646
+ in_bolt_project(params['versioned_project']) do |context|
646
647
  file = params[:splat].first
647
648
  metadatas = file_metadatas(context[:pal], params[:module_name], file)
648
649
  [200, metadatas.to_json]
@@ -655,14 +656,14 @@ module BoltServer
655
656
 
656
657
  # Returns a list of targets parsed from a Project inventory
657
658
  #
658
- # @param project_ref [String] the project_ref to compute the inventory from
659
+ # @param versioned_project [String] the versioned_project to compute the inventory from
659
660
  post '/project_inventory_targets' do
660
- return MISSING_PROJECT_REF_RESPONSE if params['project_ref'].nil?
661
+ return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
661
662
  content_type :json
662
663
  body = JSON.parse(request.body.read)
663
664
  error = validate_schema(@schemas["connect-data"], body)
664
665
  return [400, error_result(error).to_json] unless error.nil?
665
- in_bolt_project(params['project_ref']) do |context|
666
+ in_bolt_project(params['versioned_project']) do |context|
666
667
  if context[:config].inventoryfile &&
667
668
  context[:config].project.inventory_file.to_s !=
668
669
  context[:config].inventoryfile
@@ -56,7 +56,7 @@ when "compile"
56
56
  else
57
57
  e.message
58
58
  end
59
- puts({ message: message }.to_json)
59
+ puts({ message: message, backtrace: e.backtrace }.to_json)
60
60
  exit 1
61
61
  rescue StandardError => e
62
62
  puts({ message: e.message }.to_json)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bolt
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.37.0
4
+ version: 2.44.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-07 00:00:00.000000000 Z
11
+ date: 2021-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: ffi
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "<"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.14.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.14.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: hiera-eyaml
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -170,14 +184,14 @@ dependencies:
170
184
  requirements:
171
185
  - - "~>"
172
186
  - !ruby/object:Gem::Version
173
- version: '0.4'
187
+ version: '0.5'
174
188
  type: :runtime
175
189
  prerelease: false
176
190
  version_requirements: !ruby/object:Gem::Requirement
177
191
  requirements:
178
192
  - - "~>"
179
193
  - !ruby/object:Gem::Version
180
- version: '0.4'
194
+ version: '0.5'
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: puppet
183
197
  requirement: !ruby/object:Gem::Requirement
@@ -198,14 +212,14 @@ dependencies:
198
212
  requirements:
199
213
  - - "~>"
200
214
  - !ruby/object:Gem::Version
201
- version: '0.4'
215
+ version: '0.5'
202
216
  type: :runtime
203
217
  prerelease: false
204
218
  version_requirements: !ruby/object:Gem::Requirement
205
219
  requirements:
206
220
  - - "~>"
207
221
  - !ruby/object:Gem::Version
208
- version: '0.4'
222
+ version: '0.5'
209
223
  - !ruby/object:Gem::Dependency
210
224
  name: puppet-resource_api
211
225
  requirement: !ruby/object:Gem::Requirement
@@ -336,16 +350,16 @@ dependencies:
336
350
  name: puppetlabs_spec_helper
337
351
  requirement: !ruby/object:Gem::Requirement
338
352
  requirements:
339
- - - "~>"
353
+ - - "<="
340
354
  - !ruby/object:Gem::Version
341
- version: '2.7'
355
+ version: 2.15.0
342
356
  type: :development
343
357
  prerelease: false
344
358
  version_requirements: !ruby/object:Gem::Requirement
345
359
  requirements:
346
- - - "~>"
360
+ - - "<="
347
361
  - !ruby/object:Gem::Version
348
- version: '2.7'
362
+ version: 2.15.0
349
363
  - !ruby/object:Gem::Dependency
350
364
  name: rake
351
365
  requirement: !ruby/object:Gem::Requirement
@@ -458,12 +472,12 @@ files:
458
472
  - lib/bolt/config/transport/remote.rb
459
473
  - lib/bolt/config/transport/ssh.rb
460
474
  - lib/bolt/config/transport/winrm.rb
461
- - lib/bolt/config/validator.rb
462
475
  - lib/bolt/error.rb
463
476
  - lib/bolt/executor.rb
464
477
  - lib/bolt/inventory.rb
465
478
  - lib/bolt/inventory/group.rb
466
479
  - lib/bolt/inventory/inventory.rb
480
+ - lib/bolt/inventory/options.rb
467
481
  - lib/bolt/inventory/target.rb
468
482
  - lib/bolt/logger.rb
469
483
  - lib/bolt/module.rb
@@ -509,6 +523,7 @@ files:
509
523
  - lib/bolt/plugin/env_var.rb
510
524
  - lib/bolt/plugin/module.rb
511
525
  - lib/bolt/plugin/prompt.rb
526
+ - lib/bolt/plugin/puppet_connect_data.rb
512
527
  - lib/bolt/plugin/puppetdb.rb
513
528
  - lib/bolt/plugin/task.rb
514
529
  - lib/bolt/project.rb
@@ -551,6 +566,7 @@ files:
551
566
  - lib/bolt/transport/winrm/connection.rb
552
567
  - lib/bolt/util.rb
553
568
  - lib/bolt/util/puppet_log_level.rb
569
+ - lib/bolt/validator.rb
554
570
  - lib/bolt/version.rb
555
571
  - lib/bolt/yarn.rb
556
572
  - lib/bolt_server/acl.rb
@@ -1,231 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bolt/error'
4
-
5
- # This class validates config against a schema, raising an error that includes
6
- # details about any invalid configuration.
7
- #
8
- module Bolt
9
- class Config
10
- class Validator
11
- attr_reader :deprecations, :warnings
12
-
13
- def initialize
14
- @errors = []
15
- @deprecations = []
16
- @warnings = []
17
- @path = []
18
- end
19
-
20
- # This is the entry method for validating data against the schema.
21
- # It loops over each key-value pair in the data hash and validates
22
- # the value against the relevant schema definition.
23
- #
24
- def validate(data, schema, location = nil)
25
- @location = location
26
-
27
- validate_keys(data.keys, schema.keys)
28
-
29
- data.each_pair do |key, value|
30
- next unless schema.key?(key)
31
-
32
- @path.push(key)
33
-
34
- check_deprecated(key, schema[key], location)
35
- validate_value(value, schema[key])
36
- ensure
37
- @path.pop
38
- end
39
-
40
- raise_error
41
- end
42
-
43
- # Adds a warning if the given option is deprecated.
44
- #
45
- def check_deprecated(key, definition, location)
46
- if definition.key?(:_deprecation)
47
- message = "Option '#{path}' "
48
- message += "at #{location} " if location
49
- message += "is deprecated. #{definition[:_deprecation]}"
50
- @deprecations << { option: key, message: message }
51
- end
52
- end
53
-
54
- # Raises a ValidationError if there are any errors. All error messages
55
- # created during validation are concatenated into a single error
56
- # message.
57
- #
58
- private def raise_error
59
- return unless @errors.any?
60
-
61
- message = "Invalid configuration"
62
- message += " at #{@location}" if @location
63
- message += ":\n"
64
- message += @errors.map { |error| "\s\s#{error}" }.join("\n")
65
-
66
- raise Bolt::ValidationError, message
67
- end
68
-
69
- # Validate an individual value. This performs validation that is
70
- # common to all values, including type validation. After validating
71
- # the value's type, the value is passed off to an individual
72
- # validation method for the value's type.
73
- #
74
- private def validate_value(value, definition)
75
- return if plugin_reference?(value, definition)
76
- return unless valid_type?(value, definition)
77
-
78
- case value
79
- when Hash
80
- validate_hash(value, definition)
81
- when Array
82
- validate_array(value, definition)
83
- when String
84
- validate_string(value, definition)
85
- when Numeric
86
- validate_number(value, definition)
87
- end
88
- end
89
-
90
- # Validates a hash value, logging errors for any validations that fail.
91
- # This will enumerate each key-value pair in the hash and validate each
92
- # value individually.
93
- #
94
- private def validate_hash(value, definition)
95
- properties = definition[:properties] ? definition[:properties].keys : []
96
-
97
- if definition[:properties] && definition[:additionalProperties].nil?
98
- validate_keys(value.keys, properties)
99
- end
100
-
101
- if definition[:required] && (definition[:required] - value.keys).any?
102
- missing = definition[:required] - value.keys
103
- @errors << "Value at '#{path}' is missing required keys #{missing.join(', ')}"
104
- end
105
-
106
- value.each_pair do |key, val|
107
- @path.push(key)
108
-
109
- if properties.include?(key)
110
- validate_value(val, definition[:properties][key])
111
- elsif definition[:additionalProperties]
112
- validate_value(val, definition[:additionalProperties])
113
- end
114
- ensure
115
- @path.pop
116
- end
117
- end
118
-
119
- # Validates an array value, logging errors for any validations that fail.
120
- # This will enumerate the items in the array and validate each item
121
- # individually.
122
- #
123
- private def validate_array(value, definition)
124
- if definition[:uniqueItems] && value.size != value.uniq.size
125
- @errors << "Value at '#{path}' must not include duplicate elements"
126
- return
127
- end
128
-
129
- return unless definition.key?(:items)
130
-
131
- value.each_with_index do |item, index|
132
- @path.push(index)
133
- validate_value(item, definition[:items])
134
- ensure
135
- @path.pop
136
- end
137
- end
138
-
139
- # Validates a string value, logging errors for any validations that fail.
140
- #
141
- private def validate_string(value, definition)
142
- if definition.key?(:enum) && !definition[:enum].include?(value)
143
- message = "Value at '#{path}' must be "
144
- message += "one of " if definition[:enum].count > 1
145
- message += definition[:enum].join(', ')
146
- multitype_error(message, value, definition)
147
- end
148
- end
149
-
150
- # Validates a numeric value, logging errors for any validations that fail.
151
- #
152
- private def validate_number(value, definition)
153
- if definition.key?(:minimum) && value < definition[:minimum]
154
- @errors << "Value at '#{path}' must be a minimum of #{definition[:minimum]}"
155
- end
156
- end
157
-
158
- # Adds warnings for unknown config options.
159
- #
160
- private def validate_keys(keys, known_keys)
161
- (keys - known_keys).each do |key|
162
- message = "Unknown option '#{key}'"
163
- message += " at '#{path}'" if @path.any?
164
- message += " at #{@location}" if @location
165
- message += "."
166
- @warnings << message
167
- end
168
- end
169
-
170
- # Returns true if a value is a plugin reference. This also validates whether
171
- # a value can be a plugin reference in the first place. If the value is a
172
- # plugin reference but cannot be one according to the schema, then this will
173
- # log an error.
174
- #
175
- private def plugin_reference?(value, definition)
176
- if value.is_a?(Hash) && value.key?('_plugin')
177
- unless definition[:_plugin]
178
- @errors << "Value at '#{path}' is a plugin reference, which is unsupported at "\
179
- "this location"
180
- end
181
-
182
- true
183
- else
184
- false
185
- end
186
- end
187
-
188
- # Asserts the type for each option against the type specified in the schema
189
- # definition. The schema definition can specify multiple valid types, so the
190
- # value needs to only match one of the types to be valid. Returns early if
191
- # there is no type in the definition (in practice this shouldn't happen, but
192
- # this will safeguard against any dev mistakes).
193
- #
194
- private def valid_type?(value, definition)
195
- return unless definition.key?(:type)
196
-
197
- types = Array(definition[:type])
198
-
199
- if types.include?(value.class)
200
- true
201
- else
202
- if types.include?(TrueClass) || types.include?(FalseClass)
203
- types = types - [TrueClass, FalseClass] + ['Boolean']
204
- end
205
-
206
- @errors << "Value at '#{path}' must be of type #{types.join(' or ')}"
207
-
208
- false
209
- end
210
- end
211
-
212
- # Adds an error that includes additional helpful information for values
213
- # that accept multiple types.
214
- #
215
- private def multitype_error(message, value, definition)
216
- if Array(definition[:type]).count > 1
217
- types = Array(definition[:type]) - [value.class]
218
- message += " or must be of type #{types.join(' or ')}"
219
- end
220
-
221
- @errors << message
222
- end
223
-
224
- # Returns the formatted path for the key.
225
- #
226
- private def path
227
- @path.join('.')
228
- end
229
- end
230
- end
231
- end