shelly 0.0.45 → 0.0.46.pre

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/lib/shelly/app.rb CHANGED
@@ -147,7 +147,12 @@ module Shelly
147
147
  file_name_or_code
148
148
  end
149
149
 
150
- response = shelly.run(code_name, code)
150
+ response = shelly.command(code_name, code, :ruby)
151
+ response["result"]
152
+ end
153
+
154
+ def rake(task)
155
+ response = shelly.command(code_name, task, :rake)
151
156
  response["result"]
152
157
  end
153
158
 
@@ -13,12 +13,12 @@ module Shelly
13
13
  register(Backup, "backup", "backup <command>", "Manage database backups")
14
14
  register(Deploys, "deploys", "deploys <command>", "View deploy logs")
15
15
  register(Config, "config", "config <command>", "Manage application configuration files")
16
- check_unknown_options!
16
+ check_unknown_options!(:except => :rake)
17
17
 
18
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, :execute]
19
+ before_hook :logged_in?, :only => [:add, :list, :start, :stop, :logs, :delete, :ip, :logout, :execute, :rake]
20
20
  before_hook :inside_git_repository?, :only => [:add]
21
- before_hook :cloudfile_present?, :only => [:logs, :stop, :start, :ip]
21
+ before_hook :cloudfile_present?, :only => [:logs, :stop, :start, :ip, :execute, :rake]
22
22
 
23
23
  map %w(-v --version) => :version
24
24
  desc "version", "Display shelly version"
@@ -234,9 +234,8 @@ module Shelly
234
234
  say "You have been successfully logged out" if user.delete_credentials
235
235
  end
236
236
 
237
- desc "execute [CODE]", "Run code on one of application servers"
238
- method_option :cloud, :type => :string, :aliases => "-c",
239
- :desc => "Specify which cloud to run code for"
237
+ desc "execute CODE", "Run code on one of application servers"
238
+ method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
240
239
  long_desc "Run code given in parameter on one of application servers. If a file name is given, run contents of that file."
241
240
  def execute(file_name_or_code)
242
241
  cloud = options[:cloud]
@@ -253,6 +252,18 @@ module Shelly
253
252
  end
254
253
  end
255
254
 
255
+ desc "rake TASK", "Run rake task"
256
+ method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
257
+ def rake(task = nil)
258
+ task = rake_args.join(" ")
259
+ multiple_clouds(options[:cloud], "rake #{task}")
260
+ result = @app.rake(task)
261
+ say result
262
+ rescue Client::APIException => e
263
+ raise unless e[:message] == "App not running"
264
+ say_error "Cloud #{@app} is not running. Cannot run rake task."
265
+ end
266
+
256
267
  desc "redeploy", "Redeploy application"
257
268
  method_option :cloud, :type => :string, :aliases => "-c",
258
269
  :desc => "Specify which cloud to redeploy application for"
@@ -277,6 +288,23 @@ module Shelly
277
288
 
278
289
  # FIXME: move to helpers
279
290
  no_tasks do
291
+ # Returns valid arguments for rake, removes shelly gem arguments
292
+ def rake_args(args = ARGV)
293
+ skip_next = false
294
+ [].tap do |out|
295
+ args.each do |arg|
296
+ case arg
297
+ when "rake", "--debug"
298
+ when "--cloud", "-c"
299
+ skip_next = true
300
+ else
301
+ out << arg unless skip_next
302
+ skip_next = false
303
+ end
304
+ end
305
+ end
306
+ end
307
+
280
308
  def check_options(options)
281
309
  unless options.empty?
282
310
  unless ["code-name", "databases", "domains"].all? do |option|
data/lib/shelly/client.rb CHANGED
@@ -115,8 +115,8 @@ module Shelly
115
115
  get("/apps/#{code_name}")
116
116
  end
117
117
 
118
- def run(cloud, code)
119
- post("/apps/#{cloud}/run", :body => code)
118
+ def command(cloud, body, type)
119
+ post("/apps/#{cloud}/command", {:body => body, :type => type})
120
120
  end
121
121
 
122
122
  def deploy_logs(cloud)
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.0.45"
2
+ VERSION = "0.0.46.pre"
3
3
  end
@@ -293,21 +293,28 @@ config
293
293
  @response = {
294
294
  "result" => "4"
295
295
  }
296
- @client.stub(:run).and_return(@response)
296
+ @client.stub(:command).and_return(@response)
297
297
  File.open("to_run.rb", 'w') {|f| f.write("User.count\n") }
298
298
  end
299
299
 
300
300
  it "should return result of executed code" do
301
- @client.should_receive(:run).with("foo-staging", "2 + 2")
301
+ @client.should_receive(:command).with("foo-staging", "2 + 2", :ruby)
302
302
  @app.run("2 + 2").should == "4"
303
303
  end
304
304
 
305
305
  it "should send contents of file when file exists" do
306
- @client.should_receive(:run).with("foo-staging", "User.count\n")
306
+ @client.should_receive(:command).with("foo-staging", "User.count\n", :ruby)
307
307
  @app.run("to_run.rb")
308
308
  end
309
309
  end
310
310
 
311
+ describe "#rake" do
312
+ it "should return result of rake task" do
313
+ @client.should_receive(:command).with("foo-staging", "db:create", :rake).and_return({"result" => "OK"})
314
+ @app.rake("db:create").should == "OK"
315
+ end
316
+ end
317
+
311
318
  describe "#to_s" do
312
319
  it "should return code_name" do
313
320
  @app.to_s.should == "foo-staging"
@@ -29,13 +29,14 @@ Tasks:
29
29
  shelly config <command> # Manage application configuration files
30
30
  shelly delete # Delete the cloud
31
31
  shelly deploys <command> # View deploy logs
32
- shelly execute [CODE] # Run code on one of application servers
32
+ shelly execute CODE # Run code on one of application servers
33
33
  shelly help [TASK] # Describe available tasks or one specific task
34
34
  shelly ip # List cloud's IP addresses
35
35
  shelly list # List available clouds
36
36
  shelly login [EMAIL] # Log into Shelly Cloud
37
37
  shelly logout # Logout from Shelly Cloud
38
38
  shelly logs # Show latest application logs
39
+ shelly rake TASK # Run rake task
39
40
  shelly redeploy # Redeploy application
40
41
  shelly register [EMAIL] # Register new account
41
42
  shelly start # Start the cloud
@@ -936,9 +937,13 @@ OUT
936
937
  hooks(@main, :execute).should include(:logged_in?)
937
938
  end
938
939
 
940
+ it "should ensure cloudfile present" do
941
+ hooks(@main, :execute).should include(:cloudfile_present?)
942
+ end
943
+
939
944
  context "single cloud in Cloudfile" do
940
945
  it "should execute code for the cloud" do
941
- @client.should_receive(:run).with("foo-production", "User.count").
946
+ @client.should_receive(:command).with("foo-production", "User.count", :ruby).
942
947
  and_return({"result" => "3"})
943
948
  $stdout.should_receive(:puts).with("3")
944
949
  invoke(@main, :execute, "to_execute.rb")
@@ -963,7 +968,7 @@ OUT
963
968
  end
964
969
 
965
970
  it "should fetch from command line which cloud to start" do
966
- @client.should_receive(:run).with("foo-staging", "User.count").
971
+ @client.should_receive(:command).with("foo-staging", "User.count", :ruby).
967
972
  and_return({"result" => "3"})
968
973
  $stdout.should_receive(:puts).with("3")
969
974
  @main.options = {:cloud => "foo-staging"}
@@ -971,7 +976,7 @@ OUT
971
976
  end
972
977
 
973
978
  it "should run code when no file from parameter is found" do
974
- @client.should_receive(:run).with("foo-staging", "2 + 2").
979
+ @client.should_receive(:command).with("foo-staging", "2 + 2", :ruby).
975
980
  and_return({"result" => "4"})
976
981
  $stdout.should_receive(:puts).with("4")
977
982
  @main.options = {:cloud => "foo-staging"}
@@ -979,9 +984,9 @@ OUT
979
984
  end
980
985
  end
981
986
 
982
- context "cloud is not running" do
987
+ context "cloud is not in running state" do
983
988
  it "should print error" do
984
- @client.should_receive(:run).with("foo-staging", "2 + 2").
989
+ @client.should_receive(:command).with("foo-staging", "2 + 2", :ruby).
985
990
  and_raise(Shelly::Client::APIException.new(
986
991
  {"message" => "App not running"}, 504))
987
992
  $stdout.should_receive(:puts).
@@ -992,6 +997,93 @@ OUT
992
997
  end
993
998
  end
994
999
 
1000
+ describe "#rake" do
1001
+ before do
1002
+ FileUtils.mkdir_p("/projects/foo")
1003
+ Dir.chdir("/projects/foo")
1004
+ File.open("Cloudfile", 'w') {|f| f.write("foo-production:\n") }
1005
+ @user = Shelly::User.new
1006
+ @user.stub(:token)
1007
+ Shelly::User.stub(:new).and_return(@user)
1008
+ @app = Shelly::App.new
1009
+ Shelly::App.stub(:new).and_return(@app)
1010
+ @main.stub(:rake_args).and_return(%w(db:migrate))
1011
+ end
1012
+
1013
+ it "should ensure user has logged in" do
1014
+ hooks(@main, :rake).should include(:logged_in?)
1015
+ end
1016
+
1017
+ it "should ensure cloudfile present" do
1018
+ hooks(@main, :execute).should include(:cloudfile_present?)
1019
+ end
1020
+
1021
+ it "should invoke :command on app with rake task" do
1022
+ @client.should_receive(:command).with("foo-production", "db:migrate", :rake).and_return("result" => "OK")
1023
+ $stdout.should_receive(:puts).with("OK")
1024
+ invoke(@main, :rake, "db:migrate")
1025
+ end
1026
+
1027
+ it "should pass rake arguments to the client" do
1028
+ @main.stub(:rake_args).and_return(%w(-T db:schema))
1029
+ @client.should_receive(:command).with("foo-production", "-T db:schema", :rake).and_return("result" => "OK")
1030
+ $stdout.should_receive(:puts).with("OK")
1031
+ invoke(@main, :rake, nil)
1032
+ end
1033
+
1034
+ describe "#rake_args" do
1035
+ before { @main.unstub!(:rake_args) }
1036
+
1037
+ it "should return Array of rake arguments (skipping shelly gem arguments)" do
1038
+ argv = %w(rake -T db --cloud foo-production --debug)
1039
+ @main.rake_args(argv).should == %w(-T db)
1040
+ end
1041
+
1042
+ it "should take ARGV as default default argument" do
1043
+ # Rather poor, I test if method without args returns the same as method with ARGV
1044
+ @main.rake_args.should == @main.rake_args(ARGV)
1045
+ end
1046
+ end
1047
+
1048
+ context "cloud is not in running state" do
1049
+ it "should print error" do
1050
+ @client.should_receive(:command).with("foo-staging", "db:migrate", :rake).
1051
+ and_raise(Shelly::Client::APIException.new(
1052
+ {"message" => "App not running"}, 504))
1053
+ $stdout.should_receive(:puts).
1054
+ with(red "Cloud foo-staging is not running. Cannot run rake task.")
1055
+ @main.options = {:cloud => "foo-staging"}
1056
+ lambda { invoke(@main, :rake, "db:migrate") }.should raise_error(SystemExit)
1057
+ end
1058
+ end
1059
+
1060
+ context "multiple clouds in Cloudfile" do
1061
+ before do
1062
+ File.open("Cloudfile", 'w') {|f|
1063
+ f.write("foo-staging:\nfoo-production:\n") }
1064
+ end
1065
+
1066
+ it "should show information to run rake task for specific cloud and exit" do
1067
+ $stdout.should_receive(:puts).
1068
+ with(red "You have multiple clouds in Cloudfile.")
1069
+ $stdout.should_receive(:puts).
1070
+ with("Select cloud using `shelly rake db:migrate --cloud foo-production`")
1071
+ $stdout.should_receive(:puts).with("Available clouds:")
1072
+ $stdout.should_receive(:puts).with(" * foo-production")
1073
+ $stdout.should_receive(:puts).with(" * foo-staging")
1074
+ lambda { invoke(@main, :rake, "db:migrate") }.should raise_error(SystemExit)
1075
+ end
1076
+
1077
+ it "should fetch from command line for which cloud run rake task" do
1078
+ @client.should_receive(:command).with("foo-staging", "db:migrate", :rake).
1079
+ and_return({"result" => "3"})
1080
+ $stdout.should_receive(:puts).with("3")
1081
+ @main.options = {:cloud => "foo-staging"}
1082
+ invoke(@main, :rake, "db:migrate")
1083
+ end
1084
+ end
1085
+ end
1086
+
995
1087
  describe "#redeploy" do
996
1088
  before do
997
1089
  @user = Shelly::User.new
@@ -188,11 +188,11 @@ describe Shelly::Client do
188
188
  end
189
189
  end
190
190
 
191
- describe "#run" do
192
- it "should send post request with app code_name and code" do
193
- FakeWeb.register_uri(:post, api_url("apps/staging-foo/run"),
194
- :body => {:result => "4"}.to_json)
195
- response = @client.run("staging-foo", "2 + 2")
191
+ describe "#command" do
192
+ it "should send post request with app code_name, body and type" do
193
+ @client.should_receive(:post).with("/apps/staging-foo/command",
194
+ {:body => "2 + 2", :type => :ruby}).and_return({"result" => "4"})
195
+ response = @client.command("staging-foo", "2 + 2", :ruby)
196
196
  response.should == {"result" => "4"}
197
197
  end
198
198
  end
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shelly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.45
5
- prerelease:
4
+ version: 0.0.46.pre
5
+ prerelease: 7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Shelly Cloud team
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-10 00:00:00.000000000 Z
12
+ date: 2012-01-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70242679918440 !ruby/object:Gem::Requirement
16
+ requirement: &70183697675760 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70242679918440
24
+ version_requirements: *70183697675760
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70242679920240 !ruby/object:Gem::Requirement
27
+ requirement: &70183697629560 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70242679920240
35
+ version_requirements: *70183697629560
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: guard
38
- requirement: &70242679876100 !ruby/object:Gem::Requirement
38
+ requirement: &70183697575360 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70242679876100
46
+ version_requirements: *70183697575360
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: guard-rspec
49
- requirement: &70242679792880 !ruby/object:Gem::Requirement
49
+ requirement: &70183697532320 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70242679792880
57
+ version_requirements: *70183697532320
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: simplecov
60
- requirement: &70242679772100 !ruby/object:Gem::Requirement
60
+ requirement: &70183697478100 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70242679772100
68
+ version_requirements: *70183697478100
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: ruby_gntp
71
- requirement: &70242679713860 !ruby/object:Gem::Requirement
71
+ requirement: &70183697447560 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70242679713860
79
+ version_requirements: *70183697447560
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rb-fsevent
82
- requirement: &70242679679780 !ruby/object:Gem::Requirement
82
+ requirement: &70183697400160 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70242679679780
90
+ version_requirements: *70183697400160
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: fakefs
93
- requirement: &70242679649600 !ruby/object:Gem::Requirement
93
+ requirement: &70183697369060 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70242679649600
101
+ version_requirements: *70183697369060
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: fakeweb
104
- requirement: &70242679605320 !ruby/object:Gem::Requirement
104
+ requirement: &70183697325100 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70242679605320
112
+ version_requirements: *70183697325100
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: wijet-thor
115
- requirement: &70242679548560 !ruby/object:Gem::Requirement
115
+ requirement: &70183697275820 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ~>
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: 0.14.7
121
121
  type: :runtime
122
122
  prerelease: false
123
- version_requirements: *70242679548560
123
+ version_requirements: *70183697275820
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: rest-client
126
- requirement: &70242679511680 !ruby/object:Gem::Requirement
126
+ requirement: &70183697225460 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ! '>='
@@ -131,10 +131,10 @@ dependencies:
131
131
  version: '0'
132
132
  type: :runtime
133
133
  prerelease: false
134
- version_requirements: *70242679511680
134
+ version_requirements: *70183697225460
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: json
137
- requirement: &70242679459460 !ruby/object:Gem::Requirement
137
+ requirement: &70183697184400 !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements:
140
140
  - - ! '>='
@@ -142,10 +142,10 @@ dependencies:
142
142
  version: '0'
143
143
  type: :runtime
144
144
  prerelease: false
145
- version_requirements: *70242679459460
145
+ version_requirements: *70183697184400
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: wijet-launchy
148
- requirement: &70242679417320 !ruby/object:Gem::Requirement
148
+ requirement: &70183697140580 !ruby/object:Gem::Requirement
149
149
  none: false
150
150
  requirements:
151
151
  - - ! '>='
@@ -153,10 +153,10 @@ dependencies:
153
153
  version: '0'
154
154
  type: :runtime
155
155
  prerelease: false
156
- version_requirements: *70242679417320
156
+ version_requirements: *70183697140580
157
157
  - !ruby/object:Gem::Dependency
158
158
  name: progressbar
159
- requirement: &70242679388380 !ruby/object:Gem::Requirement
159
+ requirement: &70183697119220 !ruby/object:Gem::Requirement
160
160
  none: false
161
161
  requirements:
162
162
  - - ! '>='
@@ -164,7 +164,7 @@ dependencies:
164
164
  version: '0'
165
165
  type: :runtime
166
166
  prerelease: false
167
- version_requirements: *70242679388380
167
+ version_requirements: *70183697119220
168
168
  description: Tool for managing applications and clouds at shellycloud.com
169
169
  email:
170
170
  - support@shellycloud.com
@@ -237,9 +237,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
237
237
  required_rubygems_version: !ruby/object:Gem::Requirement
238
238
  none: false
239
239
  requirements:
240
- - - ! '>='
240
+ - - ! '>'
241
241
  - !ruby/object:Gem::Version
242
- version: '0'
242
+ version: 1.3.1
243
243
  requirements: []
244
244
  rubyforge_project: shelly
245
245
  rubygems_version: 1.8.10