Class: Berkshelf::Lockfile::Graph

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/berkshelf/lockfile.rb

Overview

The class representing an internal graph.

Defined Under Namespace

Classes: GraphItem

Instance Method Summary collapse

Constructor Details

#initialize(lockfile) ⇒ Graph

Create a new Lockfile graph.

Some clarifying terminology:

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


646
647
648
649
650
# File 'lib/berkshelf/lockfile.rb', line 646

def initialize(lockfile)
  @lockfile  = lockfile
  @berksfile = lockfile.berksfile
  @graph     = {}
end

Instance Method Details

#add(name, version) ⇒ GraphItem

Add each a new GraphItem to the graph.

Parameters:

  • name (#to_s)

    the name of the cookbook

  • version (#to_s)

    the version of the lock

Returns:



735
736
737
# File 'lib/berkshelf/lockfile.rb', line 735

def add(name, version)
  @graph[name.to_s] = GraphItem.new(name, version)
end

#dependency?(dependency, options = {}) ⇒ Boolean Also known as: has_dependency?

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.

Parameters:

  • dependency (Dependency, String)

    the name/dependency to find

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :ignore (String, Array<String>)

    the list of dependencies to ignore

Returns:

  • (Boolean)


711
712
713
714
715
716
717
718
719
720
721
722
723
724
# 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

#each {|Hash<String]| ... } ⇒ Object

Yields:

  • (Hash<String])

    Hash<String]



653
654
655
# File 'lib/berkshelf/lockfile.rb', line 653

def each(&block)
  @graph.values.each(&block)
end

#find(dependency) ⇒ GraphItem?

Find a given dependency in the graph.

Parameters:

Returns:



687
688
689
# File 'lib/berkshelf/lockfile.rb', line 687

def find(dependency)
  @graph[Dependency.name(dependency)]
end

#lock?(dependency) ⇒ true, false Also known as: has_lock?

Find if the given lock exists?

Parameters:

Returns:

  • (true, false)


697
698
699
# File 'lib/berkshelf/lockfile.rb', line 697

def lock?(dependency)
  !find(dependency).nil?
end

#locksHash<String, Dependency>

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.

Returns:

  • (Hash<String, Dependency>)

    a key-value hash where the key is the name of the cookbook and the value is the locked dependency



664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
# 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 = {}) ⇒ Object

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

Parameters:

  • dependency (Dependency, String)

    the name/dependency to remove

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :ignore (String, Array<String>)

    the list of dependencies to ignore



747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
# 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_lockString

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)

Examples:

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

Returns:



800
801
802
803
804
805
806
807
808
809
810
811
812
813
# 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) ⇒ Object

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

Parameters:

  • the (Array<CachedCookbook>)

    list of cookbooks to populate the graph with



775
776
777
778
779
780
781
782
783
784
785
# 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