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,7 +18,7 @@
18
18
  require 'forwardable'
19
19
 
20
20
  require 'solve'
21
- require 'chef/run_list/run_list_item'
21
+ require 'chef/run_list'
22
22
 
23
23
  require 'chef-dk/policyfile/dsl'
24
24
  require 'chef-dk/policyfile_lock'
@@ -40,16 +40,19 @@ module ChefDK
40
40
  compiler
41
41
  end
42
42
 
43
+ def_delegator :@dsl, :name
43
44
  def_delegator :@dsl, :run_list
44
45
  def_delegator :@dsl, :errors
45
46
  def_delegator :@dsl, :default_source
46
- def_delegator :@dsl, :policyfile_cookbook_specs
47
+ def_delegator :@dsl, :cookbook_location_specs
47
48
 
48
49
  attr_reader :dsl
50
+ attr_reader :storage_config
49
51
 
50
52
  def initialize
51
- @dsl = Policyfile::DSL.new
52
- @artifact_server_cookbook_specs = {}
53
+ @storage_config = Policyfile::StorageConfig.new
54
+ @dsl = Policyfile::DSL.new(storage_config)
55
+ @artifact_server_cookbook_location_specs = {}
53
56
  end
54
57
 
55
58
  def error!
@@ -58,23 +61,29 @@ module ChefDK
58
61
  end
59
62
  end
60
63
 
61
- def cookbook_spec_for(cookbook_name)
62
- policyfile_cookbook_specs[cookbook_name]
64
+ def cookbook_location_spec_for(cookbook_name)
65
+ cookbook_location_specs[cookbook_name]
63
66
  end
64
67
 
65
68
  def expanded_run_list
66
- run_list
69
+ # doesn't support roles yet...
70
+ Chef::RunList.new(*run_list)
71
+ end
72
+
73
+ # copy of the expanded_run_list, properly formatted for use in a lockfile
74
+ def normalized_run_list
75
+ expanded_run_list.map { |i| normalize_recipe(i) }
67
76
  end
68
77
 
69
78
  def lock
70
- @policyfile_lock ||= PolicyfileLock.build_from_compiler(self, cache_path: cache_path)
79
+ @policyfile_lock ||= PolicyfileLock.build_from_compiler(self, storage_config)
71
80
  end
72
81
 
73
82
  def install
74
83
  ensure_cache_dir_exists
75
84
 
76
85
  graph_solution.each do |cookbook_name, version|
77
- spec = cookbook_spec_for(cookbook_name)
86
+ spec = cookbook_location_spec_for(cookbook_name)
78
87
  if spec.nil? or !spec.version_fixed?
79
88
  spec = create_spec_for_cookbook(cookbook_name, version)
80
89
  spec.ensure_cached
@@ -84,17 +93,17 @@ module ChefDK
84
93
 
85
94
  def create_spec_for_cookbook(cookbook_name, version)
86
95
  source_options = default_source.source_options_for(cookbook_name, version)
87
- spec = Policyfile::CookbookSpec.new(cookbook_name, "= #{version}", source_options, dsl)
88
- @artifact_server_cookbook_specs[cookbook_name] = spec
96
+ spec = Policyfile::CookbookLocationSpecification.new(cookbook_name, "= #{version}", source_options, storage_config)
97
+ @artifact_server_cookbook_location_specs[cookbook_name] = spec
89
98
  end
90
99
 
91
- def all_cookbook_specs
92
- # in the installation proces, we create "artifact_server_cookbook_specs"
100
+ def all_cookbook_location_specs
101
+ # in the installation proces, we create "artifact_server_cookbook_location_specs"
93
102
  # for any cookbook that isn't sourced from a single-version source (e.g.,
94
103
  # path and git only support one version at a time), but we might have
95
104
  # specs for them to track additional version constraint demands. Merging
96
- # in this order ensures the artifact_server_cookbook_specs "win".
97
- policyfile_cookbook_specs.merge(@artifact_server_cookbook_specs)
105
+ # in this order ensures the artifact_server_cookbook_location_specs "win".
106
+ cookbook_location_specs.merge(@artifact_server_cookbook_location_specs)
98
107
  end
99
108
 
100
109
  ##
@@ -120,9 +129,23 @@ module ChefDK
120
129
  end
121
130
  end
122
131
 
132
+ def solution_dependencies
133
+ solution_deps = Policyfile::SolutionDependencies.new
134
+
135
+ all_cookbook_location_specs.each do |name, spec|
136
+ solution_deps.add_policyfile_dep(name, spec.version_constraint)
137
+ end
138
+
139
+ graph_solution.each do |name, version|
140
+ transitive_deps = artifacts_graph[name][version]
141
+ solution_deps.add_cookbook_dep(name, version, transitive_deps)
142
+ end
143
+ solution_deps
144
+ end
145
+
123
146
  def graph_demands
124
147
  cookbooks_for_demands.map do |cookbook_name|
125
- spec = cookbook_spec_for(cookbook_name)
148
+ spec = cookbook_location_spec_for(cookbook_name)
126
149
  if spec.nil?
127
150
  [ cookbook_name, DEFAULT_DEMAND_CONSTRAINT ]
128
151
  elsif spec.version_fixed?
@@ -145,9 +168,9 @@ module ChefDK
145
168
  # version number. To accomodate this, the local_artifacts_graph should be
146
169
  # merged over the upstream's artifacts graph.
147
170
  def local_artifacts_graph
148
- policyfile_cookbook_specs.inject({}) do |local_artifacts, (cookbook_name, cookbook_spec)|
149
- if cookbook_spec.version_fixed?
150
- local_artifacts[cookbook_name] = { cookbook_spec.version => cookbook_spec.dependencies }
171
+ cookbook_location_specs.inject({}) do |local_artifacts, (cookbook_name, cookbook_location_spec)|
172
+ if cookbook_location_spec.version_fixed?
173
+ local_artifacts[cookbook_name] = { cookbook_location_spec.version => cookbook_location_spec.dependencies }
151
174
  end
152
175
  local_artifacts
153
176
  end
@@ -158,8 +181,8 @@ module ChefDK
158
181
  end
159
182
 
160
183
  def version_constraint_for(cookbook_name)
161
- if (cookbook_spec = cookbook_spec_for(cookbook_name)) and cookbook_spec.version_fixed?
162
- version = cookbook_spec.version
184
+ if (cookbook_location_spec = cookbook_location_spec_for(cookbook_name)) and cookbook_location_spec.version_fixed?
185
+ version = cookbook_location_spec.version
163
186
  "= #{version}"
164
187
  else
165
188
  DEFAULT_DEMAND_CONSTRAINT
@@ -167,15 +190,16 @@ module ChefDK
167
190
  end
168
191
 
169
192
  def cookbook_version_fixed?(cookbook_name)
170
- if cookbook_spec = cookbook_spec_for(cookbook_name)
171
- cookbook_spec.version_fixed?
193
+ if cookbook_location_spec = cookbook_location_spec_for(cookbook_name)
194
+ cookbook_location_spec.version_fixed?
172
195
  else
173
196
  false
174
197
  end
175
198
  end
176
199
 
177
200
  def cookbooks_in_run_list
178
- run_list.map {|item_spec| Chef::RunList::RunListItem.new(item_spec).name }
201
+ recipes = expanded_run_list.map {|recipe| recipe.name }
202
+ recipes.map { |r| r[/^([^:]+)/, 1] }
179
203
  end
180
204
 
181
205
  def build
@@ -184,21 +208,28 @@ module ChefDK
184
208
  end
185
209
 
186
210
  def evaluate_policyfile(policyfile_string, policyfile_filename)
187
- @dsl.eval_policyfile(policyfile_string, policyfile_filename)
211
+ storage_config.use_policyfile(policyfile_filename)
212
+ @dsl.eval_policyfile(policyfile_string)
188
213
  self
189
214
  end
190
215
 
191
216
  private
192
217
 
218
+ def normalize_recipe(run_list_item)
219
+ name = run_list_item.name
220
+ name = "#{name}::default" unless name.include?("::")
221
+ "recipe[#{name}]"
222
+ end
223
+
193
224
  def cookbooks_for_demands
194
- (cookbooks_in_run_list + policyfile_cookbook_specs.keys).uniq
225
+ (cookbooks_in_run_list + cookbook_location_specs.keys).uniq
195
226
  end
196
227
 
197
228
  def cache_fixed_version_cookbooks
198
229
  ensure_cache_dir_exists
199
230
 
200
- policyfile_cookbook_specs.each do |_cookbook_name, cookbook_spec|
201
- cookbook_spec.ensure_cached if cookbook_spec.version_fixed?
231
+ cookbook_location_specs.each do |_cookbook_name, cookbook_location_spec|
232
+ cookbook_location_spec.ensure_cached if cookbook_location_spec.version_fixed?
202
233
  end
203
234
  end
204
235
 
@@ -212,6 +243,5 @@ module ChefDK
212
243
  CookbookOmnifetch.storage_path
213
244
  end
214
245
 
215
-
216
246
  end
217
247
  end
@@ -15,229 +15,173 @@
15
15
  # limitations under the License.
16
16
  #
17
17
 
18
- require 'chef-dk/cookbook_profiler/identifiers'
19
- require 'chef-dk/cookbook_profiler/null_scm'
20
- require 'chef-dk/cookbook_profiler/git'
18
+ require 'chef-dk/policyfile/storage_config'
19
+ require 'chef-dk/policyfile/cookbook_locks'
20
+ require 'chef-dk/policyfile/solution_dependencies'
21
21
 
22
22
  module ChefDK
23
23
  class PolicyfileLock
24
24
 
25
- # CachedCookbook objects represent a cookbook that has been fetched from an
26
- # upstream canonical source and stored (presumed unmodified).
27
- class CachedCookbook
28
-
29
- # The cookbook name (without any version or other info suffixed)
30
- attr_reader :name
31
-
32
- # The directory name in the cookbook cache where the cookbook is stored.
33
- # By convention, this should be the name of the cookbook followed by a
34
- # hyphen and then some sort of version identifier (depending on the
35
- # cookbook source).
36
- attr_accessor :cache_key
37
-
38
- # A URI pointing to the canonical source of the cookbook.
39
- attr_accessor :origin
40
-
41
- # A string that uniquely identifies the cookbook version. If not
42
- # explicitly set, an identifier is generated based on the cookbook's
43
- # content.
44
- attr_writer :identifier
45
-
46
- # A string in "X.Y.Z" version number format that uniquely identifies the
47
- # cookbook version. This is for compatibility with Chef Server 11.x,
48
- # where cookbooks are stored by x.y.z version numbers.
49
- attr_writer :dotted_decimal_identifier
50
-
51
- # The root of the cookbook cache.
52
- attr_reader :cache_path
53
-
54
- def initialize(name, cache_path)
55
- @name = name
56
- @cache_path = cache_path
57
- @origin = nil
58
- @cache_key = nil
59
- @identifier = nil
60
- @dotted_decimal_identifier = nil
61
- end
62
-
63
- def cookbook_path
64
- File.join(cache_path, cache_key)
65
- end
66
-
67
- def identifier
68
- @identifier || identifiers.content_identifier
69
- end
70
-
71
- def dotted_decimal_identifier
72
- @dotted_decimal_identifier || identifiers.dotted_decimal_identifier
73
- end
74
-
75
- def to_lock
76
- validate!
77
- {
78
- "version" => identifiers.semver_version,
79
- "identifier" => identifier,
80
- "dotted_decimal_identifier" => dotted_decimal_identifier,
81
- "cache_key" => cache_key,
82
- "origin" => origin
83
- }
84
- end
85
-
86
- def identifiers
87
- @identifiers ||= CookbookProfiler::Identifiers.new(cookbook_path)
88
- end
89
-
90
- def validate!
91
- unless File.exist?(cookbook_path)
92
- raise CachedCookbookNotFound, "Cookbook `#{name}' not found at expected cache location `#{cookbook_path}'"
93
- end
94
- end
95
-
96
- end
97
-
98
- # LocalCookbook objects represent cookbooks that are sourced from the local
99
- # filesystem and are assumed to be under active development.
100
- class LocalCookbook
101
-
102
- # A relative or absolute path to the cookbook. If a relative path is
103
- # given, it is resolved relative to #relative_paths_root
104
- attr_accessor :source
105
-
106
- # A string that uniquely identifies the cookbook version. If not
107
- # explicitly set, an identifier is generated based on the cookbook's
108
- # content.
109
- attr_writer :identifier
110
-
111
- # A string in "X.Y.Z" version number format that uniquely identifies the
112
- # cookbook version. This is for compatibility with Chef Server 11.x,
113
- # where cookbooks are stored by x.y.z version numbers.
114
- attr_writer :dotted_decimal_identifier
115
-
116
- # The root path from which source is expanded.
117
- attr_accessor :relative_paths_root
118
-
119
- def initialize(name, relative_paths_root)
120
- @name = name
121
- @identifier = nil
122
- @relative_paths_root = relative_paths_root
123
- end
124
-
125
- def cookbook_path
126
- File.expand_path(source, relative_paths_root)
127
- end
128
-
129
- def scm_profiler
130
- if File.exist?(File.join(cookbook_path, ".git"))
131
- CookbookProfiler::Git.new(cookbook_path)
132
- else
133
- CookbookProfiler::NullSCM.new(cookbook_path)
134
- end
135
- end
136
-
137
- def identifier
138
- @identifier || identifiers.content_identifier
139
- end
140
-
141
- def dotted_decimal_identifier
142
- @dotted_decimal_identifier || identifiers.dotted_decimal_identifier
143
- end
144
-
145
- def to_lock
146
-
147
- {
148
- "version" => identifiers.semver_version,
149
- "identifier" => identifier,
150
- "dotted_decimal_identifier" => dotted_decimal_identifier,
151
- "source" => source,
152
- "cache_key" => nil,
153
- "scm_info" => scm_profiler.profile_data
154
- }
155
- end
156
25
 
157
- def identifiers
158
- @identifiers ||= CookbookProfiler::Identifiers.new(cookbook_path)
159
- end
160
-
161
- end
162
-
163
- def self.build(options = {})
164
- lock = new(options)
26
+ def self.build(storage_config)
27
+ lock = new(storage_config)
165
28
  yield lock
166
29
  lock
167
30
  end
168
31
 
169
- def self.build_from_compiler(compiler, options = {})
170
- lock = new(options)
32
+ def self.build_from_compiler(compiler, storage_config)
33
+ lock = new(storage_config)
171
34
  lock.build_from_compiler(compiler)
172
35
  lock
173
36
  end
174
37
 
38
+ include Policyfile::StorageConfigDelegation
39
+
175
40
  attr_accessor :name
176
41
  attr_accessor :run_list
177
42
 
43
+ attr_reader :solution_dependencies
44
+
45
+ attr_reader :storage_config
46
+
178
47
  attr_reader :cookbook_locks
179
- attr_reader :cache_path
180
- attr_reader :relative_paths_root
181
48
 
182
- def initialize(options = {})
49
+ def initialize(storage_config)
183
50
  @name = nil
184
51
  @run_list = []
185
52
  @cookbook_locks = {}
186
53
  @relative_paths_root = Dir.pwd
187
- handle_options(options)
54
+ @storage_config = storage_config
55
+
56
+ @solution_dependencies = Policyfile::SolutionDependencies.new
57
+ end
58
+
59
+ def lock_data_for(cookbook_name)
60
+ @cookbook_locks[cookbook_name]
188
61
  end
189
62
 
190
63
  def cached_cookbook(name)
191
- cached_cookbook = CachedCookbook.new(name, cache_path)
192
- yield cached_cookbook
64
+ cached_cookbook = Policyfile::CachedCookbook.new(name, storage_config)
65
+ yield cached_cookbook if block_given?
193
66
  @cookbook_locks[name] = cached_cookbook
194
67
  end
195
68
 
196
69
  def local_cookbook(name)
197
- local_cookbook = LocalCookbook.new(name, relative_paths_root)
198
- yield local_cookbook
70
+ local_cookbook = Policyfile::LocalCookbook.new(name, storage_config)
71
+ yield local_cookbook if block_given?
199
72
  @cookbook_locks[name] = local_cookbook
200
73
  end
201
74
 
75
+ def dependencies
76
+ yield solution_dependencies
77
+ end
78
+
202
79
  def to_lock
203
80
  {}.tap do |lock|
204
81
  lock["name"] = name
205
82
  lock["run_list"] = run_list
206
83
  lock["cookbook_locks"] = cookbook_locks_for_lockfile
84
+ lock["solution_dependencies"] = solution_dependencies.to_lock
207
85
  end
208
86
  end
209
87
 
210
88
  def cookbook_locks_for_lockfile
211
- cookbook_locks.inject({}) do |locks_map, (name, cookbook_spec)|
212
- locks_map[name] = cookbook_spec.to_lock
89
+ cookbook_locks.inject({}) do |locks_map, (name, location_spec)|
90
+ location_spec.validate!
91
+ location_spec.gather_profile_data
92
+ locks_map[name] = location_spec.to_lock
213
93
  locks_map
214
94
  end
215
95
  end
216
96
 
97
+ def validate_cookbooks!
98
+ cookbook_locks.each do |name, cookbook_lock|
99
+ cookbook_lock.validate!
100
+ cookbook_lock.refresh!
101
+ end
102
+
103
+ # Check that versions and dependencies are still valid. First we need to
104
+ # refresh the dependency info for everything that has changed, then we
105
+ # check that the new versions and dependencies are valid for the working
106
+ # set of cookbooks. We can't do this in a single loop because the user
107
+ # may have modified two cookbooks such that the versions and constraints
108
+ # are only valid when both changes are considered together.
109
+ cookbook_locks.each do |name, cookbook_lock|
110
+ if cookbook_lock.updated?
111
+ solution_dependencies.update_cookbook_dep(name, cookbook_lock.version, cookbook_lock.dependencies)
112
+ end
113
+ end
114
+ cookbook_locks.each do |name, cookbook_lock|
115
+ if cookbook_lock.updated?
116
+ solution_dependencies.test_conflict!(cookbook_lock.name, cookbook_lock.version)
117
+ end
118
+ end
119
+
120
+ true
121
+ end
122
+
217
123
  def build_from_compiler(compiler)
218
- @run_list = compiler.expanded_run_list
124
+ @name = compiler.name
125
+
126
+ @run_list = compiler.normalized_run_list
219
127
 
220
- compiler.all_cookbook_specs.each do |cookbook_name, spec|
128
+ compiler.all_cookbook_location_specs.each do |cookbook_name, spec|
221
129
  if spec.mirrors_canonical_upstream?
222
130
  cached_cookbook(cookbook_name) do |cached_cb|
223
131
  cached_cb.cache_key = spec.cache_key
224
132
  cached_cb.origin = spec.uri
133
+ cached_cb.source_options = spec.source_options_for_lock
225
134
  end
226
135
  else
227
136
  local_cookbook(cookbook_name) do |local_cb|
228
137
  local_cb.source = spec.relative_path
229
- local_cb.relative_paths_root = spec.relative_paths_root
138
+ local_cb.source_options = spec.source_options_for_lock
230
139
  end
231
140
  end
232
141
  end
142
+
143
+ @solution_dependencies = compiler.solution_dependencies
144
+
145
+ self
146
+ end
147
+
148
+ def build_from_lock_data(lock_data)
149
+ @name = lock_data["name"]
150
+ @run_list = lock_data["run_list"]
151
+ lock_data["cookbook_locks"].each do |name, lock_info|
152
+ build_cookbook_lock_from_lock_data(name, lock_info)
153
+ end
154
+
155
+ s = Policyfile::SolutionDependencies.from_lock(lock_data["solution_dependencies"])
156
+ @solution_dependencies = s
233
157
  self
234
158
  end
235
159
 
160
+ def install_cookbooks
161
+ # note: duplicates PolicyfileCompiler#ensure_cache_dir_exists
162
+ ensure_cache_dir_exists
163
+
164
+ cookbook_locks.each do |cookbook_name, cookbook_lock|
165
+ cookbook_lock.install_locked
166
+ end
167
+ end
168
+
169
+ def ensure_cache_dir_exists
170
+ # note: duplicates PolicyfileCompiler#ensure_cache_dir_exists
171
+ unless File.exist?(cache_path)
172
+ FileUtils.mkdir_p(cache_path)
173
+ end
174
+ end
175
+
236
176
  private
237
177
 
238
- def handle_options(options)
239
- @cache_path = options[:cache_path]
240
- @relative_paths_root = options[:relative_paths_root] if options.key?(:relative_paths_root)
178
+ def build_cookbook_lock_from_lock_data(name, lock_info)
179
+ if lock_info["cache_key"].nil?
180
+ local_cookbook(name).build_from_lock_data(lock_info)
181
+ else
182
+ cached_cookbook(name).build_from_lock_data(lock_info)
183
+ end
241
184
  end
185
+
242
186
  end
243
187
  end