berkshelf 3.1.5 → 3.2.0

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/berkshelf.gemspec +6 -5
  4. data/features/commands/search.feature +2 -2
  5. data/features/commands/vendor.feature +6 -2
  6. data/features/commands/verify.feature +29 -0
  7. data/features/config.feature +13 -48
  8. data/features/step_definitions/filesystem_steps.rb +2 -2
  9. data/features/step_definitions/gem_steps.rb +3 -1
  10. data/features/step_definitions/utility_steps.rb +2 -2
  11. data/generator_files/Vagrantfile.erb +30 -30
  12. data/generator_files/metadata.rb.erb +0 -1
  13. data/lib/berkshelf.rb +5 -2
  14. data/lib/berkshelf/berksfile.rb +41 -41
  15. data/lib/berkshelf/cli.rb +11 -1
  16. data/lib/berkshelf/community_rest.rb +1 -0
  17. data/lib/berkshelf/config.rb +18 -4
  18. data/lib/berkshelf/cookbook_store.rb +1 -1
  19. data/lib/berkshelf/downloader.rb +4 -0
  20. data/lib/berkshelf/errors.rb +0 -1
  21. data/lib/berkshelf/file_syncer.rb +134 -0
  22. data/lib/berkshelf/locations/base.rb +6 -1
  23. data/lib/berkshelf/locations/git.rb +2 -2
  24. data/lib/berkshelf/lockfile.rb +14 -2
  25. data/lib/berkshelf/uploader.rb +10 -17
  26. data/lib/berkshelf/validator.rb +37 -0
  27. data/lib/berkshelf/version.rb +1 -1
  28. data/lib/berkshelf/visualizer.rb +13 -6
  29. data/spec/spec_helper.rb +1 -1
  30. data/spec/support/kitchen.rb +3 -1
  31. data/spec/support/matchers/file_system_matchers.rb +1 -1
  32. data/spec/support/matchers/filepath_matchers.rb +38 -2
  33. data/spec/support/shared_examples/formatter.rb +7 -7
  34. data/spec/unit/berkshelf/berksfile_spec.rb +51 -21
  35. data/spec/unit/berkshelf/cached_cookbook_spec.rb +5 -5
  36. data/spec/unit/berkshelf/cli_spec.rb +1 -1
  37. data/spec/unit/berkshelf/community_rest_spec.rb +12 -12
  38. data/spec/unit/berkshelf/config_spec.rb +4 -4
  39. data/spec/unit/berkshelf/cookbook_generator_spec.rb +2 -2
  40. data/spec/unit/berkshelf/cookbook_store_spec.rb +6 -6
  41. data/spec/unit/berkshelf/core_ext/file_utils_spec.rb +3 -3
  42. data/spec/unit/berkshelf/core_ext/pathname_spec.rb +23 -6
  43. data/spec/unit/berkshelf/dependency_spec.rb +4 -4
  44. data/spec/unit/berkshelf/downloader_spec.rb +5 -1
  45. data/spec/unit/berkshelf/errors_spec.rb +1 -1
  46. data/spec/unit/berkshelf/file_syncer_spec.rb +206 -0
  47. data/spec/unit/berkshelf/init_generator_spec.rb +19 -22
  48. data/spec/unit/berkshelf/installer_spec.rb +6 -6
  49. data/spec/unit/berkshelf/locations/base_spec.rb +17 -8
  50. data/spec/unit/berkshelf/locations/git_spec.rb +34 -34
  51. data/spec/unit/berkshelf/locations/path_spec.rb +3 -3
  52. data/spec/unit/berkshelf/lockfile_parser_spec.rb +1 -1
  53. data/spec/unit/berkshelf/lockfile_spec.rb +50 -36
  54. data/spec/unit/berkshelf/packager_spec.rb +6 -4
  55. data/spec/unit/berkshelf/resolver/graph_spec.rb +3 -3
  56. data/spec/unit/berkshelf/resolver_spec.rb +3 -3
  57. data/spec/unit/berkshelf/shell_spec.rb +30 -24
  58. data/spec/unit/berkshelf/uploader_spec.rb +10 -36
  59. data/spec/unit/berkshelf/validator_spec.rb +30 -0
  60. data/spec/unit/berkshelf/visualizer_spec.rb +17 -2
  61. metadata +34 -15
  62. data/lib/berkshelf/mixin/dsl_eval.rb +0 -58
  63. data/spec/unit/berkshelf/mixin/dsl_eval_spec.rb +0 -55
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b9ee0bbcbb69dc7f55aaf3ca127f9dbd3b2dafc
4
- data.tar.gz: 71e33ba4b6f966b65c8531cb01dc901e7abceeb6
3
+ metadata.gz: be55c4c1bb887daab19c58ef3a4f2f905af29033
4
+ data.tar.gz: f0d4402fa9850c728b51ba239fec76de438fef1f
5
5
  SHA512:
6
- metadata.gz: cd70423af3cc72518f759619d2ed4706299a95626915cb45f312390cfadbdda46629ef0c5c106bbd2c919fd4f3369f5b82ee6a7801460d18765595951e20d287
7
- data.tar.gz: c88ac3755f5f54469e2af5af73ec09b03d360045990daf7bf99a9badf2be0db3b16b914f3811a7d4fc597aa5cbf40a9aa0af3d24b679a11440315db9139bc7c0
6
+ metadata.gz: fe6cbe54f7acb7d5cdae6cced81df057585c0b8efba3fe532d7fd72ef7f28449f1a05a7859c977acf39f01090a0ec34da5ff3416ced45a9dd8df552aa7c126d7
7
+ data.tar.gz: 5d92e870bcac605248af9bfc0d7c5c8b827d63ea11014c7a95ff66177fcb6d67ec056f94d2605d22064a38f251ffa725799ecaf3ff202b7611dcaf3a15b2e955
@@ -1,5 +1,26 @@
1
1
  > This is a high level digest of changes. For the complete CHANGELOG diff two tags in the project's [commit history](https://github.com/berkshelf/berkshelf/commits/master).
2
2
 
3
+ # 3.2.0
4
+
5
+ * Improvements
6
+ * Add version information to edges of generated visualization graph
7
+ * Bump to latest full release of Celluloid
8
+ * Updated some errors to include more information about what went wrong / how to make it better
9
+ * Lockfiles will be named after the name of the Berksfile, not always Berksfile.lock
10
+ * Vendoring will now sync files between two directories instead of deleting the target and it's contents
11
+ * Add support for downloading from Berkshelf-API file_store location
12
+ * Add `berks verify` command to validate Ruby syntax, ERB templates, and file names of cookbooks
13
+
14
+ * Bug Fixes
15
+ * Fixed a number of typos and documentation errors
16
+ * Fix running `berks viz` when pwd has spaces in it
17
+ * Fix checking for graphviz on Windows
18
+ * Remove PaxHeader files before uploading
19
+ * BERKSHELF_PATH will always be fully expanded regardless of how it is configured
20
+
21
+ * Deprecations
22
+ * vagrant.omnibus.enabled configuration option is now deprecated
23
+
3
24
  # 3.1.5
4
25
 
5
26
  * Bug Fixes
@@ -35,21 +35,22 @@ Gem::Specification.new do |s|
35
35
  s.add_dependency 'buff-config', '~> 1.0'
36
36
  s.add_dependency 'buff-extensions', '~> 1.0'
37
37
  s.add_dependency 'buff-shell_out', '~> 0.1'
38
+ s.add_dependency 'cleanroom', '~> 1.0'
38
39
  s.add_dependency 'faraday', '~> 0.9.0'
39
40
  s.add_dependency 'minitar', '~> 0.5.4'
40
41
  s.add_dependency 'retryable', '~> 1.3.3'
41
42
  s.add_dependency 'ridley', '~> 4.0'
42
43
  s.add_dependency 'solve', '~> 1.1'
43
- s.add_dependency 'thor', '~> 0.18'
44
+ s.add_dependency 'thor', '~> 0.19'
44
45
  s.add_dependency 'octokit', '~> 3.0'
45
- s.add_dependency 'celluloid', '~> 0.16.0.pre'
46
- s.add_dependency 'celluloid-io', '~> 0.16.0.pre'
46
+ s.add_dependency 'celluloid', '~> 0.16.0'
47
+ s.add_dependency 'celluloid-io', '~> 0.16.1'
47
48
 
48
- s.add_development_dependency 'aruba', '~> 0.5'
49
+ s.add_development_dependency 'aruba', '~> 0.6'
49
50
  s.add_development_dependency 'chef-zero', '~> 1.5.0'
50
51
  s.add_development_dependency 'fuubar', '~> 1.1'
51
52
  s.add_development_dependency 'rake', '~> 0.9'
52
- s.add_development_dependency 'rspec', '~> 2.13'
53
+ s.add_development_dependency 'rspec', '~> 3.0'
53
54
  s.add_development_dependency 'spork', '~> 0.9'
54
55
  s.add_development_dependency 'test-kitchen', '~> 1.2'
55
56
  s.add_development_dependency 'webmock', '~> 1.11'
@@ -10,7 +10,7 @@ Feature: berks search
10
10
  * I successfully run `berks search berkshelf-`
11
11
  * the output should contain:
12
12
  """
13
- berkshelf-api (1.0.0)
14
- berkshelf-api-server (2.0.0)
13
+ berkshelf-api (1.2.2)
14
+ berkshelf-api-server (2.1.0)
15
15
  berkshelf-cookbook-fixture (1.0.0)
16
16
  """
@@ -94,8 +94,12 @@ Feature: Vendoring cookbooks to a directory
94
94
  cookbook 'fake'
95
95
  """
96
96
  And a directory named "cukebooks"
97
- When I run `berks vendor cukebooks`
98
- And the exit status should be "VendorError"
97
+ And a directory named "cukebooks/fake/ponies"
98
+ And a directory named "cukebooks/existing_cookbook"
99
+ When I successfully run `berks vendor cukebooks`
100
+ And the directory "cukebooks/fake" should contain version "1.0.0" of the "fake" cookbook
101
+ And a directory named "cukebooks/fake/ponies" should not exist
102
+ And a directory named "cukebooks/existing_cookbook" should not exist
99
103
 
100
104
  Scenario: vendoring into a nested directory
101
105
  Given I have a Berksfile pointing at the local Berkshelf API with:
@@ -0,0 +1,29 @@
1
+ Feature: berks verify
2
+ Scenario: running verify when there is no Lockfile present
3
+ Given a cookbook named "sparkle_motion"
4
+ And I cd to "sparkle_motion"
5
+ And I have a Berksfile pointing at the local Berkshelf API with:
6
+ """
7
+ metadata
8
+ """
9
+ And I run `berks verify`
10
+ Then the output should contain:
11
+ """
12
+ Lockfile not found! Run `berks install` to create the lockfile.
13
+ """
14
+ And the exit status should be "LockfileNotFound"
15
+
16
+ Scenario: running verify when there is a valid Lockfile present
17
+ Given a cookbook named "sparkle_motion"
18
+ And I cd to "sparkle_motion"
19
+ And I have a Berksfile pointing at the local Berkshelf API with:
20
+ """
21
+ metadata
22
+ """
23
+ When I successfully run `berks install`
24
+ And I successfully run `berks verify`
25
+ Then the output should contain:
26
+ """
27
+ Verifying (1) cookbook(s)...
28
+ Verified.
29
+ """
@@ -2,37 +2,8 @@ Feature: Reading a Berkshelf configuration file
2
2
  Scenario: Missing a Berkshelf configuration file
3
3
  When I successfully run `berks cookbook sparkle_motion`
4
4
  Then the resulting "sparkle_motion" Vagrantfile should contain:
5
- | config.omnibus.chef_version = :latest |
6
- | config.vm.box = "chef/ubuntu-14.04" |
7
- | config.vm.box_url = "https://vagrantcloud.com/chef/ubuntu-14.04/version/1/provider/virtualbox.box" |
8
-
9
- Scenario: Using a Berkshelf configuration file that disables the vagrant-omnibus plugin
10
- Given I have a Berkshelf config file containing:
11
- """
12
- {
13
- "vagrant": {
14
- "omnibus": {
15
- "enabled": false,
16
- "version": "11.4.4"
17
- },
18
- "vm": {
19
- "box": "my_box",
20
- "box_url": "http://files.vagrantup.com/lucid64.box",
21
- "forward_port": {
22
- "12345": "54321"
23
- }
24
- }
25
- }
26
- }
27
- """
28
- When I successfully run `berks cookbook sparkle_motion`
29
- Then the resulting "sparkle_motion" Vagrantfile should contain:
30
- | #config.omnibus.chef_version = :latest |
31
- | config.vm.box = "my_box" |
32
- | config.vm.box_url = "http://files.vagrantup.com/lucid64.box" |
33
- | config.vm.network :forwarded_port, guest: 12345, host: 54321 |
34
- | config.vm.network :private_network, type: "dhcp" |
35
- And the exit status should be 0
5
+ | config.omnibus.chef_version = 'latest' |
6
+ | config.vm.box = 'chef/ubuntu-14.04' |
36
7
 
37
8
  Scenario: Using a Berkshelf configuration file that sets the vagrant-omnibus plugin chef version
38
9
  Given I have a Berkshelf config file containing:
@@ -40,12 +11,10 @@ Feature: Reading a Berkshelf configuration file
40
11
  {
41
12
  "vagrant": {
42
13
  "omnibus": {
43
- "enabled": true,
44
14
  "version": "11.4.4"
45
15
  },
46
16
  "vm": {
47
- "box": "my_box",
48
- "box_url": "http://files.vagrantup.com/lucid64.box",
17
+ "box": "chef/ubuntu-14.04",
49
18
  "forward_port": {
50
19
  "12345": "54321"
51
20
  }
@@ -55,11 +24,10 @@ Feature: Reading a Berkshelf configuration file
55
24
  """
56
25
  When I successfully run `berks cookbook sparkle_motion`
57
26
  Then the resulting "sparkle_motion" Vagrantfile should contain:
58
- | config.omnibus.chef_version = "11.4.4" |
59
- | config.vm.box = "my_box" |
60
- | config.vm.box_url = "http://files.vagrantup.com/lucid64.box" |
27
+ | config.omnibus.chef_version = '11.4.4' |
28
+ | config.vm.box = 'chef/ubuntu-14.04' |
61
29
  | config.vm.network :forwarded_port, guest: 12345, host: 54321 |
62
- | config.vm.network :private_network, type: "dhcp" |
30
+ | config.vm.network :private_network, type: 'dhcp' |
63
31
  And the exit status should be 0
64
32
 
65
33
  Scenario: Using a Berkshelf configuration file that sets the vagrant-omnibus plugin chef version to latest
@@ -68,12 +36,10 @@ Feature: Reading a Berkshelf configuration file
68
36
  {
69
37
  "vagrant": {
70
38
  "omnibus": {
71
- "enabled": true,
72
39
  "version": "latest"
73
40
  },
74
41
  "vm": {
75
- "box": "my_box",
76
- "box_url": "http://files.vagrantup.com/lucid64.box",
42
+ "box": "chef/ubuntu-14.04",
77
43
  "forward_port": {
78
44
  "12345": "54321"
79
45
  }
@@ -83,11 +49,10 @@ Feature: Reading a Berkshelf configuration file
83
49
  """
84
50
  When I successfully run `berks cookbook sparkle_motion`
85
51
  Then the resulting "sparkle_motion" Vagrantfile should contain:
86
- | config.omnibus.chef_version = :latest |
87
- | config.vm.box = "my_box" |
88
- | config.vm.box_url = "http://files.vagrantup.com/lucid64.box" |
52
+ | config.omnibus.chef_version = 'latest' |
53
+ | config.vm.box = 'chef/ubuntu-14.04' |
89
54
  | config.vm.network :forwarded_port, guest: 12345, host: 54321 |
90
- | config.vm.network :private_network, type: "dhcp" |
55
+ | config.vm.network :private_network, type: 'dhcp' |
91
56
 
92
57
  Scenario: Using a partial Berkshelf configuration file
93
58
  Given I have a Berkshelf config file containing:
@@ -141,6 +106,6 @@ Feature: Reading a Berkshelf configuration file
141
106
  When I successfully run `berks cookbook sparkle_motion`
142
107
  Then the resulting "sparkle_motion" Vagrantfile should contain:
143
108
  | config.vm.provision :chef_client |
144
- | chef.chef_server_url = "localhost:4000" |
145
- | chef.validation_client_name = "my_client-validator" |
146
- | chef.validation_key_path = "/a/b/c/my_client-validator.pem" |
109
+ | chef.chef_server_url = 'localhost:4000' |
110
+ | chef.validation_client_name = 'my_client-validator' |
111
+ | chef.validation_key_path = '/a/b/c/my_client-validator.pem' |
@@ -266,6 +266,6 @@ end
266
266
  Then(/^the directory "(.*?)" should contain version "(.*?)" of the "(.*?)" cookbook$/) do |path, version, name|
267
267
  cookbook_path = File.join(current_dir, path)
268
268
  cookbook = Berkshelf::CachedCookbook.from_path(cookbook_path)
269
- expect(cookbook.version).to eql(version)
270
- expect(cookbook.cookbook_name).to eql(name)
269
+ expect(cookbook.version).to eq(version)
270
+ expect(cookbook.cookbook_name).to eq(name)
271
271
  end
@@ -1,5 +1,7 @@
1
1
  Given /^the gem "(.*)" is not installed$/ do |gem_name|
2
- Gem::Specification.stub(:find_by_name).with(gem_name).and_raise(Gem::LoadError)
2
+ allow(Gem::Specification).to receive(:find_by_name)
3
+ .with(gem_name)
4
+ .and_raise(Gem::LoadError)
3
5
  end
4
6
 
5
7
  Then /^the output should contain a warning to suggest supporting the option "(.*?)" by installing "(.*?)"$/ do |option, gem_name|
@@ -1,5 +1,5 @@
1
- Given /^pending\s+"([^\"]+)"$/ do |msg|
2
- pending
1
+ Given /^skip\s+"([^\"]+)"$/ do |msg|
2
+ skip
3
3
  end
4
4
 
5
5
  Then /the output from \`(.+)\` should be the same as \`(.+)\`/ do |actual, expected|
@@ -2,43 +2,43 @@
2
2
  # vi: set ft=ruby :
3
3
 
4
4
  # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5
- VAGRANTFILE_API_VERSION = "2"
5
+ VAGRANTFILE_API_VERSION = '2'
6
6
 
7
- Vagrant.require_version ">= 1.5.0"
7
+ Vagrant.require_version '>= 1.5.0'
8
8
 
9
9
  Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
10
10
  # All Vagrant configuration is done here. The most common configuration
11
11
  # options are documented and commented below. For a complete reference,
12
12
  # please see the online documentation at vagrantup.com.
13
13
 
14
- config.vm.hostname = "<%= "#{cookbook_name.gsub('_','-')}-berkshelf" %>"
14
+ config.vm.hostname = '<%= "#{cookbook_name.gsub('_','-')}-berkshelf" %>'
15
15
 
16
16
  # Set the version of chef to install using the vagrant-omnibus plugin
17
- <% if berkshelf_config.vagrant.omnibus.enabled -%>
18
- <% if berkshelf_config.vagrant.omnibus.version == "latest" -%>
19
- config.omnibus.chef_version = :latest
20
- <% else %>
21
- config.omnibus.chef_version = "<%= berkshelf_config.vagrant.omnibus.version %>"
22
- <% end -%>
23
- <% else %>
24
- #config.omnibus.chef_version = :latest
25
- <% end -%>
17
+ # NOTE: You will need to install the vagrant-omnibus plugin:
18
+ #
19
+ # $ vagrant plugin install vagrant-omnibus
20
+ #
21
+ if Vagrant.has_plugin?
22
+ config.omnibus.chef_version = '<%= berkshelf_config.vagrant.omnibus.version %>'
23
+ end
26
24
 
27
25
  # Every Vagrant virtual environment requires a box to build off of.
28
- # If this value is a shorthand to a box in Vagrant Cloud then
26
+ # If this value is a shorthand to a box in Vagrant Cloud then
29
27
  # config.vm.box_url doesn't need to be specified.
30
- config.vm.box = "<%= berkshelf_config.vagrant.vm.box %>"
28
+ config.vm.box = '<%= berkshelf_config.vagrant.vm.box %>'
31
29
 
30
+ <% unless berkshelf_config.vagrant.vm.box_url.nil? -%>
32
31
  # The url from where the 'config.vm.box' box will be fetched if it
33
- # is not a Vagrant Cloud box and if it doesn't already exist on the
32
+ # is not a Vagrant Cloud box and if it doesn't already exist on the
34
33
  # user's system.
35
- # config.vm.box_url = "<%= berkshelf_config.vagrant.vm.box_url %>"
34
+ config.vm.box_url = '<%= berkshelf_config.vagrant.vm.box_url %>'
35
+ <% end -%>
36
36
 
37
37
  # Assign this VM to a host-only network IP, allowing you to access it
38
38
  # via the IP. Host-only networks can talk to the host machine as well as
39
39
  # any other machines on the same network, but cannot be accessed (through this
40
40
  # network interface) by any external networks.
41
- config.vm.network :private_network, type: "dhcp"
41
+ config.vm.network :private_network, type: 'dhcp'
42
42
 
43
43
  # Create a forwarded port mapping which allows access to a specific port
44
44
  # within the machine from a port on the host machine. In the example below,
@@ -83,20 +83,20 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
83
83
  # to skip installing and copying to Vagrant's shelf.
84
84
  # config.berkshelf.except = []
85
85
 
86
- <% if berkshelf_config.vagrant.vm.provision == "chef_client" -%>
86
+ <% if berkshelf_config.vagrant.vm.provision == 'chef_client' -%>
87
87
  config.vm.provision :chef_client do |chef|
88
- chef.chef_server_url = "<%= berkshelf_config.chef.chef_server_url %>"
89
- chef.validation_client_name = "<%= berkshelf_config.chef.validation_client_name %>"
90
- chef.validation_key_path = "<%= berkshelf_config.chef.validation_key_path %>"
88
+ chef.chef_server_url = '<%= berkshelf_config.chef.chef_server_url %>'
89
+ chef.validation_client_name = '<%= berkshelf_config.chef.validation_client_name %>'
90
+ chef.validation_key_path = '<%= berkshelf_config.chef.validation_key_path %>'
91
91
 
92
92
  chef.run_list = [
93
- <% if options[:chef_minitest] -%>
94
- "recipe[minitest-handler::default]",
95
- <% end -%>
96
- "recipe[<%= cookbook_name %>::default]"
93
+ <% if options[:chef_minitest] %>
94
+ 'recipe[minitest-handler::default]',
95
+ <% end -%>
96
+ 'recipe[<%= cookbook_name %>::default]'
97
97
  ]
98
98
  end
99
- <% elsif berkshelf_config.vagrant.vm.provision == "chef_solo" -%>
99
+ <% elsif berkshelf_config.vagrant.vm.provision == 'chef_solo' -%>
100
100
  config.vm.provision :chef_solo do |chef|
101
101
  chef.json = {
102
102
  mysql: {
@@ -107,10 +107,10 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
107
107
  }
108
108
 
109
109
  chef.run_list = [
110
- <% if options[:chef_minitest] -%>
111
- "recipe[minitest-handler::default]",
112
- <% end -%>
113
- "recipe[<%= cookbook_name %>::default]"
110
+ <% if options[:chef_minitest] %>
111
+ 'recipe[minitest-handler::default]',
112
+ <% end -%>
113
+ 'recipe[<%= cookbook_name %>::default]'
114
114
  ]
115
115
  end
116
116
  <% end -%>
@@ -9,4 +9,3 @@ version IO.read(File.join(File.dirname(__FILE__), 'VERSION'))
9
9
  <% else -%>
10
10
  version '0.1.0'
11
11
  <% end -%>
12
-
@@ -1,4 +1,5 @@
1
1
  require 'buff/extensions'
2
+ require 'cleanroom'
2
3
  require 'digest/md5'
3
4
  require 'forwardable'
4
5
  require 'json'
@@ -21,11 +22,11 @@ module Berkshelf
21
22
  require_relative 'berkshelf/errors'
22
23
 
23
24
  module Mixin
24
- autoload :DSLEval, 'berkshelf/mixin/dsl_eval'
25
25
  autoload :Git, 'berkshelf/mixin/git'
26
26
  autoload :Logging, 'berkshelf/mixin/logging'
27
27
  end
28
28
 
29
+ autoload :FileSyncer, 'berkshelf/file_syncer'
29
30
  autoload :Shell, 'berkshelf/shell'
30
31
  autoload :Uploader, 'berkshelf/uploader'
31
32
  autoload :Visualizer, 'berkshelf/visualizer'
@@ -67,7 +68,8 @@ module Berkshelf
67
68
  #
68
69
  # @return [String]
69
70
  def berkshelf_path
70
- @berkshelf_path || ENV['BERKSHELF_PATH'] || File.expand_path('~/.berkshelf')
71
+ path = @berkshelf_path || ENV['BERKSHELF_PATH'] || '~/.berkshelf'
72
+ File.expand_path(path)
71
73
  end
72
74
 
73
75
  # The Berkshelf configuration.
@@ -218,6 +220,7 @@ require_relative 'berkshelf/logger'
218
220
  require_relative 'berkshelf/resolver'
219
221
  require_relative 'berkshelf/source'
220
222
  require_relative 'berkshelf/source_uri'
223
+ require_relative 'berkshelf/validator'
221
224
 
222
225
  Ridley.logger = Berkshelf.logger
223
226
  Berkshelf.logger.level = Logger::WARN
@@ -20,7 +20,7 @@ module Berkshelf
20
20
  raise BerksfileNotFound.new(file) unless File.exist?(file)
21
21
 
22
22
  begin
23
- new(file, options).dsl_eval_file(file)
23
+ new(file, options).evaluate_file(file)
24
24
  rescue => ex
25
25
  raise BerksfileReadError.new(ex)
26
26
  end
@@ -30,17 +30,9 @@ module Berkshelf
30
30
  DEFAULT_API_URL = "https://supermarket.getchef.com".freeze
31
31
 
32
32
  include Mixin::Logging
33
- include Mixin::DSLEval
33
+ include Cleanroom
34
34
  extend Forwardable
35
35
 
36
- expose_method :source
37
- expose_method :site # @todo remove in Berkshelf 4.0
38
- expose_method :chef_api # @todo remove in Berkshelf 4.0
39
- expose_method :extension
40
- expose_method :metadata
41
- expose_method :cookbook
42
- expose_method :group
43
-
44
36
  # @return [String]
45
37
  # The path on disk to the file representing this instance of Berksfile
46
38
  attr_reader :filepath
@@ -93,6 +85,7 @@ module Berkshelf
93
85
  raise LoadError, "Could not load an extension by the name `#{name}'. " \
94
86
  "Please make sure it is installed."
95
87
  end
88
+ expose :extension
96
89
 
97
90
  # Add a cookbook dependency to the Berksfile to be retrieved and have its dependencies recursively retrieved
98
91
  # and resolved.
@@ -144,12 +137,14 @@ module Berkshelf
144
137
 
145
138
  add_dependency(name, constraint, options)
146
139
  end
140
+ expose :cookbook
147
141
 
148
142
  def group(*args)
149
143
  @active_group = args
150
144
  yield
151
145
  @active_group = nil
152
146
  end
147
+ expose :group
153
148
 
154
149
  # Use a Cookbook metadata file to determine additional cookbook dependencies to retrieve. All
155
150
  # dependencies found in the metadata will use the default locations set in the Berksfile (if any are set)
@@ -166,6 +161,7 @@ module Berkshelf
166
161
 
167
162
  add_dependency(metadata.name, nil, path: path, metadata: true)
168
163
  end
164
+ expose :metadata
169
165
 
170
166
  # Add a Berkshelf API source to use when building the index of known cookbooks. The indexes will be
171
167
  # searched in the order they are added. If a cookbook is found in the first source then a cookbook
@@ -184,6 +180,7 @@ module Berkshelf
184
180
  def source(api_url)
185
181
  @sources[api_url] = Source.new(api_url)
186
182
  end
183
+ expose :source
187
184
 
188
185
  # @return [Array<Source>]
189
186
  def sources
@@ -217,6 +214,7 @@ module Berkshelf
217
214
  " replaced by the source location. Please remove your site location and try again. For more information " +
218
215
  " visit https://github.com/berkshelf/berkshelf/wiki/deprecated-locations"
219
216
  end
217
+ expose :site
220
218
 
221
219
  # @todo remove in Berkshelf 4.0
222
220
  #
@@ -226,6 +224,7 @@ module Berkshelf
226
224
  " been replaced by the source location. Please remove your site location and try again. For more " +
227
225
  " information visit https://github.com/berkshelf/berkshelf/wiki/deprecated-locations"
228
226
  end
227
+ expose :chef_api
229
228
 
230
229
  # Add a dependency of the given name and constraint to the array of dependencies.
231
230
  #
@@ -566,8 +565,8 @@ module Berkshelf
566
565
  outdir
567
566
  end
568
567
 
569
- # Install the Berksfile or Berksfile.lock and then copy the cached cookbooks into
570
- # directories within the given destination matching their name.
568
+ # Install the Berksfile or Berksfile.lock and then sync the cached cookbooks
569
+ # into directories within the given destination matching their name.
571
570
  #
572
571
  # @param [String] destination
573
572
  # filepath to vendor cookbooks to
@@ -575,16 +574,6 @@ module Berkshelf
575
574
  # @return [String, nil]
576
575
  # the expanded path cookbooks were vendored to or nil if nothing was vendored
577
576
  def vendor(destination)
578
- destination = File.expand_path(destination)
579
-
580
- if Dir.exist?(destination)
581
- raise VendorError, "destination already exists #{destination}. Delete it and try again or use a " +
582
- "different filepath."
583
- end
584
-
585
- # Ensure the parent directory exists, in case a nested path was given
586
- FileUtils.mkdir_p(File.expand_path(File.join(destination, '..')))
587
-
588
577
  scratch = Berkshelf.mktmpdir
589
578
  chefignore = nil
590
579
  cached_cookbooks = install
@@ -593,12 +582,12 @@ module Berkshelf
593
582
 
594
583
  cached_cookbooks.each do |cookbook|
595
584
  Berkshelf.formatter.vendor(cookbook, destination)
596
- cookbook_destination = File.join(scratch, cookbook.cookbook_name, '/')
585
+ cookbook_destination = File.join(scratch, cookbook.cookbook_name)
597
586
  FileUtils.mkdir_p(cookbook_destination)
598
587
 
599
588
  # Dir.glob does not support backslash as a File separator
600
589
  src = cookbook.path.to_s.gsub('\\', '/')
601
- files = Dir.glob(File.join(src, '*'))
590
+ files = FileSyncer.glob(File.join(src, '*'))
602
591
 
603
592
  chefignore = Ridley::Chef::Chefignore.new(cookbook.path.to_s) rescue nil
604
593
  chefignore.apply!(files) if chefignore
@@ -607,30 +596,41 @@ module Berkshelf
607
596
  cookbook.compile_metadata(cookbook_destination)
608
597
  end
609
598
 
610
- # Don't vendor the raw metadata (metadata.rb). The raw metadata is unecessary for the
611
- # client, and this is required until compiled metadata (metadata.json) takes precedence over
612
- # raw metadata in the Chef-Client.
613
- #
614
- # We can change back to including the raw metadata in the future after this has been fixed or
615
- # just remove these comments. There is no circumstance that I can currently think of where
616
- # raw metadata should ever be read by the client.
617
- #
618
- # - Jamie
619
- #
620
- # See the following tickets for more information:
621
- # * https://tickets.opscode.com/browse/CHEF-4811
622
- # * https://tickets.opscode.com/browse/CHEF-4810
623
- files.reject! { |file| File.basename(file) == "metadata.rb" }
624
-
625
599
  FileUtils.cp_r(files, cookbook_destination)
626
600
  end
627
601
 
628
- FileUtils.cp(lockfile.filepath, File.join(scratch, Lockfile::DEFAULT_FILENAME))
602
+ # Don't vendor the raw metadata (metadata.rb). The raw metadata is
603
+ # unecessary for the client, and this is required until compiled metadata
604
+ # (metadata.json) takes precedence over raw metadata in the Chef-Client.
605
+ #
606
+ # We can change back to including the raw metadata in the future after
607
+ # this has been fixed or just remove these comments. There is no
608
+ # circumstance that I can currently think of where raw metadata should
609
+ # ever be read by the client.
610
+ #
611
+ # - Jamie
612
+ #
613
+ # See the following tickets for more information:
614
+ #
615
+ # * https://tickets.opscode.com/browse/CHEF-4811
616
+ # * https://tickets.opscode.com/browse/CHEF-4810
617
+ FileSyncer.sync(scratch, destination, exclude: ["**/*/metadata.rb"])
629
618
 
630
- FileUtils.mv(scratch, destination)
631
619
  destination
632
620
  end
633
621
 
622
+ # Perform a validation with `Validator#validate` on each cached cookbook associated
623
+ # with the Lockfile of this Berksfile.
624
+ #
625
+ # This function will return true or raise the first errors encountered.
626
+ def verify
627
+ validate_lockfile_present!
628
+ validate_lockfile_trusted!
629
+ Berkshelf.formatter.msg "Verifying (#{lockfile.cached.length}) cookbook(s)..."
630
+ Validator.validate(lockfile.cached)
631
+ true
632
+ end
633
+
634
634
  # Visualize the current Berksfile as a "graph" using DOT.
635
635
  #
636
636
  # @param [String] outfile