File: graph_node.rb

package info (click to toggle)
ruby-semantic-puppet 1.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 292 kB
  • sloc: ruby: 2,898; makefile: 6
file content (123 lines) | stat: -rw-r--r-- 3,428 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
require 'semantic_puppet/dependency'
require 'set'

module SemanticPuppet
  module Dependency
    module GraphNode
      include Comparable

      def name
      end

      # Determines whether the modules dependencies are satisfied by the known
      # releases.
      #
      # @return [Boolean] true if all dependencies are satisfied
      def satisfied?
        dependencies.none? { |_, v| v.empty? }
      end

      def children
        @_children ||= {}
      end

      def populate_children(nodes)
        if children.empty?
          nodes = nodes.select { |node| satisfies_dependency?(node) }
          nodes.each do |node|
            children[node.name] = node
            node.populate_children(nodes)
          end
          self.freeze
        end
      end

      # @api internal
      # @return [{ String => Array<GraphNode> }] the satisfactory
      #         dependency nodes
      def dependencies
        @_dependencies ||= Hash.new { |h, k| h[k] = Array.new }
      end

      # Adds the given dependency name to the list of dependencies.
      #
      # @param name [String] the dependency name
      # @return [void]
      def add_dependency(name)
        dependencies[name]
      end

      # @return [Array<String>] the list of dependency names
      def dependency_names
        dependencies.keys
      end

      def constraints
        @_constraints ||= Hash.new { |h, k| h[k] = [] }
      end

      def constraints_for(name)
        return [] unless constraints.has_key?(name)

        constraints[name].map do |constraint|
          {
            :source      => constraint[0],
            :description => constraint[1],
            :test        => constraint[2],
          }
        end
      end

      # Constrains the named module to suitable releases, as determined by the
      # given block.
      #
      # @example Version-locking currently installed modules
      #     installed_modules.each do |m|
      #       @graph.add_constraint('installed', m.name, m.version) do |node|
      #         m.version == node.version
      #       end
      #     end
      #
      # @param source [String, Symbol] a name describing the source of the
      #               constraint
      # @param mod [String] the name of the module
      # @param desc [String] a description of the enforced constraint
      # @yieldparam node [GraphNode] the node to test the constraint against
      # @yieldreturn [Boolean] whether the node passed the constraint
      # @return [void]
      def add_constraint(source, mod, desc, &block)
        constraints["#{mod}"] << [ source, desc, block ]
      end

      def satisfies_dependency?(node)
        dependencies.key?(node.name) && satisfies_constraints?(node)
      end

      # @param release [ModuleRelease] the release to test
      def satisfies_constraints?(release)
        constraints_for(release.name).all? { |x| x[:test].call(release) }
      end

      def << (nodes)
        Array(nodes).group_by(&:name).each_pair do |name, nodes|
          changed = false
          next unless dependencies.key?(name)

          nodes.each do |node|
            if satisfies_dependency?(node)
              dependencies[name] << node
              changed = true
            end
          end
          dependencies[name].sort! if changed
        end

        return self
      end

      def <=>(other)
        name <=> other.name
      end
    end
  end
end