Skip to content
This repository
Newer
Older
100644 214 lines (173 sloc) 6.125 kb
60d4eee6 » ddollar
2011-09-21 initial
1 require "digest/sha1"
caf27cbb » ddollar
2012-02-10 get api key from heroku gem
2 require "heroku/auth"
3 require "heroku/command"
4 require "heroku/command/base"
5 require "heroku/command/help"
6 require "heroku/plugin"
60d4eee6 » ddollar
2011-09-21 initial
7 require "net/http/post/multipart"
8 require "rest_client"
9 require "thor"
10 require "tmpdir"
11 require "uri"
12 require "vulcan"
13 require "yaml"
14
15 class Vulcan::CLI < Thor
16
548e28ed » ddollar
2011-09-22 remove COMMAND from banner
17 desc "build", <<-DESC
c272dfc9 » geemus
2011-12-06 typo fixes
18 build a piece of software for the heroku cloud using COMMAND as a build command
60d4eee6 » ddollar
2011-09-21 initial
19 if no COMMAND is specified, a sensible default will be chosen for you
20
21 DESC
22
23 method_option :command, :aliases => "-c", :desc => "the command to run for compilation"
7cafe884 » lpetre
2012-03-22 Better dependency support (using arrays)
24 method_option :name, :aliases => "-n", :desc => "the name of the library (defaults to the directory name)"
60d4eee6 » ddollar
2011-09-21 initial
25 method_option :output, :aliases => "-o", :desc => "output build artifacts to this file"
165e5434 » ddollar
2012-05-31 tweak --prefix option help
26 method_option :prefix, :aliases => "-p", :desc => "vulcan will look in this path for the compiled artifacts"
5b8e6665 » tomykaira
2012-06-06 Enable tgz-ed source file
27 method_option :source, :aliases => "-s", :desc => "the source directory to build from or the tgz-ed source archive"
7cafe884 » lpetre
2012-03-22 Better dependency support (using arrays)
28 method_option :deps, :aliases => "-d", :desc => "urls of vulcan compiled libraries to build with", :type=>:array
60d4eee6 » ddollar
2011-09-21 initial
29 method_option :verbose, :aliases => "-v", :desc => "show the full build output", :type => :boolean
30
31 def build
32 app = read_config[:app] || "need a server first, use vulcan create"
33
00aced64 » ddollar
2011-09-21 tweak readme
34 source = options[:source] || Dir.pwd
7d98337f » ddollar
2012-06-25 better default name
35 name = options[:name] || File.basename(source, File.extname(source))
60d4eee6 » ddollar
2011-09-21 initial
36 output = options[:output] || "/tmp/#{name}.tgz"
37 prefix = options[:prefix] || "/app/vendor/#{name}"
d1667bf3 » ddollar
2011-09-21 put command in the right place
38 command = options[:command] || "./configure --prefix #{prefix} && make install"
7cafe884 » lpetre
2012-03-22 Better dependency support (using arrays)
39 deps = options[:deps] || []
15b90c5a » ddollar
2012-05-31 rewrite in coffeescript, include keepalive
40 server = URI.parse(ENV["VULCAN_HOST"] || "http://#{app}.herokuapp.com")
60d4eee6 » ddollar
2011-09-21 initial
41
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
42 source_is_url = URI.parse(source).scheme
43
60d4eee6 » ddollar
2011-09-21 initial
44 Dir.mktmpdir do |dir|
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
45 unless source_is_url
46 input_tgz = "#{dir}/input.tgz"
47 if source.match(/.tgz$/)
48 input_tgz = source
49 else
50 action "Packaging local directory" do
51 %x{ cd #{source} && tar czvf #{input_tgz} . 2>&1 }
52 end
5b8e6665 » tomykaira
2012-06-06 Enable tgz-ed source file
53 end
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
54 input = File.open(input_tgz, "r")
55 end
56
57 make_options = {
58 "command" => command,
59 "prefix" => prefix,
60 "secret" => config[:secret],
61 "deps" => deps
62 }
63
64 if source_is_url
65 make_options["code_url"] = source
66 else
67 make_options["code"] = UploadIO.new(input, "application/octet-stream", "input.tgz")
15b90c5a » ddollar
2012-05-31 rewrite in coffeescript, include keepalive
68 end
60d4eee6 » ddollar
2011-09-21 initial
69
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
70 request = Net::HTTP::Post::Multipart.new "/make", make_options
60d4eee6 » ddollar
2011-09-21 initial
71
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
72 if source_is_url
73 print "Initializing build... "
74 else
15b90c5a » ddollar
2012-05-31 rewrite in coffeescript, include keepalive
75 print "Uploading source package... "
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
76 end
77
78 response = Net::HTTP.start(server.host, server.port) do |http|
79 http.request(request) do |response|
80 response.read_body do |chunk|
81 unless chunk == 0.chr + "\n"
82 print chunk if options[:verbose]
60d4eee6 » ddollar
2011-09-21 initial
83 end
84 end
85 end
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
86 end
60d4eee6 » ddollar
2011-09-21 initial
87
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
88 error "Unknown error, no build output given" unless response["X-Make-Id"]
60d4eee6 » ddollar
2011-09-21 initial
89
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
90 puts ">> Downloading build artifacts to: #{output}"
60d4eee6 » ddollar
2011-09-21 initial
91
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
92 output_url = "#{server}/output/#{response["X-Make-Id"]}"
93 puts " (available at #{output_url})"
635f6c09 » halorgium
2011-11-23 Print the URL where the output is available
94
ac05ea7e » ddollar
2012-06-25 allow vulcan build to operate on urls
95 File.open(output, "w") do |output|
96 begin
97 output.print RestClient.get(output_url)
98 rescue Exception => ex
99 puts ex.inspect
60d4eee6 » ddollar
2011-09-21 initial
100 end
101 end
102 end
9f8e55e3 » ddollar
2012-01-14 gracefully handle ctrl-c
103 rescue Interrupt
104 error "Aborted by user"
60d4eee6 » ddollar
2011-09-21 initial
105 rescue Errno::EPIPE
106 error "Could not connect to build server: #{server}"
107 end
108
109 desc "create APP_NAME", <<-DESC
110 create a build server on Heroku
111
112 DESC
113
114 def create(name)
115 secret = Digest::SHA1.hexdigest("--#{rand(10000)}--#{Time.now}--")
116
117 Dir.mktmpdir do |dir|
118 Dir.chdir(dir) do
119 system "env BUNDLE_GEMFILE= heroku create #{name} -s cedar"
120 end
121 end
d1d38e12 » hone
2011-09-23 it's :app not :ap
122 write_config :app => name, :host => "#{name}.herokuapp.com", :secret => secret
60d4eee6 » ddollar
2011-09-21 initial
123 update
124 end
125
126
127 desc "update", <<-DESC
128 update the build server
129
130 DESC
131
132 def update
c272dfc9 » geemus
2011-12-06 typo fixes
133 error "no app yet, create first" unless config[:app]
60d4eee6 » ddollar
2011-09-21 initial
134
caf27cbb » ddollar
2012-02-10 get api key from heroku gem
135 # clean up old plugin, can use auth:token now
136 FileUtils.rm_rf(File.expand_path("~/.heroku/plugins/heroku-credentials"))
60d4eee6 » ddollar
2011-09-21 initial
137
138 Dir.mktmpdir do |dir|
139 Dir.chdir(dir) do
caf27cbb » ddollar
2012-02-10 get api key from heroku gem
140 Heroku::Plugin.load!
141 api_key = Heroku::Auth.api_key
142 error "invalid api key detected, try running `heroku auth:token`" if api_key =~ / /
60d4eee6 » ddollar
2011-09-21 initial
143
144 system "git init"
6410c219 » ricaurte
2012-01-19 abstracted out the heroku domain that is used for git authentications…
145 system "git remote add heroku git@#{heroku_git_domain}:#{config[:app]}.git"
60d4eee6 » ddollar
2011-09-21 initial
146 FileUtils.cp_r "#{server_path}/.", "."
147 File.open(".gitignore", "w") do |file|
148 file.puts ".env"
149 end
5f558b6a » ddollar
2012-01-14 adjust buildpack location after git remotes are set up
150
e89ac09c » ddollar
2011-09-21 silent git
151 system "git add . >/dev/null"
152 system "git commit -m commit >/dev/null"
60d4eee6 » ddollar
2011-09-21 initial
153 system "git push heroku -f master"
154
a5027664 » ddollar
2012-06-13 fix NODE_ENV, remove unused sessions
155 heroku "config:add SECRET=#{config[:secret]} SPAWN_ENV=heroku HEROKU_APP=#{config[:app]} HEROKU_API_KEY=#{api_key} NODE_PATH=lib NODE_ENV=production"
15b90c5a » ddollar
2012-05-31 rewrite in coffeescript, include keepalive
156 heroku "addons:add cloudant:oxygen"
60d4eee6 » ddollar
2011-09-21 initial
157 end
158 end
159 end
160
161 private
162
15b90c5a » ddollar
2012-05-31 rewrite in coffeescript, include keepalive
163 def action(message)
164 print "#{message}... "
165 yield
166 puts "done"
167 end
168
169 def heroku(command)
170 %x{ env BUNDLE_GEMFILE= heroku #{command} 2>&1 }
171 end
172
60d4eee6 » ddollar
2011-09-21 initial
173 def config_file
174 File.expand_path("~/.vulcan")
175 end
176
177 def config
178 read_config
179 end
180
181 def read_config
182 return {} unless File.exists?(config_file)
183 config = YAML.load_file(config_file)
184 config.is_a?(Hash) ? config : {}
185 end
186
187 def write_config(config)
188 full_config = read_config.merge(config)
189 File.open(config_file, "w") do |file|
190 file.puts YAML.dump(full_config)
191 end
192 end
193
194 def error(message)
195 puts "!! #{message}"
196 exit 1
197 end
198
199 def server_path
200 File.expand_path("../../../server", __FILE__)
201 end
7d347ed1 » ddollar
2012-04-17 dont ignore node_modules
202
6410c219 » ricaurte
2012-01-19 abstracted out the heroku domain that is used for git authentications…
203 #
204 # heroku_git_domain checks to see if the heroku-accounts plugin is present,
205 # and if so, it will set the domain to the one that matches the credentials
206 # for the currently set account
207 #
208 def heroku_git_domain
209 suffix = %x{ git config heroku.account }
210 suffix = "com" if suffix.nil? or suffix.strip == ""
211 "heroku.#{suffix.strip}"
212 end
60d4eee6 » ddollar
2011-09-21 initial
213
214 end
Something went wrong with that request. Please try again.