class Berkshelf::Lockfile::Graph

The class representing an internal graph.

Public Class Methods

new(lockfile) click to toggle source

Create a new Lockfile graph.

Some clarifying terminology:

yum-epel (0.2.0) <- lock
  yum (~> 3.0)   <- dependency

@return [Graph]

# File lib/berkshelf/lockfile.rb, line 646
def initialize(lockfile)
  @lockfile  = lockfile
  @berksfile = lockfile.berksfile
  @graph     = {}
end

Public Instance Methods

add(name, version) click to toggle source

Add each a new {GraphItem} to the graph.

@param [#to_s] name

the name of the cookbook

@param [#to_s] version

the version of the lock

@return [GraphItem]

# File lib/berkshelf/lockfile.rb, line 735
def add(name, version)
  @graph[name.to_s] = GraphItem.new(name, version)
end
dependency?(dependency, options = {}) click to toggle source

Determine if this graph contains the given dependency. This method is used by the lockfile when adding or removing dependencies to see if a dependency can be safely removed.

@param [Dependency, String] dependency

the name/dependency to find

@option options [String, Array<String>] :ignore

the list of dependencies to ignore
# File lib/berkshelf/lockfile.rb, line 711
def dependency?(dependency, options = {})
  name   = Dependency.name(dependency)
  ignore = Hash[*Array(options[:ignore]).map { |i| [i, true] }.flatten]

  @graph.values.each do |item|
    next if ignore[item.name]

    if item.dependencies.key?(name)
      return true
    end
  end

  false
end
Also aliased as: has_dependency?
each(&block) click to toggle source

@yield [Hash<String]

# File lib/berkshelf/lockfile.rb, line 653
def each(&block)
  @graph.values.each(&block)
end
find(dependency) click to toggle source

Find a given dependency in the graph.

@param [Dependency, String]

the name/dependency to find

@return [GraphItem, nil]

the item for the name
# File lib/berkshelf/lockfile.rb, line 687
def find(dependency)
  @graph[Dependency.name(dependency)]
end
has_dependency?(dependency, options = {})
Alias for: dependency?
has_lock?(dependency)
Alias for: lock?
lock?(dependency) click to toggle source

Find if the given lock exists?

@param [Dependency, String]

the name/dependency to find

@return [true, false]

# File lib/berkshelf/lockfile.rb, line 697
def lock?(dependency)
  !find(dependency).nil?
end
Also aliased as: has_lock?
locks() click to toggle source

The list of locks for this graph. Dependencies are retrieved from the lockfile, then the Berksfile, and finally a new dependency object is created if none of those exist.

@return [Hash<String, Dependency>]

a key-value hash where the key is the name of the cookbook and the
value is the locked dependency
# File lib/berkshelf/lockfile.rb, line 664
def locks
  @graph.sort.inject({}) do |hash, (name, item)|
    dependency = @lockfile.find(name) ||
      @berksfile && @berksfile.find(name) ||
      Dependency.new(@berksfile, name)

    # We need to make a copy of the dependency, or else we could be
    # modifying an existing object that other processes depend on!
    dependency = dependency.dup
    dependency.locked_version = item.version unless dependency.locked_version

    hash[item.name] = dependency
    hash
  end
end
remove(dependency, options = {}) click to toggle source

Recursively remove any dependencies from the graph unless they exist as top-level dependencies or nested dependencies.

@param [Dependency, String] dependency

the name/dependency to remove

@option options [String, Array<String>] :ignore

the list of dependencies to ignore
# File lib/berkshelf/lockfile.rb, line 747
def remove(dependency, options = {})
  name = Dependency.name(dependency)

  if @lockfile.dependency?(name)
    return
  end

  if dependency?(name, options)
    return
  end

  # Grab the nested dependencies for this particular entry so we can
  # recurse and try to remove them from the graph.
  locked = @graph[name]
  nested_dependencies = locked && locked.dependencies.keys || []

  # Now delete the entry
  @graph.delete(name)

  # Recursively try to delete the remaining dependencies for this item
  nested_dependencies.each(&method(:remove))
end
to_lock() click to toggle source

Write the contents of the graph to the lockfile format.

The resulting format looks like:

GRAPH
  apache2 (1.8.14)
  yum-epel (0.2.0)
    yum (~> 3.0)

@example lockfile.graph.to_lock #=> “GRAPHn apache2 (1.18.14)n…”

@return [String]

# File lib/berkshelf/lockfile.rb, line 800
def to_lock
  out = "#{Lockfile::GRAPH}\n"
  @graph.sort.each do |name, item|
    out << "  #{name} (#{item.version})\n"

    unless item.dependencies.empty?
      item.dependencies.sort.each do |dep_name, constraint|
        out << "    #{dep_name} (#{constraint})\n"
      end
    end
  end

  out
end
update(cookbooks) click to toggle source

Update the graph with the given cookbooks. This method destroys the existing dependency graph with this new result!

@param [Array<CachedCookbook>]

the list of cookbooks to populate the graph with
# File lib/berkshelf/lockfile.rb, line 775
def update(cookbooks)
  @graph = {}

  cookbooks.each do |cookbook|
    @graph[cookbook.cookbook_name.to_s] = GraphItem.new(
      cookbook.cookbook_name,
      cookbook.version,
      cookbook.dependencies
    )
  end
end