pagoda 0.3.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/Gemfile +3 -3
- data/Gemfile.lock +33 -24
- data/README.md +68 -0
- data/Rakefile +4 -7
- data/bin/pagoda +100 -8
- data/lib/pagoda/cli/commands/clone.rb +13 -0
- data/lib/pagoda/cli/commands/create.rb +13 -0
- data/lib/pagoda/cli/commands/deploy.rb +12 -0
- data/lib/pagoda/cli/commands/destroy.rb +16 -0
- data/lib/pagoda/cli/commands/info.rb +13 -0
- data/lib/pagoda/cli/commands/init.rb +13 -0
- data/lib/pagoda/cli/commands/list.rb +20 -0
- data/lib/pagoda/cli/commands/rename.rb +17 -0
- data/lib/pagoda/cli/commands/rollback.rb +12 -0
- data/lib/pagoda/cli/commands/ssh_key.rb +27 -0
- data/lib/pagoda/cli/commands/tunnel.rb +18 -0
- data/lib/pagoda/cli/commands.rb +11 -0
- data/lib/pagoda/{helpers.rb → cli/core_ext.rb} +10 -118
- data/lib/pagoda/cli/helpers/app.rb +143 -0
- data/lib/pagoda/cli/helpers/base.rb +199 -0
- data/lib/pagoda/cli/helpers/key.rb +69 -0
- data/lib/pagoda/cli/helpers/tunnel.rb +36 -0
- data/lib/pagoda/cli/helpers.rb +127 -0
- data/lib/pagoda/cli/override.rb +23 -0
- data/lib/pagoda/cli/version.rb +5 -0
- data/lib/pagoda/cli.rb +11 -0
- data/lib/pagoda-cli.rb +1 -0
- data/pagoda.gemspec +20 -24
- data/pagoda.rdoc +139 -0
- data/pkg/newpagoda-0.1.10.gem +0 -0
- data/pkg/newpagoda-0.1.11.gem +0 -0
- data/pkg/newpagoda-0.1.12.gem +0 -0
- data/pkg/newpagoda-0.1.13.gem +0 -0
- data/pkg/newpagoda-0.1.15.gem +0 -0
- data/pkg/newpagoda-0.1.4.gem +0 -0
- data/pkg/newpagoda-0.1.6.gem +0 -0
- data/pkg/newpagoda-0.1.7.gem +0 -0
- data/pkg/newpagoda-0.1.8.gem +0 -0
- data/pkg/newpagoda-0.1.9.gem +0 -0
- data/pkg/newpagoda-0.5.0.gem +0 -0
- data/spec/lib/helper_spec.rb +32 -0
- data/spec/lib/helpers/app_spec.rb +104 -0
- data/spec/lib/helpers/base_spec.rb +27 -0
- data/spec/lib/helpers/key_spec.rb +42 -0
- data/spec/lib/helpers/tunnel_spec.rb +30 -0
- data/spec/spec_helper.rb +17 -0
- metadata +74 -50
- data/.bundle/config +0 -1
- data/README +0 -3
- data/lib/pagoda/client.rb +0 -225
- data/lib/pagoda/command.rb +0 -96
- data/lib/pagoda/commands/app.rb +0 -247
- data/lib/pagoda/commands/auth.rb +0 -149
- data/lib/pagoda/commands/base.rb +0 -184
- data/lib/pagoda/commands/db.rb +0 -18
- data/lib/pagoda/commands/help.rb +0 -100
- data/lib/pagoda/commands/tunnel.rb +0 -49
- data/lib/pagoda/tunnel_proxy.rb +0 -130
- data/lib/pagoda/version.rb +0 -3
- data/lib/pagoda.rb +0 -3
- data/spec/base.rb +0 -21
- data/spec/client_spec.rb +0 -255
- data/spec/command_spec.rb +0 -26
- data/spec/commands/auth_spec.rb +0 -57
data/lib/pagoda/client.rb
DELETED
@@ -1,225 +0,0 @@
|
|
1
|
-
require 'pagoda/version'
|
2
|
-
require 'rexml/document'
|
3
|
-
require 'rest_client'
|
4
|
-
require 'uri'
|
5
|
-
require 'json/pure' unless {}.respond_to?(:to_json)
|
6
|
-
|
7
|
-
class Pagoda::Client
|
8
|
-
|
9
|
-
attr_reader :user, :password
|
10
|
-
|
11
|
-
class << self
|
12
|
-
def version
|
13
|
-
Pagoda::VERSION
|
14
|
-
end
|
15
|
-
|
16
|
-
def gem_version_string
|
17
|
-
"pagoda-gem/#{version}"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def initialize(user, password)
|
22
|
-
@user = user
|
23
|
-
@password = password
|
24
|
-
end
|
25
|
-
|
26
|
-
def app_list
|
27
|
-
doc = xml(get("/apps.xml").to_s)
|
28
|
-
doc.elements['apps'].elements.to_a('//app/').inject([]) do |list, app|
|
29
|
-
list << {
|
30
|
-
:name => app.elements['name'].text,
|
31
|
-
:instances => app.elements['instances'].text,
|
32
|
-
:git_url => app.elements['git-url'].text
|
33
|
-
}
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def database_exists?(app, mysql_instance)
|
38
|
-
begin
|
39
|
-
response = get("/apps/#{app}/databases/#{mysql_instance}.xml")
|
40
|
-
true
|
41
|
-
rescue RestClient::ResourceNotFound => e
|
42
|
-
false
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
def app_database_create(app)
|
48
|
-
response = post("/apps/#{app}/databases.xml", {:mysql_instance => {:ram => 10}})
|
49
|
-
end
|
50
|
-
|
51
|
-
def app_create(name, git_url)
|
52
|
-
doc = xml(post("/apps.xml", {:app => {:name => name, :git_url => git_url}}).to_s)
|
53
|
-
doc.elements.to_a('//app/*').inject({}) do |hash, element|
|
54
|
-
case element.name
|
55
|
-
when "owner"
|
56
|
-
hash[:owner] = {:username => element.elements['username'].text, :email => element.elements['email'].text}
|
57
|
-
when "collaborators"
|
58
|
-
hash[:collaborators] = element.elements.to_a('//collaborator/').inject([]) do |list, collaborator|
|
59
|
-
list << {:username => collaborator.elements['username'].text, :email => collaborator.elements['email'].text}
|
60
|
-
end
|
61
|
-
when "transactions"
|
62
|
-
hash[:transactions] = element.elements.to_a('//transaction/').inject([]) do |list, transaction|
|
63
|
-
list << {
|
64
|
-
:id => transaction.elements["id"].text,
|
65
|
-
:name => transaction.elements["name"].text,
|
66
|
-
:description => transaction.elements["description"].text,
|
67
|
-
:state => transaction.elements["state"].text,
|
68
|
-
:status => transaction.elements["status"].text
|
69
|
-
}
|
70
|
-
end
|
71
|
-
else
|
72
|
-
hash[element.name.gsub(/-/, '_').to_sym] = element.text
|
73
|
-
end
|
74
|
-
hash
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def app_info(app)
|
79
|
-
doc = xml(get("/apps/#{app}.xml").to_s)
|
80
|
-
doc.elements.to_a('//app/*').inject({}) do |hash, element|
|
81
|
-
case element.name
|
82
|
-
when "owner"
|
83
|
-
hash[:owner] = {:username => element.elements['username'].text, :email => element.elements['email'].text}
|
84
|
-
when "collaborators"
|
85
|
-
hash[:collaborators] = element.elements.to_a('//collaborator/').inject([]) do |list, collaborator|
|
86
|
-
list << {:username => collaborator.elements['username'].text, :email => collaborator.elements['email'].text}
|
87
|
-
end
|
88
|
-
when "transactions"
|
89
|
-
hash[:transactions] = element.elements.to_a('//transaction/').inject([]) do |list, transaction|
|
90
|
-
list << {
|
91
|
-
:id => transaction.elements["id"].text,
|
92
|
-
:name => transaction.elements["name"].text,
|
93
|
-
:description => transaction.elements["description"].text,
|
94
|
-
:state => transaction.elements["state"].text,
|
95
|
-
:status => transaction.elements["status"].text
|
96
|
-
}
|
97
|
-
end
|
98
|
-
else
|
99
|
-
hash[element.name.gsub(/-/, '_').to_sym] = element.text
|
100
|
-
end
|
101
|
-
hash
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def app_update(app, updates)
|
106
|
-
put("/apps/#{app}.xml", {:update => updates}).to_s
|
107
|
-
end
|
108
|
-
|
109
|
-
def app_destroy(app)
|
110
|
-
delete("/apps/#{app}.xml").to_s
|
111
|
-
end
|
112
|
-
|
113
|
-
def transaction_list(app)
|
114
|
-
doc = xml(get("/apps/#{app}/transactions.xml").to_s)
|
115
|
-
doc.elements['transactions'].elements.to_a('//transaction/').inject([]) do |list, transaction|
|
116
|
-
list << {
|
117
|
-
:id => transaction.elements['id'].text,
|
118
|
-
:name => transaction.elements['name'].text,
|
119
|
-
:description => transaction.elements['description'].text,
|
120
|
-
:state => transaction.elements['state'].text,
|
121
|
-
:status => transaction.elements['status'].text
|
122
|
-
}
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def transaction_status(app, transaction)
|
127
|
-
doc = xml(get("/apps/#{app}/transactions/#{transaction}.xml").to_s)
|
128
|
-
doc.elements.to_a('//transaction/*').inject({}) { |hash, element| hash[element.name.gsub(/-/, '_').to_sym] = element.text; hash }
|
129
|
-
end
|
130
|
-
|
131
|
-
def rewind(app, places=1)
|
132
|
-
doc = xml(put("/apps/#{app}/rewind.xml", {:places => places}).to_s)
|
133
|
-
doc.elements.to_a('//transaction/*').inject({}) { |hash, element| hash[element.name.gsub(/-/, '_').to_sym] = element.text; hash }
|
134
|
-
end
|
135
|
-
|
136
|
-
def fast_forward(app, places=1)
|
137
|
-
doc = xml(put("/apps/#{app}/fast-forward.xml", {:places => places}).to_s)
|
138
|
-
doc.elements.to_a('//transaction/*').inject({}) { |hash, element| hash[element.name.gsub(/-/, '_').to_sym] = element.text; hash }
|
139
|
-
end
|
140
|
-
|
141
|
-
def rollback(app)
|
142
|
-
get("/apps/#{app}/rollback.xml").to_s
|
143
|
-
end
|
144
|
-
|
145
|
-
def deploy_latest(app)
|
146
|
-
doc = xml(post("/apps/#{app}/deploy.xml").to_s)
|
147
|
-
doc.elements.to_a('//transaction/*').inject({}) { |hash, element| hash[element.name.gsub(/-/, '_').to_sym] = element.text; hash }
|
148
|
-
end
|
149
|
-
|
150
|
-
def deploy(app, branch, commit)
|
151
|
-
doc = xml(post("/apps/#{app}/deploy.xml", {:deploy => {:branch => branch, :commit => commit}}).to_s)
|
152
|
-
doc.elements.to_a('//transaction/*').inject({}) { |hash, element| hash[element.name.gsub(/-/, '_').to_sym] = element.text; hash }
|
153
|
-
end
|
154
|
-
|
155
|
-
# def deploy(app)
|
156
|
-
# doc = xml(put("/apps/#{app}/deploy.xml").to_s)
|
157
|
-
# doc.elements.to_a('//transaction/*').inject({}) { |hash, element| hash[element.name.gsub(/-/, '_').to_sym] = element.text; hash }
|
158
|
-
# end
|
159
|
-
|
160
|
-
def scale_up(app, qty=1)
|
161
|
-
doc = xml(put("/apps/#{app}/scale-up.xml").to_s)
|
162
|
-
doc.elements.to_a('//transaction/*').inject({}) { |hash, element| hash[element.name.gsub(/-/, '_').to_sym] = element.text; hash }
|
163
|
-
end
|
164
|
-
|
165
|
-
def scale_down(app, qty=1)
|
166
|
-
doc = xml(put("/apps/#{app}/scale-down.xml").to_s)
|
167
|
-
doc.elements.to_a('//transaction/*').inject({}) { |hash, element| hash[element.name.gsub(/-/, '_').to_sym] = element.text; hash }
|
168
|
-
end
|
169
|
-
|
170
|
-
def app_databases(app)
|
171
|
-
doc = xml(get("/apps/#{app}/databases.xml").to_s)
|
172
|
-
doc.elements['databases'].elements.to_a('//database/').inject([]) {|list, instance| list << {:name => instance.elements['name'].text} }
|
173
|
-
end
|
174
|
-
|
175
|
-
def on_warning(&blk)
|
176
|
-
@warning_callback = blk
|
177
|
-
end
|
178
|
-
|
179
|
-
protected
|
180
|
-
|
181
|
-
def resource(uri)
|
182
|
-
RestClient.proxy = ENV['HTTP_PROXY'] || ENV['http_proxy']
|
183
|
-
if uri =~ /^https?/
|
184
|
-
RestClient::Resource.new(uri, @user, @password)
|
185
|
-
else
|
186
|
-
# RestClient::Resource.new("http://127.0.0.1:3000#{uri}", @user, @password)
|
187
|
-
RestClient::Resource.new("https://dashboard.pagodabox.com#{uri}", @user, @password)
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
def get(uri, extra_headers={})
|
192
|
-
process(:get, uri, extra_headers)
|
193
|
-
end
|
194
|
-
|
195
|
-
def post(uri, payload="", extra_headers={})
|
196
|
-
process(:post, uri, extra_headers, payload)
|
197
|
-
end
|
198
|
-
|
199
|
-
def put(uri, payload="", extra_headers={})
|
200
|
-
process(:put, uri, extra_headers, payload)
|
201
|
-
end
|
202
|
-
|
203
|
-
def delete(uri, extra_headers={})
|
204
|
-
process(:delete, uri, extra_headers)
|
205
|
-
end
|
206
|
-
|
207
|
-
def process(method, uri, extra_headers={}, payload=nil)
|
208
|
-
headers = pagoda_headers.merge(extra_headers)
|
209
|
-
args = [method, payload, headers].compact
|
210
|
-
response = resource(uri).send(*args)
|
211
|
-
end
|
212
|
-
|
213
|
-
def pagoda_headers
|
214
|
-
{
|
215
|
-
'User-Agent' => self.class.gem_version_string,
|
216
|
-
'X-Ruby-Version' => RUBY_VERSION,
|
217
|
-
'X-Ruby-Platform' => RUBY_PLATFORM,
|
218
|
-
}
|
219
|
-
end
|
220
|
-
|
221
|
-
def xml(raw) # :nodoc:
|
222
|
-
REXML::Document.new(raw)
|
223
|
-
end
|
224
|
-
|
225
|
-
end
|
data/lib/pagoda/command.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
require 'pagoda/helpers'
|
2
|
-
require 'pagoda/tunnel_proxy'
|
3
|
-
require 'pagoda/commands/base'
|
4
|
-
require 'pagoda/commands/auth'
|
5
|
-
require 'pagoda/commands/app'
|
6
|
-
require 'pagoda/commands/db'
|
7
|
-
require 'pagoda/commands/help'
|
8
|
-
require 'pagoda/commands/tunnel'
|
9
|
-
|
10
|
-
module Pagoda
|
11
|
-
module Command
|
12
|
-
class InvalidCommand < RuntimeError; end
|
13
|
-
class CommandFailed < RuntimeError; end
|
14
|
-
|
15
|
-
extend Pagoda::Helpers
|
16
|
-
|
17
|
-
class << self
|
18
|
-
|
19
|
-
def run(command, args, retries=0)
|
20
|
-
begin
|
21
|
-
run_internal 'auth:reauthorize', args.dup if retries > 0
|
22
|
-
run_internal(command, args.dup)
|
23
|
-
rescue InvalidCommand
|
24
|
-
error "Unknown command: #{command}. Run 'pagoda help' for usage information."
|
25
|
-
rescue RestClient::Unauthorized
|
26
|
-
if retries < 3
|
27
|
-
STDERR.puts "Authentication failure"
|
28
|
-
run(command, args, retries+1)
|
29
|
-
else
|
30
|
-
error "Authentication failure"
|
31
|
-
end
|
32
|
-
rescue RestClient::ResourceNotFound => e
|
33
|
-
error extract_not_found(e.http_body)
|
34
|
-
rescue RestClient::RequestFailed => e
|
35
|
-
error extract_error(e.http_body) unless e.http_code == 402 || e.http_code == 102
|
36
|
-
rescue RestClient::RequestTimeout
|
37
|
-
error "API request timed out. Please try again, or contact support@pagodagrid.com if this issue persists."
|
38
|
-
rescue CommandFailed => e
|
39
|
-
error e.message
|
40
|
-
rescue Interrupt => e
|
41
|
-
error "\n[canceled]"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def run_internal(command, args)
|
46
|
-
klass, method = parse(command)
|
47
|
-
runner = klass.new(args)
|
48
|
-
raise InvalidCommand unless runner.respond_to?(method)
|
49
|
-
runner.send(method)
|
50
|
-
end
|
51
|
-
|
52
|
-
def parse(command)
|
53
|
-
parts = command.split(':')
|
54
|
-
case parts.size
|
55
|
-
when 1
|
56
|
-
begin
|
57
|
-
return eval("Pagoda::Command::#{command.capitalize}"), :index
|
58
|
-
rescue NameError, NoMethodError
|
59
|
-
return Pagoda::Command::App, command.to_sym
|
60
|
-
end
|
61
|
-
else
|
62
|
-
begin
|
63
|
-
const = Pagoda::Command
|
64
|
-
command = parts.pop
|
65
|
-
parts.each { |part| const = const.const_get(part.capitalize) }
|
66
|
-
return const, command.to_sym
|
67
|
-
rescue NameError
|
68
|
-
raise InvalidCommand
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def extract_not_found(body)
|
74
|
-
body =~ /^[\w\s]+ not found$/ ? body : "Resource not found"
|
75
|
-
end
|
76
|
-
|
77
|
-
def extract_error(body)
|
78
|
-
msg = parse_error_xml(body) || parse_error_json(body) || 'Internal server error'
|
79
|
-
end
|
80
|
-
|
81
|
-
def parse_error_xml(body)
|
82
|
-
xml_errors = REXML::Document.new(body).elements.to_a("//errors/error")
|
83
|
-
msg = xml_errors.map { |a| a.text }.join(" / ")
|
84
|
-
return msg unless msg.empty?
|
85
|
-
rescue Exception
|
86
|
-
end
|
87
|
-
|
88
|
-
def parse_error_json(body)
|
89
|
-
json = JSON.parse(body.to_s)
|
90
|
-
json['error']
|
91
|
-
rescue JSON::ParserError
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
end
|
data/lib/pagoda/commands/app.rb
DELETED
@@ -1,247 +0,0 @@
|
|
1
|
-
module Pagoda::Command
|
2
|
-
class App < Base
|
3
|
-
|
4
|
-
def list
|
5
|
-
apps = client.app_list
|
6
|
-
if !apps.empty?
|
7
|
-
display
|
8
|
-
display "APPS"
|
9
|
-
display "//////////////////////////////////"
|
10
|
-
display
|
11
|
-
apps.each do |app|
|
12
|
-
display "- #{app[:name]}"
|
13
|
-
end
|
14
|
-
else
|
15
|
-
error ["looks like you haven't launched any apps", "type 'pagoda launch' to launch this project"]
|
16
|
-
end
|
17
|
-
display
|
18
|
-
end
|
19
|
-
|
20
|
-
def create
|
21
|
-
if app_name = app(true)
|
22
|
-
error ["This project is already launched and paired to #{app_name}.", "To unpair run 'pagoda unpair'"]
|
23
|
-
end
|
24
|
-
|
25
|
-
unless locate_app_root
|
26
|
-
error ["Unable to find git config in this directory or in any parent directory"]
|
27
|
-
end
|
28
|
-
|
29
|
-
unless clone_url = extract_git_clone_url
|
30
|
-
errors = []
|
31
|
-
errors << "It appears you are using git (fantastic)."
|
32
|
-
errors << "However we only support git repos hosted with github."
|
33
|
-
errors << "Please ensure your repo is hosted with github."
|
34
|
-
error errors
|
35
|
-
end
|
36
|
-
|
37
|
-
unless name = args.dup.shift
|
38
|
-
error "Please Specify an app name ie. 'pagoda launch awesomeapp'"
|
39
|
-
end
|
40
|
-
|
41
|
-
display
|
42
|
-
display "+> Registering #{name}"
|
43
|
-
app = client.app_create(name, clone_url)
|
44
|
-
display "+> Launching...", false
|
45
|
-
loop_transaction(name)
|
46
|
-
add_app(name, clone_url)
|
47
|
-
display "+> #{name} launched"
|
48
|
-
|
49
|
-
unless option_value(nil, "--latest")
|
50
|
-
Pagoda::Command.run_internal("app:deploy", args)
|
51
|
-
end
|
52
|
-
|
53
|
-
if option_value(nil, "--with-mysql")
|
54
|
-
Pagoda::Command.run_internal("db:create", args)
|
55
|
-
end
|
56
|
-
|
57
|
-
display "-----------------------------------------------"
|
58
|
-
display
|
59
|
-
display "LIVE URL : http://#{name}.pagodabox.com"
|
60
|
-
display "ADMIN PANEL : http://dashboard.pagodabox.com"
|
61
|
-
display
|
62
|
-
display "-----------------------------------------------"
|
63
|
-
display
|
64
|
-
|
65
|
-
end
|
66
|
-
alias :launch :create
|
67
|
-
alias :register :create
|
68
|
-
|
69
|
-
def destroy
|
70
|
-
display
|
71
|
-
if confirm ["Are you totally completely sure you want to delete #{app} forever and ever?", "THIS CANNOT BE UNDONE! (y/n)"]
|
72
|
-
display "+> Destroying #{app}"
|
73
|
-
client.app_destroy(app)
|
74
|
-
display "+> #{app} has been successfully destroyed. RIP #{app}."
|
75
|
-
remove_app(app)
|
76
|
-
end
|
77
|
-
display
|
78
|
-
end
|
79
|
-
alias :delete :destroy
|
80
|
-
|
81
|
-
def info
|
82
|
-
display
|
83
|
-
info = client.app_info(app)
|
84
|
-
display "INFO - #{info[:name]}"
|
85
|
-
display "//////////////////////////////////"
|
86
|
-
display "name : #{info[:name]}"
|
87
|
-
display "clone_url : #{info[:git_url]}"
|
88
|
-
display
|
89
|
-
display "owner"
|
90
|
-
display "username : #{info[:owner][:username]}", true, 2
|
91
|
-
display "email : #{info[:owner][:email]}", true, 2
|
92
|
-
display
|
93
|
-
display "collaborators"
|
94
|
-
if info[:collaborators].any?
|
95
|
-
info[:collaborators].each_with_index do |collaborator, index|
|
96
|
-
display "username : #{collaborator[:username]}", true, 2
|
97
|
-
display "email : #{collaborator[:email]}", true, 2
|
98
|
-
end
|
99
|
-
else
|
100
|
-
display "(none)", true, 2
|
101
|
-
end
|
102
|
-
display
|
103
|
-
end
|
104
|
-
|
105
|
-
def pair
|
106
|
-
|
107
|
-
if app_name = app(true)
|
108
|
-
error ["This project is paired to #{app_name}.", "To unpair run 'pagoda unpair'"]
|
109
|
-
end
|
110
|
-
|
111
|
-
unless locate_app_root
|
112
|
-
error ["Unable to find git config in this directory or in any parent directory"]
|
113
|
-
end
|
114
|
-
|
115
|
-
unless my_repo = extract_git_clone_url
|
116
|
-
errors = []
|
117
|
-
errors << "It appears you are using git (fantastic)."
|
118
|
-
errors << "However we only support git repos hosted with github."
|
119
|
-
errors << "Please ensure your repo is hosted with github."
|
120
|
-
error errors
|
121
|
-
end
|
122
|
-
|
123
|
-
display
|
124
|
-
display "+> Locating deployed app with matching git repo"
|
125
|
-
|
126
|
-
apps = client.app_list
|
127
|
-
|
128
|
-
matching_apps = []
|
129
|
-
apps.each do |a|
|
130
|
-
if a[:git_url] == my_repo
|
131
|
-
matching_apps.push a
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
if matching_apps.count > 1
|
136
|
-
if name = app(true) || args.dup.shift
|
137
|
-
assign_app = nil
|
138
|
-
matching_apps.each do |a|
|
139
|
-
assign_app = a if a[:name] == name
|
140
|
-
end
|
141
|
-
if assign_app
|
142
|
-
display "+> Pairing this repo to deployed app - #{assign_app[:name]}"
|
143
|
-
pair_with_remote(assign_app)
|
144
|
-
display "+> Repo is now paired to '#{assign_app[:name]}'"
|
145
|
-
display
|
146
|
-
else
|
147
|
-
error "#{name} is not found among your launched app list"
|
148
|
-
end
|
149
|
-
else
|
150
|
-
errors = []
|
151
|
-
errors << "Multiple matches found"
|
152
|
-
errors << ""
|
153
|
-
matching_apps.each do |match|
|
154
|
-
errors << "-> #{match[:name]}"
|
155
|
-
end
|
156
|
-
errors << ""
|
157
|
-
errors << "You have more then one app that uses this repo."
|
158
|
-
errors << "Please specify which app you would like to pair to."
|
159
|
-
errors << ""
|
160
|
-
errors << "ex: pagoda pair #{matching_apps[0][:name]}"
|
161
|
-
error errors
|
162
|
-
end
|
163
|
-
elsif matching_apps.count == 1
|
164
|
-
match = matching_apps.first
|
165
|
-
display "+> Pairing this repo to deployed app - #{match[:name]}"
|
166
|
-
pair_with_remote match
|
167
|
-
display "+> Repo is now paired to '#{match[:name]}'"
|
168
|
-
display
|
169
|
-
else
|
170
|
-
error "Current git repo doesn't match any launched app repos"
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
def unpair
|
175
|
-
app
|
176
|
-
display
|
177
|
-
display "+> Unpairing this repo"
|
178
|
-
remove_app(app)
|
179
|
-
display "+> Free at last!"
|
180
|
-
display
|
181
|
-
end
|
182
|
-
|
183
|
-
def deploy
|
184
|
-
app
|
185
|
-
display
|
186
|
-
branch = parse_branch
|
187
|
-
commit = parse_commit
|
188
|
-
if option_value(nil, "--latest")
|
189
|
-
client.deploy_latest(app)
|
190
|
-
display "+> deploying to latest commit point on github...", false
|
191
|
-
loop_transaction
|
192
|
-
display "+> deployed"
|
193
|
-
display
|
194
|
-
else
|
195
|
-
client.deploy(app, branch, commit)
|
196
|
-
display "+> deploying current branch and commit...", false
|
197
|
-
loop_transaction
|
198
|
-
display "+> deployed"
|
199
|
-
display
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
def rewind
|
204
|
-
app
|
205
|
-
display
|
206
|
-
transaction = client.rewind(app)
|
207
|
-
display "+> undo...", false
|
208
|
-
loop_transaction
|
209
|
-
display "+> done"
|
210
|
-
display
|
211
|
-
end
|
212
|
-
alias :rollback :rewind
|
213
|
-
alias :undo :rewind
|
214
|
-
|
215
|
-
def fast_forward
|
216
|
-
app
|
217
|
-
display
|
218
|
-
transaction = client.fast_forward(app)
|
219
|
-
display "+> redo...", false
|
220
|
-
loop_transaction
|
221
|
-
display "+> done"
|
222
|
-
display
|
223
|
-
end
|
224
|
-
alias :fastforward :fast_forward
|
225
|
-
alias :forward :fast_forward
|
226
|
-
alias :redo :fast_forward
|
227
|
-
|
228
|
-
protected
|
229
|
-
|
230
|
-
def pair_with_remote(app)
|
231
|
-
my_app_list = read_apps
|
232
|
-
current_root = locate_app_root
|
233
|
-
in_list = false
|
234
|
-
my_app_list.each do |app_str|
|
235
|
-
app_arr = app_str.split(" ")
|
236
|
-
if app[:git_url] == app_arr[1] && app[:name] == app_arr[0] || app_arr[2] == current_root
|
237
|
-
in_list = true
|
238
|
-
end
|
239
|
-
end
|
240
|
-
unless in_list
|
241
|
-
add_app app[:name]
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
|
246
|
-
end
|
247
|
-
end
|