Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 169 lines (135 sloc) 4.99 kb
60d4eee @ddollar initial
ddollar authored
1 require "digest/sha1"
2 require "net/http/post/multipart"
3 require "rest_client"
4 require "thor"
5 require "tmpdir"
6 require "uri"
7 require "vulcan"
8 require "yaml"
9
10 class Vulcan::CLI < Thor
11
12 desc "build [COMMAND]", <<-DESC
13 build a piece of software for the heroku cloud using COMMANd as a build command
14 if no COMMAND is specified, a sensible default will be chosen for you
15
16 DESC
17
18 method_option :command, :aliases => "-c", :desc => "the command to run for compilation"
19 method_option :name, :aliases => "-n", :desc => "the name of the library (defaults ot the directory name)"
20 method_option :output, :aliases => "-o", :desc => "output build artifacts to this file"
21 method_option :prefix, :aliases => "-p", :desc => "the build/install --prefix of the software"
22 method_option :source, :aliases => "-s", :desc => "the source directory to build from"
23 method_option :verbose, :aliases => "-v", :desc => "show the full build output", :type => :boolean
24
25 def build
26 app = read_config[:app] || "need a server first, use vulcan create"
27
28 name = options[:name] || File.basename(Dir.pwd)
29 output = options[:output] || "/tmp/#{name}.tgz"
30 prefix = options[:prefix] || "/app/vendor/#{name}"
31 source = options[:source] || Dir.pwd
d1667bf @ddollar put command in the right place
ddollar authored
32 command = options[:command] || "./configure --prefix #{prefix} && make install"
60d4eee @ddollar initial
ddollar authored
33 server = URI.parse(ENV["MAKE_SERVER"] || "http://#{app}.herokuapp.com")
34
35 Dir.mktmpdir do |dir|
36 puts ">> Packaging local directory"
37 %x{ cd #{source} && tar czvf #{dir}/input.tgz . 2>&1 }
38
39 puts ">> Uploading code for build"
40 File.open("#{dir}/input.tgz", "r") do |input|
41 request = Net::HTTP::Post::Multipart.new "/make",
42 "code" => UploadIO.new(input, "application/octet-stream", "input.tgz"),
43 "command" => command,
44 "prefix" => prefix
45
46 puts ">> Building with: #{command}"
47 response = Net::HTTP.start(server.host, server.port) do |http|
48 http.request(request) do |response|
49 response.read_body do |chunk|
50 print chunk if options[:verbose]
51 end
52 end
53 end
54
55 error "Unknown error, no build output given" unless response["X-Make-Id"]
56
57 puts ">> Downloading build artifacts to: #{output}"
58
59 File.open(output, "w") do |output|
60 begin
61 output.print RestClient.get("#{server}/output/#{response["X-Make-Id"]}")
62 rescue Exception => ex
63 puts ex.inspect
64 end
65 end
66 end
67 end
68 rescue Errno::EPIPE
69 error "Could not connect to build server: #{server}"
70 end
71
72 desc "create APP_NAME", <<-DESC
73 create a build server on Heroku
74
75 DESC
76
77 def create(name)
78 secret = Digest::SHA1.hexdigest("--#{rand(10000)}--#{Time.now}--")
79
80 Dir.mktmpdir do |dir|
81 Dir.chdir(dir) do
82 system "env BUNDLE_GEMFILE= heroku create #{name} -s cedar"
83 end
84 end
85 write_config :ap=> name, :host => "#{name}.herokuapp.com", :secret => secret
86 update
87 end
88
89
90 desc "update", <<-DESC
91 update the build server
92
93 DESC
94
95 def update
96 error "no apyet, create first" unless config[:app]
97
98 FileUtils.mkdir_p File.expand_path("~/.heroku/plugins/heroku-credentials")
99
100 File.open(File.expand_path("~/.heroku/plugins/heroku-credentials/init.rb"), "w") do |file|
101 file.puts <<-CONTENTS
378efdd @ddollar better api key getting
ddollar authored
102 class Heroku::Auth
103 def self.api_key
104 Heroku::Client.auth(user, password, host)["api_key"]
105 end
106 end
60d4eee @ddollar initial
ddollar authored
107 class Heroku::Command::Credentials < Heroku::Command::Base
108 def index
378efdd @ddollar better api key getting
ddollar authored
109 puts Heroku::Auth.api_key
60d4eee @ddollar initial
ddollar authored
110 end
111 end
112 CONTENTS
113 end
114
115 Dir.mktmpdir do |dir|
116 Dir.chdir(dir) do
117 api_key = %x{ env BUNDLE_GEMFILE= heroku credentials }
118
119 system "git init"
120 system "git remote add heroku git@heroku.com:#{config[:app]}.git"
121 FileUtils.cp_r "#{server_path}/.", "."
122 File.open(".gitignore", "w") do |file|
123 file.puts ".env"
124 file.puts "node_modules"
125 end
e89ac09 @ddollar silent git
ddollar authored
126 system "git add . >/dev/null"
127 system "git commit -m commit >/dev/null"
60d4eee @ddollar initial
ddollar authored
128 system "git push heroku -f master"
129
130 %x{ env BUNDLE_GEMFILE= heroku config:add SECRET=#{config[:secret]} SPAWN_ENV=heroku HEROKU_APP=#{config[:app]} HEROKU_API_KEY=#{api_key} 2>&1 }
131 %x{ env BUNDLE_GEMFILE= heroku addons:add cloudant:oxygen }
132 end
133 end
134 end
135
136 private
137
138 def config_file
139 File.expand_path("~/.vulcan")
140 end
141
142 def config
143 read_config
144 end
145
146 def read_config
147 return {} unless File.exists?(config_file)
148 config = YAML.load_file(config_file)
149 config.is_a?(Hash) ? config : {}
150 end
151
152 def write_config(config)
153 full_config = read_config.merge(config)
154 File.open(config_file, "w") do |file|
155 file.puts YAML.dump(full_config)
156 end
157 end
158
159 def error(message)
160 puts "!! #{message}"
161 exit 1
162 end
163
164 def server_path
165 File.expand_path("../../../server", __FILE__)
166 end
167
168 end
Something went wrong with that request. Please try again.