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


642
643
644
645
646
# File 'lib/berkshelf/lockfile.rb', line 642

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:



731
732
733
# File 'lib/berkshelf/lockfile.rb', line 731

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)


707
708
709
710
711
712
713
714
715
716
717
718
719
720
# File 'lib/berkshelf/lockfile.rb', line 707

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]



649
650
651
# File 'lib/berkshelf/lockfile.rb', line 649

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

#find(dependency) ⇒ GraphItem?

Find a given dependency in the graph.

Parameters:

Returns:



683
684
685
# File 'lib/berkshelf/lockfile.rb', line 683

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)


693
694
695
# File 'lib/berkshelf/lockfile.rb', line 693

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



660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
# File 'lib/berkshelf/lockfile.rb', line 660

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



743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
# File 'lib/berkshelf/lockfile.rb', line 743

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:



796
797
798
799
800
801
802
803
804
805
806
807
808
809
# File 'lib/berkshelf/lockfile.rb', line 796

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 |name, constraint|
        out << "    #{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



771
772
773
774
775
776
777
778
779
780
781
# File 'lib/berkshelf/lockfile.rb', line 771

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