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
@@ -20,6 +20,8 @@ require 'chef-dk/policyfile_compiler'
20
20
 
21
21
  describe ChefDK::PolicyfileCompiler do
22
22
 
23
+ let(:storage_config) { ChefDK::Policyfile::StorageConfig.new.use_policyfile("TestPolicyfile.rb") }
24
+
23
25
  let(:policyfile) { ChefDK::PolicyfileCompiler.evaluate(policyfile_rb, "TestPolicyfile.rb") }
24
26
 
25
27
  describe "Evaluate a policyfile" do
@@ -60,7 +62,7 @@ TestPolicyfile.rb:1: syntax error, unexpected end-of-input, expecting tCONSTANT
60
62
  {{{{::::{{::
61
63
  ^
62
64
  E
63
- expect(policyfile).to have(1).errors
65
+ expect(policyfile.errors.size).to eq(1)
64
66
  expect(policyfile.errors.first).to eq(expected_error.chomp)
65
67
  end
66
68
 
@@ -71,7 +73,7 @@ E
71
73
  let(:policyfile_rb) { "raise 'oops'" }
72
74
 
73
75
  it "has an error message with code context" do
74
- expect(policyfile).to have(1).errors
76
+ expect(policyfile.errors.size).to eq(1)
75
77
  expected_message = <<-E
76
78
  Evaluation of policyfile 'TestPolicyfile.rb' raised an exception
77
79
  Exception: RuntimeError "oops"
@@ -105,7 +107,7 @@ E
105
107
  end
106
108
 
107
109
  it "has an invalid source error" do
108
- expect(policyfile).to have(1).errors
110
+ expect(policyfile.errors.size).to eq(1)
109
111
  expect(policyfile.errors.first).to eq("Invalid default_source type ':herp'")
110
112
  end
111
113
  end
@@ -119,17 +121,35 @@ E
119
121
  end
120
122
 
121
123
  it "has an invalid source error" do
122
- expect(policyfile).to have(1).errors
124
+ expect(policyfile.errors.size).to eq(1)
123
125
  expect(policyfile.errors.first).to eq("You must specify the server's URI when using a default_source :chef_server")
124
126
  end
125
127
 
126
128
  end
129
+
130
+ context "when a per-cookbook source is specified with invalid options" do
131
+ let(:policyfile_rb) do
132
+ <<-EOH
133
+ run_list "foo"
134
+
135
+ cookbook "foo", herp: "derp"
136
+ EOH
137
+ end
138
+
139
+ it "has an invalid source error" do
140
+ expect(policyfile.errors.size).to eq(1)
141
+ message = "Cookbook `foo' has invalid source options `{:herp=>\"derp\"}'"
142
+ expect(policyfile.errors.first).to eq(message)
143
+ end
144
+ end
127
145
  end
128
146
 
129
147
  context "Given a minimal valid policyfile" do
130
148
 
131
149
  let(:policyfile_rb) do
132
150
  <<-EOH
151
+ name "hello"
152
+
133
153
  run_list "foo", "bar"
134
154
  EOH
135
155
  end
@@ -138,6 +158,10 @@ E
138
158
  expect(policyfile.errors).to eq([])
139
159
  end
140
160
 
161
+ it "has a name" do
162
+ expect(policyfile.name).to eq("hello")
163
+ end
164
+
141
165
  it "has a run_list" do
142
166
  expect(policyfile.run_list).to eq(%w[foo bar])
143
167
  end
@@ -194,6 +218,8 @@ E
194
218
  end
195
219
 
196
220
  it "has a default source" do
221
+ skip "Chef server isn't yet supported in cookbook-omnifetch (pending /universe endpoint in Chef Server)"
222
+
197
223
  expect(policyfile.errors).to eq([])
198
224
  expected = ChefDK::Policyfile::ChefServerCookbookSource.new("https://mychef.example.com")
199
225
  expect(policyfile.default_source).to eq(expected)
@@ -219,8 +245,8 @@ E
219
245
  end
220
246
 
221
247
  it "sets the source of the cookbook to the local path" do
222
- expected_cb_spec = ChefDK::Policyfile::CookbookSpec.new("foo", ">= 0.0.0", {path: "local_cookbooks/foo"}, "TestPolicyfile.rb")
223
- expect(policyfile.policyfile_cookbook_specs).to eq("foo" => expected_cb_spec)
248
+ expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("foo", ">= 0.0.0", {path: "local_cookbooks/foo"}, storage_config)
249
+ expect(policyfile.cookbook_location_specs).to eq("foo" => expected_cb_spec)
224
250
  end
225
251
 
226
252
  end
@@ -234,8 +260,8 @@ E
234
260
  end
235
261
 
236
262
  it "sets the source of the cookbook to the git URL" do
237
- expected_cb_spec = ChefDK::Policyfile::CookbookSpec.new("foo", ">= 0.0.0", {git: "git://example.com:me/foo-cookbook.git"}, "TestPolicyfile.rb")
238
- expect(policyfile.policyfile_cookbook_specs).to eq("foo" => expected_cb_spec)
263
+ expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("foo", ">= 0.0.0", {git: "git://example.com:me/foo-cookbook.git"}, storage_config)
264
+ expect(policyfile.cookbook_location_specs).to eq("foo" => expected_cb_spec)
239
265
  end
240
266
 
241
267
  end
@@ -248,9 +274,11 @@ E
248
274
  EOH
249
275
  end
250
276
 
251
- it "sets the source of the cookbook to the git URL" do
252
- expected_cb_spec = ChefDK::Policyfile::CookbookSpec.new("foo", ">= 0.0.0", {chef_server: "https://mychefserver.example.com"}, "TestPolicyfile.rb")
253
- expect(policyfile.policyfile_cookbook_specs).to eq("foo" => expected_cb_spec)
277
+ # Chef server isn't yet supported in cookbook-omnifetch (pending /universe endpoint in Chef Server)
278
+ # We have to skip at the example definition level or else we fail in the before block
279
+ skip "sets the source of the cookbook to the git URL" do
280
+ expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("foo", ">= 0.0.0", {chef_server: "https://mychefserver.example.com"}, storage_config)
281
+ expect(policyfile.cookbook_location_specs).to eq("foo" => expected_cb_spec)
254
282
  end
255
283
 
256
284
  end
@@ -273,7 +301,7 @@ Cookbook 'foo' assigned to conflicting sources
273
301
  Previous source: {:path=>"local_cookbooks/foo"}
274
302
  Conflicts with: {:chef_server=>"https://mychefserver.example.com"}
275
303
  EOH
276
- expect(policyfile).to have(1).errors
304
+ expect(policyfile.errors.size).to eq(1)
277
305
  expect(policyfile.errors.first).to eq(expected)
278
306
  end
279
307
 
@@ -17,17 +17,13 @@
17
17
 
18
18
  require 'spec_helper'
19
19
  require 'shared/setup_git_cookbooks'
20
+ require 'shared/fixture_cookbook_checksums'
21
+ require 'chef-dk/policyfile/storage_config'
20
22
  require 'chef-dk/policyfile_lock.rb'
21
23
 
22
- describe ChefDK::PolicyfileLock do
24
+ describe ChefDK::PolicyfileLock, "building a lockfile" do
23
25
 
24
- def id_to_dotted(sha1_id)
25
- major = sha1_id[0...14]
26
- minor = sha1_id[14...28]
27
- patch = sha1_id[28..40]
28
- decimal_integers =[major, minor, patch].map {|hex| hex.to_i(16) }
29
- decimal_integers.join(".")
30
- end
26
+ include_context "fixture cookbooks checksums"
31
27
 
32
28
  # For debugging giant nested hashes...
33
29
  def expect_hash_equal(actual, expected)
@@ -50,35 +46,73 @@ describe ChefDK::PolicyfileLock do
50
46
  File.expand_path("spec/unit/fixtures/", project_root)
51
47
  end
52
48
 
53
- let(:policyfile_lock_options) do
54
- { cache_path: cache_path, relative_paths_root: relative_paths_root }
49
+ let(:storage_config) do
50
+ ChefDK::Policyfile::StorageConfig.new( cache_path: cache_path, relative_paths_root: relative_paths_root )
55
51
  end
56
52
 
57
- describe "when first created" do
53
+ context "when a cached cookbook omits the cache key" do
58
54
 
59
55
  let(:policyfile_lock) do
60
- described_class.new(policyfile_lock_options)
56
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
57
+
58
+ p.name = "invalid_cache_key_policyfile"
59
+
60
+ p.run_list = [ "recipe[foo]" ]
61
+
62
+ p.cached_cookbook("nosuchthing") do |cb|
63
+ end
64
+ end
61
65
  end
62
66
 
63
- it "uses CWD for relative_paths_root if none is given" do
64
- policyfile_lock = described_class.new
65
- expect(policyfile_lock.relative_paths_root).to eq(Dir.pwd)
67
+ it "raises a descriptive error" do
68
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::CachedCookbookNotFound)
66
69
  end
67
70
 
68
- it "uses the provided option for relative_paths_root" do
69
- expect(policyfile_lock.relative_paths_root).to eq(relative_paths_root)
71
+ end
72
+
73
+ context "when a local cookbook omits the path" do
74
+
75
+ let(:policyfile_lock) do
76
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
77
+
78
+ p.name = "invalid_local_cookbook"
79
+
80
+ p.run_list = [ "recipe[foo]" ]
81
+
82
+ p.local_cookbook("nosuchthing") do |cb|
83
+ end
84
+ end
70
85
  end
71
86
 
72
- it "uses the provided cache_path" do
73
- expect(policyfile_lock.cache_path).to eq(cache_path)
87
+ it "raises a descriptive error" do
88
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::LocalCookbookNotFound)
89
+ end
90
+ end
91
+
92
+ context "when a local cookbook has an incorrect path" do
93
+
94
+ let(:policyfile_lock) do
95
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
96
+
97
+ p.name = "invalid_local_cookbook"
98
+
99
+ p.run_list = [ "recipe[foo]" ]
100
+
101
+ p.local_cookbook("nosuchthing") do |cb|
102
+ cb.source = "nopenopenope"
103
+ end
104
+ end
74
105
  end
75
106
 
107
+ it "raises a descriptive error" do
108
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::LocalCookbookNotFound)
109
+ end
76
110
  end
77
111
 
78
112
  context "when a cookbook is not in the cache" do
79
113
 
80
114
  let(:policyfile_lock) do
81
- ChefDK::PolicyfileLock.build(policyfile_lock_options) do |p|
115
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
82
116
 
83
117
  p.name = "invalid_cache_key_policyfile"
84
118
 
@@ -99,7 +133,7 @@ describe ChefDK::PolicyfileLock do
99
133
  context "with a minimal policyfile" do
100
134
 
101
135
  let(:policyfile_lock) do
102
- ChefDK::PolicyfileLock.build(policyfile_lock_options) do |p|
136
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
103
137
 
104
138
  p.name = "minimal_policyfile"
105
139
 
@@ -122,12 +156,14 @@ describe ChefDK::PolicyfileLock do
122
156
 
123
157
  "foo" => {
124
158
  "version" => "1.0.0",
125
- "identifier" => "e4611e9b5ec0636a18979e7dd22537222a2eab47",
126
- "dotted_decimal_identifier" => id_to_dotted("e4611e9b5ec0636a18979e7dd22537222a2eab47"),
159
+ "identifier" => cookbook_foo_cksum,
160
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
127
161
  "cache_key" => "foo-1.0.0",
128
- "origin" => nil
162
+ "origin" => nil,
163
+ "source_options" => nil
129
164
  },
130
- }
165
+ },
166
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
131
167
  }
132
168
  end
133
169
 
@@ -151,7 +187,7 @@ describe ChefDK::PolicyfileLock do
151
187
  end
152
188
 
153
189
  let(:policyfile_lock) do
154
- ChefDK::PolicyfileLock.build(policyfile_lock_options) do |p|
190
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
155
191
 
156
192
  p.name = "dev_cookbook"
157
193
 
@@ -174,8 +210,8 @@ describe ChefDK::PolicyfileLock do
174
210
 
175
211
  "bar" => {
176
212
  "version" => "0.1.0",
177
- "identifier" => "f7694dbebe4109dfc857af7e2e4475c322c65259",
178
- "dotted_decimal_identifier" => id_to_dotted("f7694dbebe4109dfc857af7e2e4475c322c65259"),
213
+ "identifier" => cookbook_bar_cksum,
214
+ "dotted_decimal_identifier" => cookbook_bar_cksum_dotted,
179
215
 
180
216
  "source" => "bar",
181
217
  "cache_key" => nil,
@@ -187,8 +223,10 @@ describe ChefDK::PolicyfileLock do
187
223
  "published" => true,
188
224
  "synchronized_remote_branches"=>["origin/master"]
189
225
  },
226
+ "source_options" => nil
190
227
  },
191
- }
228
+ },
229
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
192
230
  }
193
231
  end
194
232
 
@@ -207,7 +245,7 @@ describe ChefDK::PolicyfileLock do
207
245
  end
208
246
 
209
247
  let(:policyfile_lock) do
210
- ChefDK::PolicyfileLock.build(policyfile_lock_options) do |p|
248
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
211
249
 
212
250
  p.name = "custom_identifier"
213
251
 
@@ -245,7 +283,8 @@ describe ChefDK::PolicyfileLock do
245
283
  "identifier" => "1.0.0",
246
284
  "dotted_decimal_identifier" => "1.0.0",
247
285
  "cache_key" => "foo-1.0.0",
248
- "origin" => nil
286
+ "origin" => nil,
287
+ "source_options" => nil
249
288
  },
250
289
 
251
290
  "bar" => {
@@ -263,8 +302,10 @@ describe ChefDK::PolicyfileLock do
263
302
  "published" => false,
264
303
  "synchronized_remote_branches"=>[]
265
304
  },
305
+ "source_options" => nil
266
306
  },
267
- }
307
+ },
308
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
268
309
  }
269
310
  end
270
311
 
@@ -284,7 +325,7 @@ describe ChefDK::PolicyfileLock do
284
325
 
285
326
  let(:policyfile_lock) do
286
327
 
287
- ChefDK::PolicyfileLock.build(policyfile_lock_options) do |p|
328
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
288
329
 
289
330
  # Required
290
331
  p.name = "basic_example"
@@ -332,16 +373,17 @@ describe ChefDK::PolicyfileLock do
332
373
 
333
374
  "foo" => {
334
375
  "version" => "1.0.0",
335
- "identifier" => "e4611e9b5ec0636a18979e7dd22537222a2eab47",
336
- "dotted_decimal_identifier" => id_to_dotted("e4611e9b5ec0636a18979e7dd22537222a2eab47"),
376
+ "identifier" => cookbook_foo_cksum,
377
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
337
378
  "origin" => "https://community.getchef.com/api/cookbooks/foo/1.0.0",
338
- "cache_key" => "foo-1.0.0"
379
+ "cache_key" => "foo-1.0.0",
380
+ "source_options" => nil
339
381
  },
340
382
 
341
383
  "bar" => {
342
384
  "version" => "0.1.0",
343
- "identifier" => "f7694dbebe4109dfc857af7e2e4475c322c65259",
344
- "dotted_decimal_identifier" => id_to_dotted("f7694dbebe4109dfc857af7e2e4475c322c65259"),
385
+ "identifier" => cookbook_bar_cksum,
386
+ "dotted_decimal_identifier" => cookbook_bar_cksum_dotted,
345
387
  "source" => "bar",
346
388
  "cache_key" => nil,
347
389
 
@@ -353,27 +395,32 @@ describe ChefDK::PolicyfileLock do
353
395
  "published" => false,
354
396
  "synchronized_remote_branches"=>[]
355
397
  },
398
+ "source_options" => nil
356
399
  },
357
400
 
358
401
  "baz" => {
359
402
  "version" => "1.2.3",
360
- "identifier"=>"08c6ac1d202f4d59ad67953559084886f6ba710a",
361
- "dotted_decimal_identifier" => id_to_dotted("08c6ac1d202f4d59ad67953559084886f6ba710a"),
403
+ "identifier"=> cookbook_baz_cksum,
404
+ "dotted_decimal_identifier" => cookbook_baz_cksum_dotted,
362
405
  "cache_key" => "baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb",
363
- "origin" => "git://github.com/opscode-cookbooks/bar.git"
406
+ "origin" => "git://github.com/opscode-cookbooks/bar.git",
407
+ "source_options" => nil
364
408
  },
365
409
 
366
410
  "dep_of_bar" => {
367
411
  "version" => "1.2.3",
368
- "identifier" => "e6c08ea35bce8009386710d8c9bcd6caa036e8bc",
369
- "dotted_decimal_identifier" => id_to_dotted("e6c08ea35bce8009386710d8c9bcd6caa036e8bc"),
412
+ "identifier" => cookbook_dep_of_bar_cksum,
413
+ "dotted_decimal_identifier" => cookbook_dep_of_bar_cksum_dotted,
370
414
  "origin" => "https://chef-server.example.com/cookbooks/dep_of_bar/1.2.3",
371
415
  "cache_key" => "dep_of_bar-1.2.3",
416
+ "source_options" => nil
372
417
 
373
418
  },
374
419
 
375
420
  },
376
421
 
422
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
423
+
377
424
  }
378
425
  end
379
426
 
@@ -396,6 +443,55 @@ describe ChefDK::PolicyfileLock do
396
443
 
397
444
  end
398
445
 
446
+ context "with solution dependencies specified" do
447
+
448
+ let(:policyfile_lock) do
449
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
450
+
451
+ p.name = "minimal_policyfile"
452
+
453
+ p.run_list = [ "recipe[foo]" ]
454
+ p.cached_cookbook("foo") do |cb|
455
+ cb.cache_key = "foo-1.0.0"
456
+ end
457
+
458
+ p.dependencies do |deps|
459
+ deps.add_cookbook_dep("foo", "1.0.0", [])
460
+ end
461
+
462
+ end
463
+ end
464
+
465
+ let(:compiled_policyfile) do
466
+ {
467
+
468
+ "name" => "minimal_policyfile",
469
+
470
+ "run_list" => ["recipe[foo]"],
471
+
472
+ "cookbook_locks" => {
473
+
474
+ "foo" => {
475
+ "version" => "1.0.0",
476
+ "identifier" => cookbook_foo_cksum,
477
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
478
+ "cache_key" => "foo-1.0.0",
479
+ "origin" => nil,
480
+ "source_options" => nil
481
+ },
482
+ },
483
+ "solution_dependencies" => {
484
+ "Policyfile" => [],
485
+ "dependencies" => {"foo (1.0.0)" => []}
486
+ }
487
+ }
488
+ end
489
+
490
+ it "computes a minimal policyfile" do
491
+ expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
492
+ end
493
+
494
+ end
399
495
  describe "building a policyfile lock from a policyfile compiler" do
400
496
 
401
497
  include_context "setup git cookbooks"
@@ -404,52 +500,66 @@ describe ChefDK::PolicyfileLock do
404
500
  tempdir
405
501
  end
406
502
 
407
- let(:cached_cookbook_spec) do
408
- double( "ChefDK::Policyfile::CookbookSpec",
503
+ let(:cached_cookbook_uri) { "https://supermarket.getchef.com/api/v1/cookbooks/foo/versions/1.0.0/download" }
504
+
505
+ let(:cached_location_spec) do
506
+ double( "ChefDK::Policyfile::CookbookLocationSpecification",
409
507
  mirrors_canonical_upstream?: true,
410
508
  cache_key: "foo-1.0.0",
411
- uri: "https://supermarket.getchef.com/api/v1/cookbooks/foo/versions/1.0.0/download")
509
+ uri: cached_cookbook_uri,
510
+ source_options_for_lock: { "artifactserver" => cached_cookbook_uri, "version" => "1.0.0" })
412
511
  end
413
512
 
414
- let(:local_cookbook_spec) do
415
- double( "ChefDK::Policyfile::CookbookSpec",
513
+ let(:local_location_spec) do
514
+ double( "ChefDK::Policyfile::CookbookLocationSpecification",
416
515
  mirrors_canonical_upstream?: false,
417
516
  relative_paths_root: relative_paths_root,
418
- relative_path: "bar")
517
+ relative_path: "bar",
518
+ source_options_for_lock: { "path" => "bar" })
419
519
  end
420
520
 
521
+ let(:policyfile_solution_dependencies) do
522
+ ChefDK::Policyfile::SolutionDependencies.new.tap do |s|
523
+ s.add_policyfile_dep("foo", "~> 1.0")
524
+ s.add_cookbook_dep("foo", "1.0.0", [])
525
+ s.add_cookbook_dep("bar", "0.1.0", [])
526
+ end
527
+ end
421
528
 
422
529
  let(:policyfile_compiler) do
423
530
  double( "ChefDK::PolicyfileCompiler",
424
- expanded_run_list: %w[foo bar],
425
- all_cookbook_specs: {"foo" => cached_cookbook_spec, "bar" => local_cookbook_spec})
531
+ name: "my-policyfile",
532
+ normalized_run_list: %w[recipe[foo::default] recipe[bar::default]],
533
+ all_cookbook_location_specs: {"foo" => cached_location_spec, "bar" => local_location_spec},
534
+ solution_dependencies: policyfile_solution_dependencies )
426
535
  end
427
536
 
428
537
  let(:policyfile_lock) do
429
- ChefDK::PolicyfileLock.build_from_compiler(policyfile_compiler, cache_path: cache_path)
538
+ ChefDK::PolicyfileLock.build_from_compiler(policyfile_compiler, storage_config)
430
539
  end
431
540
 
432
541
  let(:compiled_policyfile) do
433
542
  {
434
543
 
435
- "name" => nil,
544
+ "name" => "my-policyfile",
436
545
 
437
- "run_list" => ["foo", "bar"],
546
+ "run_list" => ["recipe[foo::default]", "recipe[bar::default]"],
438
547
 
439
548
  "cookbook_locks" => {
440
549
 
441
550
  "foo" => {
442
551
  "version" => "1.0.0",
443
- "identifier" => "e4611e9b5ec0636a18979e7dd22537222a2eab47",
444
- "dotted_decimal_identifier" => id_to_dotted("e4611e9b5ec0636a18979e7dd22537222a2eab47"),
552
+ "identifier" => cookbook_foo_cksum,
553
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
445
554
  "cache_key" => "foo-1.0.0",
446
- "origin" => cached_cookbook_spec.uri
555
+ "origin" => cached_cookbook_uri,
556
+ "source_options" => { "artifactserver" => cached_cookbook_uri, "version" => "1.0.0" }
447
557
  },
448
558
 
449
559
  "bar" => {
450
560
  "version" => "0.1.0",
451
- "identifier" => "f7694dbebe4109dfc857af7e2e4475c322c65259",
452
- "dotted_decimal_identifier" => id_to_dotted("f7694dbebe4109dfc857af7e2e4475c322c65259"),
561
+ "identifier" => cookbook_bar_cksum,
562
+ "dotted_decimal_identifier" => cookbook_bar_cksum_dotted,
453
563
  "source" => "bar",
454
564
  "cache_key" => nil,
455
565
 
@@ -460,24 +570,29 @@ describe ChefDK::PolicyfileLock do
460
570
  "working_tree_clean" => true,
461
571
  "published" => false,
462
572
  "synchronized_remote_branches"=>[]
463
- }
573
+ },
574
+ "source_options" => { "path" => "bar" }
464
575
  }
576
+ },
577
+
578
+ "solution_dependencies" => {
579
+ "Policyfile" => [ [ "foo", "~> 1.0" ] ],
580
+ "dependencies" => { "foo (1.0.0)" => [], "bar (0.1.0)" => [] }
465
581
  }
466
582
  }
467
583
  end
468
584
 
469
-
470
585
  it "adds a cached cookbook lock generator for the compiler's cached cookbook" do
471
586
  expect(policyfile_lock.cookbook_locks).to have_key("foo")
472
587
  cb_lock = policyfile_lock.cookbook_locks["foo"]
473
- expect(cb_lock.origin).to eq(cached_cookbook_spec.uri)
474
- expect(cb_lock.cache_key).to eq(cached_cookbook_spec.cache_key)
588
+ expect(cb_lock.origin).to eq(cached_location_spec.uri)
589
+ expect(cb_lock.cache_key).to eq(cached_location_spec.cache_key)
475
590
  end
476
591
 
477
592
  it "adds a local cookbook lock generator for the compiler's local cookbook" do
478
593
  expect(policyfile_lock.cookbook_locks).to have_key("bar")
479
594
  cb_lock = policyfile_lock.cookbook_locks["bar"]
480
- expect(cb_lock.source).to eq(local_cookbook_spec.relative_path)
595
+ expect(cb_lock.source).to eq(local_location_spec.relative_path)
481
596
  end
482
597
 
483
598
  it "generates a lockfile data structure" do