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


592
593
594
595
596
# File 'lib/berkshelf/lockfile.rb', line 592

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:



681
682
683
# File 'lib/berkshelf/lockfile.rb', line 681

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)


657
658
659
660
661
662
663
664
665
666
667
668
669
670
# File 'lib/berkshelf/lockfile.rb', line 657

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]



599
600
601
# File 'lib/berkshelf/lockfile.rb', line 599

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

#find(dependency) ⇒ GraphItem?

Find a given dependency in the graph.

Parameters:

Returns:



633
634
635
# File 'lib/berkshelf/lockfile.rb', line 633

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)


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

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



610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
# File 'lib/berkshelf/lockfile.rb', line 610

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

    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



693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
# File 'lib/berkshelf/lockfile.rb', line 693

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:



746
747
748
749
750
751
752
753
754
755
756
757
758
759
# File 'lib/berkshelf/lockfile.rb', line 746

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



721
722
723
724
725
726
727
728
729
730
731
# File 'lib/berkshelf/lockfile.rb', line 721

def update(cookbooks)
  @graph = {}

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