webbynode-mason 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Mason
2
+
3
+ Build things
4
+
5
+ $ gem install mason
6
+
7
+ ### Install buildpacks locally
8
+
9
+ $ mason buildpacks
10
+ * buildpacks (~/.mason/buildpacks)
11
+ = nodejs: https://github.com/heroku/heroku-buildpack-nodejs.git
12
+ = ruby: https://github.com/ddollar/heroku-buildpack-ruby.git
13
+
14
+ $ mason buildpacks:install https://github.com/heroku/heroku-buildpack-python.git
15
+ * installing buildpack https://github.com/heroku/heroku-buildpack-python.git
16
+
17
+ ### Use buildpacks to build things
18
+
19
+ $ mason build /tmp/app
20
+ * detecting buildpack... done
21
+ = name: Ruby
22
+ = url: https://github.com/heroku/heroku-buildpack-ruby.git
23
+ * compiling:
24
+ ... COMPILE OUTPUT
25
+ * packaging... done
26
+ = type: dir
27
+ = file: /tmp/mason.out
28
+
29
+ $ mason build /tmp/app -t dir -o /tmp/compiledapp
30
+ * detecting buildpack... done
31
+ = name: Ruby
32
+ = url: https://github.com/heroku/heroku-buildpack-ruby.git
33
+ * compiling...
34
+ ... COMPILE OUTPUT
35
+ * packaging... done
36
+ = type: dir
37
+ = dir: /tmp/compiledapp
38
+
39
+ $ mason build /tmp/app -b https://github.com/ddollar/buildpack-other.git -t tgz
40
+ * detecting buildpack... done
41
+ = name: Other
42
+ = url: https://github.com/ddollar/buildpack-other.git
43
+ * compiling...
44
+ ... COMPILE OUTPUT
45
+ * packaging... done
46
+ = type: tgz
47
+ = file: /tmp/app.tgz
48
+
49
+ ### Build things for other platforms using Vagrant
50
+
51
+ You will need [VirtualBox](https://www.virtualbox.org/wiki/Downloads) for Vagrant to function.
52
+
53
+ $ gem install vagrant
54
+
55
+ $ vagrant box add lucid64 http://files.vagrantup.com/lucid64.box
56
+
57
+ $ mason stacks:create lucid64
58
+ * creating stack lucid64... done
59
+
60
+ $ mason stacks:up lucid64
61
+ * booting stack lucid64 (this may take a while)... done
62
+
63
+ $ mason:build /tmp/app -t tgz -o /tmp/compiled.tgz -s lucid64
64
+ * booting stack lucid64 (this may take a while)... done
65
+ * detecting buildpack... done
66
+ = name: Baz
67
+ = url: https://github.com/ddollar/buildpack-baz.git
68
+ * compiling...
69
+ ... COMPILE OUTPUT
70
+ * packaging... done
71
+ = type: tgz
72
+ = dir: /tmp/compiled.tgz
data/bin/mason ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path("../../lib", __FILE__)
4
+
5
+ require "mason/cli"
6
+
7
+ begin
8
+ Mason::CLI.run
9
+ rescue Errno::EPIPE
10
+ rescue Mason::CommandFailed => ex
11
+ end
@@ -0,0 +1,5 @@
1
+ Vagrant::Config.run do |config|
2
+ config.vagrant.dotfile_name = File.expand_path("~/.mason/vagrant")
3
+
4
+ BOXES
5
+ end
data/lib/mason.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Mason
2
+
3
+ class CommandFailed < StandardError; end
4
+
5
+ end
@@ -0,0 +1,98 @@
1
+ require "mason"
2
+ require "tmpdir"
3
+ require "yaml"
4
+ require "foreman/engine"
5
+
6
+ class Mason::Buildpack
7
+
8
+ attr_reader :dir, :name, :url
9
+
10
+ def initialize(dir)
11
+ @dir = dir
12
+ Dir.chdir(@dir) do
13
+ @name = File.basename(@dir)
14
+ @url = %x{ git config remote.origin.url }.chomp
15
+ end
16
+ end
17
+
18
+ def <=>(other)
19
+ self.name <=> other.name
20
+ end
21
+
22
+ def detect(app)
23
+ mkchtmpdir do
24
+ output = %x{ #{script("detect")} "#{app}" }
25
+ $?.exitstatus.zero? ? output.chomp : nil
26
+ end
27
+ end
28
+
29
+ def compile(app, env_file=nil, cache=nil)
30
+ cache_dir = cache || "#{app}/.git/cache"
31
+ puts " caching in #{cache_dir}"
32
+ compile_dir = Dir.mktmpdir
33
+ FileUtils.rm_rf compile_dir
34
+ FileUtils.cp_r app, compile_dir, :preserve => true
35
+ FileUtils.mkdir_p cache_dir
36
+ Dir.chdir(compile_dir) do
37
+ IO.popen(%{ #{script("compile")} "#{compile_dir}" "#{cache_dir}" }) do |io|
38
+ until io.eof?
39
+ data = io.gets
40
+ data.gsub!(/^-----> /, " + ")
41
+ data.gsub!(/^ /, " ")
42
+ data.gsub!(/^\s+\!\s+$/, "")
43
+ data.gsub!(/^\s+\!\s+/, " ! ")
44
+ data.gsub!(/^\s+$/, "")
45
+ print data
46
+ end
47
+ end
48
+ raise "compile failed" unless $?.exitstatus.zero?
49
+ end
50
+ release = YAML.load(`#{script('release')} "#{compile_dir}"`)
51
+ write_env(compile_dir, release, env_file)
52
+ write_procfile(compile_dir, release)
53
+ compile_dir
54
+ end
55
+
56
+ private
57
+
58
+ def write_env(compile_dir, release, env_file)
59
+ env = env_file ? Foreman::Engine.new.load_env(env_file) : {}
60
+ config = release["config_vars"].merge(env)
61
+
62
+ File.open(File.join(compile_dir, ".env"), "w") do |f|
63
+ f.puts config.map{|k, v| "#{k}=#{v}"}.join("\n")
64
+ end
65
+ end
66
+
67
+ def write_procfile(compile_dir, release)
68
+ filename = File.join(compile_dir, "Procfile")
69
+ process_types = release["default_process_types"] || {}
70
+
71
+ if File.exists? filename
72
+ Foreman::Procfile.new(filename).entries do |name, command|
73
+ process_types[name] = command
74
+ end
75
+ end
76
+
77
+ File.open(filename, "w") do |f|
78
+ process_types.each do |name, command|
79
+ f.puts "#{name}: #{command}"
80
+ end
81
+ end
82
+ end
83
+
84
+ def mkchtmpdir
85
+ ret = nil
86
+ Dir.mktmpdir do |dir|
87
+ Dir.chdir(dir) do
88
+ ret = yield(dir)
89
+ end
90
+ end
91
+ ret
92
+ end
93
+
94
+ def script(name)
95
+ File.join(dir, "bin", name)
96
+ end
97
+ end
98
+
@@ -0,0 +1,75 @@
1
+ require "fileutils"
2
+ require "mason"
3
+ require "mason/buildpack"
4
+ require "uri"
5
+ require "digest/sha1"
6
+
7
+ class Mason::Buildpacks
8
+
9
+ def self.install(url, ad_hoc=false)
10
+ root_dir = ad_hoc ? ad_hoc_root : root
11
+ FileUtils.mkdir_p root_dir
12
+
13
+ Dir.chdir(root_dir) do
14
+ uri = URI.parse(url)
15
+ if uri.path =~ /buildpack-(\w+)/
16
+ name = $1
17
+ name += "-#{Digest::SHA1.hexdigest(url).to_s[0 .. 8]}" if ad_hoc
18
+ branch = uri.fragment || "master"
19
+ if File.exists?(name)
20
+ # Can't do a fetch here as it won't update local branches
21
+ system "cd #{name} && git checkout master && git pull"
22
+ raise "failed to update buildpack checkout" unless $?.exitstatus.zero?
23
+ else
24
+ system "git clone #{url.split('#').first} #{name} >/dev/null 2>&1"
25
+ raise "failed to clone buildpack" unless $?.exitstatus.zero?
26
+ end
27
+ system "cd #{name} && git checkout #{branch} 2> /dev/null"
28
+ raise "failed to check out branch #{branch}" unless $?.exitstatus.zero?
29
+ File.expand_path(root_dir + "/" + name)
30
+ else
31
+ raise "BUILDPACK should be a url containing buildpack-NAME.git"
32
+ end
33
+ end
34
+ end
35
+
36
+ def self.uninstall(name)
37
+ Dir.chdir(root) do
38
+ raise "#{name} buildpack is not installed" unless File.exists?(name)
39
+ FileUtils.rm_rf name
40
+ end
41
+ end
42
+
43
+ def self.root(ad_hoc=false, expand=true)
44
+ dir = "~/.mason/buildpacks"
45
+ expand ? File.expand_path(dir) : dir
46
+ end
47
+
48
+ def self.ad_hoc_root(expand=true)
49
+ dir = "~/.mason/buildpacks-ad-hoc"
50
+ expand ? File.expand_path(dir) : dir
51
+ end
52
+
53
+ def self.buildpacks
54
+ @buildpacks ||= begin
55
+ Dir[File.join(root, "*")].map do |buildpack_dir|
56
+ Mason::Buildpack.new(buildpack_dir)
57
+ end
58
+ end
59
+ end
60
+
61
+ def self.detect(app, buildpack_url)
62
+ if buildpack_url
63
+ puts "Using $BUILDPACK_URL: #{buildpack_url}"
64
+ buildpack_dir = install(buildpack_url, true)
65
+ return Mason::Buildpack.new(buildpack_dir)
66
+ else
67
+ buildpacks.each do |buildpack|
68
+ ret = buildpack.detect(app)
69
+ return [buildpack, ret] if ret
70
+ end
71
+ end
72
+ nil
73
+ end
74
+
75
+ end
data/lib/mason/cli.rb ADDED
@@ -0,0 +1,279 @@
1
+ require "mason"
2
+ require "mason/buildpacks"
3
+ require "mason/stacks"
4
+ require "mason/version"
5
+ require "thor"
6
+ require "thor/shell/basic"
7
+
8
+ class Mason::CLI < Thor
9
+
10
+ class_option :debug, :type => :boolean, :desc => "show backtraces"
11
+ class_option :help, :type => :boolean, :aliases => "-h", :desc => "help for this command"
12
+
13
+ map %w( -v -V --version ) => :version
14
+
15
+ desc "version", "display version"
16
+
17
+ def version
18
+ puts "mason v#{Mason::VERSION}"
19
+ end
20
+
21
+ desc "build APP", "build an app"
22
+
23
+ method_option :buildpack, :type => :string, :aliases => "-b", :desc => "use a custom buildpack"
24
+ method_option :output, :type => :string, :aliases => "-o", :desc => "output location"
25
+ method_option :quiet, :type => :boolean, :aliases => "-q", :desc => "quiet packaging output"
26
+ method_option :stack, :type => :string, :aliases => "-s", :desc => "use a stack for building"
27
+ method_option :type, :type => :string, :aliases => "-t", :desc => "output type (dir, img, tgz)"
28
+ method_option :env_file, :type => :string, :aliases => "-e", :desc => "config environment file"
29
+ method_option :cache, :type => :string, :aliases => "-c", :desc => "cache directory"
30
+
31
+ def build(app)
32
+ app = File.expand_path(app)
33
+
34
+ raise "no such directory: #{app}" unless File.exists?(app)
35
+
36
+ type = options[:type]
37
+ output = options[:output]
38
+
39
+ type = File.extname(output)[1..-1] if !type && output
40
+ output = "#{app}.#{type}" if !output && type
41
+
42
+ type ||= "dir"
43
+ output ||= "/tmp/mason.out"
44
+
45
+ output = File.expand_path(output)
46
+
47
+ raise "no such output format: #{type}" unless %w( dir img tgz ).include?(type)
48
+
49
+ if stack = options[:stack]
50
+ if Mason::Stacks.state(stack) == :up
51
+ puts "* using stack #{stack}"
52
+ else
53
+ print "* booting stack #{stack} (this may take a while)... "
54
+ Mason::Stacks.up(stack)
55
+ puts "done"
56
+ end
57
+
58
+ buildpacks_dir = File.expand_path("~/.mason/share/#{stack}/buildpacks")
59
+ compile_dir = File.expand_path("~/.mason/share/#{stack}/app")
60
+ mason_dir = File.expand_path("~/.mason/share/#{stack}/mason")
61
+
62
+ FileUtils.rm_rf buildpacks_dir
63
+ FileUtils.rm_rf compile_dir
64
+ FileUtils.rm_rf mason_dir
65
+
66
+ FileUtils.cp_r(File.expand_path("~/.mason/buildpacks"), buildpacks_dir,
67
+ :preserve => true)
68
+ FileUtils.cp_r(File.expand_path("../../../", __FILE__), mason_dir,
69
+ :preserve => true)
70
+ FileUtils.cp_r(app, compile_dir, :preserve => true)
71
+
72
+ mason_args = %{ /share/app -q -o /share/output -t #{type} }
73
+ mason_args += %{ -b "#{options[:buildpack]}" } if options[:buildpack]
74
+
75
+ Mason::Stacks.run(stack, <<-COMMAND)
76
+ gem spec thor 2>&1 >/dev/null || sudo gem install thor
77
+ /usr/bin/env ruby -rubygems /share/mason/bin/mason build #{mason_args}
78
+ COMMAND
79
+
80
+ FileUtils.rm_rf output
81
+ FileUtils.cp_r(File.expand_path("~/.mason/share/#{stack}/output"), output,
82
+ :preserve => true)
83
+
84
+ puts "* packaging"
85
+ puts " = type: #{type}"
86
+ puts " = location: #{output}"
87
+ else
88
+ print "* detecting buildpack... "
89
+
90
+ buildpack_url = ENV["BUILDPACK_URL"] || options[:buildpack]
91
+ buildpack, ret = Mason::Buildpacks.detect(app, buildpack_url)
92
+ raise "no valid buildpack detected" unless buildpack
93
+
94
+ puts "done"
95
+ puts " = name: #{buildpack.name}"
96
+ puts " = url: #{buildpack.url}"
97
+ puts " = display: #{ret}"
98
+
99
+ puts "* compiling..."
100
+ compile_dir = buildpack.compile(app, options[:env_file], options[:cache])
101
+
102
+ print "* packaging... " unless options[:quiet]
103
+ case type.to_sym
104
+ when :tgz then
105
+ Dir.chdir(compile_dir) do
106
+ system %{ tar czf "#{output}" . }
107
+ end
108
+ when :img then
109
+ raise "img not supported yet"
110
+ when :dir then
111
+ FileUtils.rm_rf output
112
+ FileUtils.cp_r compile_dir, output, :preserve => true
113
+ else
114
+ raise "no such output type: #{type}"
115
+ end
116
+
117
+ unless options[:quiet]
118
+ puts "done"
119
+ puts " = type: #{type}"
120
+ puts " = location: #{output}"
121
+ end
122
+ end
123
+
124
+ end
125
+
126
+ desc "vagrant COMMAND", "run a vagrant command in the mason environment"
127
+
128
+ def vagrant(*args)
129
+ Mason::Stacks.vagrant(args)
130
+ end
131
+
132
+ desc "buildpacks", "list installed buildpacks"
133
+
134
+ def buildpacks
135
+ buildpacks = Mason::Buildpacks.buildpacks
136
+
137
+ puts "* buildpacks (#{Mason::Buildpacks.root(false)})"
138
+ buildpacks.sort.each do |buildpack|
139
+ puts " = #{buildpack.name}: #{buildpack.url}"
140
+ end
141
+
142
+ puts " - no buildpacks installed, use buildpacks:install" if buildpacks.length.zero?
143
+ end
144
+
145
+ class Buildpacks < Thor
146
+
147
+ desc "buildpacks:install URL", "install a buildpack"
148
+
149
+ def install(url)
150
+ puts "* installing buildpack #{url}"
151
+ Mason::Buildpacks.install url
152
+ end
153
+
154
+ desc "buildpacks:uninstall NAME", "uninstall a buildpack"
155
+
156
+ def uninstall(name)
157
+ puts "* uninstalling buildpack #{name}"
158
+ Mason::Buildpacks.uninstall name
159
+ end
160
+
161
+ end
162
+
163
+ desc "stacks", "list available stacks"
164
+
165
+ def stacks
166
+ stacks = Mason::Stacks.stacks
167
+
168
+ puts "* available stacks"
169
+ stacks.keys.each do |name|
170
+ puts " - #{name} [#{Mason::Stacks.state(name)}]"
171
+ end
172
+
173
+ puts " - no stacks created, use stacks:create" if stacks.length.zero?
174
+ end
175
+
176
+ class Stacks < Thor
177
+
178
+ # Hackery. Take the run method away from Thor so that we can redefine it.
179
+ class << self
180
+ def is_thor_reserved_word?(word, type)
181
+ return false if word == 'run'
182
+ super
183
+ end
184
+ end
185
+
186
+ desc "stacks:create VAGRANT_BOX_NAME", "create a new stack"
187
+
188
+ method_option :name, :type => :string, :aliases => "-n", :desc => "use an alternate stack name"
189
+
190
+ def create(box)
191
+ name = options[:name] || box
192
+ print "* creating stack #{name}... "
193
+ Mason::Stacks.create(name, box)
194
+ puts "done"
195
+ end
196
+
197
+ desc "stacks:destroy STACK", "destroy a stack"
198
+
199
+ def destroy(name)
200
+ print "* destroying stack #{name}... "
201
+ Mason::Stacks.destroy(name)
202
+ puts "done"
203
+ end
204
+
205
+ desc "stacks:up STACK", "boot a stack"
206
+
207
+ def up(name)
208
+ print "* booting stack #{name} (this will take a while)..."
209
+ Mason::Stacks.up(name)
210
+ puts "done"
211
+ end
212
+
213
+ desc "stacks:down STACK", "suspend a stack"
214
+
215
+ def down(name)
216
+ print "* stopping stack #{name}..."
217
+ Mason::Stacks.down(name)
218
+ puts "done"
219
+ end
220
+
221
+ desc "stacks:run STACK COMMAND", "run a command on a stack"
222
+
223
+ def run(name, *args)
224
+ Mason::Stacks.run(name, args.join(" "))
225
+ end
226
+
227
+ end
228
+
229
+ # hack thor
230
+ def self.run
231
+ args = ARGV.dup
232
+ parts = args.first.to_s.split(":")
233
+ method = parts.pop
234
+ ns = parts.pop
235
+
236
+ args[0] = method
237
+
238
+ klass = case ns
239
+ when "buildpacks" then Buildpacks
240
+ when "stacks" then Stacks
241
+ else self
242
+ end
243
+
244
+ unless (args & %w( -h --help )).empty?
245
+ klass.task_help(Thor::Shell::Basic.new, args.first)
246
+ return
247
+ end
248
+
249
+ klass.start(args)
250
+ rescue StandardError => ex
251
+ $stderr.puts " ! #{ex}"
252
+ $stderr.puts " " + ex.backtrace.join("\n ") if ARGV.include?("--debug")
253
+ exit 1
254
+ end
255
+
256
+ private
257
+
258
+ def vagrantfile
259
+ FileUtils.mkdir_p File.expand_path("~/.mason")
260
+ file = File.expand_path("~/.mason/Vagrantfile")
261
+ build_vagrantfile unless File.exists?(file)
262
+ file
263
+ end
264
+
265
+ def build_vagrantfile(boxes={})
266
+ data = File.read(File.expand_path("../../../data/Vagrantfile.template", __FILE__))
267
+ data.gsub! "BOXES", (boxes.map do |name, box|
268
+ <<-BOX
269
+ config.vm.define :#{name} do |config|
270
+ config.vm.box = "#{box}"
271
+ end
272
+ BOX
273
+ end.join("\n"))
274
+ File.open(File.expand_path("~/.mason/Vagrantfile"), "w") do |file|
275
+ file.puts data
276
+ end
277
+ end
278
+
279
+ end
@@ -0,0 +1,113 @@
1
+ require "fileutils"
2
+ require "mason"
3
+
4
+ class Mason::Stacks
5
+
6
+ def self.load_vagrant!
7
+ require "vagrant"
8
+ if Gem::Version.new(Vagrant::VERSION) < Gem::Version.new("1.0.1")
9
+ raise "mason requires vagrant 1.0.1 or higher"
10
+ end
11
+ build_vagrantfile unless File.exists?(vagrantfile)
12
+ end
13
+
14
+ def self.vagrant_env(display=false)
15
+ load_vagrant!
16
+ ui = display ? Vagrant::UI::Basic : nil
17
+ Vagrant::Environment.new(:vagrantfile_name => vagrantfile, :ui_class => ui)
18
+ end
19
+
20
+ def self.vms
21
+ vagrant_env.vms
22
+ end
23
+
24
+ def self.vagrant(args)
25
+ vagrant_env(true).cli(args)
26
+ end
27
+
28
+ def self.stacks
29
+ @stacks ||= begin
30
+ vms.inject({}) do |hash, (name, vm)|
31
+ next(hash) if name == :default
32
+ hash.update(name => vm.box ? vm.box.name : "")
33
+ end
34
+ end
35
+ end
36
+
37
+ def self.create(name, box)
38
+ raise "stack already exists: #{name}" if stacks.keys.include?(name.to_sym)
39
+ raise "vagrant box does not exist: #{box}" unless vagrant_env.boxes.map(&:name).include?(box)
40
+ build_vagrantfile(stacks.update(name => box))
41
+ end
42
+
43
+ def self.destroy(name)
44
+ raise "no such stack: #{name}" unless stacks.keys.include?(name.to_sym)
45
+ vm = vms[name.to_sym]
46
+ vm.halt rescue nil
47
+ vm.destroy rescue nil
48
+ s = stacks
49
+ s.delete(name.to_sym)
50
+ build_vagrantfile(s)
51
+ end
52
+
53
+ def self.state(name)
54
+ raise "no such stack: #{name}" unless stacks.keys.include?(name.to_sym)
55
+ case vms[name.to_sym].state.to_sym
56
+ when :running then :up
57
+ else :down
58
+ end
59
+ end
60
+
61
+ def self.up(name)
62
+ raise "no such stack: #{name}" unless stacks.keys.include?(name.to_sym)
63
+ return if state(name) == :up
64
+ vms[name.to_sym].up
65
+ end
66
+
67
+ def self.down(name)
68
+ raise "no such stack: #{name}" unless stacks.keys.include?(name.to_sym)
69
+ return if state(name) == :down
70
+ vms[name.to_sym].suspend
71
+ end
72
+
73
+ def self.run(name, command)
74
+ raise "no suck stack: #{name}" unless stacks.keys.include?(name.to_sym)
75
+ vms[name.to_sym].channel.execute(command, :error_check => false) do |type, data|
76
+ print data
77
+ end
78
+ end
79
+
80
+ def self.vagrantfile
81
+ File.expand_path("~/.mason/Vagrantfile")
82
+ end
83
+
84
+ def self.vagrantfile_template
85
+ File.expand_path("../../../data/Vagrantfile.template", __FILE__)
86
+ end
87
+
88
+ def self.share_dir(name)
89
+ dir = File.expand_path("~/.mason/share/#{name}")
90
+ FileUtils.mkdir_p dir unless File.exists?(dir)
91
+ dir
92
+ end
93
+
94
+ def self.build_vagrantfile(stacks={})
95
+ data = File.read(vagrantfile_template)
96
+ ip_base = 3
97
+ data.gsub! "BOXES", (stacks.map do |name, box|
98
+ ip_base += 1
99
+ <<-BOX
100
+ config.vm.define :#{name} do |config|
101
+ config.vm.box = "#{box}"
102
+ config.vm.base_mac = "080027706AA#{ip_base}"
103
+ config.vm.network :hostonly, "33.33.33.#{ip_base}"
104
+ config.vm.share_folder "share", "/share", "#{share_dir(name)}"
105
+ end
106
+ BOX
107
+ end.join("\n").chomp)
108
+ File.open(vagrantfile, "w") do |file|
109
+ file.puts data
110
+ end
111
+ end
112
+
113
+ end
@@ -0,0 +1,3 @@
1
+ module Mason
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,23 @@
1
+ require './lib/mason/buildpack'
2
+
3
+ describe Mason::Buildpack do
4
+ let(:tempdir) { Dir.tmpdir }
5
+
6
+ subject { Mason::Buildpack.new("/tmp") }
7
+
8
+ before do
9
+ FileUtils.mkdir_p tempdir
10
+ end
11
+
12
+ after do
13
+ FileUtils.rm_rf tempdir
14
+ end
15
+
16
+ describe "#write_procfile" do
17
+ it "uses Foreman to create the Procfile" do
18
+ File.open("#{tempdir}/Procfile", "w+") { |f| f.puts "web: ls -la" }
19
+ subject.send :write_procfile, tempdir, {}
20
+ File.read("#{tempdir}/Procfile").should =~ /web: ls -la/
21
+ end
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: webbynode-mason
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - David Dollar
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: foreman
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.53.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.53.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.11.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.11.0
62
+ description: Build things
63
+ email: ddollar@gmail.com
64
+ executables:
65
+ - mason
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - bin/mason
70
+ - data/Vagrantfile.template
71
+ - lib/mason/buildpack.rb
72
+ - lib/mason/buildpacks.rb
73
+ - lib/mason/cli.rb
74
+ - lib/mason/stacks.rb
75
+ - lib/mason/version.rb
76
+ - lib/mason.rb
77
+ - README.md
78
+ - spec/buildpack_spec.rb
79
+ homepage: http://github.com/ddollar/mason
80
+ licenses: []
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 1.8.21
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Build things
103
+ test_files: []