groundwork 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/groundwork ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require File.join(File.dirname(__FILE__),"..","lib","groundwork.rb")
4
+
5
+ begin
6
+ options = Groundwork::parse_options
7
+
8
+ case options[:command]
9
+ when "generate"
10
+ generate_opts = Trollop::options(options[:remainder]) do
11
+ opt :force, :default=>false
12
+ end
13
+
14
+ name = options[:remainder].shift || "Recipe"
15
+
16
+ if File.exists?(name+".recipe") && !generate_opts[:force]
17
+ raise RuntimeError.new("File already exists: #{name}.recipe")
18
+ end
19
+
20
+ recipe = Groundwork::Recipe.generate
21
+ File.open(name+".recipe","w"){|f| f.print recipe}
22
+ else
23
+ end
24
+ rescue
25
+ puts $!.to_s
26
+ end
data/lib/groundwork.rb ADDED
@@ -0,0 +1,175 @@
1
+ require "rubygems"
2
+ require "trollop"
3
+ require "erb"
4
+ require "pathname"
5
+ require File.join(File.dirname(__FILE__), "options.rb")
6
+ require File.join(File.dirname(__FILE__), "tar_wrapper.rb")
7
+
8
+ module Groundwork
9
+ class Recipe
10
+ def initialize &block
11
+ if block_given?
12
+ instance_eval &block
13
+ end
14
+ end
15
+
16
+ def tar= data
17
+ @tar = TarWrapper.new(data)
18
+ end
19
+
20
+ # Creates a directory. If a block is passed,
21
+ # the block will be run inside that directory
22
+ def directory *name, &block
23
+ FileUtils.mkdir_p File.join(name)
24
+ if block_given?
25
+ FileUtils.cd File.join(name), &block
26
+ end
27
+ end
28
+
29
+ # If opts is a string, it's the contents of the file, verbatim
30
+ # If opts is a hash, it must contain either:
31
+ # * :from, copies the text of the given filename verbatim
32
+ # * :from_erb, uses the text of the filename as an erb template
33
+ # * :erb, uses the given string as an erb template
34
+ def file name, opts = nil
35
+ name = File.join(name)
36
+ File.open(File.join(name),"w") do |file|
37
+ if opts.is_a? String
38
+ file.print opts
39
+ elsif opts.is_a? Hash
40
+ file.print( if opts[:from]
41
+ read_file opts[:from]
42
+ elsif opts[:from_erb]
43
+ ERB.new(read_file(opts[:from_erb])).result(binding)
44
+ elsif opts[:erb]
45
+ ERB.new(opts[:erb]).result(binding)
46
+ end )
47
+ elsif opts.nil?
48
+ # write nothing
49
+ else
50
+ raise ArgumentError.new
51
+ end
52
+ end
53
+ end
54
+
55
+ # When you compile a recipe, it runs it to determine which files to bake in.
56
+ # If you have a file that might not be generated by running your script with
57
+ # no options, you can call possible on it to ensure it gets baked into
58
+ # the script. This function only has an effect during compilation, it does
59
+ # nothing when the script is actually run.
60
+ def possible name ; end
61
+
62
+ # Takes a block and lists the files that that block will require as templates.
63
+ # See Groundwork::Recipe#possible
64
+ def self.required_files &block
65
+ dummy = Object.new
66
+ files = []
67
+
68
+ class << dummy
69
+ attr_reader :files
70
+
71
+ def directory *args
72
+ yield if block_given?
73
+ end
74
+
75
+ def file name, opts=nil
76
+ @files << opts[:from] if opts[:from]
77
+ @files << opts[:from_erb] if opts[:from_erb]
78
+ end
79
+
80
+ def possible name
81
+ @files << name
82
+ end
83
+
84
+ def method_missing *args ; end
85
+ end
86
+
87
+ dummy.instance_variable_set "@files", []
88
+ dummy.instance_eval &block
89
+
90
+ dummy.files
91
+ end
92
+
93
+ # Takes a script file, finds the files it requires (paths relative to the script file),
94
+ # reads/tars them and returns a string containing the script and the TAR blob, ready
95
+ # to write to a file
96
+ def self.compile script_file
97
+ script = File.read(script_file)
98
+ out = StringIO.new
99
+ data = nil
100
+
101
+ FileUtils.cd(File.dirname(script_file)) do
102
+ files = required_files do
103
+ eval script
104
+ end
105
+
106
+ data = TarWrapper.compress files
107
+ end
108
+
109
+ out.puts "if $0==__FILE__"
110
+ out.puts " require 'rubygems'"
111
+ out.puts " require 'kickstart'"
112
+ out.puts "end"
113
+ out.puts ""
114
+ out.puts script
115
+ out.puts ""
116
+ out.puts "__END__"
117
+ out.puts data
118
+
119
+ out.string
120
+ end
121
+
122
+ # Takes a filename and runs the script contained in it. The file should be
123
+ # the results of Groundwork::Recipe#compile
124
+ def self.run script_file
125
+ (script, data) = File.read(script_file).split("\n__END__\n")
126
+
127
+ Groundwork::Recipe.new do
128
+ self.tar = data
129
+ eval script
130
+ end
131
+ end
132
+
133
+ # Generate a tree of file and directory calls that would create the given
134
+ # directory
135
+ def self.generate dir = FileUtils.pwd
136
+ base = Pathname.new dir
137
+
138
+ handle_dir = lambda do |d, output, indent|
139
+ FileUtils.cd d do
140
+ Dir["*"].each do |file|
141
+ if File.directory? file
142
+ if Dir[File.join(file,"*")].empty?
143
+ output.puts((" "*indent)+"directory \"#{file}\"")
144
+ else
145
+ output.puts("")
146
+ output.puts((" "*indent)+"directory \"#{file}\" do")
147
+ handle_dir[file, output, indent+2]
148
+ output.puts((" "*indent)+"end")
149
+ output.puts("")
150
+ end
151
+ else
152
+ rel = Pathname.new(File.join(FileUtils.pwd,file))
153
+ relpath = rel.relative_path_from(base).to_s
154
+ output.puts((" "*indent)+"file \"#{file}\", :from => \"#{relpath}\"")
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ str = StringIO.new
161
+ handle_dir[dir, str, 0]
162
+ str.string.gsub(/\n\n+/,"\n\n") # Collapse adjacent blank lines
163
+ end
164
+
165
+ private
166
+
167
+ def read_file name
168
+ if @tar
169
+ @tar[name]
170
+ else
171
+ File.read(name)
172
+ end
173
+ end
174
+ end
175
+ end
data/lib/options.rb ADDED
@@ -0,0 +1,32 @@
1
+ require "abbrev"
2
+
3
+ module Groundwork
4
+ def self.parse_options opts=ARGV
5
+ global_opts = Trollop::options(opts) do
6
+ banner "Groundwork"
7
+ version "0.0.1"
8
+ stop_on_unknown
9
+ end
10
+
11
+ cmd=short_for(opts.shift)
12
+
13
+ return({ :options=>global_opts,
14
+ :command=>cmd,
15
+ :remainder=>opts
16
+ })
17
+ end
18
+
19
+ def self.short_for cmd_start, all_commands=["generate"]
20
+ return cmd_start unless cmd_start
21
+ return cmd_start if all_commands.index(cmd_start)
22
+
23
+ completions = all_commands.abbrev(cmd_start)
24
+ if completions[cmd_start]
25
+ completions[cmd_start]
26
+ elsif completions.values.uniq.empty?
27
+ raise RuntimeError.new("Unknown command \"#{cmd_start}\".")
28
+ else
29
+ raise RuntimeError.new("\"#{cmd_start}\" is ambiguous. Which did you mean:\n\t"+cmd_poss.join("\n\t"))
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ require "rubygems"
2
+ require "archive/tar/minitar"
3
+ require "base64"
4
+
5
+ class Groundwork::TarWrapper
6
+ include Archive::Tar
7
+
8
+ # Takes a base64-encoded, tarred string
9
+ def initialize encoded
10
+ tar = Base64.decode64(encoded)
11
+ @files = {}
12
+ Minitar::Reader.new(StringIO.new(tar)).each do |entry|
13
+ next unless entry.file?
14
+ @files[entry.full_name] = entry.read
15
+ end
16
+ end
17
+
18
+ def [] name
19
+ @files[name]
20
+ end
21
+
22
+ def self.compress files
23
+ string = StringIO.new
24
+ output = Minitar::Output.new(string)
25
+
26
+ files.each do |file|
27
+ Minitar.pack_file(file, output)
28
+ end
29
+
30
+ output.close
31
+ Base64.encode64 string.string
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: groundwork
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Andrews, Ross
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-02-23 00:00:00 -06:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: trollop
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 10
30
+ - 2
31
+ version: 1.10.2
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: archive-tar-minitar
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 5
44
+ - 2
45
+ version: 0.5.2
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ description: Create scripts that describe the groundwork for laying out your projects, and generate project frameworks
49
+ email: randrews@geekfu.org
50
+ executables:
51
+ - groundwork
52
+ extensions: []
53
+
54
+ extra_rdoc_files: []
55
+
56
+ files:
57
+ - lib/groundwork.rb
58
+ - lib/tar_wrapper.rb
59
+ - lib/options.rb
60
+ has_rdoc: true
61
+ homepage: https://github.com/randrews/groundwork
62
+ licenses: []
63
+
64
+ post_install_message:
65
+ rdoc_options: []
66
+
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project: groundwork
86
+ rubygems_version: 1.3.6
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: A project scaffolding generator
90
+ test_files: []
91
+