lib/berkshelf/lockfile.rb in berkshelf-3.0.0.beta3 vs lib/berkshelf/lockfile.rb in berkshelf-3.0.0.beta4
- old
+ new
@@ -3,10 +3,33 @@
module Berkshelf
# The object representation of the Berkshelf lockfile. The lockfile is useful
# when working in teams where the same cookbook versions are desired across
# multiple workstations.
class Lockfile
+ class << self
+ # Initialize a Lockfile from the given filepath
+ #
+ # @param [String] filepath
+ # filepath to the lockfile
+ def from_file(filepath)
+ new(filepath: filepath)
+ end
+
+ # Initialize a Lockfile from the given Berksfile
+ #
+ # @param [Berkshelf::Berksfile] berksfile
+ # the Berksfile associated with the Lockfile
+ def from_berksfile(berksfile)
+ filepath = File.join(File.dirname(File.expand_path(berksfile.filepath)), Lockfile::DEFAULT_FILENAME)
+ new(berksfile: berksfile, filepath: filepath)
+ end
+ end
+
+ DEFAULT_FILENAME = "Berksfile.lock"
+
+ include Berkshelf::Mixin::Logging
+
# @return [Pathname]
# the path to this Lockfile
attr_reader :filepath
# @return [Berkshelf::Berksfile]
@@ -15,17 +38,56 @@
# Create a new lockfile instance associated with the given Berksfile. If a
# Lockfile exists, it is automatically loaded. Otherwise, an empty instance is
# created and ready for use.
#
- # @param berksfile [Berkshelf::Berksfile]
+ # @option options [String] :filepath
+ # filepath to the lockfile
+ # @option options [Berkshelf::Berksfile] :berksfile
# the Berksfile associated with this Lockfile
- def initialize(berksfile)
- @berksfile = berksfile
- @filepath = File.expand_path("#{berksfile.filepath}.lock")
+ def initialize(options = {})
+ @filepath = options[:filepath].to_s
+ @berksfile = options[:berksfile]
@dependencies = {}
load! if File.exists?(@filepath)
+ end
+
+ # Resolve this Berksfile and apply the locks found in the generated Berksfile.lock to the
+ # target Chef environment
+ #
+ # @param [String] environment_name
+ #
+ # @option options [Hash] :ssl_verify (true)
+ # Disable/Enable SSL verification during uploads
+ #
+ # @raise [EnvironmentNotFound]
+ # if the target environment was not found
+ # @raise [ChefConnectionError]
+ # if you are locking cookbooks with an invalid or not-specified client configuration
+ def apply(environment_name, options = {})
+ Berkshelf.ridley_connection(options) do |conn|
+ unless environment = conn.environment.find(environment_name)
+ raise EnvironmentNotFound.new(environment_name)
+ end
+
+ environment.cookbook_versions = {}.tap do |cookbook_versions|
+ dependencies.each do |dependency|
+ if dependency.locked_version.nil?
+ # A locked version must be present for each entry. Older versions of the lockfile
+ # may have contained dependencies with a special type of location that would attempt
+ # to dynamically determine the locked version. This is incorrect and the Lockfile
+ # should be regenerated if that is the case.
+ raise InvalidLockFile, "Your lockfile contains a dependency without a locked version. This " +
+ "may be because you have an old lockfile. Regenerate your lockfile and try again."
+ end
+
+ cookbook_versions[dependency.name] = "= #{dependency.locked_version.to_s}"
+ end
+ end
+
+ environment.save
+ end
end
# Load the lockfile from file system.
def load!
contents = File.read(filepath).strip