shelly 0.0.43 → 0.0.44.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,23 +9,24 @@ module Shelly
9
9
  class Main < Command
10
10
  include Thor::Actions
11
11
 
12
- register(User, "user", "user <command>", "Manages users using this cloud")
13
- register(Backup, "backup", "backup <command>", "Manages database backups from this cloud")
14
- register(Deploys, "deploys", "deploys <command>", "View cloud deploy logs")
15
- register(Config, "config", "config <command>", "Manages cloud configuration files")
12
+ register(User, "user", "user <command>", "Manage collaborators")
13
+ register(Backup, "backup", "backup <command>", "Manage database backups")
14
+ register(Deploys, "deploys", "deploys <command>", "View deploy logs")
15
+ register(Config, "config", "config <command>", "Manage application configuration files")
16
16
  check_unknown_options!
17
17
 
18
- before_hook :logged_in?, :only => [:add, :list, :start, :stop, :logs, :delete]
19
- before_hook :inside_git_repository?, :only => [:add, :ip]
18
+ # FIXME: it should be possible to pass single symbol, instead of one element array
19
+ before_hook :logged_in?, :only => [:add, :list, :start, :stop, :logs, :delete, :ip, :logout]
20
+ before_hook :inside_git_repository?, :only => [:add]
20
21
  before_hook :cloudfile_present?, :only => [:logs, :stop, :start, :ip]
21
22
 
22
23
  map %w(-v --version) => :version
23
- desc "version", "Displays shelly version"
24
+ desc "version", "Display shelly version"
24
25
  def version
25
26
  say "shelly version #{Shelly::VERSION}"
26
27
  end
27
28
 
28
- desc "register [EMAIL]", "Registers new user account on Shelly Cloud"
29
+ desc "register [EMAIL]", "Register new account"
29
30
  def register(email = nil)
30
31
  user = Shelly::User.new
31
32
  user.ssh_key_registered?
@@ -38,12 +39,10 @@ module Shelly
38
39
  end
39
40
  say "Successfully registered!"
40
41
  say "Check you mailbox for email address confirmation"
41
- rescue Client::APIError => e
42
- if e.validation?
43
- e.each_error { |error| say_error "#{error}", :with_exit => false }
44
- exit 1
45
- end
46
- rescue RestClient::Conflict
42
+ rescue Client::ValidationException => e
43
+ e.each_error { |error| say_error "#{error}", :with_exit => false }
44
+ exit 1
45
+ rescue Client::ConflictException
47
46
  say_error "User with your ssh key already exists.", :with_exit => false
48
47
  say_error "You can login using: shelly login [EMAIL]", :with_exit => false
49
48
  exit 1
@@ -52,7 +51,7 @@ module Shelly
52
51
  say_error "Use ssh-keygen to generate ssh key pair"
53
52
  end
54
53
 
55
- desc "login [EMAIL]", "Logs user in to Shelly Cloud"
54
+ desc "login [EMAIL]", "Log into Shelly Cloud"
56
55
  def login(email = nil)
57
56
  user = Shelly::User.new
58
57
  raise Errno::ENOENT, user.ssh_key_path unless user.ssh_key_exists?
@@ -63,16 +62,12 @@ module Shelly
63
62
  user.upload_ssh_key
64
63
  say "Uploading your public SSH key"
65
64
  list
66
- rescue Client::APIError => e
67
- if e.validation?
68
- e.each_error { |error| say_error "#{error}", :with_exit => false }
69
- end
70
- if e.unauthorized?
71
- say_error "Wrong email or password", :with_exit => false
72
- say_error "You can reset password by using link:", :with_exit => false
73
- say_error "#{e.url}", :with_exit => false
74
- end
75
- exit 1
65
+ rescue Client::ValidationException => e
66
+ e.each_error { |error| say_error "#{error}", :with_exit => false }
67
+ rescue Client::UnauthorizedException => e
68
+ say_error "Wrong email or password", :with_exit => false
69
+ say_error "You can reset password by using link:", :with_exit => false
70
+ say_error "#{e[:url]}"
76
71
  rescue Errno::ENOENT => e
77
72
  say_error e, :with_exit => false
78
73
  say_error "Use ssh-keygen to generate ssh key pair"
@@ -82,11 +77,11 @@ module Shelly
82
77
  :desc => "Unique code-name of your cloud"
83
78
  method_option :databases, :type => :array, :aliases => "-d",
84
79
  :banner => Shelly::App::DATABASE_KINDS.join(', '),
85
- :desc => "Array of databases of your choice"
80
+ :desc => "List of databases of your choice"
86
81
  method_option :domains, :type => :array,
87
82
  :banner => "CODE-NAME.shellyapp.com, YOUR-DOMAIN.com",
88
- :desc => "Array of your domains"
89
- desc "add", "Adds new cloud to Shelly Cloud"
83
+ :desc => "List of your domains"
84
+ desc "add", "Add a new cloud"
90
85
  def add
91
86
  check_options(options)
92
87
  @app = Shelly::App.new
@@ -107,16 +102,14 @@ module Shelly
107
102
  info_adding_cloudfile_to_repository
108
103
  info_deploying_to_shellycloud
109
104
 
110
- rescue Client::APIError => e
111
- if e.validation?
112
- e.each_error { |error| say_error error, :with_exit => false }
113
- say_new_line
114
- say_error "Fix erros in the below command and type it again to create your cloud" , :with_exit => false
115
- say_error "shelly add --code-name=#{@app.code_name} --databases=#{@app.databases.join} --domains=#{@app.code_name}.shellyapp.com"
116
- end
105
+ rescue Client::ValidationException => e
106
+ e.each_error { |error| say_error error, :with_exit => false }
107
+ say_new_line
108
+ say_error "Fix erros in the below command and type it again to create your cloud" , :with_exit => false
109
+ say_error "shelly add --code-name=#{@app.code_name} --databases=#{@app.databases.join} --domains=#{@app.code_name}.shellyapp.com"
117
110
  end
118
111
 
119
- desc "list", "Lists all your clouds"
112
+ desc "list", "List available clouds"
120
113
  def list
121
114
  user = Shelly::User.new
122
115
  apps = user.apps
@@ -129,16 +122,12 @@ module Shelly
129
122
  else
130
123
  say "You have no clouds yet", :green
131
124
  end
132
- rescue Client::APIError => e
133
- if e.unauthorized?
134
- say_error "You are not logged in, use `shelly login`"
135
- end
136
125
  end
126
+
137
127
  map "status" => :list
138
128
 
139
- desc "ip", "Lists clouds IP's"
129
+ desc "ip", "List cloud's IP addresses"
140
130
  def ip
141
- say_error "No Cloudfile found" unless Cloudfile.present?
142
131
  @cloudfile = Cloudfile.new
143
132
  @cloudfile.clouds.each do |cloud|
144
133
  begin
@@ -146,31 +135,26 @@ module Shelly
146
135
  say "Cloud #{cloud}:", :green
147
136
  print_wrapped "Web server IP: #{@app.web_server_ip}", :ident => 2
148
137
  print_wrapped "Mail server IP: #{@app.mail_server_ip}", :ident => 2
149
- rescue Client::APIError => e
150
- if e.not_found?
151
- say_error "You have no access to '#{cloud}' cloud defined in Cloudfile", :with_exit => false
152
- else
153
- say_error e.message, :with_exit => false
154
- end
138
+ rescue Client::NotFoundException => e
139
+ raise unless e.resource == :cloud
140
+ say_error "You have no access to '#{cloud}' cloud defined in Cloudfile", :with_exit => false
155
141
  end
156
142
  end
157
143
  end
158
144
 
159
- desc "start", "Starts the cloud"
160
- method_option :cloud, :type => :string, :aliases => "-c",
161
- :desc => "Specify which cloud to start"
145
+ desc "start", "Start the cloud"
146
+ method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
162
147
  def start
163
- multiple_clouds(options[:cloud], "start", "Select cloud to start using:")
148
+ multiple_clouds(options[:cloud], "start")
164
149
  @app.start
165
- say "Starting cloud #{@app.code_name}. Check status with:", :green
150
+ say "Starting cloud #{@app}. Check status with:", :green
166
151
  say " shelly list"
167
- rescue RestClient::Conflict => e
168
- response = JSON.parse(e.response)
169
- case response['state']
152
+ rescue Client::ConflictException => e
153
+ case e[:state]
170
154
  when "running"
171
- say_error "Not starting: cloud '#{@app.code_name}' is already running"
155
+ say_error "Not starting: cloud '#{@app}' is already running"
172
156
  when "deploying", "configuring"
173
- say_error "Not starting: cloud '#{@app.code_name}' is currently deploying"
157
+ say_error "Not starting: cloud '#{@app}' is currently deploying"
174
158
  when "no_code"
175
159
  say_error "Not starting: no source code provided", :with_exit => false
176
160
  say_error "Push source code using:", :with_exit => false
@@ -178,36 +162,32 @@ module Shelly
178
162
  when "deploy_failed", "configuration_failed"
179
163
  say_error "Not starting: deployment failed", :with_exit => false
180
164
  say_error "Support has been notified", :with_exit => false
181
- say_error "See #{response['link']} for reasons of failure"
165
+ say_error "Check `shelly deploys show last --cloud #{@app}` for reasons of failure"
182
166
  when "no_billing"
183
167
  say_error "Please fill in billing details to start foo-production. Opening browser.", :with_exit => false
184
168
  @app.open_billing_page
185
169
  end
186
170
  exit 1
187
- rescue Client::APIError => e
188
- if e.not_found?
189
- say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
190
- end
171
+ rescue Client::NotFoundException => e
172
+ raise unless e.resource == :cloud
173
+ say_error "You have no access to '#{@app}' cloud defined in Cloudfile"
191
174
  end
192
175
 
193
- desc "stop", "Stops the cloud"
194
- method_option :cloud, :type => :string, :aliases => "-c",
195
- :desc => "Specify which cloud to stop"
176
+ desc "stop", "Stop the cloud"
177
+ method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
196
178
  def stop
197
- multiple_clouds(options[:cloud], "stop", "Select cloud to stop using:")
179
+ multiple_clouds(options[:cloud], "stop")
198
180
  @app.stop
199
181
  say "Cloud '#{@app.code_name}' stopped"
200
- rescue Client::APIError => e
201
- if e.not_found?
202
- say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
203
- end
182
+ rescue Client::NotFoundException => e
183
+ raise unless e.resource == :cloud
184
+ say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
204
185
  end
205
186
 
206
- desc "delete", "Delete cloud from Shelly Cloud"
207
- method_option :cloud, :type => :string, :aliases => "-c",
208
- :desc => "Specify which cloud to delete"
187
+ desc "delete", "Delete the cloud"
188
+ method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
209
189
  def delete
210
- multiple_clouds(options[:cloud], "delete", "Select cloud to delete using:")
190
+ multiple_clouds(options[:cloud], "delete")
211
191
  say "You are about to delete application: #{@app.code_name}."
212
192
  say "Press Control-C at any moment to cancel."
213
193
  say "Please confirm each question by typing yes and pressing Enter."
@@ -224,18 +204,16 @@ module Shelly
224
204
  else
225
205
  say "Missing git remote"
226
206
  end
227
- rescue Client::APIError => e
228
- if e.not_found?
229
- say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
230
- end
207
+ rescue Client::NotFoundException => e
208
+ raise unless e.resource == :cloud
209
+ say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
231
210
  end
232
211
 
233
- desc "logs", "Show latest application logs from each instance"
234
- method_option :cloud, :type => :string, :aliases => "-c",
235
- :desc => "Specify which cloud to show logs for"
212
+ desc "logs", "Show latest application logs"
213
+ method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
236
214
  def logs
237
215
  cloud = options[:cloud]
238
- multiple_clouds(cloud, "logs", "Select which to show logs for using:")
216
+ multiple_clouds(cloud, "logs")
239
217
  begin
240
218
  logs = @app.application_logs
241
219
  say "Cloud #{@app.code_name}:", :green
@@ -243,11 +221,39 @@ module Shelly
243
221
  say "Instance #{i+1}:", :green
244
222
  say log
245
223
  end
246
- rescue Client::APIError => e
247
- if e.not_found?
248
- say_error "You have no access to cloud '#{cloud || @app.code_name}'"
249
- end
224
+ rescue Client::NotFoundException => e
225
+ raise unless e.resource == :cloud
226
+ say_error "You have no access to '#{cloud || @app.code_name}' cloud defined in Cloudfile"
227
+ end
228
+ end
229
+
230
+ desc "logout", "Logout from Shelly Cloud"
231
+ def logout
232
+ user = Shelly::User.new
233
+ say "Your public SSH key has been removed from Shelly Cloud" if user.delete_ssh_key
234
+ say "You have been successfully logged out" if user.delete_credentials
235
+ end
236
+
237
+ desc "redeploy", "Redeploy application"
238
+ method_option :cloud, :type => :string, :aliases => "-c",
239
+ :desc => "Specify which cloud to redeploy application for"
240
+ def redeploy
241
+ multiple_clouds(options[:cloud], "redeploy")
242
+ @app.redeploy
243
+ say "Redeploying your application for cloud '#{@app}'", :green
244
+ rescue Client::ConflictException => e
245
+ case e[:state]
246
+ when "deploying", "configuring"
247
+ say_error "Your application is being redeployed at the moment"
248
+ when "no_code", "no_billing", "turned_off"
249
+ say_error "Cloud #{@app} is not running", :with_exit => false
250
+ say "Start your cloud with `shelly start --cloud #{@app}`"
251
+ exit 1
252
+ else raise
250
253
  end
254
+ rescue Client::NotFoundException => e
255
+ raise unless e.resource == :cloud
256
+ say_error "You have no access to '#{@app}' cloud defined in Cloudfile"
251
257
  end
252
258
 
253
259
  # FIXME: move to helpers
@@ -257,6 +263,7 @@ module Shelly
257
263
  unless ["code-name", "databases", "domains"].all? do |option|
258
264
  options.include?(option.to_s) && options[option.to_s] != option.to_s
259
265
  end && valid_databases?(options["databases"])
266
+ # FIXME: ' to `
260
267
  say_error "Try 'shelly help add' for more information"
261
268
  end
262
269
  end
@@ -302,7 +309,7 @@ module Shelly
302
309
  databases = ask("Unknown database kind. Supported are: #{kinds.join(", ")}:")
303
310
  end while not valid
304
311
 
305
- databases.empty? ? ["postgresql"] : databases
312
+ databases.empty? ? ["postgresql"] : databases - ["none"]
306
313
  end
307
314
 
308
315
  def info_adding_cloudfile_to_repository
@@ -17,8 +17,12 @@ module Shelly
17
17
 
18
18
  def start
19
19
  Shelly::CLI::Main.start(args)
20
- rescue => e
21
- raise e if debug?
20
+ rescue SystemExit; raise
21
+ rescue Interrupt
22
+ say_new_line
23
+ say_error "[canceled]"
24
+ rescue Exception
25
+ raise if debug?
22
26
  say_error "Unknown error, to see debug information run command with --debug"
23
27
  end
24
28
  end
@@ -7,7 +7,6 @@ module Shelly
7
7
  include Helpers
8
8
 
9
9
  before_hook :logged_in?, :only => [:list, :add]
10
- before_hook :inside_git_repository?, :only => [:list, :add]
11
10
  before_hook :cloudfile_present?, :only => [:list, :add]
12
11
 
13
12
  desc "list", "List users with access to clouds defined in Cloudfile"
@@ -18,12 +17,9 @@ module Shelly
18
17
  @app = App.new(cloud)
19
18
  say "Cloud #{cloud}:"
20
19
  @app.users.each { |user| say " #{user["email"]}" }
21
- rescue Client::APIError => e
22
- if e.not_found?
23
- say_error "You have no access to '#{cloud}' cloud defined in Cloudfile", :with_exit => false
24
- else
25
- say_error e.message, :with_exit => false
26
- end
20
+ rescue Client::NotFoundException => e
21
+ raise unless e.resource == :cloud
22
+ say_error "You have no access to '#{cloud}' cloud defined in Cloudfile"
27
23
  end
28
24
  end
29
25
  end
@@ -36,19 +32,17 @@ module Shelly
36
32
  @cloudfile.clouds.each do |cloud|
37
33
  begin
38
34
  @user.send_invitation(cloud, user_email)
39
- rescue Client::APIError => e
40
- if e.validation? && e.errors.include?(["email", "#{email} has already been taken"])
35
+ say "Sending invitation to #{user_email} to work on #{cloud}", :green
36
+ rescue Client::ValidationException => e
37
+ if e.errors.include?(["email", "#{email} has already been taken"])
41
38
  say_error "User #{email} is already in the cloud #{cloud}", :with_exit => false
42
- elsif e.not_found?
43
- say_error "You have no access to '#{cloud}' cloud defined in Cloudfile", :with_exit => false
44
- elsif e.validation?
39
+ else
45
40
  e.each_error { |error| say_error error, :with_exit => false }
46
41
  exit 1
47
- else
48
- say_error e.message, :with_exit => false
49
42
  end
50
- else
51
- say "Sending invitation to #{user_email} to work on #{cloud}", :green
43
+ rescue Client::NotFoundException => e
44
+ raise unless e.resource == :cloud
45
+ say_error "You have no access to '#{cloud}' cloud defined in Cloudfile"
52
46
  end
53
47
  end
54
48
  end
data/lib/shelly/client.rb CHANGED
@@ -4,41 +4,24 @@ require "cgi"
4
4
 
5
5
  module Shelly
6
6
  class Client
7
- class APIError < Exception
7
+ class APIException < Exception
8
8
  attr_reader :status_code, :body
9
9
 
10
- def initialize(status_code, body = {})
10
+ def initialize(body = {}, status_code = nil)
11
11
  @status_code = status_code
12
12
  @body = body
13
13
  end
14
14
 
15
- def message
16
- body["message"]
15
+ def [](key)
16
+ body[key.to_s]
17
17
  end
18
+ end
18
19
 
20
+ class UnauthorizedException < APIException; end
21
+ class ConflictException < APIException; end
22
+ class ValidationException < APIException
19
23
  def errors
20
- body["errors"]
21
- end
22
-
23
- def url
24
- body["url"]
25
- end
26
-
27
- def validation?
28
- message == "Validation Failed"
29
- end
30
-
31
- def not_found?
32
- status_code == 404
33
- end
34
-
35
- def resource_not_found
36
- return unless not_found?
37
- message =~ /Couldn't find (.*) with/ && $1.downcase.to_sym
38
- end
39
-
40
- def unauthorized?
41
- status_code == 401
24
+ self[:errors]
42
25
  end
43
26
 
44
27
  def each_error
@@ -47,6 +30,11 @@ module Shelly
47
30
  end
48
31
  end
49
32
  end
33
+ class NotFoundException < APIException
34
+ def resource
35
+ self[:resource].to_sym
36
+ end
37
+ end
50
38
 
51
39
  attr_reader :email, :password
52
40
 
@@ -104,7 +92,11 @@ module Shelly
104
92
  end
105
93
 
106
94
  def add_ssh_key(ssh_key)
107
- post("/ssh_key", :ssh_key => ssh_key)
95
+ post("/ssh_keys", :ssh_key => ssh_key)
96
+ end
97
+
98
+ def logout(ssh_key)
99
+ delete("/ssh_keys", :ssh_key => ssh_key)
108
100
  end
109
101
 
110
102
  def start_cloud(cloud)
@@ -124,15 +116,15 @@ module Shelly
124
116
  end
125
117
 
126
118
  def deploy_logs(cloud)
127
- get("/apps/#{cloud}/deploys")
119
+ get("/apps/#{cloud}/deployment_logs")
128
120
  end
129
121
 
130
122
  def deploy_log(cloud, log)
131
- get("/apps/#{cloud}/deploys/#{log}")
123
+ get("/apps/#{cloud}/deployment_logs/#{log}")
132
124
  end
133
125
 
134
126
  def application_logs(cloud)
135
- get("/apps/#{cloud}/logs")
127
+ get("/apps/#{cloud}/application_logs")
136
128
  end
137
129
 
138
130
  def database_backups(code_name)
@@ -159,6 +151,10 @@ module Shelly
159
151
  get("/apps/#{cloud}/users")
160
152
  end
161
153
 
154
+ def redeploy(cloud)
155
+ post("/apps/#{cloud}/deploys")
156
+ end
157
+
162
158
  def post(path, params = {})
163
159
  request(path, :post, params)
164
160
  end
@@ -220,10 +216,18 @@ module Shelly
220
216
  def process_response(response)
221
217
  body = JSON.parse(response.body) rescue JSON::ParserError && {}
222
218
  code = response.code
223
- raise APIError.new(code, body) if (400..599).include?(code)
219
+ if (400..599).include?(code)
220
+ exception_class = case response.code
221
+ when 401; UnauthorizedException
222
+ when 404; NotFoundException
223
+ when 409; ConflictException
224
+ when 422; ValidationException
225
+ else; APIException
226
+ end
227
+ raise exception_class.new(body, code)
228
+ end
224
229
  response.return!
225
230
  body
226
231
  end
227
232
  end
228
233
  end
229
-
@@ -6,7 +6,7 @@ module Shelly
6
6
  super("Progress", total)
7
7
  self.format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
8
8
  end
9
-
9
+
10
10
  def progress_callback
11
11
  lambda { |size| inc(size) }
12
12
  end
@@ -63,19 +63,15 @@ module Shelly
63
63
  user = Shelly::User.new
64
64
  user.token
65
65
  user
66
- rescue Client::APIError => e
67
- if e.unauthorized?
68
- say_error "You are not logged in. To log in use:", :with_exit => false
69
- say " shelly login"
70
- exit 1
71
- end
66
+ rescue Client::UnauthorizedException
67
+ say_error "You are not logged in. To log in use: `shelly login`"
72
68
  end
73
69
 
74
- def multiple_clouds(cloud, action, message)
70
+ def multiple_clouds(cloud, action)
75
71
  clouds = Cloudfile.new.clouds
76
72
  if clouds.count > 1 && cloud.nil?
77
- say "You have multiple clouds in Cloudfile. #{message}"
78
- say " shelly #{action} --cloud #{clouds.first}"
73
+ say_error "You have multiple clouds in Cloudfile.", :with_exit => false
74
+ say "Select cloud using `shelly #{action} --cloud #{clouds.first}`"
79
75
  say "Available clouds:"
80
76
  clouds.each do |cloud|
81
77
  say " * #{cloud}"
@@ -85,6 +81,5 @@ module Shelly
85
81
  @app = Shelly::App.new
86
82
  @app.code_name = cloud || clouds.first
87
83
  end
88
-
89
84
  end
90
85
  end
data/lib/shelly/user.rb CHANGED
@@ -44,6 +44,14 @@ module Shelly
44
44
  set_credentials_permissions
45
45
  end
46
46
 
47
+ def delete_credentials
48
+ File.delete(credentials_path) if credentials_exists?
49
+ end
50
+
51
+ def delete_ssh_key
52
+ shelly.logout(File.read(ssh_key_path)) if ssh_key_exists?
53
+ end
54
+
47
55
  def ssh_key_exists?
48
56
  File.exists?(ssh_key_path)
49
57
  end
@@ -53,8 +61,8 @@ module Shelly
53
61
  end
54
62
 
55
63
  def ssh_key_registered?
56
- ssh_key = File.read(ssh_key_path).strip
57
- shelly.ssh_key_available?(ssh_key)
64
+ ssh_key = File.read(ssh_key_path).strip
65
+ shelly.ssh_key_available?(ssh_key)
58
66
  end
59
67
 
60
68
  def self.guess_email
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.0.43"
2
+ VERSION = "0.0.44.pre"
3
3
  end
data/lib/thor/thor.rb CHANGED
@@ -5,6 +5,10 @@ class Thor
5
5
  @hook[method] = options
6
6
  end
7
7
 
8
+ def hooks
9
+ @hook
10
+ end
11
+
8
12
  def send(*args)
9
13
  if args.first == :dispatch && !args[2].empty?
10
14
  running_task = args[2].first
data/shelly.gemspec CHANGED
@@ -16,8 +16,9 @@ Gem::Specification.new do |s|
16
16
  s.add_development_dependency "rake"
17
17
  s.add_development_dependency "guard"
18
18
  s.add_development_dependency "guard-rspec"
19
+ s.add_development_dependency "simplecov"
19
20
  if RUBY_PLATFORM =~ /darwin/
20
- s.add_development_dependency "growl_notify"
21
+ s.add_development_dependency "ruby_gntp"
21
22
  s.add_development_dependency "rb-fsevent"
22
23
  end
23
24
  s.add_development_dependency "fakefs"
data/spec/helpers.rb CHANGED
@@ -15,5 +15,12 @@ module RSpec
15
15
  def red(string)
16
16
  "\e[31m#{string}\e[0m"
17
17
  end
18
+
19
+ def hooks(model, method)
20
+ model.class.hooks.inject([]) do |result, v|
21
+ result << v[0] if v[1][:only].include?(method)
22
+ result
23
+ end
24
+ end
18
25
  end
19
26
  end
@@ -82,24 +82,24 @@ describe Shelly::App do
82
82
  @app.delete_config("path")
83
83
  end
84
84
  end
85
-
85
+
86
86
  describe "#attributes" do
87
87
  before do
88
88
  @response = {"web_server_ip" => "192.0.2.1", "mail_server_ip" => "192.0.2.3"}
89
89
  @client.stub(:app).and_return(@response)
90
90
  end
91
-
91
+
92
92
  it "should fetch app attributes from API and cache them" do
93
93
  @client.should_receive(:app).with("foo-staging").exactly(:once).and_return(@response)
94
94
  2.times { @app.attributes }
95
95
  end
96
-
96
+
97
97
  describe "#web_server_ip" do
98
98
  it "should return web server ip address" do
99
99
  @app.web_server_ip.should == "192.0.2.1"
100
100
  end
101
101
  end
102
-
102
+
103
103
  describe "#mail_server_ip" do
104
104
  it "should return mail server ip address" do
105
105
  @app.mail_server_ip.should == "192.0.2.3"
@@ -280,6 +280,13 @@ config
280
280
  end
281
281
  end
282
282
  end
283
+
284
+ describe "#redeploy" do
285
+ it "should redeploy app via API" do
286
+ @client.should_receive(:redeploy).with("foo-staging")
287
+ @app.redeploy
288
+ end
289
+ end
283
290
 
284
291
  describe "#to_s" do
285
292
  it "should return code_name" do
@@ -287,4 +294,3 @@ config
287
294
  end
288
295
  end
289
296
  end
290
-