summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser/ast/component.rb
blob: f5105c44b73cfc62ae699131c48e251bb527fbaf (plain)
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
class Puppet::Parser::AST
    # Evaluate the stored parse tree for a given component.  This will
    # receive the arguments passed to the component and also the type and
    # name of the component.
    class Component < AST::Branch
        class << self
            attr_accessor :name
        end

        # The class name
        @name = :component

        attr_accessor :name, :args, :code, :scope, :autoname, :keyword

        def evaluate(scope,hash,objtype,objname)

            scope = scope.newscope

            # The type is the component or class name
            scope.type = objtype

            # The name is the name the user has chosen or that has
            # been dynamically generated.  This is almost never used
            scope.name = objname

            scope.keyword = self.keyword

            # Retain the fact that we were autonamed, if so
            if self.autoname
                scope.autoname = true
            end

            #if self.is_a?(Node)
            #    scope.isnodescope
            #end

            # Additionally, add a tag for whatever kind of class
            # we are
            scope.tag(objtype)

            unless objname =~ /-\d+/ # it was generated
                scope.tag(objname)
            end
            #scope.base = self.class.name


            # define all of the arguments in our local scope
            if self.args

                # Verify that all required arguments are either present or
                # have been provided with defaults.
                # FIXME This should probably also require each parent
                # class's arguments...
                self.args.each { |arg, default|
                    unless hash.include?(arg)
                        if defined? default and ! default.nil?
                            hash[arg] = default
                            #Puppet.debug "Got default %s for %s in %s" %
                            #    [default.inspect, arg.inspect, objname.inspect]
                        else
                            error = Puppet::ParseError.new(
                                "Must pass %s to %s of type %s" %
                                    [arg.inspect,name,objtype]
                            )
                            error.line = self.line
                            error.file = self.file
                            raise error
                        end
                    end
                }
            end

            # Set each of the provided arguments as variables in the
            # component's scope.
            hash["name"] = objname
            hash.each { |arg,value|
                begin
                    scope.setvar(arg,hash[arg])
                rescue Puppet::ParseError => except
                    except.line = self.line
                    except.file = self.file
                    raise except
                rescue Puppet::ParseError => except
                    except.line = self.line
                    except.file = self.file
                    raise except
                rescue => except
                    error = Puppet::ParseError.new(except.message)
                    error.line = self.line
                    error.file = self.file
                    error.backtrace = except.backtrace
                    raise error
                end
            }

            # Now just evaluate the code with our new bindings.
            self.code.safeevaluate(scope)

            # We return the scope, so that our children can make their scopes
            # under ours.  This allows them to find our definitions.
            return scope
        end
    end

end