Skip to content
Newer
Older
100644 194 lines (156 sloc) 5.56 KB
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
1 require "digest/sha1"
caf27cb @ddollar get api key from heroku gem
ddollar authored Feb 10, 2012
2 require "heroku/auth"
3 require "heroku/command"
4 require "heroku/command/base"
5 require "heroku/command/help"
6 require "heroku/plugin"
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
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
548e28e @ddollar remove COMMAND from banner
ddollar authored Sep 22, 2011
17 desc "build", <<-DESC
c272dfc @geemus typo fixes
geemus authored Dec 6, 2011
18 build a piece of software for the heroku cloud using COMMAND as a build command
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
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"
7cafe88 @lpetre Better dependency support (using arrays)
lpetre authored Mar 22, 2012
24 method_option :name, :aliases => "-n", :desc => "the name of the library (defaults to the directory name)"
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
25 method_option :output, :aliases => "-o", :desc => "output build artifacts to this file"
165e543 @ddollar tweak --prefix option help
ddollar authored May 31, 2012
26 method_option :prefix, :aliases => "-p", :desc => "vulcan will look in this path for the compiled artifacts"
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
27 method_option :source, :aliases => "-s", :desc => "the source directory to build from"
7cafe88 @lpetre Better dependency support (using arrays)
lpetre authored Mar 22, 2012
28 method_option :deps, :aliases => "-d", :desc => "urls of vulcan compiled libraries to build with", :type=>:array
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
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
00aced6 @ddollar tweak readme
ddollar authored Sep 21, 2011
34 source = options[:source] || Dir.pwd
35 name = options[:name] || File.basename(source)
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
36 output = options[:output] || "/tmp/#{name}.tgz"
37 prefix = options[:prefix] || "/app/vendor/#{name}"
d1667bf @ddollar put command in the right place
ddollar authored Sep 21, 2011
38 command = options[:command] || "./configure --prefix #{prefix} && make install"
7cafe88 @lpetre Better dependency support (using arrays)
lpetre authored Mar 22, 2012
39 deps = options[:deps] || []
15b90c5 @ddollar rewrite in coffeescript, include keepalive
ddollar authored May 31, 2012
40 server = URI.parse(ENV["VULCAN_HOST"] || "http://#{app}.herokuapp.com")
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
41
42 Dir.mktmpdir do |dir|
15b90c5 @ddollar rewrite in coffeescript, include keepalive
ddollar authored May 31, 2012
43 action "Packaging local directory" do
44 %x{ cd #{source} && tar czvf #{dir}/input.tgz . 2>&1 }
45 end
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
46
47 File.open("#{dir}/input.tgz", "r") do |input|
48 request = Net::HTTP::Post::Multipart.new "/make",
49 "code" => UploadIO.new(input, "application/octet-stream", "input.tgz"),
50 "command" => command,
00aced6 @ddollar tweak readme
ddollar authored Sep 22, 2011
51 "prefix" => prefix,
24bf5ba @lpetre adding support for vulcan build -d <dep1>,...,<depN>
lpetre authored Mar 22, 2012
52 "secret" => config[:secret],
53 "deps" => deps
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
54
15b90c5 @ddollar rewrite in coffeescript, include keepalive
ddollar authored May 31, 2012
55 print "Uploading source package... "
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
56 response = Net::HTTP.start(server.host, server.port) do |http|
57 http.request(request) do |response|
58 response.read_body do |chunk|
15b90c5 @ddollar rewrite in coffeescript, include keepalive
ddollar authored May 31, 2012
59 unless chunk == 0.chr + "\n"
60 print chunk if options[:verbose]
61 end
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
62 end
63 end
64 end
65
66 error "Unknown error, no build output given" unless response["X-Make-Id"]
67
68 puts ">> Downloading build artifacts to: #{output}"
69
635f6c0 @halorgium Print the URL where the output is available
halorgium authored Nov 23, 2011
70 output_url = "#{server}/output/#{response["X-Make-Id"]}"
71 puts " (available at #{output_url})"
72
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
73 File.open(output, "w") do |output|
74 begin
635f6c0 @halorgium Print the URL where the output is available
halorgium authored Nov 24, 2011
75 output.print RestClient.get(output_url)
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
76 rescue Exception => ex
77 puts ex.inspect
78 end
79 end
80 end
81 end
9f8e55e @ddollar gracefully handle ctrl-c
ddollar authored Jan 14, 2012
82 rescue Interrupt
83 error "Aborted by user"
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
84 rescue Errno::EPIPE
85 error "Could not connect to build server: #{server}"
86 end
87
88 desc "create APP_NAME", <<-DESC
89 create a build server on Heroku
90
91 DESC
92
93 def create(name)
94 secret = Digest::SHA1.hexdigest("--#{rand(10000)}--#{Time.now}--")
95
96 Dir.mktmpdir do |dir|
97 Dir.chdir(dir) do
98 system "env BUNDLE_GEMFILE= heroku create #{name} -s cedar"
99 end
100 end
d1d38e1 @hone it's :app not :ap
hone authored Sep 23, 2011
101 write_config :app => name, :host => "#{name}.herokuapp.com", :secret => secret
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
102 update
103 end
104
105
106 desc "update", <<-DESC
107 update the build server
108
109 DESC
110
111 def update
c272dfc @geemus typo fixes
geemus authored Dec 6, 2011
112 error "no app yet, create first" unless config[:app]
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
113
caf27cb @ddollar get api key from heroku gem
ddollar authored Feb 11, 2012
114 # clean up old plugin, can use auth:token now
115 FileUtils.rm_rf(File.expand_path("~/.heroku/plugins/heroku-credentials"))
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
116
117 Dir.mktmpdir do |dir|
118 Dir.chdir(dir) do
caf27cb @ddollar get api key from heroku gem
ddollar authored Feb 11, 2012
119 Heroku::Plugin.load!
120 api_key = Heroku::Auth.api_key
121 error "invalid api key detected, try running `heroku auth:token`" if api_key =~ / /
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
122
123 system "git init"
6410c21 @ricaurte abstracted out the heroku domain that is used for git authentications…
ricaurte authored Jan 19, 2012
124 system "git remote add heroku git@#{heroku_git_domain}:#{config[:app]}.git"
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
125 FileUtils.cp_r "#{server_path}/.", "."
126 File.open(".gitignore", "w") do |file|
127 file.puts ".env"
128 end
5f558b6 @ddollar adjust buildpack location after git remotes are set up
ddollar authored Jan 14, 2012
129
e89ac09 @ddollar silent git
ddollar authored Sep 21, 2011
130 system "git add . >/dev/null"
131 system "git commit -m commit >/dev/null"
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
132 system "git push heroku -f master"
133
a502766 @ddollar fix NODE_ENV, remove unused sessions
ddollar authored Jun 13, 2012
134 heroku "config:add SECRET=#{config[:secret]} SPAWN_ENV=heroku HEROKU_APP=#{config[:app]} HEROKU_API_KEY=#{api_key} NODE_PATH=lib NODE_ENV=production"
15b90c5 @ddollar rewrite in coffeescript, include keepalive
ddollar authored May 31, 2012
135 heroku "addons:add cloudant:oxygen"
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
136 end
137 end
138 end
139
140 private
141
15b90c5 @ddollar rewrite in coffeescript, include keepalive
ddollar authored May 31, 2012
142 def action(message)
143 print "#{message}... "
144 yield
145 puts "done"
146 end
147
148 def heroku(command)
149 %x{ env BUNDLE_GEMFILE= heroku #{command} 2>&1 }
150 end
151
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
152 def config_file
153 File.expand_path("~/.vulcan")
154 end
155
156 def config
157 read_config
158 end
159
160 def read_config
161 return {} unless File.exists?(config_file)
162 config = YAML.load_file(config_file)
163 config.is_a?(Hash) ? config : {}
164 end
165
166 def write_config(config)
167 full_config = read_config.merge(config)
168 File.open(config_file, "w") do |file|
169 file.puts YAML.dump(full_config)
170 end
171 end
172
173 def error(message)
174 puts "!! #{message}"
175 exit 1
176 end
177
178 def server_path
179 File.expand_path("../../../server", __FILE__)
180 end
7d347ed @ddollar dont ignore node_modules
ddollar authored Apr 17, 2012
181
6410c21 @ricaurte abstracted out the heroku domain that is used for git authentications…
ricaurte authored Jan 20, 2012
182 #
183 # heroku_git_domain checks to see if the heroku-accounts plugin is present,
184 # and if so, it will set the domain to the one that matches the credentials
185 # for the currently set account
186 #
187 def heroku_git_domain
188 suffix = %x{ git config heroku.account }
189 suffix = "com" if suffix.nil? or suffix.strip == ""
190 "heroku.#{suffix.strip}"
191 end
60d4eee @ddollar initial
ddollar authored Sep 21, 2011
192
193 end
Something went wrong with that request. Please try again.