shelly 0.0.32 → 0.0.33

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.
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  .bundle
3
+ .tmp.swp
3
4
  Gemfile.lock
4
5
  pkg/*
5
6
  .rvmrc
data/lib/shelly/app.rb CHANGED
@@ -106,6 +106,22 @@ module Shelly
106
106
  configs.find_all { |config| config["created_by_user"] == false }
107
107
  end
108
108
 
109
+ def config(id)
110
+ shelly.app_config(code_name, id)
111
+ end
112
+
113
+ def create_config(path, content)
114
+ shelly.app_create_config(code_name, path, content)
115
+ end
116
+
117
+ def update_config(id, content)
118
+ shelly.app_update_config(code_name, id, content)
119
+ end
120
+
121
+ def delete_config(id)
122
+ shelly.app_delete_config(code_name, id)
123
+ end
124
+
109
125
  def open_billing_page
110
126
  url = "#{shelly.shellyapp_url}/login?api_key=#{current_user.token}&return_to=/apps/#{code_name}/edit_billing"
111
127
  Launchy.open(url)
@@ -6,12 +6,14 @@ module Shelly
6
6
  namespace :backup
7
7
  include Helpers
8
8
 
9
- desc "list", "List database backup clouds defined in Cloudfile"
10
- def list(cloud = nil)
9
+ desc "list", "List database backups"
10
+ method_option :cloud, :type => :string, :aliases => "-c",
11
+ :desc => "Specify which cloud to list backups for"
12
+ def list
11
13
  logged_in?
12
14
  say_error "Must be run inside your project git repository" unless App.inside_git_repository?
13
15
  say_error "No Cloudfile found" unless Cloudfile.present?
14
- multiple_clouds(cloud, "backup list", "Select cloud to view database backups using:")
16
+ multiple_clouds(options[:cloud], "backup list", "Select cloud to view database backups for using:")
15
17
  backups = @app.database_backups
16
18
  unless backups.empty?
17
19
  backups.unshift({"filename" => "Filename", "size" => "Size"})
@@ -20,14 +20,14 @@ module Shelly
20
20
  user_configs = @app.user_configs
21
21
  unless user_configs.empty?
22
22
  say "Custom configuration files:"
23
- user_configs.each { |config| say " * #{config["path"]}" }
23
+ print_configs(user_configs)
24
24
  else
25
25
  say "You have no custom configuration files."
26
26
  end
27
27
  shelly_configs = @app.shelly_generated_configs
28
28
  unless shelly_configs.empty?
29
29
  say "Following files are created by Shelly Cloud:"
30
- shelly_configs.each { |config| say " * #{config["path"]}" }
30
+ print_configs(shelly_configs)
31
31
  end
32
32
  else
33
33
  say "Cloud #{cloud} has no configuration files"
@@ -42,6 +42,121 @@ module Shelly
42
42
  end
43
43
  end
44
44
 
45
+ method_option :cloud, :type => :string, :aliases => "-c",
46
+ :desc => "Specify which cloud to show configuration file for"
47
+ desc "show CONFIG_ID", "View configuration file"
48
+ def show(id = nil)
49
+ logged_in?
50
+ say_error "No Cloudfile found" unless Cloudfile.present?
51
+ say_error "No configuration file specified" unless id
52
+ multiple_clouds(options[:cloud], "show #{id}", "Specify cloud using:")
53
+ config = @app.config(id)
54
+ say "Content of #{config["path"]}:", :green
55
+ say config["content"]
56
+ end
57
+
58
+ map "new" => :create
59
+ method_option :cloud, :type => :string, :aliases => "-c",
60
+ :desc => "Specify for which cloud create configuration file"
61
+ desc "create PATH", "Create configuration file"
62
+ def create(path = nil)
63
+ logged_in?
64
+ say_error "No Cloudfile found" unless Cloudfile.present?
65
+ say_error "No path specified" unless path
66
+ output = open_editor(path)
67
+ multiple_clouds(options[:cloud], "create #{path}", "Specify cloud using:")
68
+ @app.create_config(path, output)
69
+ say "File '#{path}' created, it will be used after next code deploy", :green
70
+ rescue Client::APIError => e
71
+ if e.unauthorized?
72
+ say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
73
+ elsif e.validation?
74
+ e.each_error { |error| say_error error, :with_exit => false }
75
+ exit 1
76
+ else
77
+ say_error e.message
78
+ end
79
+ end
80
+
81
+ map "update" => :edit
82
+ method_option :cloud, :type => :string, :aliases => "-c",
83
+ :desc => "Specify for which cloud edit configuration file"
84
+ desc "edit CONFIG_ID", "Edit configuration file"
85
+ def edit(id = nil)
86
+ logged_in?
87
+ say_error "No Cloudfile found" unless Cloudfile.present?
88
+ say_error "No configuration file specified" unless id
89
+ multiple_clouds(options[:cloud], "edit #{id}", "Specify cloud using:")
90
+ config = @app.config(id)
91
+ content = open_editor(config["path"], config["content"])
92
+ @app.update_config(id, content)
93
+ say "File '#{config["path"]}' updated, it will be used after next code deploy", :green
94
+ rescue Client::APIError => e
95
+ if e.unauthorized?
96
+ say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
97
+ elsif e.validation?
98
+ e.each_error { |error| say_error error, :with_exit => false }
99
+ exit 1
100
+ else
101
+ say_error e.message
102
+ end
103
+ end
104
+
105
+ method_option :cloud, :type => :string, :aliases => "-c",
106
+ :desc => "Specify for which cloud delete configuration file"
107
+ desc "delete CONFIG_ID", "Delete configuration file"
108
+ def delete(id = nil)
109
+ logged_in?
110
+ say_error "No Cloudfile found" unless Cloudfile.present?
111
+ say_error "No configuration file specified" unless id
112
+ multiple_clouds(options[:cloud], "delete #{id}", "Specify cloud using:")
113
+ config = @app.config(id)
114
+ answer = ask("Are you sure you want to delete '#{config["path"]}' [y/n]: ")
115
+ if answer =~ /yes|YES|y|Y/
116
+ @app.delete_config(id)
117
+ say "File deleted, redeploy your cloud to make changes", :green
118
+ else
119
+ say "File not deleted"
120
+ end
121
+ rescue Client::APIError => e
122
+ if e.unauthorized?
123
+ say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
124
+ elsif e.validation?
125
+ e.each_error { |error| say_error error, :with_exit => false }
126
+ exit 1
127
+ else
128
+ say_error e.message
129
+ end
130
+ end
131
+
132
+ no_tasks do
133
+ def print_configs(configs)
134
+ print_table(configs.map { |config|
135
+ [" * ", config["id"], config["path"]] })
136
+ end
137
+
138
+ def open_editor(path, output = "")
139
+ filename = "shelly-edit-"
140
+ 0.upto(20) { filename += rand(9).to_s }
141
+ filename << File.extname(path)
142
+ filename = File.join(Dir.tmpdir, filename)
143
+ tf = File.open(filename, "w")
144
+ tf.sync = true
145
+ tf.puts output
146
+ tf.close
147
+ no_editor unless system("#{ENV['EDITOR']} #{tf.path}")
148
+ tf = File.open(filename, "r")
149
+ output = tf.gets(nil)
150
+ tf.close
151
+ File.unlink(filename)
152
+ output
153
+ end
154
+
155
+ def no_editor
156
+ say_error "Please set EDITOR environment variable"
157
+ end
158
+ end
159
+
45
160
  end
46
161
  end
47
162
  end
@@ -8,10 +8,12 @@ module Shelly
8
8
  include Helpers
9
9
 
10
10
  desc "list", "Lists deploy logs"
11
- def list(cloud = nil)
11
+ method_option :cloud, :type => :string, :aliases => "-c",
12
+ :desc => "Specify which cloud to show deploy logs for"
13
+ def list
12
14
  logged_in?
13
15
  say_error "No Cloudfile found" unless Cloudfile.present?
14
- multiple_clouds(cloud, "deploys list", "Select cloud to view deploy logs using:")
16
+ multiple_clouds(options[:cloud], "deploys list", "Select cloud to view deploy logs using:")
15
17
  logs = @app.deploy_logs
16
18
  unless logs.empty?
17
19
  say "Available deploy logs", :green
@@ -30,10 +32,12 @@ module Shelly
30
32
  end
31
33
 
32
34
  desc "show LOG", "Show specific deploy log"
33
- def show(log = nil, cloud = nil)
35
+ method_option :cloud, :type => :string, :aliases => "-c",
36
+ :desc => "Specify which cloud to show deploy logs for"
37
+ def show(log = nil)
34
38
  say_error "No Cloudfile found" unless Cloudfile.present?
35
39
  specify_log(log)
36
- multiple_clouds(cloud, "deploys show #{log}", "Select log and cloud to view deploy logs using:")
40
+ multiple_clouds(options[:cloud], "deploys show #{log}", "Select log and cloud to view deploy logs using:")
37
41
  content = @app.deploy_log(log)
38
42
  say "Log for deploy done on #{content["created_at"]}", :green
39
43
  if content["bundle_install"]
@@ -161,11 +161,13 @@ module Shelly
161
161
  end
162
162
  end
163
163
 
164
- desc "start [CODE-NAME]", "Starts specific cloud"
165
- def start(cloud = nil)
164
+ desc "start", "Starts the cloud"
165
+ method_option :cloud, :type => :string, :aliases => "-c",
166
+ :desc => "Specify which cloud to start"
167
+ def start
166
168
  logged_in?
167
169
  say_error "No Cloudfile found" unless Cloudfile.present?
168
- multiple_clouds(cloud, "start", "Select which to start using:")
170
+ multiple_clouds(options[:cloud], "start", "Select cloud to start using:")
169
171
  @app.start
170
172
  say "Starting cloud #{@app.code_name}. Check status with:", :green
171
173
  say " shelly list"
@@ -195,11 +197,13 @@ module Shelly
195
197
  end
196
198
  end
197
199
 
198
- desc "stop [CODE-NAME]", "Stops specific cloud"
199
- def stop(cloud = nil)
200
+ desc "stop", "Stops the cloud"
201
+ method_option :cloud, :type => :string, :aliases => "-c",
202
+ :desc => "Specify which cloud to stop"
203
+ def stop
200
204
  logged_in?
201
205
  say_error "No Cloudfile found" unless Cloudfile.present?
202
- multiple_clouds(cloud, "stop", "Select which to stop using:")
206
+ multiple_clouds(options[:cloud], "stop", "Select cloud to stop using:")
203
207
  @app.stop
204
208
  say "Cloud '#{@app.code_name}' stopped"
205
209
  rescue Client::APIError => e
@@ -208,31 +212,28 @@ module Shelly
208
212
  end
209
213
  end
210
214
 
211
- desc "delete CODE-NAME", "Delete cloud from Shelly Cloud"
212
- def delete(code_name = nil)
215
+ desc "delete", "Delete cloud from Shelly Cloud"
216
+ method_option :cloud, :type => :string, :aliases => "-c",
217
+ :desc => "Specify which cloud to delete"
218
+ def delete
213
219
  user = Shelly::User.new
214
220
  user.token
215
- if code_name.present?
216
- app = Shelly::App.new(code_name)
217
- say "You are about to delete application: #{code_name}."
218
- say "Press Control-C at any moment to cancel."
219
- say "Please confirm each question by typing yes and pressing Enter."
220
- say_new_line
221
- ask_to_delete_files
222
- ask_to_delete_database
223
- ask_to_delete_application
224
- app.delete
225
- say_new_line
226
- say "Scheduling application delete - done"
227
- if App.inside_git_repository?
228
- app.remove_git_remote
229
- say "Removing git remote - done"
230
- else
231
- say "Missing git remote"
232
- end
221
+ multiple_clouds(options[:cloud], "delete", "Select cloud to delete using:")
222
+ say "You are about to delete application: #{@app.code_name}."
223
+ say "Press Control-C at any moment to cancel."
224
+ say "Please confirm each question by typing yes and pressing Enter."
225
+ say_new_line
226
+ ask_to_delete_files
227
+ ask_to_delete_database
228
+ ask_to_delete_application
229
+ @app.delete
230
+ say_new_line
231
+ say "Scheduling application delete - done"
232
+ if App.inside_git_repository?
233
+ @app.remove_git_remote
234
+ say "Removing git remote - done"
233
235
  else
234
- say_error "Missing CODE-NAME", :with_exit => false
235
- say_error "Use: shelly delete CODE-NAME"
236
+ say "Missing git remote"
236
237
  end
237
238
  rescue Client::APIError => e
238
239
  say_error e.message
@@ -245,13 +246,13 @@ module Shelly
245
246
  cloud = options[:cloud]
246
247
  logged_in?
247
248
  say_error "No Cloudfile found" unless Cloudfile.present?
248
- multiple_clouds(cloud, "logs --cloud", "Select which to show logs for using:")
249
+ multiple_clouds(cloud, "logs", "Select which to show logs for using:")
249
250
  begin
250
251
  logs = @app.application_logs
251
252
  say "Cloud #{@app.code_name}:", :green
252
253
  logs.each_with_index do |log, i|
253
- say "Instance #{i+1}:"
254
- print_wrapped log, :ident => 2
254
+ say "Instance #{i+1}:", :green
255
+ say log
255
256
  end
256
257
  rescue Client::APIError => e
257
258
  if e.unauthorized?
data/lib/shelly/client.rb CHANGED
@@ -62,6 +62,22 @@ module Shelly
62
62
  get("/apps/#{cloud}/configs")
63
63
  end
64
64
 
65
+ def app_config(cloud, id)
66
+ get("/apps/#{cloud}/configs/#{id}")
67
+ end
68
+
69
+ def app_create_config(cloud, path, content)
70
+ post("/apps/#{cloud}/configs", :config => {:path => path, :content => content})
71
+ end
72
+
73
+ def app_update_config(cloud, id, content)
74
+ put("/apps/#{cloud}/configs/#{id}", :config => {:content => content})
75
+ end
76
+
77
+ def app_delete_config(cloud, id)
78
+ delete("/apps/#{cloud}/configs/#{id}")
79
+ end
80
+
65
81
  def send_invitation(cloud, email)
66
82
  post("/apps/#{cloud}/collaborations", :email => email)
67
83
  end
@@ -61,7 +61,7 @@ module Shelly
61
61
  clouds = Cloudfile.new.clouds
62
62
  if clouds.count > 1 && cloud.nil?
63
63
  say "You have multiple clouds in Cloudfile. #{message}"
64
- say " shelly #{action} #{clouds.first}"
64
+ say " shelly #{action} --cloud #{clouds.first}"
65
65
  say "Available clouds:"
66
66
  clouds.each do |cloud|
67
67
  say " * #{cloud}"
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.0.32"
2
+ VERSION = "0.0.33"
3
3
  end
@@ -38,8 +38,8 @@ describe Shelly::CLI::Backup do
38
38
  end
39
39
 
40
40
  it "should show information to select specific cloud and exit" do
41
- $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Select cloud to view database backups using:")
42
- $stdout.should_receive(:puts).with(" shelly backup list foo-production")
41
+ $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Select cloud to view database backups for using:")
42
+ $stdout.should_receive(:puts).with(" shelly backup list --cloud foo-production")
43
43
  $stdout.should_receive(:puts).with("Available clouds:")
44
44
  $stdout.should_receive(:puts).with(" * foo-production")
45
45
  $stdout.should_receive(:puts).with(" * foo-staging")
@@ -53,7 +53,8 @@ describe Shelly::CLI::Backup do
53
53
  $stdout.should_receive(:puts).with(" Filename | Size")
54
54
  $stdout.should_receive(:puts).with(" backup.postgre.tar.gz | 10kb")
55
55
  $stdout.should_receive(:puts).with(" backup.mongo.tar.gz | 22kb")
56
- @backup.list("foo-staging")
56
+ @backup.options = {:cloud => 'foo-staging'}
57
+ @backup.list
57
58
  end
58
59
  end
59
60
  end
@@ -10,14 +10,18 @@ describe Shelly::CLI::Config do
10
10
  Shelly::Client.stub(:new).and_return(@client)
11
11
  $stdout.stub(:puts)
12
12
  $stdout.stub(:print)
13
+ FileUtils.mkdir_p("/projects/foo")
14
+ Dir.chdir("/projects/foo")
15
+ @client.stub(:token).and_return("abc")
16
+ File.open("Cloudfile", 'w') {|f| f.write("foo-staging:\n") }
17
+ FileUtils.mkdir_p("/tmp")
18
+ Dir.stub(:tmpdir).and_return("/tmp")
19
+ ENV["EDITOR"] = "vim"
13
20
  end
14
21
 
15
22
  describe "#list" do
16
23
  before do
17
- FileUtils.mkdir_p("/projects/foo")
18
- Dir.chdir("/projects/foo")
19
24
  File.open("Cloudfile", 'w') {|f| f.write("foo-staging:\nfoo-production:\n") }
20
- @client.stub(:token).and_return("abc")
21
25
  end
22
26
 
23
27
  it "should exit with message if there is no Cloudfile" do
@@ -37,19 +41,201 @@ describe Shelly::CLI::Config do
37
41
  end
38
42
 
39
43
  it "should list available configuration files for clouds" do
40
- @client.should_receive(:app_configs).with("foo-staging").and_return([{"created_by_user" => true, "path" => "config/settings.yml"}])
41
- @client.should_receive(:app_configs).with("foo-production").and_return([{"created_by_user" => false, "path" => "config/app.yml"}])
44
+ @client.should_receive(:app_configs).with("foo-staging").and_return([{"id" => 1, "created_by_user" => true, "path" => "config/settings.yml"}])
45
+ @client.should_receive(:app_configs).with("foo-production").and_return([{"id" => 2, "created_by_user" => false, "path" => "config/app.yml"}])
42
46
  $stdout.should_receive(:puts).with(green "Configuration files for foo-production")
43
47
  $stdout.should_receive(:puts).with("You have no custom configuration files.")
44
48
  $stdout.should_receive(:puts).with("Following files are created by Shelly Cloud:")
45
- $stdout.should_receive(:puts).with(" * config/app.yml")
49
+ $stdout.should_receive(:puts).with(/ * 2\s+config\/app.yml/)
46
50
  $stdout.should_receive(:puts).with(green "Configuration files for foo-staging")
47
51
  $stdout.should_receive(:puts).with("Custom configuration files:")
48
- $stdout.should_receive(:puts).with(" * config/settings.yml")
52
+ $stdout.should_receive(:puts).with(/ * 1\s+config\/settings.yml/)
49
53
 
50
54
  @config.list
51
55
  end
52
56
 
53
57
  end
54
58
 
59
+ describe "#show" do
60
+ it "should exit with message if there is no Cloudfile" do
61
+ File.delete("Cloudfile")
62
+ $stdout.should_receive(:puts).with(red "No Cloudfile found")
63
+ lambda { @config.show(1) }.should raise_error(SystemExit)
64
+ end
65
+
66
+ it "should exit if no id was specified" do
67
+ $stdout.should_receive(:puts).with(red "No configuration file specified")
68
+ lambda { @config.show }.should raise_error(SystemExit)
69
+ end
70
+
71
+ it "should show config" do
72
+ @client.should_receive(:app_config).with("foo-staging", 1).and_return({"path" => "test.rb", "content" => "example content"})
73
+ $stdout.should_receive(:puts).with(green "Content of test.rb:")
74
+ $stdout.should_receive(:puts).with("example content")
75
+ @config.show(1)
76
+ end
77
+
78
+ context "multiple clouds" do
79
+ before do
80
+ File.open("Cloudfile", 'w') {|f| f.write("foo-staging:\nfoo-production:\n") }
81
+ end
82
+
83
+ it "should show info to select cloud and exit" do
84
+ $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Specify cloud using:")
85
+ lambda { @config.show(1) }.should raise_error(SystemExit)
86
+ end
87
+
88
+ it "should use cloud specified by parameter" do
89
+ @client.should_receive(:app_config).with("foo-production", 1).and_return({"path" => "test.rb", "content" => "example content"})
90
+ @config.options = {:cloud => "foo-production"}
91
+ @config.show(1)
92
+ end
93
+ end
94
+ end
95
+
96
+ describe "#create" do
97
+ it "should exit with message if there is no Cloudfile" do
98
+ File.delete("Cloudfile")
99
+ $stdout.should_receive(:puts).with(red "No Cloudfile found")
100
+ lambda { @config.create("path") }.should raise_error(SystemExit)
101
+ end
102
+
103
+ it "should exit if no id was specified" do
104
+ $stdout.should_receive(:puts).with(red "No path specified")
105
+ lambda { @config.create }.should raise_error(SystemExit)
106
+ end
107
+
108
+ it "should ask to set EDITOR environment variable if not set" do
109
+ @config.stub(:system) {false}
110
+ $stdout.should_receive(:puts).with(red "Please set EDITOR environment variable")
111
+ lambda { @config.create("path") }.should raise_error(SystemExit)
112
+ end
113
+
114
+ it "should create file" do
115
+ @config.should_receive(:system).with(/vim \/tmp\/shelly-edit/).and_return(true)
116
+ @client.should_receive(:app_create_config).with("foo-staging", "path", "\n").and_return({})
117
+ $stdout.should_receive(:puts).with(green "File 'path' created, it will be used after next code deploy")
118
+ @config.create("path")
119
+ end
120
+
121
+ context "multiple clouds" do
122
+ before do
123
+ File.open("Cloudfile", 'w') {|f| f.write("foo-staging:\nfoo-production:\n") }
124
+ end
125
+
126
+ it "should show info to select cloud and exit" do
127
+ @config.stub(:system) {true}
128
+ $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Specify cloud using:")
129
+ lambda { @config.create("path") }.should raise_error(SystemExit)
130
+ end
131
+
132
+ it "should use cloud specified by parameter" do
133
+ @config.should_receive(:system).with(/vim \/tmp\/shelly-edit/).and_return(true)
134
+ @client.should_receive(:app_create_config).with("foo-production", "path", "\n").and_return({})
135
+ @config.options = {:cloud => "foo-production"}
136
+ @config.create("path")
137
+ end
138
+ end
139
+ end
140
+
141
+
142
+ describe "#edit" do
143
+ it "should exit with message if there is no Cloudfile" do
144
+ File.delete("Cloudfile")
145
+ $stdout.should_receive(:puts).with(red "No Cloudfile found")
146
+ lambda { @config.edit(1) }.should raise_error(SystemExit)
147
+ end
148
+
149
+ it "should exit if no path was specified" do
150
+ $stdout.should_receive(:puts).with(red "No configuration file specified")
151
+ lambda { @config.edit }.should raise_error(SystemExit)
152
+ end
153
+
154
+ it "should ask to set EDITOR environment variable if not set" do
155
+ @client.should_receive(:app_config).with("foo-staging", 1).and_return({"path" => "test.rb", "content" => "example content"})
156
+ @config.stub(:system) {false}
157
+ $stdout.should_receive(:puts).with(red "Please set EDITOR environment variable")
158
+ lambda { @config.edit(1) }.should raise_error(SystemExit)
159
+ end
160
+
161
+ it "should create file" do
162
+ @client.should_receive(:app_config).with("foo-staging", 1).and_return({"path" => "test.rb", "content" => "example content"})
163
+ @config.should_receive(:system).with(/vim \/tmp\/shelly-edit/).and_return(true)
164
+ @client.should_receive(:app_update_config).with("foo-staging", 1, "example content\n").and_return({"path" => "test.rb", "content" => "example content"})
165
+ $stdout.should_receive(:puts).with(green "File 'test.rb' updated, it will be used after next code deploy")
166
+ @config.edit(1)
167
+ end
168
+
169
+ context "multiple clouds" do
170
+ before do
171
+ File.open("Cloudfile", 'w') {|f| f.write("foo-staging:\nfoo-production:\n") }
172
+ end
173
+
174
+ it "should show info to select cloud and exit" do
175
+ @config.stub(:system) {true}
176
+ $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Specify cloud using:")
177
+ lambda { @config.edit(1) }.should raise_error(SystemExit)
178
+ end
179
+
180
+ it "should use cloud specified by parameter" do
181
+ @client.should_receive(:app_config).with("foo-production", 1).and_return({"path" => "test.rb", "content" => "example content"})
182
+ @config.should_receive(:system).with(/vim \/tmp\/shelly-edit/).and_return(true)
183
+ @client.should_receive(:app_update_config).with("foo-production", 1, "example content\n").and_return({"path" => "test.rb", "content" => "example content"})
184
+ @config.options = {:cloud => "foo-production"}
185
+ @config.edit(1)
186
+ end
187
+ end
188
+ end
189
+
190
+ describe "#delete" do
191
+ it "should exit with message if there is no Cloudfile" do
192
+ File.delete("Cloudfile")
193
+ $stdout.should_receive(:puts).with(red "No Cloudfile found")
194
+ lambda { @config.delete(1) }.should raise_error(SystemExit)
195
+ end
196
+
197
+ it "should exit if no path was specified" do
198
+ $stdout.should_receive(:puts).with(red "No configuration file specified")
199
+ lambda { @config.delete }.should raise_error(SystemExit)
200
+ end
201
+
202
+ it "should delete configuration file" do
203
+ @client.should_receive(:app_config).with("foo-staging", 1).and_return({"path" => "test.rb", "content" => "example content"})
204
+ @client.should_receive(:app_delete_config).with("foo-staging", 1).and_return({})
205
+ $stdout.should_receive(:puts).with(green "File deleted, redeploy your cloud to make changes")
206
+ fake_stdin(["y"]) do
207
+ @config.delete(1)
208
+ end
209
+ end
210
+
211
+ it "should not delete file if user answered other than yes/y" do
212
+ @client.should_receive(:app_config).with("foo-staging", 1).and_return({"path" => "test.rb", "content" => "example content"})
213
+ @client.should_not_receive(:app_delete_config)
214
+ $stdout.should_receive(:puts).with("File not deleted")
215
+ fake_stdin(["n"]) do
216
+ @config.delete(1)
217
+ end
218
+ end
219
+
220
+ context "multiple clouds" do
221
+ before do
222
+ File.open("Cloudfile", 'w') {|f| f.write("foo-staging:\nfoo-production:\n") }
223
+ end
224
+
225
+ it "should show info to select cloud and exit" do
226
+ $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Specify cloud using:")
227
+ lambda { @config.delete(1) }.should raise_error(SystemExit)
228
+ end
229
+
230
+ it "should use cloud specified by parameter" do
231
+ @client.should_receive(:app_config).with("foo-production", 1).and_return({"path" => "test.rb", "content" => "example content"})
232
+ @client.should_receive(:app_delete_config).with("foo-production", 1).and_return({})
233
+ $stdout.should_receive(:puts).with(green "File deleted, redeploy your cloud to make changes")
234
+ @config.options = {:cloud => "foo-production"}
235
+ fake_stdin(["y"]) do
236
+ @config.delete(1)
237
+ end
238
+ end
239
+ end
240
+ end
55
241
  end
@@ -42,7 +42,7 @@ describe Shelly::CLI::Deploys do
42
42
 
43
43
  it "should show information to select specific cloud and exit" do
44
44
  $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Select cloud to view deploy logs using:")
45
- $stdout.should_receive(:puts).with(" shelly deploys list foo-production")
45
+ $stdout.should_receive(:puts).with(" shelly deploys list --cloud foo-production")
46
46
  $stdout.should_receive(:puts).with("Available clouds:")
47
47
  $stdout.should_receive(:puts).with(" * foo-production")
48
48
  $stdout.should_receive(:puts).with(" * foo-staging")
@@ -53,7 +53,8 @@ describe Shelly::CLI::Deploys do
53
53
  @client.should_receive(:deploy_logs).with("foo-staging").and_return([{"failed" => false, "created_at" => "2011-12-12-14-14-59"}])
54
54
  $stdout.should_receive(:puts).with(green "Available deploy logs")
55
55
  $stdout.should_receive(:puts).with(" * 2011-12-12-14-14-59")
56
- @deploys.list("foo-staging")
56
+ @deploys.options = {:cloud => "foo-staging"}
57
+ @deploys.list
57
58
  end
58
59
  end
59
60
 
@@ -99,7 +100,7 @@ describe Shelly::CLI::Deploys do
99
100
 
100
101
  it "should show information to select specific cloud and exit" do
101
102
  $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Select log and cloud to view deploy logs using:")
102
- $stdout.should_receive(:puts).with(" shelly deploys show last foo-production")
103
+ $stdout.should_receive(:puts).with(" shelly deploys show last --cloud foo-production")
103
104
  $stdout.should_receive(:puts).with("Available clouds:")
104
105
  $stdout.should_receive(:puts).with(" * foo-production")
105
106
  $stdout.should_receive(:puts).with(" * foo-staging")
@@ -109,7 +110,8 @@ describe Shelly::CLI::Deploys do
109
110
  it "should render the logs" do
110
111
  @client.should_receive(:deploy_log).with("foo-staging", "last").and_return(response)
111
112
  expected_output
112
- @deploys.show("last", "foo-staging")
113
+ @deploys.options = {:cloud => "foo-staging"}
114
+ @deploys.show("last")
113
115
  end
114
116
  end
115
117
 
@@ -26,7 +26,7 @@ Tasks:
26
26
  shelly add # Adds new cloud to Shelly Cloud
27
27
  shelly backup <command> # Manages database backups from this cloud
28
28
  shelly config <command> # Manages cloud configuration files
29
- shelly delete CODE-NAME # Delete cloud from Shelly Cloud
29
+ shelly delete # Delete cloud from Shelly Cloud
30
30
  shelly deploys <command> # View cloud deploy logs
31
31
  shelly help [TASK] # Describe available tasks or one specific task
32
32
  shelly ip # Lists clouds IP's
@@ -34,8 +34,8 @@ Tasks:
34
34
  shelly login [EMAIL] # Logs user in to Shelly Cloud
35
35
  shelly logs # Show latest application logs from each instance
36
36
  shelly register [EMAIL] # Registers new user account on Shelly Cloud
37
- shelly start [CODE-NAME] # Starts specific cloud
38
- shelly stop [CODE-NAME] # Stops specific cloud
37
+ shelly start # Starts the cloud
38
+ shelly stop # Stops the cloud
39
39
  shelly user <command> # Manages users using this cloud
40
40
  shelly version # Displays shelly version
41
41
 
@@ -538,8 +538,8 @@ OUT
538
538
  end
539
539
 
540
540
  it "should show information to start specific cloud and exit" do
541
- $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Select which to start using:")
542
- $stdout.should_receive(:puts).with(" shelly start foo-production")
541
+ $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Select cloud to start using:")
542
+ $stdout.should_receive(:puts).with(" shelly start --cloud foo-production")
543
543
  $stdout.should_receive(:puts).with("Available clouds:")
544
544
  $stdout.should_receive(:puts).with(" * foo-production")
545
545
  $stdout.should_receive(:puts).with(" * foo-staging")
@@ -550,7 +550,8 @@ OUT
550
550
  @client.should_receive(:start_cloud).with("foo-staging")
551
551
  $stdout.should_receive(:puts).with(green "Starting cloud foo-staging. Check status with:")
552
552
  $stdout.should_receive(:puts).with(" shelly list")
553
- @main.start("foo-staging")
553
+ @main.options = {:cloud => "foo-staging"}
554
+ @main.start
554
555
  end
555
556
  end
556
557
 
@@ -654,8 +655,8 @@ OUT
654
655
  end
655
656
 
656
657
  it "should show information to start specific cloud and exit" do
657
- $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Select which to stop using:")
658
- $stdout.should_receive(:puts).with(" shelly stop foo-production")
658
+ $stdout.should_receive(:puts).with("You have multiple clouds in Cloudfile. Select cloud to stop using:")
659
+ $stdout.should_receive(:puts).with(" shelly stop --cloud foo-production")
659
660
  $stdout.should_receive(:puts).with("Available clouds:")
660
661
  $stdout.should_receive(:puts).with(" * foo-production")
661
662
  $stdout.should_receive(:puts).with(" * foo-staging")
@@ -665,7 +666,8 @@ OUT
665
666
  it "should fetch from command line which cloud to start" do
666
667
  @client.should_receive(:stop_cloud).with("foo-staging")
667
668
  $stdout.should_receive(:puts).with("Cloud 'foo-staging' stopped")
668
- @main.stop("foo-staging")
669
+ @main.options = {:cloud => "foo-staging"}
670
+ @main.stop
669
671
  end
670
672
  end
671
673
  end
@@ -734,9 +736,14 @@ OUT
734
736
  Shelly::App.stub(:new).and_return(@app)
735
737
  end
736
738
 
737
- context "when code_name is not nil" do
739
+ context "when cloud is given" do
740
+ before do
741
+ File.open("Cloudfile", 'w') {|f|
742
+ f.write("foo-staging:\nfoo-production:\n") }
743
+ end
744
+
738
745
  it "should ask about delete application parts" do
739
- $stdout.should_receive(:puts).with("You are about to delete application: foo-bar.")
746
+ $stdout.should_receive(:puts).with("You are about to delete application: foo-staging.")
740
747
  $stdout.should_receive(:puts).with("Press Control-C at any moment to cancel.")
741
748
  $stdout.should_receive(:puts).with("Please confirm each question by typing yes and pressing Enter.")
742
749
  $stdout.should_receive(:puts).with("\n")
@@ -747,7 +754,8 @@ OUT
747
754
  $stdout.should_receive(:puts).with("Scheduling application delete - done")
748
755
  $stdout.should_receive(:puts).with("Removing git remote - done")
749
756
  fake_stdin(["yes", "yes", "yes"]) do
750
- @main.delete("foo-bar")
757
+ @main.options = {:cloud => "foo-staging"}
758
+ @main.delete
751
759
  end
752
760
  end
753
761
 
@@ -755,23 +763,35 @@ OUT
755
763
  @app.should_not_receive(:delete)
756
764
  lambda{
757
765
  fake_stdin(["yes", "yes", "no"]) do
758
- @main.delete("foo-bar")
766
+ @main.options = {:cloud => "foo-staging"}
767
+ @main.delete
759
768
  end
760
769
  }.should raise_error(SystemExit)
761
770
  end
762
771
  end
763
772
 
764
773
  context "when git repository doesn't exist" do
774
+ before do
775
+ File.open("Cloudfile", 'w') {|f|
776
+ f.write("foo-staging:\n") }
777
+ end
778
+
765
779
  it "should say that Git remote missing" do
766
780
  Shelly::App.stub(:inside_git_repository?).and_return(false)
767
781
  $stdout.should_receive(:puts).with("Missing git remote")
768
782
  fake_stdin(["yes", "yes", "yes"]) do
769
- @main.delete("foo-bar")
783
+ @main.options = {:cloud => "foo-staging"}
784
+ @main.delete
770
785
  end
771
786
  end
772
787
  end
773
788
 
774
- context "when application with CODE-NAME doesn't exist" do
789
+ context "when cloud given in option doesn't exist" do
790
+ before do
791
+ File.open("Cloudfile", 'w') {|f|
792
+ f.write("foo-staging:\n") }
793
+ end
794
+
775
795
  it "should raise Client::APIError" do
776
796
  response = {:message => "Application not found"}
777
797
  exception = Shelly::Client::APIError.new(response.to_json)
@@ -779,17 +799,33 @@ OUT
779
799
  $stdout.should_receive(:puts).with("\e[31mApplication not found\e[0m")
780
800
  lambda{
781
801
  fake_stdin(["yes", "yes", "yes"]) do
782
- @main.delete("foo-bar")
802
+ @main.options = {:cloud => "foo-bar"}
803
+ @main.delete
783
804
  end
784
805
  }.should raise_error(SystemExit)
785
806
  end
786
807
  end
787
808
 
788
- context "when code_name is nil" do
789
- it "should display error when no code_name" do
790
- $stdout.should_receive(:puts).with("\e[31mMissing CODE-NAME\e[0m")
791
- $stdout.should_receive(:puts).with("\e[31mUse: shelly delete CODE-NAME\e[0m")
792
- lambda{ @main.delete }.should raise_error(SystemExit)
809
+ context "when no cloud option is given" do
810
+ before do
811
+ File.open("Cloudfile", 'w') {|f|
812
+ f.write("foo-staging:\n") }
813
+ end
814
+
815
+ it "should take the cloud from Cloudfile" do
816
+ $stdout.should_receive(:puts).with("You are about to delete application: foo-staging.")
817
+ $stdout.should_receive(:puts).with("Press Control-C at any moment to cancel.")
818
+ $stdout.should_receive(:puts).with("Please confirm each question by typing yes and pressing Enter.")
819
+ $stdout.should_receive(:puts).with("\n")
820
+ $stdout.should_receive(:print).with("I want to delete all files stored on Shelly Cloud (yes/no): ")
821
+ $stdout.should_receive(:print).with("I want to delete all database data stored on Shelly Cloud (yes/no): ")
822
+ $stdout.should_receive(:print).with("I want to delete the application (yes/no): ")
823
+ $stdout.should_receive(:puts).with("\n")
824
+ $stdout.should_receive(:puts).with("Scheduling application delete - done")
825
+ $stdout.should_receive(:puts).with("Removing git remote - done")
826
+ fake_stdin(["yes", "yes", "yes"]) do
827
+ @main.delete
828
+ end
793
829
  end
794
830
  end
795
831
  end
@@ -839,8 +875,8 @@ OUT
839
875
  it "should show logs for the cloud" do
840
876
  @client.stub(:application_logs).and_return(["log1"])
841
877
  $stdout.should_receive(:puts).with(green "Cloud foo-production:")
842
- $stdout.should_receive(:puts).with("Instance 1:")
843
- $stdout.should_receive(:puts).with(" log1")
878
+ $stdout.should_receive(:puts).with(green "Instance 1:")
879
+ $stdout.should_receive(:puts).with("log1")
844
880
  @main.logs
845
881
  end
846
882
  end
@@ -865,8 +901,8 @@ OUT
865
901
  @client.should_receive(:application_logs).with("foo-staging").
866
902
  and_return(["log1"])
867
903
  $stdout.should_receive(:puts).with(green "Cloud foo-staging:")
868
- $stdout.should_receive(:puts).with("Instance 1:")
869
- $stdout.should_receive(:puts).with(" log1")
904
+ $stdout.should_receive(:puts).with(green "Instance 1:")
905
+ $stdout.should_receive(:puts).with("log1")
870
906
  @main.options = {:cloud => "foo-staging"}
871
907
  @main.logs
872
908
  end
@@ -876,10 +912,10 @@ OUT
876
912
  it "should show logs from each instance" do
877
913
  @client.stub(:application_logs).and_return(["log1", "log2"])
878
914
  $stdout.should_receive(:puts).with(green "Cloud foo-production:")
879
- $stdout.should_receive(:puts).with("Instance 1:")
880
- $stdout.should_receive(:puts).with(" log1")
881
- $stdout.should_receive(:puts).with("Instance 2:")
882
- $stdout.should_receive(:puts).with(" log2")
915
+ $stdout.should_receive(:puts).with(green "Instance 1:")
916
+ $stdout.should_receive(:puts).with("log1")
917
+ $stdout.should_receive(:puts).with(green "Instance 2:")
918
+ $stdout.should_receive(:puts).with("log2")
883
919
  @main.logs
884
920
  end
885
921
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shelly
3
3
  version: !ruby/object:Gem::Version
4
- hash: 95
4
+ hash: 93
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 32
10
- version: 0.0.32
9
+ - 33
10
+ version: 0.0.33
11
11
  platform: ruby
12
12
  authors:
13
13
  - Shelly Cloud team
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-12-19 00:00:00 Z
18
+ date: 2011-12-26 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rspec