chef-dk 0.2.0 → 0.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/chef-dk/authenticated_http.rb +40 -0
  4. data/lib/chef-dk/chef_runner.rb +5 -0
  5. data/lib/chef-dk/command/exec.rb +4 -1
  6. data/lib/chef-dk/command/generate.rb +11 -0
  7. data/lib/chef-dk/command/generator_commands.rb +20 -365
  8. data/lib/chef-dk/command/generator_commands/app.rb +99 -0
  9. data/lib/chef-dk/command/generator_commands/attribute.rb +37 -0
  10. data/lib/chef-dk/command/generator_commands/base.rb +76 -0
  11. data/lib/chef-dk/command/generator_commands/cookbook.rb +100 -0
  12. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +99 -0
  13. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -0
  14. data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -0
  15. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -0
  16. data/lib/chef-dk/command/generator_commands/repo.rb +96 -0
  17. data/lib/chef-dk/command/generator_commands/template.rb +45 -0
  18. data/lib/chef-dk/command/verify.rb +28 -0
  19. data/lib/chef-dk/component_test.rb +16 -3
  20. data/lib/chef-dk/cookbook_omnifetch.rb +2 -0
  21. data/lib/chef-dk/cookbook_profiler/identifiers.rb +3 -15
  22. data/lib/chef-dk/exceptions.rb +15 -0
  23. data/lib/chef-dk/generator.rb +102 -25
  24. data/lib/chef-dk/policyfile/community_cookbook_source.rb +0 -7
  25. data/lib/chef-dk/policyfile/{cookbook_spec.rb → cookbook_location_specification.rb} +35 -6
  26. data/lib/chef-dk/policyfile/cookbook_locks.rb +305 -0
  27. data/lib/chef-dk/policyfile/dsl.rb +26 -12
  28. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +70 -0
  29. data/lib/chef-dk/policyfile/solution_dependencies.rb +204 -0
  30. data/lib/chef-dk/policyfile/storage_config.rb +77 -0
  31. data/lib/chef-dk/policyfile/uploader.rb +110 -0
  32. data/lib/chef-dk/policyfile_compiler.rb +59 -29
  33. data/lib/chef-dk/policyfile_lock.rb +104 -160
  34. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +1 -1
  35. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +0 -1
  36. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +66 -0
  37. data/lib/chef-dk/skeletons/code_generator/files/default/repo/Rakefile +65 -0
  38. data/lib/chef-dk/skeletons/code_generator/files/default/repo/certificates/README.md +19 -0
  39. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/README-policy.md +9 -0
  40. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/README.md +54 -0
  41. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +63 -0
  42. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +5 -0
  43. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +16 -0
  44. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +7 -1
  45. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +62 -0
  46. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -0
  47. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apache2.erb +201 -0
  48. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -0
  49. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -0
  50. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -0
  51. data/lib/chef-dk/skeletons/code_generator/templates/default/default_recipe.rb.erb +1 -4
  52. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +3 -3
  53. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/config/rake.rb.erb +38 -0
  54. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +11 -0
  55. data/lib/chef-dk/version.rb +1 -1
  56. data/spec/shared/a_file_generator.rb +121 -0
  57. data/spec/shared/a_generated_file.rb +12 -0
  58. data/spec/shared/fixture_cookbook_checksums.rb +47 -0
  59. data/spec/spec_helper.rb +4 -2
  60. data/spec/unit/chef_runner_spec.rb +12 -5
  61. data/spec/unit/cli_spec.rb +4 -4
  62. data/spec/unit/command/base_spec.rb +1 -1
  63. data/spec/unit/command/exec_spec.rb +37 -27
  64. data/spec/unit/command/generate_spec.rb +3 -3
  65. data/spec/unit/command/generator_commands/app_spec.rb +131 -0
  66. data/spec/unit/command/generator_commands/attribute_spec.rb +32 -0
  67. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -0
  68. data/spec/unit/command/generator_commands/cookbook_spec.rb +205 -0
  69. data/spec/unit/command/generator_commands/lwrp_spec.rb +32 -0
  70. data/spec/unit/command/generator_commands/recipe_spec.rb +32 -0
  71. data/spec/unit/command/generator_commands/repo_spec.rb +287 -0
  72. data/spec/unit/command/generator_commands/template_spec.rb +32 -0
  73. data/spec/unit/command/shell_init_spec.rb +4 -4
  74. data/spec/unit/command/verify_spec.rb +9 -9
  75. data/spec/unit/commands_map_spec.rb +1 -1
  76. data/spec/unit/component_test_spec.rb +3 -3
  77. data/spec/unit/cookbook_profiler/git_spec.rb +7 -7
  78. data/spec/unit/cookbook_profiler/identifiers_spec.rb +12 -8
  79. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +1 -1
  80. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +1 -1
  81. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +1 -1
  82. data/spec/unit/fixtures/example_cookbook/Berksfile +1 -1
  83. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -0
  84. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -0
  85. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -0
  86. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -0
  87. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +1 -1
  88. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
  89. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
  90. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
  91. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
  92. data/spec/unit/generator_spec.rb +120 -0
  93. data/spec/unit/policyfile/{cookbook_spec_spec.rb → cookbook_location_specification_spec.rb} +83 -38
  94. data/spec/unit/policyfile/cookbook_locks_spec.rb +354 -0
  95. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +85 -0
  96. data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -0
  97. data/spec/unit/policyfile/storage_config_spec.rb +98 -0
  98. data/spec/unit/policyfile/uploader_spec.rb +292 -0
  99. data/spec/unit/policyfile_demands_spec.rb +177 -24
  100. data/spec/unit/policyfile_evaluation_spec.rb +40 -12
  101. data/spec/unit/{policyfile_builder_spec.rb → policyfile_lock_build_spec.rb} +179 -64
  102. data/spec/unit/policyfile_lock_install_spec.rb +138 -0
  103. data/spec/unit/policyfile_lock_validation_spec.rb +610 -0
  104. metadata +103 -59
  105. data/spec/unit/command/generator_commands_spec.rb +0 -504
@@ -18,13 +18,6 @@
18
18
  require 'json'
19
19
  require 'chef-dk/cookbook_omnifetch'
20
20
  require 'chef-dk/exceptions'
21
- # TODO: chef bug. Chef::HTTP::Simple needs to require this itself.
22
- # Fixed in 2ed829e661f9a357fc9a8cdf316c84f077dad7f9 waiting for that to be
23
- # released...
24
- require 'tempfile'
25
- require 'chef/platform/query_helpers' # should be handled by http/simple
26
- require 'chef/http/cookie_manager' # should be handled by http/simple
27
- require 'chef/http/validate_content_length' # should be handled by http/simple
28
21
  require 'chef/http/simple'
29
22
 
30
23
  # TODO: fix hardcoding
@@ -16,26 +16,41 @@
16
16
  #
17
17
 
18
18
  require 'semverse'
19
- require 'cookbook-omnifetch'
19
+ require 'chef-dk/cookbook_omnifetch'
20
+ require 'chef-dk/policyfile/storage_config'
20
21
 
21
22
  module ChefDK
22
23
  module Policyfile
23
24
 
24
- class CookbookSpec
25
+ class CookbookLocationSpecification
26
+
27
+ #--
28
+ # Provides #relative_paths_root, which is required by CookbookOmnifetch
29
+ # API contract
30
+ include StorageConfigDelegation
25
31
 
26
32
  SOURCE_TYPES = [:git, :github, :path, :artifactserver]
27
33
 
34
+ #--
35
+ # Required by CookbookOmnifetch API contract
28
36
  attr_reader :version_constraint
37
+
38
+ #--
39
+ # Required by CookbookOmnifetch API contract
29
40
  attr_reader :name
41
+
42
+ #--
43
+ # Required by CookbookOmnifetch API contract
30
44
  attr_reader :source_options
31
45
  attr_reader :source_type
46
+ attr_reader :storage_config
32
47
 
33
- def initialize(name, version_constraint, source_options, policyfile_filename)
48
+ def initialize(name, version_constraint, source_options, storage_config)
34
49
  @name = name
35
50
  @version_constraint = Semverse::Constraint.new(version_constraint)
36
51
  @source_options = source_options
37
- @policyfile_filename = policyfile_filename
38
52
  @source_type = SOURCE_TYPES.find { |type| source_options.key?(type) }
53
+ @storage_config = storage_config
39
54
  end
40
55
 
41
56
  def ==(other)
@@ -55,7 +70,20 @@ module ChefDK
55
70
  end
56
71
  end
57
72
 
73
+ def valid?
74
+ errors.empty?
75
+ end
76
+
77
+ def errors
78
+ error_messages = []
79
+ if installer.nil?
80
+ error_messages << "Cookbook `#{name}' has invalid source options `#{source_options.inspect}'"
81
+ end
82
+ error_messages
83
+ end
84
+
58
85
  def installer
86
+ # TODO: handle 'bad' return values here (invalid source_options, etc.)
59
87
  @installer ||= CookbookOmnifetch.init(self, source_options)
60
88
  end
61
89
 
@@ -84,11 +112,12 @@ module ChefDK
84
112
  end
85
113
 
86
114
  def cached_cookbook
115
+ # TODO: handle 'bad' return values here (cookbook not installed yet)
87
116
  installer.cached_cookbook
88
117
  end
89
118
 
90
- def relative_paths_root
91
- File.dirname(@policyfile_filename)
119
+ def source_options_for_lock
120
+ installer.lock_data
92
121
  end
93
122
 
94
123
  end
@@ -0,0 +1,305 @@
1
+
2
+ require 'chef-dk/exceptions'
3
+
4
+ require 'chef-dk/cookbook_profiler/null_scm'
5
+ require 'chef-dk/cookbook_profiler/git'
6
+
7
+ require 'chef-dk/cookbook_profiler/identifiers'
8
+ require 'chef-dk/policyfile/storage_config'
9
+
10
+ require 'chef-dk/policyfile/cookbook_location_specification'
11
+
12
+ module ChefDK
13
+
14
+ module Policyfile
15
+
16
+ # Base class for CookbookLock implementations
17
+ class CookbookLock
18
+
19
+ include Policyfile::StorageConfigDelegation
20
+
21
+ # The cookbook name (without any version or other info suffixed)
22
+ attr_reader :name
23
+
24
+ # Options specifying the source and revision of this cookbook. These can
25
+ # be passed to a CookbookLocationSpecification to create an object that can install the
26
+ # same revision of the cookbook on another machine.
27
+ attr_accessor :source_options
28
+
29
+ # A string that uniquely identifies the cookbook version. If not
30
+ # explicitly set, an identifier is generated based on the cookbook's
31
+ # content.
32
+ attr_accessor :identifier
33
+
34
+ # A string in "X.Y.Z" version number format that uniquely identifies the
35
+ # cookbook version. This is for compatibility with Chef Server 11.x,
36
+ # where cookbooks are stored by x.y.z version numbers.
37
+ attr_accessor :dotted_decimal_identifier
38
+
39
+ attr_reader :storage_config
40
+
41
+ attr_accessor :version
42
+
43
+ def initialize(name, storage_config)
44
+ @name = name
45
+ @version = nil
46
+ @source_options = nil
47
+ @identifier = nil
48
+ @dotted_decimal_identifier = nil
49
+ @storage_config = storage_config
50
+ end
51
+
52
+ def install_locked
53
+ cookbook_location_spec.ensure_cached
54
+ end
55
+
56
+ def cookbook_location_spec
57
+ raise InvalidCookbookLockData, "Cannot create CookbookLocationSpecification for #{name} without version" if version.nil?
58
+ raise InvalidCookbookLockData, "Cannot create CookbookLocationSpecification for #{name} without source options" if source_options.nil?
59
+ @location_spec ||= CookbookLocationSpecification.new(name, "= #{version}", source_options, storage_config)
60
+ end
61
+
62
+ def dependencies
63
+ cookbook_location_spec.dependencies
64
+ end
65
+
66
+ def gather_profile_data
67
+ @identifier ||= identifiers.content_identifier
68
+ @dotted_decimal_identifier ||= identifiers.dotted_decimal_identifier
69
+ @version ||= identifiers.semver_version
70
+ end
71
+
72
+ def identifiers
73
+ @identifiers ||= CookbookProfiler::Identifiers.new(cookbook_version)
74
+ end
75
+
76
+ def cookbook_path
77
+ raise NotImplementedError, "#{self.class} must override #to_lock with a specific implementation"
78
+ end
79
+
80
+ def to_lock
81
+ raise NotImplementedError, "#{self.class} must override #to_lock with a specific implementation"
82
+ end
83
+
84
+ def build_from_lock_data(lock_data)
85
+ raise NotImplementedError, "#{self.class} must override #build_from_lock_data with a specific implementation"
86
+ end
87
+
88
+ def validate!
89
+ raise NotImplementedError, "#{self.class} must override #validate! with a specific implementation"
90
+ end
91
+
92
+ def refresh!
93
+ raise NotImplementedError, "#{self.class} must override #refresh! with a specific implementation"
94
+ end
95
+
96
+ def updated?
97
+ false
98
+ end
99
+
100
+ def identifier_updated?
101
+ false
102
+ end
103
+
104
+ def version_updated?
105
+ false
106
+ end
107
+
108
+ def symbolize_source_options_keys(source_options_from_json)
109
+ source_options_from_json ||= {}
110
+ source_options_from_json.inject({}) do |normalized_source_opts, (key, value)|
111
+ normalized_source_opts[key.to_sym] = value
112
+ normalized_source_opts
113
+ end
114
+ end
115
+
116
+ def cookbook_version
117
+ @cookbook_version ||= cookbook_loader.cookbook_version
118
+ end
119
+
120
+ def cookbook_loader
121
+ @cookbook_loader ||=
122
+ begin
123
+ loader = Chef::Cookbook::CookbookVersionLoader.new(cookbook_path, chefignore)
124
+ loader.load!
125
+ loader
126
+ end
127
+ end
128
+
129
+ def chefignore
130
+ @chefignore ||= Chef::Cookbook::Chefignore.new(File.join(cookbook_path, "chefignore"))
131
+ end
132
+ end
133
+
134
+ # CachedCookbook objects represent a cookbook that has been fetched from an
135
+ # upstream canonical source and stored (presumed unmodified).
136
+ class CachedCookbook < CookbookLock
137
+
138
+ # The directory name in the cookbook cache where the cookbook is stored.
139
+ # By convention, this should be the name of the cookbook followed by a
140
+ # hyphen and then some sort of version identifier (depending on the
141
+ # cookbook source).
142
+ attr_accessor :cache_key
143
+
144
+ # A URI pointing to the canonical source of the cookbook.
145
+ attr_accessor :origin
146
+
147
+ def initialize(name, storage_config)
148
+ @name = name
149
+ @version = nil
150
+ @origin = nil
151
+ @source_options = nil
152
+ @cache_key = nil
153
+ @identifier = nil
154
+ @dotted_decimal_identifier = nil
155
+ @storage_config = storage_config
156
+ end
157
+
158
+ def cookbook_path
159
+ if cache_key.nil?
160
+ raise MissingCookbookLockData, "Cannot locate cached cookbook `#{name}' because the `cache_key' attribute is not set"
161
+ end
162
+ File.join(cache_path, cache_key)
163
+ end
164
+
165
+ def build_from_lock_data(lock_data)
166
+ @version = lock_data["version"]
167
+ @identifier = lock_data["identifier"]
168
+ @dotted_decimal_identifier = lock_data["dotted_decimal_identifier"]
169
+ @cache_key = lock_data["cache_key"]
170
+ @origin = lock_data["origin"]
171
+ @source_options = symbolize_source_options_keys(lock_data["source_options"])
172
+ end
173
+
174
+ def to_lock
175
+ validate!
176
+ {
177
+ "version" => version,
178
+ "identifier" => identifier,
179
+ "dotted_decimal_identifier" => dotted_decimal_identifier,
180
+ "cache_key" => cache_key,
181
+ "origin" => origin,
182
+ "source_options" => source_options
183
+ }
184
+ end
185
+
186
+ def validate!
187
+ if cache_key.nil?
188
+ raise CachedCookbookNotFound, "Cookbook `#{name}' does not have a `cache_key` set, cannot locate cookbook"
189
+ end
190
+ unless File.exist?(cookbook_path)
191
+ raise CachedCookbookNotFound, "Cookbook `#{name}' not found at expected cache location `#{cache_key}' (full path: `#{cookbook_path}')"
192
+ end
193
+ end
194
+
195
+ # We do not expect the cookbook to get mutated out-of-band, so refreshing
196
+ # the data generally should have no affect. If the cookbook has been
197
+ # mutated, though, then a CachedCookbookModified exception is raised.
198
+ def refresh!
199
+ # This behavior fits better with the intent of the #validate! method,
200
+ # but we cannot check for modifications there because the user may be
201
+ # setting custom identifiers.
202
+ if @identifier and identifiers.content_identifier != @identifier
203
+ message = "Cached cookbook `#{name}' (#{version}) has been modified since the lockfile was generated. " +
204
+ "Cached cookbooks cannot be modified. (full path: `#{cookbook_path}')"
205
+ raise CachedCookbookModified, message
206
+ end
207
+ end
208
+
209
+ end
210
+
211
+ # LocalCookbook objects represent cookbooks that are sourced from the local
212
+ # filesystem and are assumed to be under active development.
213
+ class LocalCookbook < CookbookLock
214
+
215
+ # A relative or absolute path to the cookbook. If a relative path is
216
+ # given, it is resolved relative to #relative_paths_root
217
+ attr_accessor :source
218
+
219
+ def initialize(name, storage_config)
220
+ @name = name
221
+ @identifier = nil
222
+ @storage_config = storage_config
223
+
224
+ @identifier_updated = false
225
+ @version_updated = false
226
+ end
227
+
228
+ def cookbook_path
229
+ File.expand_path(source, relative_paths_root)
230
+ end
231
+
232
+ def scm_profiler
233
+ if File.exist?(File.join(cookbook_path, ".git"))
234
+ CookbookProfiler::Git.new(cookbook_path)
235
+ else
236
+ CookbookProfiler::NullSCM.new(cookbook_path)
237
+ end
238
+ end
239
+
240
+ def scm_info
241
+ scm_profiler.profile_data
242
+ end
243
+
244
+ def to_lock
245
+ validate!
246
+ {
247
+ "version" => version,
248
+ "identifier" => identifier,
249
+ "dotted_decimal_identifier" => dotted_decimal_identifier,
250
+ "source" => source,
251
+ "cache_key" => nil,
252
+ "scm_info" => scm_info,
253
+ "source_options" => source_options
254
+ }
255
+ end
256
+
257
+ def build_from_lock_data(lock_data)
258
+ @version = lock_data["version"]
259
+ @identifier = lock_data["identifier"]
260
+ @dotted_decimal_identifier = lock_data["dotted_decimal_identifier"]
261
+ @source = lock_data["source"]
262
+ @source_options = symbolize_source_options_keys(lock_data["source_options"])
263
+ end
264
+
265
+ def validate!
266
+ if source.nil?
267
+ raise LocalCookbookNotFound, "Cookbook `#{name}' does not have a `source` set, cannot locate cookbook"
268
+ end
269
+ unless File.exist?(cookbook_path)
270
+ raise LocalCookbookNotFound, "Cookbook `#{name}' not found at path source `#{source}` (full path: `#{cookbook_path}')"
271
+ end
272
+ unless cookbook_version.name.to_s == name
273
+ msg = "The cookbook at path source `#{source}' is expected to be named `#{name}', but is now named `#{cookbook_version.name}' (full path: #{cookbook_path})"
274
+ raise MalformedCookbook, msg
275
+ end
276
+ end
277
+
278
+ def refresh!
279
+ old_identifier, old_version = @identifier, @version
280
+ @identifier, @dotted_decimal_identifier, @version = nil, nil, nil
281
+ gather_profile_data
282
+ if @identifier != old_identifier
283
+ @identifier_updated = true
284
+ end
285
+ if @version != old_version
286
+ @version_updated = true
287
+ end
288
+ self
289
+ end
290
+
291
+ def updated?
292
+ @identifier_updated || @version_updated
293
+ end
294
+
295
+ def version_updated?
296
+ @version_updated
297
+ end
298
+
299
+ def identifier_updated?
300
+ @identifier_updated
301
+ end
302
+
303
+ end
304
+ end
305
+ end
@@ -16,25 +16,38 @@
16
16
  #
17
17
 
18
18
  require 'chef-dk/policyfile/cookbook_sources'
19
- require 'chef-dk/policyfile/cookbook_spec'
19
+ require 'chef-dk/policyfile/cookbook_location_specification'
20
+ require 'chef-dk/policyfile/storage_config'
20
21
 
21
22
  module ChefDK
22
23
  module Policyfile
23
24
  class DSL
24
25
 
26
+ include StorageConfigDelegation
27
+
28
+ attr_writer :name
29
+
25
30
  attr_reader :errors
26
31
  attr_reader :run_list
27
32
  attr_reader :default_source
28
- attr_reader :policyfile_cookbook_specs
33
+ attr_reader :cookbook_location_specs
29
34
 
30
- attr_accessor :policyfile_filename
35
+ attr_reader :storage_config
31
36
 
32
- def initialize
37
+ def initialize(storage_config)
38
+ @name = nil
33
39
  @errors = []
34
40
  @run_list = []
35
41
  @default_source = NullCookbookSource.new
36
- @policyfile_cookbook_specs = {}
37
- @policyfile_filename = nil
42
+ @cookbook_location_specs = {}
43
+ @storage_config = storage_config
44
+ end
45
+
46
+ def name(name = nil)
47
+ unless name.nil?
48
+ @name = name
49
+ end
50
+ @name
38
51
  end
39
52
 
40
53
  def run_list(*run_list_items)
@@ -64,20 +77,21 @@ module ChefDK
64
77
  end
65
78
 
66
79
  constraint = version_and_source_opts.first || ">= 0.0.0"
67
- spec = CookbookSpec.new(name, constraint, source_options, policyfile_filename)
80
+ spec = CookbookLocationSpecification.new(name, constraint, source_options, storage_config)
68
81
 
69
82
 
70
- if existing_source = @policyfile_cookbook_specs[name]
83
+ if existing_source = @cookbook_location_specs[name]
71
84
  err = "Cookbook '#{name}' assigned to conflicting sources\n\n"
72
85
  err << "Previous source: #{existing_source.source_options.inspect}\n"
73
86
  err << "Conflicts with: #{source_options.inspect}\n"
74
87
  @errors << err
75
88
  else
76
- @policyfile_cookbook_specs[name] = spec
89
+ @cookbook_location_specs[name] = spec
90
+ @errors += spec.errors
77
91
  end
78
92
  end
79
93
 
80
- def eval_policyfile(policyfile_string, policyfile_filename)
94
+ def eval_policyfile(policyfile_string)
81
95
  @policyfile_filename = policyfile_filename
82
96
  instance_eval(policyfile_string, policyfile_filename)
83
97
  validate!
@@ -95,8 +109,8 @@ module ChefDK
95
109
  error_message << " #{error_context(policyfile_string, policyfile_filename, e)}\n\n"
96
110
  unless trace.empty?
97
111
  error_message << " Backtrace:\n"
98
- error_message << filtered_bt(policyfile_filename, e).inject("") { |formatted_trace, line| formatted_trace << " #{line}" }
99
- error_message << "\n"
112
+ # TODO: need a way to disable filtering
113
+ error_message << filtered_bt(policyfile_filename, e).inject("") { |formatted_trace, line| formatted_trace << " #{line}\n" }
100
114
  end
101
115
  @errors << error_message
102
116
  end