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,4 +1,5 @@
1
- require_relative 'dependency'
1
+ require_relative "dependency"
2
+ require "chef/environment"
2
3
 
3
4
  module Berkshelf
4
5
  class Lockfile
@@ -24,10 +25,10 @@ module Berkshelf
24
25
  end
25
26
  end
26
27
 
27
- DEFAULT_FILENAME = 'Berksfile.lock'.freeze
28
+ DEFAULT_FILENAME = "Berksfile.lock".freeze
28
29
 
29
- DEPENDENCIES = 'DEPENDENCIES'.freeze
30
- GRAPH = 'GRAPH'.freeze
30
+ DEPENDENCIES = "DEPENDENCIES".freeze
31
+ GRAPH = "GRAPH".freeze
31
32
 
32
33
  include Berkshelf::Mixin::Logging
33
34
 
@@ -57,7 +58,7 @@ module Berkshelf
57
58
  @dependencies = {}
58
59
  @graph = Graph.new(self)
59
60
 
60
- parse if File.exists?(@filepath)
61
+ parse if File.exist?(@filepath)
61
62
  end
62
63
 
63
64
  # Parse the lockfile.
@@ -75,7 +76,7 @@ module Berkshelf
75
76
  # @return [Boolean]
76
77
  # true if this lockfile exists on the disk, false otherwise
77
78
  def present?
78
- File.exists?(filepath) && !File.read(filepath).strip.empty?
79
+ File.exist?(filepath) && !File.read(filepath).strip.empty?
79
80
  end
80
81
 
81
82
  # Determine if we can "trust" this lockfile. A lockfile is trustworthy if:
@@ -94,7 +95,7 @@ module Berkshelf
94
95
  # @return [Boolean]
95
96
  # true if this lockfile is trusted, false otherwise
96
97
  def trusted?
97
- Berkshelf.log.info 'Checking if lockfile is trusted'
98
+ Berkshelf.log.info "Checking if lockfile is trusted"
98
99
 
99
100
  checked = {}
100
101
 
@@ -113,7 +114,7 @@ module Berkshelf
113
114
  return false
114
115
  end
115
116
 
116
- if cookbook = locked.cached_cookbook
117
+ if ( cookbook = locked.cached_cookbook )
117
118
  Berkshelf.log.debug " Detected there is a cached cookbook"
118
119
 
119
120
  unless (cookbook.dependencies.keys - graphed.dependencies.keys).empty?
@@ -154,7 +155,7 @@ module Berkshelf
154
155
  #
155
156
  # @return [Boolean]
156
157
  def satisfies_transitive?(graph_item, checked, level = 0)
157
- indent = ' '*(level + 2)
158
+ indent = " " * (level + 2)
158
159
 
159
160
  Berkshelf.log.debug "#{indent}Checking transitive dependencies for #{graph_item}"
160
161
 
@@ -203,20 +204,23 @@ module Berkshelf
203
204
  # if you are locking cookbooks with an invalid or not-specified client
204
205
  # configuration
205
206
  def apply(name, options = {})
206
- locks = graph.locks.inject({}) do |hash, (name, dependency)|
207
- hash[name] = "= #{dependency.locked_version.to_s}"
208
- hash
207
+ locks = graph.locks.inject({}) do |hash, (dep_name, dependency)|
208
+ hash[dep_name] = "= #{dependency.locked_version}"
209
+ hash
209
210
  end
210
211
 
211
212
  if options[:envfile]
212
213
  update_environment_file(options[:envfile], locks) if options[:envfile]
213
214
  else
214
215
  Berkshelf.ridley_connection(options) do |connection|
215
- environment = connection.environment.find(name)
216
-
217
- raise EnvironmentNotFound.new(name) if environment.nil?
216
+ environment =
217
+ begin
218
+ Chef::Environment.from_hash(connection.get("environments/#{name}"))
219
+ rescue Berkshelf::APIClient::ServiceNotFound
220
+ raise EnvironmentNotFound.new(name)
221
+ end
218
222
 
219
- environment.cookbook_versions = locks
223
+ environment.cookbook_versions locks
220
224
  environment.save unless options[:envfile]
221
225
  end
222
226
  end
@@ -224,7 +228,7 @@ module Berkshelf
224
228
 
225
229
  # @return [Array<CachedCookbook>]
226
230
  def cached
227
- graph.locks.values.collect { |dependency| dependency.cached_cookbook }
231
+ graph.locks.values.collect(&:cached_cookbook)
228
232
  end
229
233
 
230
234
  # The list of dependencies constrained in this lockfile.
@@ -297,7 +301,7 @@ module Berkshelf
297
301
  unless locked.installed?
298
302
  name = locked.name
299
303
  version = locked.locked_version || locked.version_constraint
300
- raise CookbookNotFound.new(name, version, 'in the cookbook store')
304
+ raise CookbookNotFound.new(name, version, "in the cookbook store")
301
305
  end
302
306
 
303
307
  locked.cached_cookbook
@@ -314,17 +318,17 @@ module Berkshelf
314
318
  # @raise [EnvironmentFileNotFound]
315
319
  # If environment file doesn't exist
316
320
  def update_environment_file(environment_file, locks)
317
- unless File.exists?(environment_file)
321
+ unless File.exist?(environment_file)
318
322
  raise EnvironmentFileNotFound.new(environment_file)
319
323
  end
320
324
 
321
325
  json_environment = JSON.parse(File.read(environment_file))
322
326
 
323
- json_environment['cookbook_versions'] = locks
327
+ json_environment["cookbook_versions"] = locks
324
328
 
325
329
  json = JSON.pretty_generate(json_environment)
326
330
 
327
- File.open(environment_file, 'w'){ |f| f.puts(json) }
331
+ File.open(environment_file, "w") { |f| f.puts(json) }
328
332
 
329
333
  Berkshelf.log.info "Updated environment file #{environment_file}"
330
334
  end
@@ -395,7 +399,6 @@ module Berkshelf
395
399
  end
396
400
  Berkshelf.log.debug ""
397
401
 
398
-
399
402
  # Unlock any locked dependencies that are no longer in the Berksfile
400
403
  Berkshelf.log.debug "Unlocking dependencies no longer in the Berksfile"
401
404
 
@@ -432,7 +435,7 @@ module Berkshelf
432
435
  # constraints are satisfied by it.
433
436
  dependency.locked_version = graphed.version
434
437
 
435
- if cookbook = dependency.cached_cookbook
438
+ if ( cookbook = dependency.cached_cookbook )
436
439
  Berkshelf.log.debug " Cached cookbook exists"
437
440
  Berkshelf.log.debug " Updating cookbook dependencies if required"
438
441
  graphed.set_dependencies(cookbook.dependencies)
@@ -441,11 +444,11 @@ module Berkshelf
441
444
 
442
445
  # Iteratively remove orphan dependencies
443
446
  orphans = true
444
- while orphans do
447
+ while orphans
445
448
  orphans = false
446
449
  graph.each do |cookbook|
447
450
  name = cookbook.name
448
- unless dependency?(name) or graph.dependency?(name)
451
+ unless dependency?(name) || graph.dependency?(name)
449
452
  Berkshelf.log.debug "#{cookbook} identified as orphan; removing it"
450
453
  unlock(name)
451
454
  orphans = true
@@ -461,7 +464,6 @@ module Berkshelf
461
464
  Berkshelf.log.debug ""
462
465
  end
463
466
 
464
-
465
467
  # Write the contents of the current statue of the lockfile to disk. This
466
468
  # method uses an atomic file write. A temporary file is created, written,
467
469
  # and then copied over the existing one. This ensures any partial updates
@@ -473,7 +475,7 @@ module Berkshelf
473
475
  def save
474
476
  return false if dependencies.empty?
475
477
 
476
- tempfile = Tempfile.new(['Berksfile', '.lock'])
478
+ tempfile = Tempfile.new(["Berksfile", ".lock"])
477
479
 
478
480
  tempfile.write(to_lock)
479
481
 
@@ -509,359 +511,355 @@ module Berkshelf
509
511
  "#<Berkshelf::Lockfile #{Pathname.new(filepath).basename}, dependencies: #{dependencies.inspect}>"
510
512
  end
511
513
 
512
- private
514
+ # The class responsible for parsing the lockfile and turning it into a
515
+ # useful data structure.
516
+ class LockfileParser
517
+ NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'.freeze
518
+ DEPENDENCY_PATTERN = /^ {2}#{NAME_VERSION}$/.freeze
519
+ DEPENDENCIES_PATTERN = /^ {4}#{NAME_VERSION}$/.freeze
520
+ OPTION_PATTERN = /^ {4}(.+)\: (.+)/.freeze
513
521
 
514
- # The class responsible for parsing the lockfile and turning it into a
515
- # useful data structure.
516
- class LockfileParser
517
- NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'.freeze
518
- DEPENDENCY_PATTERN = /^ {2}#{NAME_VERSION}$/.freeze
519
- DEPENDENCIES_PATTERN = /^ {4}#{NAME_VERSION}$/.freeze
520
- OPTION_PATTERN = /^ {4}(.+)\: (.+)/.freeze
522
+ # Create a new lockfile parser.
523
+ #
524
+ # @param [Lockfile]
525
+ def initialize(lockfile)
526
+ @lockfile = lockfile
527
+ @berksfile = lockfile.berksfile
528
+ end
521
529
 
522
- # Create a new lockfile parser.
523
- #
524
- # @param [Lockfile]
525
- def initialize(lockfile)
526
- @lockfile = lockfile
527
- @berksfile = lockfile.berksfile
528
- end
530
+ # Parse the lockfile contents, adding the correct things to the lockfile.
531
+ #
532
+ # @return [true]
533
+ def run
534
+ @parsed_dependencies = {}
529
535
 
530
- # Parse the lockfile contents, adding the correct things to the lockfile.
531
- #
532
- # @return [true]
533
- def run
534
- @parsed_dependencies = {}
536
+ contents = File.read(@lockfile.filepath)
535
537
 
536
- contents = File.read(@lockfile.filepath)
538
+ if contents.strip.empty?
539
+ Berkshelf.formatter.warn "Your lockfile at '#{@lockfile.filepath}' " \
540
+ "is empty. I am going to parse it anyway, but there is a chance " \
541
+ "that a larger problem is at play. If you manually edited your " \
542
+ "lockfile, you may have corrupted it."
543
+ end
537
544
 
538
- if contents.strip.empty?
539
- Berkshelf.formatter.warn "Your lockfile at '#{@lockfile.filepath}' " \
540
- "is empty. I am going to parse it anyway, but there is a chance " \
541
- "that a larger problem is at play. If you manually edited your " \
542
- "lockfile, you may have corrupted it."
545
+ if contents.strip[0] == "{"
546
+ Berkshelf.formatter.warn "It looks like you are using an older " \
547
+ "version of the lockfile. Attempting to convert..."
548
+
549
+ dependencies = "#{Lockfile::DEPENDENCIES}\n"
550
+ graph = "#{Lockfile::GRAPH}\n"
551
+
552
+ begin
553
+ hash = JSON.parse(contents)
554
+ rescue JSON::ParserError
555
+ Berkshelf.formatter.warn "Could not convert lockfile! This is a " \
556
+ "problem. You see, previous versions of the lockfile were " \
557
+ "actually a lie. It lied to you about your version locks, and we " \
558
+ "are really sorry about that.\n\n" \
559
+ "Here's the good news - we fixed it!\n\n" \
560
+ "Here's the bad news - you probably should not trust your old " \
561
+ "lockfile. You should manually delete your old lockfile and " \
562
+ "re-run the installer."
543
563
  end
544
564
 
545
- if contents.strip[0] == '{'
546
- Berkshelf.formatter.warn "It looks like you are using an older " \
547
- "version of the lockfile. Attempting to convert..."
548
-
549
- dependencies = "#{Lockfile::DEPENDENCIES}\n"
550
- graph = "#{Lockfile::GRAPH}\n"
551
-
552
- begin
553
- hash = JSON.parse(contents)
554
- rescue JSON::ParserError
555
- Berkshelf.formatter.warn "Could not convert lockfile! This is a " \
556
- "problem. You see, previous versions of the lockfile were " \
557
- "actually a lie. It lied to you about your version locks, and we " \
558
- "are really sorry about that.\n\n" \
559
- "Here's the good news - we fixed it!\n\n" \
560
- "Here's the bad news - you probably should not trust your old " \
561
- "lockfile. You should manually delete your old lockfile and " \
562
- "re-run the installer."
563
- end
564
-
565
- hash['dependencies'] && hash['dependencies'].sort .each do |name, info|
566
- dependencies << " #{name} (>= 0.0.0)\n"
567
- info.each do |key, value|
568
- unless key == 'locked_version'
569
- dependencies << " #{key}: #{value}\n"
570
- end
565
+ hash["dependencies"] && hash["dependencies"].sort .each do |name, info|
566
+ dependencies << " #{name} (>= 0.0.0)\n"
567
+ info.each do |key, value|
568
+ unless key == "locked_version"
569
+ dependencies << " #{key}: #{value}\n"
571
570
  end
572
-
573
- graph << " #{name} (#{info['locked_version']})\n"
574
571
  end
575
572
 
576
- contents = "#{dependencies}\n#{graph}"
577
- end
578
-
579
- contents.split(/(?:\r?\n)+/).each do |line|
580
- if line == Lockfile::DEPENDENCIES
581
- @state = :dependency
582
- elsif line == Lockfile::GRAPH
583
- @state = :graph
584
- else
585
- send("parse_#{@state}", line)
586
- end
573
+ graph << " #{name} (#{info["locked_version"]})\n"
587
574
  end
588
575
 
589
- @parsed_dependencies.each do |name, options|
590
- graph_item = @lockfile.graph.find(name)
591
- options[:locked_version] = graph_item.version if graph_item
576
+ contents = "#{dependencies}\n#{graph}"
577
+ end
592
578
 
593
- dependency = Dependency.new(@berksfile, name, options)
594
- @lockfile.add(dependency)
579
+ contents.split(/(?:\r?\n)+/).each do |line|
580
+ if line == Lockfile::DEPENDENCIES
581
+ @state = :dependency
582
+ elsif line == Lockfile::GRAPH
583
+ @state = :graph
584
+ else
585
+ send("parse_#{@state}", line)
595
586
  end
596
-
597
- true
598
587
  end
599
588
 
600
- private
601
-
602
- # Parse a dependency line.
603
- #
604
- # @param [String] line
605
- def parse_dependency(line)
606
- if line =~ DEPENDENCY_PATTERN
607
- name, version = $1, $2
608
-
609
- @parsed_dependencies[name] ||= {}
610
- @parsed_dependencies[name][:constraint] = version if version
611
- @current_dependency = @parsed_dependencies[name]
612
- elsif line =~ OPTION_PATTERN
613
- key, value = $1, $2
614
- @current_dependency[key.to_sym] = value
615
- end
616
- end
589
+ @parsed_dependencies.each do |name, options|
590
+ graph_item = @lockfile.graph.find(name)
591
+ options[:locked_version] = graph_item.version if graph_item
617
592
 
618
- # Parse a graph line.
619
- #
620
- # @param [String] line
621
- def parse_graph(line)
622
- if line =~ DEPENDENCY_PATTERN
623
- name, version = $1, $2
624
-
625
- @lockfile.graph.find(name) || @lockfile.graph.add(name, version)
626
- @current_lock = name
627
- elsif line =~ DEPENDENCIES_PATTERN
628
- name, constraint = $1, $2
629
- @lockfile.graph.find(@current_lock).add_dependency(name, constraint)
630
- end
631
- end
593
+ dependency = Dependency.new(@berksfile, name, options)
594
+ @lockfile.add(dependency)
595
+ end
596
+
597
+ true
632
598
  end
633
599
 
634
- # The class representing an internal graph.
635
- class Graph
636
- include Enumerable
600
+ private
637
601
 
638
- # Create a new Lockfile graph.
639
- #
640
- # Some clarifying terminology:
641
- #
642
- # yum-epel (0.2.0) <- lock
643
- # yum (~> 3.0) <- dependency
644
- #
645
- # @return [Graph]
646
- def initialize(lockfile)
647
- @lockfile = lockfile
648
- @berksfile = lockfile.berksfile
649
- @graph = {}
602
+ # Parse a dependency line.
603
+ #
604
+ # @param [String] line
605
+ def parse_dependency(line)
606
+ if line =~ DEPENDENCY_PATTERN
607
+ name, version = $1, $2
608
+
609
+ @parsed_dependencies[name] ||= {}
610
+ @parsed_dependencies[name][:constraint] = version if version
611
+ @current_dependency = @parsed_dependencies[name]
612
+ elsif line =~ OPTION_PATTERN
613
+ key, value = $1, $2
614
+ @current_dependency[key.to_sym] = value
650
615
  end
616
+ end
651
617
 
652
- # @yield [Hash<String]
653
- def each(&block)
654
- @graph.values.each(&block)
618
+ # Parse a graph line.
619
+ #
620
+ # @param [String] line
621
+ def parse_graph(line)
622
+ if line =~ DEPENDENCY_PATTERN
623
+ name, version = $1, $2
624
+
625
+ @lockfile.graph.find(name) || @lockfile.graph.add(name, version)
626
+ @current_lock = name
627
+ elsif line =~ DEPENDENCIES_PATTERN
628
+ name, constraint = $1, $2
629
+ @lockfile.graph.find(@current_lock).add_dependency(name, constraint)
655
630
  end
631
+ end
632
+ end
656
633
 
657
- # The list of locks for this graph. Dependencies are retrieved from the
658
- # lockfile, then the Berksfile, and finally a new dependency object is
659
- # created if none of those exist.
660
- #
661
- # @return [Hash<String, Dependency>]
662
- # a key-value hash where the key is the name of the cookbook and the
663
- # value is the locked dependency
664
- def locks
665
- @graph.sort.inject({}) do |hash, (name, item)|
666
- dependency = @lockfile.find(name) ||
667
- @berksfile && @berksfile.find(name) ||
668
- Dependency.new(@berksfile, name)
669
-
670
- # We need to make a copy of the dependency, or else we could be
671
- # modifying an existing object that other processes depend on!
672
- dependency = dependency.dup
673
- dependency.locked_version = item.version unless dependency.locked_version
674
-
675
- hash[item.name] = dependency
676
- hash
677
- end
678
- end
634
+ # The class representing an internal graph.
635
+ class Graph
636
+ include Enumerable
679
637
 
680
- # Find a given dependency in the graph.
681
- #
682
- # @param [Dependency, String]
683
- # the name/dependency to find
684
- #
685
- # @return [GraphItem, nil]
686
- # the item for the name
687
- def find(dependency)
688
- @graph[Dependency.name(dependency)]
689
- end
638
+ # Create a new Lockfile graph.
639
+ #
640
+ # Some clarifying terminology:
641
+ #
642
+ # yum-epel (0.2.0) <- lock
643
+ # yum (~> 3.0) <- dependency
644
+ #
645
+ # @return [Graph]
646
+ def initialize(lockfile)
647
+ @lockfile = lockfile
648
+ @berksfile = lockfile.berksfile
649
+ @graph = {}
650
+ end
690
651
 
691
- # Find if the given lock exists?
692
- #
693
- # @param [Dependency, String]
694
- # the name/dependency to find
695
- #
696
- # @return [true, false]
697
- def lock?(dependency)
698
- !find(dependency).nil?
652
+ # @yield [Hash<String]
653
+ def each(&block)
654
+ @graph.values.each(&block)
655
+ end
656
+
657
+ # The list of locks for this graph. Dependencies are retrieved from the
658
+ # lockfile, then the Berksfile, and finally a new dependency object is
659
+ # created if none of those exist.
660
+ #
661
+ # @return [Hash<String, Dependency>]
662
+ # a key-value hash where the key is the name of the cookbook and the
663
+ # value is the locked dependency
664
+ def locks
665
+ @graph.sort.inject({}) do |hash, (name, item)|
666
+ dependency = @lockfile.find(name) ||
667
+ @berksfile && @berksfile.find(name) ||
668
+ Dependency.new(@berksfile, name)
669
+
670
+ # We need to make a copy of the dependency, or else we could be
671
+ # modifying an existing object that other processes depend on!
672
+ dependency = dependency.dup
673
+ dependency.locked_version = item.version unless dependency.locked_version
674
+
675
+ hash[item.name] = dependency
676
+ hash
699
677
  end
700
- alias_method :has_lock?, :lock?
678
+ end
701
679
 
702
- # Determine if this graph contains the given dependency. This method is
703
- # used by the lockfile when adding or removing dependencies to see if a
704
- # dependency can be safely removed.
705
- #
706
- # @param [Dependency, String] dependency
707
- # the name/dependency to find
708
- #
709
- # @option options [String, Array<String>] :ignore
710
- # the list of dependencies to ignore
711
- def dependency?(dependency, options = {})
712
- name = Dependency.name(dependency)
713
- ignore = Hash[*Array(options[:ignore]).map { |i| [i, true] }.flatten]
680
+ # Find a given dependency in the graph.
681
+ #
682
+ # @param [Dependency, String]
683
+ # the name/dependency to find
684
+ #
685
+ # @return [GraphItem, nil]
686
+ # the item for the name
687
+ def find(dependency)
688
+ @graph[Dependency.name(dependency)]
689
+ end
690
+
691
+ # Find if the given lock exists?
692
+ #
693
+ # @param [Dependency, String]
694
+ # the name/dependency to find
695
+ #
696
+ # @return [true, false]
697
+ def lock?(dependency)
698
+ !find(dependency).nil?
699
+ end
700
+ alias_method :has_lock?, :lock?
701
+
702
+ # Determine if this graph contains the given dependency. This method is
703
+ # used by the lockfile when adding or removing dependencies to see if a
704
+ # dependency can be safely removed.
705
+ #
706
+ # @param [Dependency, String] dependency
707
+ # the name/dependency to find
708
+ #
709
+ # @option options [String, Array<String>] :ignore
710
+ # the list of dependencies to ignore
711
+ def dependency?(dependency, options = {})
712
+ name = Dependency.name(dependency)
713
+ ignore = Hash[*Array(options[:ignore]).map { |i| [i, true] }.flatten]
714
714
 
715
- @graph.values.each do |item|
716
- next if ignore[item.name]
715
+ @graph.values.each do |item|
716
+ next if ignore[item.name]
717
717
 
718
- if item.dependencies.key?(name)
719
- return true
720
- end
718
+ if item.dependencies.key?(name)
719
+ return true
721
720
  end
722
-
723
- false
724
721
  end
725
- alias_method :has_dependency?, :dependency?
726
722
 
727
- # Add each a new {GraphItem} to the graph.
728
- #
729
- # @param [#to_s] name
730
- # the name of the cookbook
731
- # @param [#to_s] version
732
- # the version of the lock
733
- #
734
- # @return [GraphItem]
735
- def add(name, version)
736
- @graph[name.to_s] = GraphItem.new(name, version)
737
- end
723
+ false
724
+ end
725
+ alias_method :has_dependency?, :dependency?
738
726
 
739
- # Recursively remove any dependencies from the graph unless they exist as
740
- # top-level dependencies or nested dependencies.
741
- #
742
- # @param [Dependency, String] dependency
743
- # the name/dependency to remove
744
- #
745
- # @option options [String, Array<String>] :ignore
746
- # the list of dependencies to ignore
747
- def remove(dependency, options = {})
748
- name = Dependency.name(dependency)
727
+ # Add each a new {GraphItem} to the graph.
728
+ #
729
+ # @param [#to_s] name
730
+ # the name of the cookbook
731
+ # @param [#to_s] version
732
+ # the version of the lock
733
+ #
734
+ # @return [GraphItem]
735
+ def add(name, version)
736
+ @graph[name.to_s] = GraphItem.new(name, version)
737
+ end
749
738
 
750
- if @lockfile.dependency?(name)
751
- return
752
- end
739
+ # Recursively remove any dependencies from the graph unless they exist as
740
+ # top-level dependencies or nested dependencies.
741
+ #
742
+ # @param [Dependency, String] dependency
743
+ # the name/dependency to remove
744
+ #
745
+ # @option options [String, Array<String>] :ignore
746
+ # the list of dependencies to ignore
747
+ def remove(dependency, options = {})
748
+ name = Dependency.name(dependency)
753
749
 
754
- if dependency?(name, options)
755
- return
756
- end
750
+ if @lockfile.dependency?(name)
751
+ return
752
+ end
757
753
 
758
- # Grab the nested dependencies for this particular entry so we can
759
- # recurse and try to remove them from the graph.
760
- locked = @graph[name]
761
- nested_dependencies = locked && locked.dependencies.keys || []
754
+ if dependency?(name, options)
755
+ return
756
+ end
757
+
758
+ # Grab the nested dependencies for this particular entry so we can
759
+ # recurse and try to remove them from the graph.
760
+ locked = @graph[name]
761
+ nested_dependencies = locked && locked.dependencies.keys || []
762
762
 
763
- # Now delete the entry
764
- @graph.delete(name)
763
+ # Now delete the entry
764
+ @graph.delete(name)
765
+
766
+ # Recursively try to delete the remaining dependencies for this item
767
+ nested_dependencies.each(&method(:remove))
768
+ end
765
769
 
766
- # Recursively try to delete the remaining dependencies for this item
767
- nested_dependencies.each(&method(:remove))
770
+ # Update the graph with the given cookbooks. This method destroys the
771
+ # existing dependency graph with this new result!
772
+ #
773
+ # @param [Array<CachedCookbook>]
774
+ # the list of cookbooks to populate the graph with
775
+ def update(cookbooks)
776
+ @graph = {}
777
+
778
+ cookbooks.each do |cookbook|
779
+ @graph[cookbook.cookbook_name.to_s] = GraphItem.new(
780
+ cookbook.cookbook_name,
781
+ cookbook.version,
782
+ cookbook.dependencies
783
+ )
768
784
  end
785
+ end
769
786
 
770
- # Update the graph with the given cookbooks. This method destroys the
771
- # existing dependency graph with this new result!
772
- #
773
- # @param [Array<CachedCookbook>]
774
- # the list of cookbooks to populate the graph with
775
- def update(cookbooks)
776
- @graph = {}
777
-
778
- cookbooks.each do |cookbook|
779
- @graph[cookbook.cookbook_name.to_s] = GraphItem.new(
780
- cookbook.cookbook_name,
781
- cookbook.version,
782
- cookbook.dependencies,
783
- )
787
+ # Write the contents of the graph to the lockfile format.
788
+ #
789
+ # The resulting format looks like:
790
+ #
791
+ # GRAPH
792
+ # apache2 (1.8.14)
793
+ # yum-epel (0.2.0)
794
+ # yum (~> 3.0)
795
+ #
796
+ # @example lockfile.graph.to_lock #=> "GRAPH\n apache2 (1.18.14)\n..."
797
+ #
798
+ # @return [String]
799
+ #
800
+ def to_lock
801
+ out = "#{Lockfile::GRAPH}\n"
802
+ @graph.sort.each do |name, item|
803
+ out << " #{name} (#{item.version})\n"
804
+
805
+ unless item.dependencies.empty?
806
+ item.dependencies.sort.each do |dep_name, constraint|
807
+ out << " #{dep_name} (#{constraint})\n"
808
+ end
784
809
  end
785
810
  end
786
811
 
787
- # Write the contents of the graph to the lockfile format.
788
- #
789
- # The resulting format looks like:
790
- #
791
- # GRAPH
792
- # apache2 (1.8.14)
793
- # yum-epel (0.2.0)
794
- # yum (~> 3.0)
795
- #
796
- # @example lockfile.graph.to_lock #=> "GRAPH\n apache2 (1.18.14)\n..."
812
+ out
813
+ end
814
+
815
+ # A single item inside the graph.
816
+ class GraphItem
817
+ # The name of the cookbook that corresponds to this graph item.
797
818
  #
798
819
  # @return [String]
820
+ # the name of the cookbook
821
+ attr_reader :name
822
+
823
+ # The locked version for this graph item.
799
824
  #
800
- def to_lock
801
- out = "#{Lockfile::GRAPH}\n"
802
- @graph.sort.each do |name, item|
803
- out << " #{name} (#{item.version})\n"
804
-
805
- unless item.dependencies.empty?
806
- item.dependencies.sort.each do |name, constraint|
807
- out << " #{name} (#{constraint})\n"
808
- end
809
- end
810
- end
825
+ # @return [String]
826
+ # the locked version of the graph item (as a string)
827
+ attr_reader :version
811
828
 
812
- out
829
+ # The list of dependencies and their constraints.
830
+ #
831
+ # @return [Hash<String, String>]
832
+ # the list of dependencies for this graph item, where the key
833
+ # corresponds to the name of the dependency and the value is the
834
+ # version constraint.
835
+ attr_reader :dependencies
836
+
837
+ # Create a new graph item.
838
+ def initialize(name, version, dependencies = {})
839
+ @name = name.to_s
840
+ @version = version.to_s
841
+ @dependencies = dependencies
813
842
  end
814
843
 
815
- private
816
-
817
- # A single item inside the graph.
818
- class GraphItem
819
- # The name of the cookbook that corresponds to this graph item.
820
- #
821
- # @return [String]
822
- # the name of the cookbook
823
- attr_reader :name
824
-
825
- # The locked version for this graph item.
826
- #
827
- # @return [String]
828
- # the locked version of the graph item (as a string)
829
- attr_reader :version
830
-
831
- # The list of dependencies and their constraints.
832
- #
833
- # @return [Hash<String, String>]
834
- # the list of dependencies for this graph item, where the key
835
- # corresponds to the name of the dependency and the value is the
836
- # version constraint.
837
- attr_reader :dependencies
838
-
839
- # Create a new graph item.
840
- def initialize(name, version, dependencies = {})
841
- @name = name.to_s
842
- @version = version.to_s
843
- @dependencies = dependencies
844
- end
845
-
846
- # Add a new dependency to the list.
847
- #
848
- # @param [#to_s] name
849
- # the name to use
850
- # @param [#to_s] constraint
851
- # the version constraint to use
852
- def add_dependency(name, constraint)
853
- @dependencies[name.to_s] = constraint.to_s
854
- end
844
+ # Add a new dependency to the list.
845
+ #
846
+ # @param [#to_s] name
847
+ # the name to use
848
+ # @param [#to_s] constraint
849
+ # the version constraint to use
850
+ def add_dependency(name, constraint)
851
+ @dependencies[name.to_s] = constraint.to_s
852
+ end
855
853
 
856
- def set_dependencies(dependencies)
857
- @dependencies = dependencies.to_hash
858
- end
854
+ def set_dependencies(dependencies)
855
+ @dependencies = dependencies.to_hash
856
+ end
859
857
 
860
- # @private
861
- def to_s
862
- "#{name} (#{version})"
863
- end
864
- end
858
+ # @private
859
+ def to_s
860
+ "#{name} (#{version})"
861
+ end
865
862
  end
863
+ end
866
864
  end
867
865
  end