apperol 0.0.7 → 0.0.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0e9e981c70db00587f3b2340a9d452ce9176edd0
4
- data.tar.gz: f898bafdb9d0d814335b91de19e9c33c4e727f35
3
+ metadata.gz: 5ac9811222d781a47081d4c75503a5c4a0d1fdd6
4
+ data.tar.gz: 42f10ad07bf9cf917604fd01425fa35538bd95ff
5
5
  SHA512:
6
- metadata.gz: acb1d55c64aa1d3fc98f247c44d7bf6ec686a61db8898e4b88cb9790bfe4bbcb30a9647280692ebce533eefebd13030ca2024bbd4dff1290d62b60758ce218b0
7
- data.tar.gz: 7dfb3ecb7b81c2f6110c069f5bf5b64d0f82fbb4f905bdca8db2ead39aab7ebb93ba4ae539046bafe19de251b44fac989e76ed9021423740cd9c7d31ef8f86a1
6
+ metadata.gz: 96ec2f030b2e8f6fc5e4a628cb8377e9bc41141fe48397742c592d73448e5b78b219f45c3a42ebbd9bab24196220f36d7f534b72a4a31e35588cf32b84feba61
7
+ data.tar.gz: b46aa47a94c0dd798cf9812b8e486d690c45cf92c659929718018c49aabd2a347180390c6e98458c4a9b8f0bf2b8b05bbdc4dd40be3668e7623ab35d190ec078
data/.gitignore CHANGED
@@ -11,4 +11,5 @@
11
11
  *.so
12
12
  *.o
13
13
  *.a
14
+ *.gem
14
15
  mkmf.log
data/apperol.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "apperol"
8
8
  spec.version = Apperol::VERSION
9
9
  spec.authors = ["Yannick"]
10
- spec.email = ["yannick@heroku.com"]
10
+ spec.email = ["yannick@heroku.com", "opensource@heroku.com"]
11
11
  spec.summary = %q{Create heroku app from heroku repository}
12
12
  spec.description = %q{Create heroku app from heroku repository with app.json}
13
13
  spec.homepage = "https://github.com/ys/apperol"
data/lib/apperol/cli.rb CHANGED
@@ -7,6 +7,9 @@ require "netrc"
7
7
  require "spinning_cursor"
8
8
 
9
9
  require_relative "app_json"
10
+ require_relative "creds"
11
+ require_relative "heroku_client"
12
+ require_relative "github_client"
10
13
 
11
14
  module Apperol
12
15
  class CLI
@@ -48,66 +51,91 @@ module Apperol
48
51
  @app_extension = args.shift
49
52
 
50
53
  unless @app_extension
51
- $stderr.puts("usage: apperol [options] [app_extension]")
54
+ $stderr.puts(parser.help)
52
55
  exit EX_USAGE
53
56
  end
54
57
  end
55
58
 
56
59
  def call
57
- heroku_app_setup
60
+ launch_app_setup do |response|
61
+ build_id = response["id"]
62
+ output_stream_url = get_output_stream_url(build_id)
63
+ stream_build(output_stream_url)
64
+ finalizing_setup(build_id)
65
+ end
58
66
  end
59
67
 
60
- def heroku_app_setup
61
- req = Net::HTTP::Post.new(app_setup_url, initheader = heroku_headers)
62
- req.basic_auth *heroku_creds
63
- req.body = app_setup_payload
68
+ private
69
+
70
+ def launch_app_setup
64
71
  $stdout.puts("Setting up heroku app #{heroku_app_name}-#{@app_extension}")
65
- res = heroku_http.request(req)
66
- if res.code != "202"
67
- $stderr.puts JSON.parse(res.body)["message"]
72
+ response = heroku_client.post(app_setup_url, app_setup_payload)
73
+ if response.status != 202
74
+ $stderr.puts response.body["message"]
68
75
  exit 1
69
76
  else
70
- poll_app_status(JSON.parse(res.body))
77
+ yield response.body
71
78
  end
72
79
  end
73
80
 
74
- def poll_app_status(response)
75
- req = Net::HTTP::Get.new(app_setup_url(response["id"]), initheader = heroku_headers)
76
- req.basic_auth *heroku_creds
77
- res = {}
78
- spin_wait("Setting up your app", "App setup done") do
79
- loop do
80
- res = JSON.parse(heroku_http.request(req).body)
81
- break unless res["status"] == "pending"
82
- end
81
+ def get_output_stream_url(build_id)
82
+ response = loop_on_build_until(build_id) do |response|
83
+ !response.body["build"]["output_stream_url"].nil? || response.body["status"] != "pending"
83
84
  end
84
- if res["status"] == "succeeded"
85
- unless res["postdeploy"].empty?
86
- $stdout.puts(res["postdeploy"]["output"])
87
- end
88
- $stdout.puts("Application #{res["app"]["name"]}.herokuapp.com has been successfully created.")
85
+ response.body["build"]["output_stream_url"]
86
+ end
87
+
88
+ def stream_build(url)
89
+ heroku_client.stream_build(url) do |chunk|
90
+ puts chunk
91
+ end
92
+ end
93
+
94
+ def finalizing_setup(build_id)
95
+ response = loop_on_build_until(build_id) do |response|
96
+ response.body["status"] != "pending"
97
+ end
98
+ if response.body["status"] == "succeeded"
99
+ $stdout.puts("Application #{response.body["app"]["name"]}.herokuapp.com has been successfully created.")
89
100
  exit 0
90
101
  else
91
- $stderr.puts("error: #{res["failure_message"]}")
92
- unless res["manifest_errors"].empty?
93
- $stderr.puts(" #{res["manifest_errors"]}")
102
+ $stderr.puts("error: #{response.body["failure_message"]}")
103
+ unless response.body["manifest_errors"].empty?
104
+ $stderr.puts(" #{response.body["manifest_errors"]}")
94
105
  end
95
- unless res["postdeploy"].empty?
96
- $stderr.puts(res["postdeploy"]["output"])
106
+ unless response.body["postdeploy"].empty?
107
+ $stderr.puts(response.body["postdeploy"]["output"])
97
108
  end
98
109
  exit 1
99
110
  end
100
111
  end
101
112
 
113
+ def loop_on_build_until(build_id)
114
+ response = nil
115
+ spin_wait("Setting up your app", "App setup done") do
116
+ loop do
117
+ response = heroku_client.get(app_setup_url(build_id))
118
+ break if yield(response)
119
+ end
120
+ end
121
+ response
122
+ end
123
+
124
+ def heroku_client
125
+ @heroku_client ||= Apperol::HerokuClient.new
126
+ end
127
+
128
+ def github_client
129
+ @github_client ||= Apperol::GithubClient.new
130
+ end
131
+
102
132
  def spin_wait(banner_txt, message_txt)
103
133
  SpinningCursor.run do
104
134
  banner banner_txt
105
135
  type :dots
106
136
  message message_txt
107
137
  end
108
-
109
138
  yield
110
-
111
139
  SpinningCursor.stop
112
140
  end
113
141
 
@@ -115,19 +143,6 @@ module Apperol
115
143
  URI("https://api.heroku.com/app-setups/#{id}")
116
144
  end
117
145
 
118
- def heroku_headers
119
- {
120
- "Content-Type" => "application/json",
121
- "Accept" => "application/vnd.heroku+json; version=3"
122
- }
123
- end
124
-
125
- def heroku_http
126
- @heroku_http ||= Net::HTTP.new(app_setup_url.hostname, app_setup_url.port).tap do |http|
127
- http.use_ssl = true
128
- end
129
- end
130
-
131
146
  def app_setup_payload
132
147
  payload = {
133
148
  app: {
@@ -155,27 +170,13 @@ module Apperol
155
170
  end
156
171
 
157
172
  def github_tarball_location
158
- $stdout.puts("Getting tarball location for empirical branch #{github_branch}")
159
- res = github_get(tarball_path)
160
- if res["Location"]
161
- res["Location"]
162
- else
163
- $stderr.puts("error: No tarball found for #{github_url + tarball_path} : #{JSON.parse(res.body)["message"]}")
173
+ $stdout.puts("Getting tarball location for #{repo} on branch #{branch}")
174
+ location = github_client.tarball(repo, branch)
175
+ unless location
176
+ $stderr.puts("error: No tarball found for #{repo}")
164
177
  exit 1
165
178
  end
166
- end
167
-
168
- def github_get(path)
169
- puts github_url + path
170
- req = Net::HTTP::Get.new(github_url + path)
171
- req.basic_auth *github_creds
172
- github_http.request(req)
173
- end
174
-
175
- def github_http
176
- @github_http ||= Net::HTTP.new(github_url.hostname, github_url.port).tap do |http|
177
- http.use_ssl = true
178
- end
179
+ location
179
180
  end
180
181
 
181
182
  def personal_app?
@@ -196,19 +197,12 @@ module Apperol
196
197
 
197
198
  def user
198
199
  @user ||= @options.fetch(:user) {
199
- res = github_get("/user")
200
- JSON.parse(res.body)["login"]
201
- }
202
- end
203
-
204
- def rollbar_token
205
- @options.fetch(:rollbar_token) {
206
- $stdout.puts("Missing rollbar_token option, its not required but you won't have exception tracking")
207
- ""
200
+ res = github_client.get("/user")
201
+ res.body["login"]
208
202
  }
209
203
  end
210
204
 
211
- def github_branch
205
+ def branch
212
206
  @options.fetch(:branch, "master")
213
207
  end
214
208
 
@@ -222,26 +216,6 @@ module Apperol
222
216
  }
223
217
  end
224
218
 
225
- def github_url
226
- URI("https://api.github.com")
227
- end
228
-
229
- def tarball_path
230
- "/repos/#{repo}/tarball/#{github_branch}"
231
- end
232
-
233
- def github_creds
234
- netrc["api.github.com"]
235
- end
236
-
237
- def heroku_creds
238
- netrc["api.heroku.com"]
239
- end
240
-
241
- def netrc
242
- @netrc ||= Netrc.read
243
- end
244
-
245
219
  def heroku_app_name
246
220
  Dir.pwd.split("/").last
247
221
  end
@@ -0,0 +1,29 @@
1
+ module Apperol
2
+ class Creds
3
+ class << self
4
+ def heroku
5
+ instance.heroku
6
+ end
7
+
8
+ def github
9
+ instance.github
10
+ end
11
+
12
+ def instance
13
+ @instance ||= new
14
+ end
15
+ end
16
+
17
+ def heroku
18
+ netrc["api.heroku.com"]
19
+ end
20
+
21
+ def github
22
+ netrc["api.github.com"]
23
+ end
24
+
25
+ def netrc
26
+ @netrc ||= Netrc.read
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require_relative "response"
2
+
3
+ module Apperol
4
+ class GithubClient
5
+
6
+ def tarball(repository, branch = "master")
7
+ tarball_path = "/repos/#{repository}/tarball/#{branch}"
8
+ res = get(tarball_path)
9
+ res.header("Location")
10
+ end
11
+
12
+ def get(path)
13
+ req = Net::HTTP::Get.new(url + path)
14
+ req.basic_auth *Apperol::Creds.github
15
+ res = client.request(req)
16
+ Apperol::Response.new(res.code, res.body, headers: res.to_hash)
17
+ end
18
+
19
+ def client
20
+ @client ||= Net::HTTP.new(url.hostname, url.port).tap do |http|
21
+ http.use_ssl = true
22
+ end
23
+ end
24
+
25
+ def url
26
+ URI("https://api.github.com")
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,54 @@
1
+ require_relative "response"
2
+
3
+ module Apperol
4
+ class HerokuClient
5
+
6
+ def get(url)
7
+ request = Net::HTTP::Get.new(url, initheader = default_headers)
8
+ request.basic_auth *Apperol::Creds.heroku
9
+ res = client.request(request)
10
+ Apperol::Response.new(res.code, res.body)
11
+ end
12
+
13
+ def post(url, body)
14
+ request = Net::HTTP::Post.new(url, initheader = default_headers)
15
+ request.basic_auth *Apperol::Creds.heroku
16
+ request.body = body
17
+ res = client.request(request)
18
+ Apperol::Response.new(res.code, res.body)
19
+ end
20
+
21
+ def stream_build(url)
22
+ req = Net::HTTP::Get.new(url, initheader = default_headers)
23
+ req.basic_auth *Apperol::Creds.heroku
24
+ builds_client.request req do |response|
25
+ response.read_body do |chunk|
26
+ yield chunk
27
+ end
28
+ end
29
+ end
30
+
31
+ def builds_client
32
+ @builds_client ||= Net::HTTP.new(builds_url.hostname, 443).tap do |http|
33
+ http.use_ssl = true
34
+ end
35
+ end
36
+
37
+ def builds_url
38
+ URI("https://build-output.heroku.com")
39
+ end
40
+
41
+ def default_headers
42
+ {
43
+ "Content-Type" => "application/json",
44
+ "Accept" => "application/vnd.heroku+json; version=edge"
45
+ }
46
+ end
47
+
48
+ def client
49
+ @client ||= Net::HTTP.new("api.heroku.com", 443).tap do |http|
50
+ http.use_ssl = true
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,24 @@
1
+ module Apperol
2
+ class Response
3
+ attr_accessor :status, :original_body, :headers
4
+
5
+ def initialize(status, body, options = {})
6
+ @status = status.to_i
7
+ @original_body = body
8
+ @headers = options[:headers]
9
+ end
10
+
11
+ def body
12
+ @body ||= JSON.parse(original_body)
13
+ end
14
+
15
+ def header(key)
16
+ @headers[key.downcase].first
17
+ end
18
+
19
+ def [](key)
20
+ puts @headers
21
+ @headers[key.downcase].first
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Apperol
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apperol
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yannick
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-23 00:00:00.000000000 Z
11
+ date: 2014-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -69,6 +69,7 @@ dependencies:
69
69
  description: Create heroku app from heroku repository with app.json
70
70
  email:
71
71
  - yannick@heroku.com
72
+ - opensource@heroku.com
72
73
  executables:
73
74
  - apperol
74
75
  extensions: []
@@ -84,6 +85,10 @@ files:
84
85
  - lib/apperol.rb
85
86
  - lib/apperol/app_json.rb
86
87
  - lib/apperol/cli.rb
88
+ - lib/apperol/creds.rb
89
+ - lib/apperol/github_client.rb
90
+ - lib/apperol/heroku_client.rb
91
+ - lib/apperol/response.rb
87
92
  - lib/apperol/version.rb
88
93
  homepage: https://github.com/ys/apperol
89
94
  licenses: