Class: Groundwork::Recipe

Inherits:
Object
  • Object
show all
Defined in:
lib/recipe.rb,
lib/recipe_class.rb

Direct Known Subclasses

RecipeUnpacker

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = [], &block) ⇒ Recipe

Returns a new instance of Recipe.



3
4
5
6
7
8
9
# File 'lib/recipe.rb', line 3

def initialize args=[], &block
    @args = args
    @name = args[0]
    if block_given?
        instance_eval &block
    end
end

Class Method Details

.compile(script, in_directory) ⇒ Object

Takes a script file, finds the files it requires (paths relative to the script file), reads/tars them and returns a string containing the script and the TAR blob, ready to write to a file



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/recipe_class.rb', line 43

def compile script, in_directory
    out = StringIO.new
    data = nil

    FileUtils.cd(in_directory) do
        files = required_files do
            eval script
        end

        data = TarWrapper.compress files
    end

    out.puts script
    out.puts ""
    out.puts "__END__"
    out.puts data

    out.string
end

.compile_file(filename) ⇒ Object



36
37
38
# File 'lib/recipe_class.rb', line 36

def compile_file filename
    compile File.read(filename), File.dirname(filename)
end

.generate(dir = FileUtils.pwd, options = {}) ⇒ Object

Generate a tree of file and directory calls that would create the given directory



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
124
125
126
127
# File 'lib/recipe_class.rb', line 96

def generate dir = FileUtils.pwd, options = {}
    base = Pathname.new dir

    handle_dir = lambda do |d, output, indent|
        FileUtils.cd d do
            Dir["*"].each do |file|
                rel = Pathname.new(File.join(FileUtils.pwd,file))
                relpath = rel.relative_path_from(base).to_s

                next if options[:ignore] && options[:ignore].any?{|p| File.fnmatch(p,relpath) }

                if File.directory? file
                    if Dir[File.join(file,"*")].empty?
                        output.puts((" "*indent)+"directory \"#{file}\"")
                    else
                        output.puts("")
                        output.puts((" "*indent)+"directory \"#{file}\" do")
                        handle_dir[file, output, indent+2]
                        output.puts((" "*indent)+"end")
                        output.puts("")
                    end
                else
                    output.puts((" "*indent)+"file \"#{file}\", :from => \"#{relpath}\"")
                end
            end
        end
    end

    str = StringIO.new
    handle_dir[dir, str, 0]
    str.string.gsub(/\n\n+/,"\n\n") # Collapse adjacent blank lines
end

.required_files(&block) ⇒ Object

Takes a block and lists the files that that block will require as templates. See Groundwork::Recipe#possible



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
# File 'lib/recipe_class.rb', line 7

def required_files &block
    dummy = Object.new
    files = []

    class << dummy
        attr_reader :files

        def directory *args
            yield if block_given?
        end

        def file name, opts=nil
            @files << opts[:from] if opts[:from]
            @files << opts[:from_erb] if opts[:from_erb]
        end

        def possible name
            @files << name
        end

        def method_missing *args ; end
    end

    dummy.instance_variable_set "@files", []
    dummy.instance_eval &block

    dummy.files
end

.run(script_file, args = []) ⇒ Object

Takes a filename and runs the script contained in it. The file should be the results of Groundwork::Recipe#compile



65
66
67
68
69
70
71
72
# File 'lib/recipe_class.rb', line 65

def run script_file, args=[]
    (script, data) = File.read(script_file).split("\n__END__\n")

    Groundwork::Recipe.new args do
        self.tar = data if data
        eval script
    end
end

.unpack(unpack_to, filename) ⇒ Object

Takes the name of a directory and a block, and unpacks the script given in the block into the directory.

If the second argument is given, the script is loaded from that filename instead of using the block



79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/recipe_class.rb', line 79

def unpack unpack_to, filename
    (recipe, data) = File.read(filename).split("\n__END__\n")

    FileUtils.mkdir unpack_to

    FileUtils.cd unpack_to do
        Groundwork::RecipeUnpacker.new do
            self.tar = data if data
            eval recipe
        end

        File.open("#{unpack_to}.recipe.rb","w"){|f| f.puts recipe }
    end
end

Instance Method Details

#directory(*name, &block) ⇒ Object

Creates a directory. If a block is passed, the block will be run inside that directory



31
32
33
34
35
36
# File 'lib/recipe.rb', line 31

def directory *name, &block
    FileUtils.mkdir_p File.join(name)
    if block_given?
        FileUtils.cd File.join(name), &block
    end
end

#file(name, opts = nil) ⇒ Object

If opts is a string, it’s the contents of the file, verbatim If opts is a hash, it must contain either:

  • :from, copies the text of the given filename verbatim

  • :from_erb, uses the text of the filename as an erb template

  • :erb, uses the given string as an erb template



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/recipe.rb', line 43

def file name, opts = nil
    name = File.join(name)
    File.open(File.join(name),"w") do |file|
        if opts.is_a? String
            file.print opts
        elsif opts.is_a? Hash
            file.print( if opts[:from]
                            read_file opts[:from]
                        elsif opts[:from_erb]
                            ERB.new(read_file(opts[:from_erb])).result(binding)
                        elsif opts[:erb]
                            ERB.new(opts[:erb]).result(binding)
                        end )
        elsif opts.nil?
            # write nothing
        else
            raise ArgumentError.new
        end
    end
end

#options(&block) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/recipe.rb', line 15

def options &block
    opts = Trollop::options(@args) do
        self.instance_eval &block
    end

    opts.each do |name, val|
        instance_variable_set "@#{name}", val
    end

    @name = @args[0]

    opts
end

#possible(name) ⇒ Object

When you compile a recipe, it runs it to determine which files to bake in. If you have a file that might not be generated by running your script with no options, you can call possible on it to ensure it gets baked into the script. This function only has an effect during compilation, it does nothing when the script is actually run.



69
# File 'lib/recipe.rb', line 69

def possible name ; end

#tar=(data) ⇒ Object



11
12
13
# File 'lib/recipe.rb', line 11

def tar= data
    @tar = TarWrapper.new(data)
end