summaryrefslogtreecommitdiffstats
path: root/lib/puppet/util/autoload.rb
blob: f171254af196636ed4f32266311ba83178baf14d (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
106
107
# Autoload paths, either based on names or all at once.
class Puppet::Util::Autoload
    include Puppet::Util

    @autoloaders = {}

    attr_accessor :object, :path, :objwarn, :wrap


    class << self
        attr_reader :autoloaders
        private :autoloaders
    end
    Puppet::Util.classproxy self, :autoloaders, "[]", "[]=", :clear

    attr_reader :loaded
    private :loaded

    Puppet::Util.proxy self, :loaded, :clear

    def handle_libdir
        dir = Puppet[:libdir]

        $: << dir unless $:.include?(dir)
    end

    def initialize(obj, path, options = {})
        @path = path.to_s
        @object = obj

        self.class[obj] = self

        options.each do |opt, value|
            opt = opt.intern if opt.is_a? String
            begin
                self.send(opt.to_s + "=", value)
            rescue NoMethodError
                raise ArgumentError, "%s is not a valid option" % opt
            end
        end

        unless defined? @wrap
            @wrap = true
        end

        @loaded = {}
    end

    def load(name)
        name = symbolize(name)
        handle_libdir()

        path = File.join(@path, name.to_s + ".rb")

        begin
            Kernel.load path, @wrap
            @loaded[name] = true
            return true
        rescue LoadError => detail
            # I have no idea what's going on here, but different versions
            # of ruby are raising different errors on missing files.
            unless detail.to_s =~ /^no such file/i
                warn "Could not autoload %s: %s" % [name, detail]
                if Puppet[:trace]
                    puts detail.backtrace
                end
            end
            return false
        end
    end

    def loaded?(name)
        name = symbolize(name)
        @loaded[name]
    end

    def loadall
        handle_libdir()
        # Load every instance of everything we can find.
        $:.each do |dir|
            fdir = File.join(dir, @path)
            if FileTest.exists?(fdir) and FileTest.directory?(fdir)
                Dir.glob("#{fdir}/*.rb").each do |file|
                    # Load here, rather than require, so that facts
                    # can be reloaded.  This has some short-comings, I
                    # believe, but it works as long as real classes
                    # aren't used.
                    name = File.basename(file).sub(".rb", '').intern
                    next if @loaded.include? name
                    next if $".include?(File.join(@path, name.to_s + ".rb"))
                    filepath = File.join(@path, name.to_s + ".rb")
                    begin
                        Kernel.require filepath
                        @loaded[name] = true
                    rescue => detail
                        if Puppet[:trace]
                            puts detail.backtrace
                        end
                        warn "Could not autoload %s: %s" % [file.inspect, detail]
                    end
                end
            end
        end
    end
end

# $Id$