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


604
605
606
607
608
# File 'lib/berkshelf/lockfile.rb', line 604

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:



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

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)


669
670
671
672
673
674
675
676
677
678
679
680
681
682
# File 'lib/berkshelf/lockfile.rb', line 669

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]



611
612
613
# File 'lib/berkshelf/lockfile.rb', line 611

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

#find(dependency) ⇒ GraphItem?

Find a given dependency in the graph.

Parameters:

Returns:



645
646
647
# File 'lib/berkshelf/lockfile.rb', line 645

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)


655
656
657
# File 'lib/berkshelf/lockfile.rb', line 655

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



622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
# File 'lib/berkshelf/lockfile.rb', line 622

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



705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
# File 'lib/berkshelf/lockfile.rb', line 705

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:



758
759
760
761
762
763
764
765
766
767
768
769
770
771
# File 'lib/berkshelf/lockfile.rb', line 758

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



733
734
735
736
737
738
739
740
741
742
743
# File 'lib/berkshelf/lockfile.rb', line 733

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