lib/berkshelf/lockfile.rb in berkshelf-2.0.18 vs lib/berkshelf/lockfile.rb in berkshelf-3.0.0.beta1
- old
+ new
@@ -1,12 +1,12 @@
+require_relative 'dependency'
+
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
- require_relative 'cookbook_source'
-
# @return [Pathname]
# the path to this Lockfile
attr_reader :filepath
# @return [Berkshelf::Berksfile]
@@ -18,28 +18,28 @@
# created and ready for use.
#
# @param berksfile [Berkshelf::Berksfile]
# the Berksfile associated with this Lockfile
def initialize(berksfile)
- @berksfile = berksfile
- @filepath = File.expand_path("#{berksfile.filepath}.lock")
- @sources = {}
+ @berksfile = berksfile
+ @filepath = File.expand_path("#{berksfile.filepath}.lock")
+ @dependencies = {}
load! if File.exists?(@filepath)
end
# Load the lockfile from file system.
def load!
contents = File.read(filepath).strip
- hash = parse(contents)
+ hash = parse(contents)
- hash[:sources].each do |name, options|
+ hash[:dependencies].each do |name, options|
# Dynamically calculate paths relative to the Berksfile if a path is given
options[:path] &&= File.expand_path(options[:path], File.dirname(filepath))
begin
- add(CookbookSource.new(berksfile, name.to_s, options))
+ add(Berkshelf::Dependency.new(berksfile, name.to_s, options))
rescue Berkshelf::CookbookNotFound
# It's possible that a source is locked that contains a path location, and
# that path location was renamed or no longer exists. When loading the
# lockfile, Berkshelf will throw an error if it can't find a cookbook that
# previously existed at a path location.
@@ -47,75 +47,74 @@
end
end
# The list of sources constrained in this lockfile.
#
- # @return [Array<Berkshelf::CookbookSource>]
- # the list of sources in this lockfile
- def sources
- @sources.values
+ # @return [Array<Berkshelf::Dependency>]
+ # the list of dependencies in this lockfile
+ def dependencies
+ @dependencies.values
end
- # Find the given source in this lockfile. This method accepts a source
+ # Find the given dependency in this lockfile. This method accepts a dependency
# attribute which may either be the name of a cookbook (String) or an
- # actual cookbook source.
+ # actual cookbook dependency.
#
- # @param [String, Berkshelf::CookbookSource] source
- # the cookbook source/name to find
- # @return [CookbookSource, nil]
- # the cookbook source from this lockfile or nil if one was not found
- def find(source)
- @sources[cookbook_name(source).to_s]
+ # @param [String, Berkshelf::Dependency] dependency
+ # the cookbook dependency/name to find
+ # @return [Berkshelf::Dependency, nil]
+ # the cookbook dependency from this lockfile or nil if one was not found
+ def find(dependency)
+ @dependencies[cookbook_name(dependency).to_s]
end
- # Determine if this lockfile contains the given source.
+ # Determine if this lockfile contains the given dependency.
#
- # @param [String, Berkshelf::CookbookSource] source
- # the cookbook source/name to determine existence of
+ # @param [String, Berkshelf::Dependency] dependency
+ # the cookbook dependency/name to determine existence of
# @return [Boolean]
- # true if the source exists, false otherwise
- def has_source?(source)
- !find(source).nil?
+ # true if the dependency exists, false otherwise
+ def has_dependency?(dependency)
+ !find(dependency).nil?
end
- # Replace the current list of sources with `sources`. This method does
+ # Replace the current list of dependencies with `dependencies`. This method does
# not write out the lockfile - it only changes the state of the object.
#
- # @param [Array<Berkshelf::CookbookSource>] sources
- # the list of sources to update
- # @option options [String] :sha
- # the sha of the Berksfile updating the sources
- def update(sources)
- reset_sources!
- sources.each { |source| append(source) }
+ # @param [Array<Berkshelf::Dependency>] dependencies
+ # the list of dependencies to update
+ def update(dependencies)
+ reset_dependencies!
+
+ dependencies.each { |dependency| append(dependency) }
save
end
- # Add the given source to the `sources` list, if it doesn't already exist.
+ # Add the given dependency to the `dependencies` list, if it doesn't already exist.
#
- # @param [Berkshelf::CookbookSource] source
- # the source to append to the sources list
- def add(source)
- @sources[cookbook_name(source)] = source
+ # @param [Berkshelf::Dependency] dependency
+ # the dependency to append to the dependencies list
+ def add(dependency)
+ @dependencies[cookbook_name(dependency)] = dependency
end
alias_method :append, :add
- # Remove the given source from this lockfile. This method accepts a source
+ # Remove the given dependency from this lockfile. This method accepts a dependency
# attribute which may either be the name of a cookbook (String) or an
- # actual cookbook source.
+ # actual cookbook dependency.
#
- # @param [String, Berkshelf::CookbookSource] source
- # the cookbook source/name to remove
+ # @param [String, Berkshelf::Dependency] dependency
+ # the cookbook dependency/name to remove
#
# @raise [Berkshelf::CookbookNotFound]
- # if the provided source does not exist
- def remove(source)
- unless has_source?(source)
- raise Berkshelf::CookbookNotFound, "'#{cookbook_name(source)}' does not exist in this lockfile!"
+ # if the provided dependency does not exist
+ def remove(dependency)
+ unless has_dependency?(dependency)
+ raise Berkshelf::CookbookNotFound, "'#{cookbook_name(dependency)}' does not exist in this lockfile!"
end
- @sources.delete(cookbook_name(source))
+ @dependencies.delete(cookbook_name(dependency))
end
alias_method :unlock, :remove
# @return [String]
# the string representation of the lockfile
@@ -124,21 +123,21 @@
end
# @return [String]
# the detailed string representation of the lockfile
def inspect
- "#<Berkshelf::Lockfile #{Pathname.new(filepath).basename}, sources: #{sources.inspect}>"
+ "#<Berkshelf::Lockfile #{Pathname.new(filepath).basename}, dependencies: #{dependencies.inspect}>"
end
# Write the current lockfile to a hash
#
# @return [Hash]
# the hash representation of this lockfile
- # * :sources [Array<Berkshelf::CookbookSource>] the list of sources
+ # * :dependencies [Array<Berkshelf::Dependency>] the list of dependencies
def to_hash
{
- sources: @sources
+ dependencies: @dependencies
}
end
# The JSON representation of this lockfile
#
@@ -157,16 +156,27 @@
# @param [String] contents
#
# @return [Hash]
def parse(contents)
# Ruby's JSON.parse cannot handle an empty string/file
- return { sha: nil, sources: [] } if contents.strip.empty?
+ return { dependencies: [] } if contents.strip.empty?
- JSON.parse(contents, symbolize_names: true)
+ hash = JSON.parse(contents, symbolize_names: true)
+
+ # Legacy support for 2.0 lockfiles
+ # @todo Remove in 4.0
+ if hash[:sources]
+ LockfileLegacy.warn!
+ hash[:dependencies] = hash.delete(:sources)
+ end
+
+ return hash
rescue Exception => e
+ # Legacy support for 1.0 lockfiles
+ # @todo Remove in 4.0
if e.class == JSON::ParserError && contents =~ /^cookbook ["'](.+)["']/
- Berkshelf.ui.warn 'You are using the old lockfile format. Attempting to convert...'
+ LockfileLegacy.warn!
return LockfileLegacy.parse(berksfile, contents)
else
raise Berkshelf::LockfileParserError.new(filepath, e)
end
end
@@ -176,54 +186,66 @@
File.open(filepath, 'w') do |file|
file.write to_json + "\n"
end
end
- # Clear the sources array
- def reset_sources!
- @sources = {}
+ def reset_dependencies!
+ @dependencies = {}
end
# Return the name of this cookbook (because it's the key in our
# table).
#
- # @param [Berkshelf::CookbookSource, #to_s] source
- # the source to find the name from
+ # @param [Berkshelf::Dependency, #to_s] dependency
+ # the dependency to find the name from
#
# @return [String]
# the name of the cookbook
- def cookbook_name(source)
- source.is_a?(CookbookSource) ? source.name : source.to_s
+ def cookbook_name(dependency)
+ dependency.is_a?(Berkshelf::Dependency) ? dependency.name : dependency.to_s
end
# Legacy support for old lockfiles
#
# @todo Remove this class in Berkshelf 3.0.0
class LockfileLegacy
- require 'pathname'
-
class << self
# Read the old lockfile content and instance eval in context.
#
# @param [Berkshelf::Berksfile] berksfile
# the associated berksfile
# @param [String] content
# the string content read from a legacy lockfile
def parse(berksfile, content)
- sources = {}.tap do |hash|
+ dependencies = {}.tap do |hash|
content.split("\n").each do |line|
next if line.empty?
-
- source = self.new(berksfile, line)
+ source = new(berksfile, line)
hash[source.name] = source.options
end
end
{
- sources: sources,
+ dependencies: dependencies,
}
end
+
+ # Warn the user they he/she is using an old Lockfile format.
+ #
+ # This automatically outputs to the {Berkshelf.ui}; nothing is
+ # returned.
+ #
+ # @return [nil]
+ def warn!
+ Berkshelf.ui.warn(warning_message)
+ end
+
+ private
+ # @return [String]
+ def warning_message
+ 'You are using the old lockfile format. Attempting to convert...'
+ end
end
# @return [Hash]
# the hash of options
attr_reader :options
@@ -243,22 +265,22 @@
def initialize(berksfile, content)
@berksfile = berksfile
instance_eval(content).to_hash
end
- # Method defined in legacy lockfiles (since we are using
- # instance_eval).
+ # Method defined in legacy lockfiles (since we are using instance_eval).
#
# @param [String] name
# the name of this cookbook
# @option options [String] :locked_version
# the locked version of this cookbook
def cookbook(name, options = {})
- @name = name
+ @name = name
@options = manipulate(options)
end
private
+
# Perform various manipulations on the hash.
#
# @param [Hash] options
def manipulate(options = {})
if options[:path]