berkshelf 5.2.0 → 8.0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +19 -47
  3. data/Rakefile +14 -4
  4. data/berkshelf.gemspec +61 -40
  5. data/bin/berks +2 -2
  6. data/lib/berkshelf/api-client.rb +1 -0
  7. data/lib/berkshelf/api_client/chef_server_connection.rb +29 -0
  8. data/lib/berkshelf/api_client/connection.rb +57 -0
  9. data/lib/berkshelf/api_client/errors.rb +10 -0
  10. data/lib/berkshelf/api_client/remote_cookbook.rb +56 -0
  11. data/lib/berkshelf/api_client/version.rb +5 -0
  12. data/lib/berkshelf/api_client.rb +24 -0
  13. data/lib/berkshelf/berksfile.rb +149 -122
  14. data/lib/berkshelf/cached_cookbook.rb +127 -24
  15. data/lib/berkshelf/chef_config_compat.rb +51 -0
  16. data/lib/berkshelf/chef_repo_universe.rb +47 -0
  17. data/lib/berkshelf/cli.rb +143 -174
  18. data/lib/berkshelf/commands/shelf.rb +20 -19
  19. data/lib/berkshelf/community_rest.rb +59 -94
  20. data/lib/berkshelf/config.rb +97 -127
  21. data/lib/berkshelf/cookbook_store.rb +7 -6
  22. data/lib/berkshelf/core_ext/file.rb +1 -1
  23. data/lib/berkshelf/core_ext/file_utils.rb +4 -4
  24. data/lib/berkshelf/core_ext.rb +1 -1
  25. data/lib/berkshelf/dependency.rb +25 -32
  26. data/lib/berkshelf/downloader.rb +66 -39
  27. data/lib/berkshelf/errors.rb +23 -17
  28. data/lib/berkshelf/file_syncer.rb +24 -47
  29. data/lib/berkshelf/formatters/human.rb +7 -5
  30. data/lib/berkshelf/formatters/json.rb +6 -6
  31. data/lib/berkshelf/installer.rb +120 -111
  32. data/lib/berkshelf/location.rb +14 -14
  33. data/lib/berkshelf/locations/base.rb +1 -1
  34. data/lib/berkshelf/locations/git.rb +16 -24
  35. data/lib/berkshelf/locations/github.rb +2 -2
  36. data/lib/berkshelf/locations/path.rb +2 -2
  37. data/lib/berkshelf/lockfile.rb +326 -328
  38. data/lib/berkshelf/logger.rb +64 -1
  39. data/lib/berkshelf/mixin/git.rb +6 -5
  40. data/lib/berkshelf/packager.rb +44 -10
  41. data/lib/berkshelf/resolver/graph.rb +1 -1
  42. data/lib/berkshelf/resolver.rb +4 -4
  43. data/lib/berkshelf/ridley_compat.rb +109 -0
  44. data/lib/berkshelf/shell.rb +2 -1
  45. data/lib/berkshelf/shell_out.rb +18 -0
  46. data/lib/berkshelf/source.rb +77 -33
  47. data/lib/berkshelf/source_uri.rb +4 -4
  48. data/lib/berkshelf/ssl_policies.rb +38 -0
  49. data/lib/berkshelf/thor.rb +1 -1
  50. data/lib/berkshelf/thor_ext/hash_with_indifferent_access.rb +1 -1
  51. data/lib/berkshelf/thor_ext.rb +1 -1
  52. data/lib/berkshelf/uploader.rb +106 -70
  53. data/lib/berkshelf/validator.rb +13 -5
  54. data/lib/berkshelf/version.rb +1 -1
  55. data/lib/berkshelf/visualizer.rb +16 -11
  56. data/lib/berkshelf.rb +106 -81
  57. data/spec/config/knife.rb +4 -4
  58. data/spec/data/trusted_certs/example.crt +22 -0
  59. data/spec/fixtures/Berksfile +3 -3
  60. data/spec/fixtures/complex-cookbook-path/cookbooks/app/metadata.rb +2 -0
  61. data/spec/fixtures/complex-cookbook-path/cookbooks/jenkins/metadata.rb +2 -0
  62. data/spec/fixtures/complex-cookbook-path/cookbooks/jenkins-config/metadata.rb +4 -0
  63. data/spec/fixtures/cookbook-path/jenkins-config/metadata.rb +3 -3
  64. data/spec/fixtures/cookbook-path-uploader/apt-2.3.6/metadata.rb +2 -0
  65. data/spec/fixtures/cookbook-path-uploader/build-essential-1.4.2/metadata.rb +2 -0
  66. data/spec/fixtures/cookbook-path-uploader/jenkins-2.0.3/metadata.rb +5 -0
  67. data/spec/fixtures/cookbook-path-uploader/jenkins-config-0.1.0/metadata.rb +4 -0
  68. data/spec/fixtures/cookbook-path-uploader/runit-1.5.8/metadata.rb +5 -0
  69. data/spec/fixtures/cookbook-path-uploader/yum-3.0.6/metadata.rb +2 -0
  70. data/spec/fixtures/cookbook-path-uploader/yum-epel-0.2.0/metadata.rb +3 -0
  71. data/spec/fixtures/cookbook-store/jenkins-2.0.3/metadata.rb +5 -5
  72. data/spec/fixtures/cookbook-store/jenkins-2.0.4/metadata.rb +4 -4
  73. data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +3 -3
  74. data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +3 -3
  75. data/spec/spec_helper.rb +56 -64
  76. data/spec/support/chef_api.rb +15 -16
  77. data/spec/support/chef_server.rb +71 -69
  78. data/spec/support/git.rb +59 -58
  79. data/spec/support/kitchen.rb +0 -14
  80. data/spec/support/matchers/file_system_matchers.rb +4 -5
  81. data/spec/support/matchers/filepath_matchers.rb +2 -2
  82. data/spec/support/path_helpers.rb +17 -17
  83. data/spec/support/shared_examples/formatter.rb +1 -1
  84. data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/attributes/default.rb +0 -0
  85. data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/files/default/file.h +0 -0
  86. data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/metadata.rb +2 -0
  87. data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/recipes/default.rb +0 -0
  88. data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/templates/default/template.erb +0 -0
  89. data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/attributes/default.rb +0 -0
  90. data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/files/default/file.h +0 -0
  91. data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/metadata.rb +2 -0
  92. data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/recipes/default.rb +0 -0
  93. data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/templates/default/template.erb +0 -0
  94. data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/attributes/default.rb +0 -0
  95. data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/files/default/file.h +0 -0
  96. data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/metadata.rb +2 -0
  97. data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/recipes/default.rb +0 -0
  98. data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/templates/default/template.erb +0 -0
  99. data/spec/unit/berkshelf/berksfile_spec.rb +84 -105
  100. data/spec/unit/berkshelf/berkshelf/api_client/chef_server_connection_spec.rb +65 -0
  101. data/spec/unit/berkshelf/berkshelf/api_client/connection_spec.rb +157 -0
  102. data/spec/unit/berkshelf/berkshelf/api_client/remote_cookbook_spec.rb +23 -0
  103. data/spec/unit/berkshelf/berkshelf/api_client_spec.rb +9 -0
  104. data/spec/unit/berkshelf/cached_cookbook_spec.rb +45 -47
  105. data/spec/unit/berkshelf/chef_repo_universe_spec.rb +37 -0
  106. data/spec/unit/berkshelf/cli_spec.rb +7 -8
  107. data/spec/unit/berkshelf/community_rest_spec.rb +82 -90
  108. data/spec/unit/berkshelf/config_spec.rb +51 -22
  109. data/spec/unit/berkshelf/cookbook_store_spec.rb +41 -41
  110. data/spec/unit/berkshelf/core_ext/file_utils_spec.rb +7 -8
  111. data/spec/unit/berkshelf/core_ext/pathname_spec.rb +1 -1
  112. data/spec/unit/berkshelf/dependency_spec.rb +48 -48
  113. data/spec/unit/berkshelf/downloader_spec.rb +191 -34
  114. data/spec/unit/berkshelf/errors_spec.rb +3 -3
  115. data/spec/unit/berkshelf/file_syncer_spec.rb +87 -87
  116. data/spec/unit/berkshelf/formatters/base_spec.rb +23 -23
  117. data/spec/unit/berkshelf/formatters/human_spec.rb +2 -2
  118. data/spec/unit/berkshelf/formatters/json_spec.rb +2 -2
  119. data/spec/unit/berkshelf/formatters/null_spec.rb +3 -3
  120. data/spec/unit/berkshelf/installer_spec.rb +8 -8
  121. data/spec/unit/berkshelf/location_spec.rb +11 -11
  122. data/spec/unit/berkshelf/locations/base_spec.rb +35 -36
  123. data/spec/unit/berkshelf/locations/git_spec.rb +90 -93
  124. data/spec/unit/berkshelf/locations/path_spec.rb +40 -41
  125. data/spec/unit/berkshelf/lockfile_parser_spec.rb +71 -71
  126. data/spec/unit/berkshelf/lockfile_spec.rb +205 -211
  127. data/spec/unit/berkshelf/logger_spec.rb +3 -3
  128. data/spec/unit/berkshelf/mixin/logging_spec.rb +5 -5
  129. data/spec/unit/berkshelf/packager_spec.rb +2 -2
  130. data/spec/unit/berkshelf/resolver/graph_spec.rb +10 -8
  131. data/spec/unit/berkshelf/resolver_spec.rb +17 -17
  132. data/spec/unit/berkshelf/ridley_compat_spec.rb +16 -0
  133. data/spec/unit/berkshelf/shell_spec.rb +34 -34
  134. data/spec/unit/berkshelf/source_spec.rb +186 -20
  135. data/spec/unit/berkshelf/source_uri_spec.rb +1 -1
  136. data/spec/unit/berkshelf/ssl_policies_spec.rb +86 -0
  137. data/spec/unit/berkshelf/uploader_spec.rb +146 -64
  138. data/spec/unit/berkshelf/validator_spec.rb +23 -16
  139. data/spec/unit/berkshelf/visualizer_spec.rb +24 -15
  140. data/spec/unit/berkshelf_spec.rb +18 -18
  141. metadata +138 -289
  142. data/.gitignore +0 -29
  143. data/.travis.yml +0 -64
  144. data/CHANGELOG.legacy.md +0 -307
  145. data/CHANGELOG.md +0 -1358
  146. data/CONTRIBUTING.md +0 -64
  147. data/Gemfile.lock +0 -399
  148. data/Guardfile +0 -23
  149. data/PLUGINS.md +0 -25
  150. data/README.md +0 -70
  151. data/Thorfile +0 -61
  152. data/appveyor.yml +0 -31
  153. data/docs/berkshelf_for_newcomers.md +0 -65
  154. data/features/berksfile.feature +0 -46
  155. data/features/commands/apply.feature +0 -41
  156. data/features/commands/contingent.feature +0 -48
  157. data/features/commands/cookbook.feature +0 -35
  158. data/features/commands/info.feature +0 -99
  159. data/features/commands/init.feature +0 -27
  160. data/features/commands/install.feature +0 -636
  161. data/features/commands/list.feature +0 -78
  162. data/features/commands/outdated.feature +0 -130
  163. data/features/commands/package.feature +0 -17
  164. data/features/commands/search.feature +0 -17
  165. data/features/commands/shelf/list.feature +0 -32
  166. data/features/commands/shelf/show.feature +0 -143
  167. data/features/commands/shelf/uninstall.feature +0 -96
  168. data/features/commands/show.feature +0 -83
  169. data/features/commands/update.feature +0 -142
  170. data/features/commands/upload.feature +0 -426
  171. data/features/commands/vendor.feature +0 -111
  172. data/features/commands/verify.feature +0 -29
  173. data/features/commands/viz.feature +0 -66
  174. data/features/community_site.feature +0 -37
  175. data/features/config.feature +0 -111
  176. data/features/help.feature +0 -11
  177. data/features/json_formatter.feature +0 -161
  178. data/features/lifecycle.feature +0 -378
  179. data/features/lockfile.feature +0 -378
  180. data/features/step_definitions/berksfile_steps.rb +0 -39
  181. data/features/step_definitions/chef/config_steps.rb +0 -12
  182. data/features/step_definitions/chef_server_steps.rb +0 -60
  183. data/features/step_definitions/cli_steps.rb +0 -18
  184. data/features/step_definitions/config_steps.rb +0 -46
  185. data/features/step_definitions/environment_steps.rb +0 -7
  186. data/features/step_definitions/filesystem_steps.rb +0 -269
  187. data/features/step_definitions/gem_steps.rb +0 -13
  188. data/features/step_definitions/json_steps.rb +0 -23
  189. data/features/step_definitions/utility_steps.rb +0 -11
  190. data/features/support/aruba.rb +0 -12
  191. data/features/support/env.rb +0 -82
  192. data/generator_files/Berksfile.erb +0 -11
  193. data/generator_files/CHANGELOG.md.erb +0 -3
  194. data/generator_files/Gemfile.erb +0 -8
  195. data/generator_files/README.md.erb +0 -42
  196. data/generator_files/Thorfile.erb +0 -11
  197. data/generator_files/Vagrantfile.erb +0 -117
  198. data/generator_files/chefignore +0 -94
  199. data/generator_files/default_recipe.erb +0 -6
  200. data/generator_files/default_test.rb.erb +0 -11
  201. data/generator_files/gitignore.erb +0 -23
  202. data/generator_files/helpers.rb.erb +0 -7
  203. data/generator_files/licenses/apachev2.erb +0 -13
  204. data/generator_files/licenses/gplv2.erb +0 -15
  205. data/generator_files/licenses/gplv3.erb +0 -14
  206. data/generator_files/licenses/mit.erb +0 -20
  207. data/generator_files/licenses/reserved.erb +0 -3
  208. data/generator_files/metadata.rb.erb +0 -11
  209. data/lib/berkshelf/base_generator.rb +0 -43
  210. data/lib/berkshelf/commands/test_command.rb +0 -13
  211. data/lib/berkshelf/cookbook_generator.rb +0 -133
  212. data/lib/berkshelf/init_generator.rb +0 -195
  213. data/spec/fixtures/cookbooks/example_cookbook/.gitignore +0 -2
  214. data/spec/fixtures/cookbooks/example_cookbook/.kitchen.yml +0 -26
  215. data/spec/unit/berkshelf/cookbook_generator_spec.rb +0 -110
  216. data/spec/unit/berkshelf/init_generator_spec.rb +0 -263
@@ -1,7 +1,7 @@
1
1
  module Berkshelf
2
2
  # All tasks that operate on the Berkshelf shelf.
3
3
  class Shelf < Thor
4
- desc 'list', 'List all cookbooks and their versions'
4
+ desc "list", "List all cookbooks and their versions"
5
5
  def list
6
6
  cookbooks = store.cookbooks.inject({}) do |hash, cookbook|
7
7
  (hash[cookbook.cookbook_name] ||= []).push(cookbook.version)
@@ -9,17 +9,17 @@ module Berkshelf
9
9
  end
10
10
 
11
11
  if cookbooks.empty?
12
- Berkshelf.formatter.msg 'There are no cookbooks in the Berkshelf shelf'
12
+ Berkshelf.formatter.msg "There are no cookbooks in the Berkshelf shelf"
13
13
  else
14
- Berkshelf.formatter.msg 'Cookbooks in the Berkshelf shelf:'
14
+ Berkshelf.formatter.msg "Cookbooks in the Berkshelf shelf:"
15
15
  cookbooks.sort.each do |cookbook, versions|
16
- Berkshelf.formatter.msg(" * #{cookbook} (#{versions.sort.join(', ')})")
16
+ Berkshelf.formatter.msg(" * #{cookbook} (#{versions.sort.join(", ")})")
17
17
  end
18
18
  end
19
19
  end
20
20
 
21
- method_option :version, aliases: '-v', type: :string, desc: 'Version to show'
22
- desc 'show', 'Display information about a cookbook in the Berkshelf shelf'
21
+ method_option :version, aliases: "-v", type: :string, desc: "Version to show"
22
+ desc "show", "Display information about a cookbook in the Berkshelf shelf"
23
23
  def show(name)
24
24
  cookbooks = find(name, options[:version])
25
25
 
@@ -35,9 +35,9 @@ module Berkshelf
35
35
  end
36
36
  end
37
37
 
38
- method_option :version, aliases: '-v', type: :string, desc: 'Version to remove'
39
- method_option :force, aliases: '-f', type: :boolean, desc: 'Force removal, even if other cookbooks are contingent', default: false
40
- desc 'uninstall', 'Remove a cookbook from the Berkshelf shelf'
38
+ method_option :version, aliases: "-v", type: :string, desc: "Version to remove"
39
+ method_option :force, aliases: "-f", type: :boolean, desc: "Force removal, even if other cookbooks are contingent", default: false
40
+ desc "uninstall", "Remove a cookbook from the Berkshelf shelf"
41
41
  def uninstall(name)
42
42
  cookbooks = find(name, options[:version])
43
43
  cookbooks.each { |c| uninstall_cookbook(c, options[:force]) }
@@ -67,14 +67,15 @@ module Berkshelf
67
67
  # the list of cookbooks that match the parameters - this is always an
68
68
  # array!
69
69
  def find(name, version = nil)
70
- cookbooks = if version
71
- [store.cookbook(name, version)].compact
72
- else
73
- store.cookbooks(name).sort
74
- end
70
+ cookbooks =
71
+ if version
72
+ [store.cookbook(name, version)].compact
73
+ else
74
+ store.cookbooks(name).sort
75
+ end
75
76
 
76
77
  if cookbooks.empty?
77
- raise CookbookNotFound.new(name, version, 'in the Berkshelf shelf')
78
+ raise CookbookNotFound.new(name, version, "in the Berkshelf shelf")
78
79
  end
79
80
 
80
81
  cookbooks
@@ -95,10 +96,10 @@ module Berkshelf
95
96
  # if contingencies exist
96
97
  def uninstall_cookbook(cookbook, force = false)
97
98
  unless options[:force] || (contingent = contingencies(cookbook)).empty?
98
- contingent = contingent.map { |c| "#{c.cookbook_name} (#{c.version})" }.join(', ')
99
+ contingent = contingent.map { |c| "#{c.cookbook_name} (#{c.version})" }.join(", ")
99
100
  confirm = Berkshelf.ui.ask("[#{contingent}] depend on #{cookbook.cookbook_name}.\n\nAre you sure you want to continue? (y/N)")
100
101
 
101
- exit unless confirm.to_s.upcase[0] == 'Y'
102
+ exit unless confirm.to_s.upcase[0] == "Y"
102
103
  end
103
104
 
104
105
  FileUtils.rm_rf(cookbook.path)
@@ -120,7 +121,7 @@ module Berkshelf
120
121
  end
121
122
 
122
123
  class Cli < Thor
123
- desc 'shelf SUBCOMMAND', 'Interact with the cookbook store'
124
- subcommand 'shelf', Berkshelf::Shelf
124
+ desc "shelf SUBCOMMAND", "Interact with the cookbook store"
125
+ subcommand "shelf", Berkshelf::Shelf
125
126
  end
126
127
  end
@@ -1,9 +1,8 @@
1
- require 'open-uri'
2
- require 'retryable'
3
- require 'mixlib/archive'
1
+ require "retryable" unless defined?(Retryable)
2
+ require "mixlib/archive" unless defined?(Mixlib::Archive)
4
3
 
5
4
  module Berkshelf
6
- class CommunityREST < Faraday::Connection
5
+ class CommunityREST
7
6
  class << self
8
7
  # @param [String] target
9
8
  # file path to the tar.gz archive on disk
@@ -25,30 +24,30 @@ module Berkshelf
25
24
  #
26
25
  # @return [String]
27
26
  def uri_escape_version(version)
28
- version.to_s.gsub('.', '_')
27
+ version.to_s.tr(".", "_")
29
28
  end
30
29
 
31
30
  # @param [String] uri
32
31
  #
33
32
  # @return [String]
34
33
  def version_from_uri(uri)
35
- File.basename(uri.to_s).gsub('_', '.')
34
+ File.basename(uri.to_s).tr("_", ".")
36
35
  end
37
36
 
38
37
  private
39
38
 
40
- def is_gzip_file(path)
41
- # You cannot write "\x1F\x8B" because the default encoding of
42
- # ruby >= 1.9.3 is UTF-8 and 8B is an invalid in UTF-8.
43
- IO.binread(path, 2) == [0x1F, 0x8B].pack("C*")
44
- end
39
+ def is_gzip_file(path)
40
+ # You cannot write "\x1F\x8B" because the default encoding of
41
+ # ruby >= 1.9.3 is UTF-8 and 8B is an invalid in UTF-8.
42
+ IO.binread(path, 2) == [0x1F, 0x8B].pack("C*")
43
+ end
45
44
 
46
- def is_tar_file(path)
47
- IO.binread(path, 8, 257).to_s == "ustar\x0000"
48
- end
45
+ def is_tar_file(path)
46
+ IO.binread(path, 8, 257).to_s == "ustar\x0000"
47
+ end
49
48
  end
50
49
 
51
- V1_API = 'https://supermarket.chef.io'.freeze
50
+ V1_API = "https://supermarket.chef.io".freeze
52
51
 
53
52
  # @return [String]
54
53
  attr_reader :api_uri
@@ -58,6 +57,8 @@ module Berkshelf
58
57
  # @return [Float]
59
58
  # time to wait between retries
60
59
  attr_reader :retry_interval
60
+ # @return [Berkshelf::RidleyCompat]
61
+ attr_reader :connection
61
62
 
62
63
  # @param [String] uri (CommunityREST::V1_API)
63
64
  # location of community site to connect to
@@ -67,23 +68,14 @@ module Berkshelf
67
68
  # @option options [Float] :retry_interval (0.5)
68
69
  # how often we should pause between retries
69
70
  def initialize(uri = V1_API, options = {})
70
- options = options.reverse_merge(retries: 5, retry_interval: 0.5, ssl: Berkshelf::Config.instance.ssl)
71
- @api_uri = uri
72
- @retries = options.delete(:retries)
71
+ options = options.dup
72
+ options = { retries: 5, retry_interval: 0.5, ssl: Berkshelf::Config.instance.ssl }.merge(options)
73
+ @api_uri = uri
74
+ options[:server_url] = uri
75
+ @retries = options.delete(:retries)
73
76
  @retry_interval = options.delete(:retry_interval)
74
77
 
75
- options[:builder] ||= Faraday::RackBuilder.new do |b|
76
- b.response :parse_json
77
- b.response :follow_redirects
78
- b.request :retry,
79
- max: @retries,
80
- interval: @retry_interval,
81
- exceptions: [Faraday::Error::TimeoutError]
82
-
83
- b.adapter :httpclient
84
- end
85
-
86
- super(api_uri, options)
78
+ @connection = Berkshelf::RidleyCompatJSON.new(**options)
87
79
  end
88
80
 
89
81
  # Download and extract target cookbook archive to the local file system,
@@ -97,14 +89,14 @@ module Berkshelf
97
89
  # @return [String, nil]
98
90
  # cookbook filepath, or nil if archive does not contain a cookbook
99
91
  def download(name, version)
100
- archive = stream(find(name, version)[:file])
92
+ archive = stream(find(name, version)["file"])
101
93
  scratch = Dir.mktmpdir
102
94
  extracted = self.class.unpack(archive.path, scratch)
103
95
 
104
96
  if File.cookbook?(extracted)
105
97
  extracted
106
98
  else
107
- Dir.glob(File.join(extracted, '*')).find do |dir|
99
+ Dir.glob("#{extracted}/*").find do |dir|
108
100
  File.cookbook?(dir)
109
101
  end
110
102
  end
@@ -113,50 +105,53 @@ module Berkshelf
113
105
  end
114
106
 
115
107
  def find(name, version)
116
- response = get("cookbooks/#{name}/versions/#{self.class.uri_escape_version(version)}")
117
-
118
- case response.status
119
- when (200..299)
120
- response.body
121
- when 404
122
- raise CookbookNotFound.new(name, nil, "at `#{api_uri}'")
123
- else
124
- raise CommunitySiteError.new(api_uri, "'#{name}' (#{version})")
125
- end
108
+ body = connection.get("cookbooks/#{name}/versions/#{self.class.uri_escape_version(version)}")
109
+
110
+ # Artifactory responds with a 200 and blank body for unknown cookbooks.
111
+ raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") if body.nil?
112
+
113
+ body
114
+ rescue CookbookNotFound
115
+ raise
116
+ rescue Berkshelf::APIClient::ServiceNotFound
117
+ raise CookbookNotFound.new(name, nil, "at `#{api_uri}'")
118
+ rescue
119
+ raise CommunitySiteError.new(api_uri, "'#{name}' (#{version})")
126
120
  end
127
121
 
128
122
  # Returns the latest version of the cookbook and its download link.
129
123
  #
130
124
  # @return [String]
131
125
  def latest_version(name)
132
- response = get("cookbooks/#{name}")
126
+ body = connection.get("cookbooks/#{name}")
133
127
 
134
- case response.status
135
- when (200..299)
136
- self.class.version_from_uri response.body['latest_version']
137
- when 404
138
- raise CookbookNotFound.new(name, nil, "at `#{api_uri}'")
139
- else
140
- raise CommunitySiteError.new(api_uri, "the latest version of '#{name}'")
141
- end
128
+ # Artifactory responds with a 200 and blank body for unknown cookbooks.
129
+ raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") if body.nil?
130
+
131
+ self.class.version_from_uri body["latest_version"]
132
+ rescue Berkshelf::APIClient::ServiceNotFound
133
+ raise CookbookNotFound.new(name, nil, "at `#{api_uri}'")
134
+ rescue
135
+ raise CommunitySiteError.new(api_uri, "the latest version of '#{name}'")
142
136
  end
143
137
 
144
138
  # @param [String] name
145
139
  #
146
140
  # @return [Array]
147
141
  def versions(name)
148
- response = get("cookbooks/#{name}")
142
+ body = connection.get("cookbooks/#{name}")
149
143
 
150
- case response.status
151
- when (200..299)
152
- response.body['versions'].collect do |version_uri|
153
- self.class.version_from_uri(version_uri)
154
- end
155
- when 404
156
- raise CookbookNotFound.new(name, nil, "at `#{api_uri}'")
157
- else
158
- raise CommunitySiteError.new(api_uri, "versions of '#{name}'")
144
+ # Artifactory responds with a 200 and blank body for unknown cookbooks.
145
+ raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") if body.nil?
146
+
147
+ body["versions"].collect do |version_uri|
148
+ self.class.version_from_uri(version_uri)
159
149
  end
150
+
151
+ rescue Berkshelf::APIClient::ServiceNotFound
152
+ raise CookbookNotFound.new(name, nil, "at `#{api_uri}'")
153
+ rescue
154
+ raise CommunitySiteError.new(api_uri, "versions of '#{name}'")
160
155
  end
161
156
 
162
157
  # @param [String] name
@@ -176,43 +171,13 @@ module Berkshelf
176
171
  #
177
172
  # @return [Tempfile]
178
173
  def stream(target)
179
- local = Tempfile.new('community-rest-stream')
174
+ local = Tempfile.new("community-rest-stream")
180
175
  local.binmode
181
-
182
- Retryable.retryable(tries: retries, on: OpenURI::HTTPError, sleep: retry_interval) do
183
- open(target, 'rb', open_uri_options) do |remote|
184
- local.write(remote.read)
185
- end
176
+ Retryable.retryable(tries: retries, on: Berkshelf::APIClientError, sleep: retry_interval) do
177
+ connection.streaming_request(target, {}, local)
186
178
  end
187
-
188
- local
189
179
  ensure
190
180
  local.close(false) unless local.nil?
191
181
  end
192
-
193
- private
194
-
195
- def open_uri_options
196
- options = {}
197
- options.merge!(headers)
198
- options.merge!(open_uri_proxy_options)
199
- options.merge!(ssl_verify_mode: ssl_verify_mode)
200
- end
201
-
202
- def open_uri_proxy_options
203
- if proxy && proxy[:user] && proxy[:password]
204
- {proxy_http_basic_authentication: [ proxy[:uri], proxy[:user], proxy[:password] ]}
205
- else
206
- {}
207
- end
208
- end
209
-
210
- def ssl_verify_mode
211
- if Berkshelf::Config.instance.ssl.verify.nil? || Berkshelf::Config.instance.ssl.verify
212
- OpenSSL::SSL::VERIFY_PEER
213
- else
214
- OpenSSL::SSL::VERIFY_NONE
215
- end
216
- end
217
182
  end
218
183
  end
@@ -1,22 +1,32 @@
1
- require 'buff/config/json'
2
- require 'openssl'
1
+ require "mixlib/config" unless defined?(Mixlib::Config)
2
+ require "openssl" unless defined?(OpenSSL)
3
+
4
+ # we need this method, but have to inject it into mixlib-config directly
5
+ # to have it available from config contexts
6
+ module Mixlib
7
+ module Config
8
+ def each(&block)
9
+ save(true).each(&block)
10
+ end
11
+ end
12
+ end
3
13
 
4
14
  module Berkshelf
5
- class Config < Buff::Config::JSON
15
+ class Config
6
16
  class << self
7
17
  # @return [String]
8
18
  def store_location
9
- File.join(Berkshelf.berkshelf_path, 'config.json')
19
+ File.join(Berkshelf.berkshelf_path, "config.json")
10
20
  end
11
21
 
12
22
  # @return [String]
13
23
  def local_location
14
- ENV['BERKSHELF_CONFIG'] || File.join('.', '.berkshelf', 'config.json')
24
+ ENV["BERKSHELF_CONFIG"] || File.join(".", ".berkshelf", "config.json")
15
25
  end
16
26
 
17
27
  # @return [String]
18
28
  def path
19
- path = File.exists?(local_location) ? local_location : store_location
29
+ path = File.exist?(local_location) ? local_location : store_location
20
30
  File.expand_path(path)
21
31
  end
22
32
 
@@ -30,22 +40,12 @@ module Berkshelf
30
40
  @instance = nil
31
41
  end
32
42
 
33
- # @return [String, nil]
34
- # the contents of the file
35
- def file
36
- File.read(path) if File.exists?(path)
37
- end
38
-
39
43
  # Instantiate and return or just return the currently instantiated Berkshelf
40
44
  # configuration
41
45
  #
42
46
  # @return [Config]
43
47
  def instance
44
- @instance ||= if file
45
- from_json file
46
- else
47
- new
48
- end
48
+ @instance ||= new(path)
49
49
  coerce_ssl
50
50
  end
51
51
 
@@ -54,131 +54,101 @@ module Berkshelf
54
54
  # @return [Config]
55
55
  def reload
56
56
  @instance = nil
57
- self.instance
57
+ instance
58
58
  end
59
-
59
+
60
60
  # force proper X509 types from any configuration strings
61
61
  #
62
62
  # @return [Config]
63
63
  def coerce_ssl
64
- ssl = @instance.ssl
64
+ ssl = @instance[:ssl]
65
65
  ssl[:ca_cert] = OpenSSL::X509::Certificate.new(File.read(ssl[:ca_cert])) if ssl[:ca_cert] && ssl[:ca_cert].is_a?(String)
66
66
  ssl[:client_cert] = OpenSSL::X509::Certificate.new(File.read(ssl[:client_cert])) if ssl[:client_cert] && ssl[:client_cert].is_a?(String)
67
67
  ssl[:client_key] = OpenSSL::PKey::RSA.new(File.read(ssl[:client_key])) if ssl[:client_key] && ssl[:client_key].is_a?(String)
68
68
  @instance
69
69
  end
70
+
71
+ def from_file(path)
72
+ new(path)
73
+ end
70
74
  end
71
75
 
76
+ attr_accessor :path
77
+
72
78
  # @param [String] path
73
- # @param [Hash] options
74
- # @see {Buff::Config::JSON}
75
- def initialize(path = self.class.path, options = {})
76
- super(path, options).tap do
77
- # Deprecation
78
- if !self.vagrant.omnibus.enabled.nil?
79
- Berkshelf.ui.warn "`vagrant.omnibus.enabled' is deprecated and " \
80
- "will be removed in a future release. Please remove the " \
81
- "`enabled' attribute from your Berkshelf config."
82
- end
83
- if !self.vagrant.vm.box_url.nil?
84
- Berkshelf.ui.warn "`vagrant.vm.box_url' is deprecated and " \
85
- "will be removed in a future release. Please remove the " \
86
- "`box_url' attribute from your Berkshelf config."
79
+ def initialize(path = self.class.path)
80
+ # this is a bit tricky, mixlib-config wants to extend a class and create effectively a global config object while
81
+ # what we want to do is use an instance, so we create an anonymous class and shove it into an instance variable.
82
+ # this is actually similar to what mixlib-config itself does to create config contexts.
83
+ @klass = Class.new
84
+ @klass.extend(Mixlib::Config)
85
+ @klass.extend(BerksConfig)
86
+
87
+ @path = File.expand_path(path)
88
+ @klass.from_file(@path) if File.exist?(@path)
89
+ # yeah, if !File.exist?() you just get back an empty config object
90
+
91
+ Berkshelf.ui.warn "The `cookbook.copyright' config is deprecated and will be removed in a future release." unless cookbook.copyright.nil?
92
+ Berkshelf.ui.warn "The `cookbook.email' config is deprecated and will be removed in a future release." unless cookbook.email.nil?
93
+ Berkshelf.ui.warn "The `cookbook.license' config is deprecated and will be removed in a future release." unless cookbook.license.nil?
94
+ Berkshelf.ui.warn "The `vagrant.vm.box' config is deprecated and will be removed in a future release." unless vagrant.vm.box.nil?
95
+ Berkshelf.ui.warn "The `vagrant.vm.forward_port' config is deprecated and will be removed in a future release." unless vagrant.vm.forward_port.nil?
96
+ Berkshelf.ui.warn "The `vagrant.vm.provision' config is deprecated and will be removed in a future release." unless vagrant.vm.provision.nil?
97
+ Berkshelf.ui.warn "The `vagrant.vm.omnibus.version' config is deprecated and will be removed in a future release." unless vagrant.vm.omnibus.version.nil?
98
+ end
99
+
100
+ def method_missing(method, *args, &block)
101
+ @klass.send(method, *args, &block)
102
+ end
103
+
104
+ module BerksConfig
105
+ def self.extended(base)
106
+ base.class_exec do
107
+ config_strict_mode true
108
+ config_context :api do
109
+ default :timeout, "30"
110
+ end
111
+ config_context :chef do
112
+ default :chef_server_url, Berkshelf.chef_config.chef_server_url
113
+ default :validation_client_name, Berkshelf.chef_config.validation_client_name
114
+ default :validation_key_path, Berkshelf.chef_config.validation_key
115
+ default :client_key, Berkshelf.chef_config.client_key
116
+ default :node_name, Berkshelf.chef_config.node_name
117
+ default :trusted_certs_dir, Berkshelf.chef_config.trusted_certs_dir
118
+ default :artifactory_api_key, Berkshelf.chef_config.artifactory_api_key
119
+ end
120
+ config_context :cookbook do
121
+ default :copyright, nil
122
+ default :email, nil
123
+ default :license, nil
124
+ end
125
+ default :allowed_licenses, []
126
+ default :raise_license_exception, false
127
+ config_context :vagrant do
128
+ config_context :vm do
129
+ default :box, nil
130
+ default :forward_port, nil
131
+ default :provision, nil
132
+ config_context :omnibus do
133
+ default :version, nil
134
+ end
135
+ end
136
+ end
137
+ config_context :ssl do
138
+ default :verify, true
139
+ default :cert_store, false
140
+ default :ca_file, nil
141
+ default :ca_path, nil
142
+ default :ca_cert, nil
143
+ default :client_cert, nil
144
+ default :client_key, nil
145
+ end
146
+ default :github, []
147
+ default :gitlab, []
148
+ # :git, :ssh, or :https
149
+ default :github_protocol, :https
87
150
  end
88
151
  end
89
152
  end
90
-
91
- attribute 'api.timeout',
92
- type: String,
93
- default: '30'
94
- attribute 'chef.chef_server_url',
95
- type: String,
96
- default: Berkshelf.chef_config.chef_server_url
97
- attribute 'chef.validation_client_name',
98
- type: String,
99
- default: Berkshelf.chef_config.validation_client_name
100
- attribute 'chef.validation_key_path',
101
- type: String,
102
- default: Berkshelf.chef_config.validation_key
103
- attribute 'chef.client_key',
104
- type: String,
105
- default: Berkshelf.chef_config.client_key
106
- attribute 'chef.node_name',
107
- type: String,
108
- default: Berkshelf.chef_config.node_name
109
- attribute 'cookbook.copyright',
110
- type: String,
111
- default: Berkshelf.chef_config.cookbook_copyright
112
- attribute 'cookbook.email',
113
- type: String,
114
- default: Berkshelf.chef_config.cookbook_email
115
- attribute 'cookbook.license',
116
- type: String,
117
- default: Berkshelf.chef_config.cookbook_license
118
- attribute 'allowed_licenses',
119
- type: Array,
120
- default: Array.new
121
- attribute 'raise_license_exception',
122
- type: Buff::Boolean,
123
- default: false
124
- attribute 'vagrant.vm.box',
125
- type: String,
126
- default: 'bento/ubuntu-14.04',
127
- required: true
128
- # @todo Deprecated, remove?
129
- attribute 'vagrant.vm.box_url',
130
- type: String,
131
- default: nil
132
- attribute 'vagrant.vm.forward_port',
133
- type: Hash,
134
- default: Hash.new
135
- attribute 'vagrant.vm.provision',
136
- type: String,
137
- default: 'chef_solo'
138
- # @todo Deprecated, remove. There's a really weird tri-state here where
139
- # nil is used to represent an unset value, just FYI
140
- attribute 'vagrant.omnibus.enabled',
141
- type: Buff::Boolean,
142
- default: nil
143
- attribute 'vagrant.omnibus.version',
144
- type: String,
145
- default: 'latest'
146
- attribute 'ssl.verify',
147
- type: Buff::Boolean,
148
- default: true,
149
- required: true
150
- attribute 'ssl.cert_store',
151
- type: Buff::Boolean,
152
- default: false,
153
- required: false
154
- attribute 'ssl.ca_file',
155
- type: String,
156
- default: nil,
157
- required: false
158
- attribute 'ssl.ca_path',
159
- type: String,
160
- default: nil,
161
- required: false
162
- attribute 'ssl.client_cert',
163
- type: String,
164
- default: nil,
165
- required: false
166
- attribute 'ssl.client_key',
167
- type: String,
168
- default: nil,
169
- required: false
170
- attribute 'github',
171
- type: Array,
172
- default: [],
173
- required: false
174
- attribute 'gitlab',
175
- type: Array,
176
- default: [],
177
- required: false
178
- attribute 'github_protocol',
179
- # :git, :ssh, or :https
180
- type: Symbol,
181
- default: :https,
182
- required: false
183
153
  end
184
154
  end
@@ -1,4 +1,5 @@
1
- require 'fileutils'
1
+ require "fileutils" unless defined?(FileUtils)
2
+ require "chef/exceptions"
2
3
 
3
4
  module Berkshelf
4
5
  class CookbookStore
@@ -7,7 +8,7 @@ module Berkshelf
7
8
  #
8
9
  # @return [String]
9
10
  def default_path
10
- File.join(Berkshelf.berkshelf_path, 'cookbooks')
11
+ File.join(Berkshelf.berkshelf_path, "cookbooks")
11
12
  end
12
13
 
13
14
  # @return [Berkshelf::CookbookStore]
@@ -48,7 +49,7 @@ module Berkshelf
48
49
 
49
50
  # Destroy the contents of the initialized storage path.
50
51
  def clean!
51
- FileUtils.rm_rf(Dir.glob(File.join(storage_path, '*')))
52
+ FileUtils.rm_rf(Dir.glob("#{storage_path}/*"))
52
53
  end
53
54
 
54
55
  # Import a cookbook found on the local filesystem into this instance of the cookbook store.
@@ -65,7 +66,7 @@ module Berkshelf
65
66
  destination = cookbook_path(name, version)
66
67
  FileUtils.mv(path, destination)
67
68
  cookbook(name, version)
68
- rescue => ex
69
+ rescue
69
70
  FileUtils.rm_f(destination)
70
71
  raise
71
72
  end
@@ -106,7 +107,7 @@ module Berkshelf
106
107
 
107
108
  begin
108
109
  CachedCookbook.from_store_path(path)
109
- rescue Ridley::Errors::MissingNameAttribute
110
+ rescue Chef::Exceptions::MetadataNotValid
110
111
  # Skip cached cookbooks that do not have a name attribute.
111
112
  skipped_cookbooks << File.basename(path)
112
113
  next
@@ -162,7 +163,7 @@ module Berkshelf
162
163
  graph = Solve::Graph.new
163
164
  cookbooks(name).each { |cookbook| graph.artifact(name, cookbook.version) }
164
165
 
165
- name, version = Solve.it!(graph, [[name, constraint]], ENV['DEBUG_RESOLVER'] ? { ui: Berkshelf.ui } : {}).first
166
+ name, version = Solve.it!(graph, [[name, constraint]], ENV["DEBUG_RESOLVER"] ? { ui: Berkshelf.ui } : {}).first
166
167
 
167
168
  cookbook(name, version)
168
169
  rescue Solve::Errors::NoSolutionError
@@ -7,7 +7,7 @@ class File
7
7
  #
8
8
  # @return [Boolean]
9
9
  def cookbook?(path)
10
- File.exists?(File.join(path, "metadata.json")) || File.exists?(File.join(path, "metadata.rb"))
10
+ File.exist?(File.join(path, "metadata.json")) || File.exist?(File.join(path, "metadata.rb"))
11
11
  end
12
12
  alias_method :chef_cookbook?, :cookbook?
13
13
  end