shelly 0.0.44.pre → 0.0.44.pre2

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
@@ -138,6 +138,19 @@ module Shelly
138
138
  shelly.app_delete_config(code_name, path)
139
139
  end
140
140
 
141
+ # returns result of execution of given code, or false when app was not
142
+ # running
143
+ def run(file_name_or_code)
144
+ code = if File.exists?(file_name_or_code)
145
+ File.read(file_name_or_code)
146
+ else
147
+ file_name_or_code
148
+ end
149
+
150
+ response = shelly.run(code_name, code)
151
+ response["result"]
152
+ end
153
+
141
154
  def attributes
142
155
  @attributes ||= shelly.app(code_name)
143
156
  end
@@ -40,6 +40,7 @@ module Shelly
40
40
  end
41
41
  end
42
42
 
43
+ # FIXME: Check if path argument is present via Thor (mandatory arguments)
43
44
  method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
44
45
  desc "show PATH", "View configuration file"
45
46
  def show(path = nil)
@@ -67,7 +68,9 @@ module Shelly
67
68
  output = open_editor(path)
68
69
  multiple_clouds(options[:cloud], "create #{path}")
69
70
  @app.create_config(path, output)
70
- say "File '#{path}' created, it will be used after next code deploy", :green
71
+ say "File '#{path}' created.", :green
72
+ say "To make changes to running application redeploy it using:"
73
+ say "`shelly redeploy --cloud #{@app}`"
71
74
  rescue Client::NotFoundException => e
72
75
  raise unless e.resource == :cloud
73
76
  say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
@@ -85,7 +88,9 @@ module Shelly
85
88
  config = @app.config(path)
86
89
  content = open_editor(config["path"], config["content"])
87
90
  @app.update_config(path, content)
88
- say "File '#{config["path"]}' updated, it will be used after next code deploy", :green
91
+ say "File '#{config["path"]}' updated.", :green
92
+ say "To make changes to running application redeploy it using:"
93
+ say "`shelly redeploy --cloud #{@app}`"
89
94
  rescue Client::NotFoundException => e
90
95
  case e.resource
91
96
  when :cloud
@@ -108,7 +113,9 @@ module Shelly
108
113
  answer = yes?("Are you sure you want to delete 'path' (yes/no): ")
109
114
  if answer
110
115
  @app.delete_config(path)
111
- say "File deleted, redeploy your cloud to make changes", :green
116
+ say "File '#{path}' deleted.", :green
117
+ say "To make changes to running application redeploy it using:"
118
+ say "`shelly redeploy --cloud #{@app}`"
112
119
  else
113
120
  say "File not deleted"
114
121
  end
@@ -16,7 +16,7 @@ module Shelly
16
16
  check_unknown_options!
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]
19
+ before_hook :logged_in?, :only => [:add, :list, :start, :stop, :logs, :delete, :ip, :logout, :execute]
20
20
  before_hook :inside_git_repository?, :only => [:add]
21
21
  before_hook :cloudfile_present?, :only => [:logs, :stop, :start, :ip]
22
22
 
@@ -234,9 +234,24 @@ 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
+ long_desc "Run code given in parameter on one of application servers. If a file name is given, run contents of that file."
239
+ def execute(file_name_or_code)
240
+ cloud = options[:cloud]
241
+ multiple_clouds(cloud, "execute")
242
+
243
+ result = @app.run(file_name_or_code)
244
+ say result
245
+
246
+ rescue Client::APIException => e
247
+ if e[:message] == "App not running"
248
+ say_error "Cloud #{@app} is not running. Cannot run code."
249
+ else
250
+ raise
251
+ end
252
+ end
253
+
237
254
  desc "redeploy", "Redeploy application"
238
- method_option :cloud, :type => :string, :aliases => "-c",
239
- :desc => "Specify which cloud to redeploy application for"
240
255
  def redeploy
241
256
  multiple_clouds(options[:cloud], "redeploy")
242
257
  @app.redeploy
data/lib/shelly/client.rb CHANGED
@@ -115,6 +115,10 @@ 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)
120
+ end
121
+
118
122
  def deploy_logs(cloud)
119
123
  get("/apps/#{cloud}/deployment_logs")
120
124
  end
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.0.44.pre"
2
+ VERSION = "0.0.44.pre2"
3
3
  end
@@ -288,6 +288,26 @@ config
288
288
  end
289
289
  end
290
290
 
291
+ describe "#run" do
292
+ before do
293
+ @response = {
294
+ "result" => "4"
295
+ }
296
+ @client.stub(:run).and_return(@response)
297
+ File.open("to_run.rb", 'w') {|f| f.write("User.count\n") }
298
+ end
299
+
300
+ it "should return result of executed code" do
301
+ @client.should_receive(:run).with("foo-staging", "2 + 2")
302
+ @app.run("2 + 2").should == "4"
303
+ end
304
+
305
+ it "should send contents of file when file exists" do
306
+ @client.should_receive(:run).with("foo-staging", "User.count\n")
307
+ @app.run("to_run.rb")
308
+ end
309
+ end
310
+
291
311
  describe "#to_s" do
292
312
  it "should return code_name" do
293
313
  @app.to_s.should == "foo-staging"
@@ -145,7 +145,9 @@ describe Shelly::CLI::Config do
145
145
  it "should create file" do
146
146
  @config.should_receive(:system).with(/vim \/tmp\/shelly-edit/).and_return(true)
147
147
  @client.should_receive(:app_create_config).with("foo-staging", "path", "\n").and_return({})
148
- $stdout.should_receive(:puts).with(green "File 'path' created, it will be used after next code deploy")
148
+ $stdout.should_receive(:puts).with(green "File 'path' created.")
149
+ $stdout.should_receive(:puts).with("To make changes to running application redeploy it using:")
150
+ $stdout.should_receive(:puts).with("`shelly redeploy --cloud foo-staging`")
149
151
  invoke(@config, :create, "path")
150
152
  end
151
153
 
@@ -208,7 +210,9 @@ describe Shelly::CLI::Config do
208
210
  @client.should_receive(:app_config).with("foo-staging", "path").and_return({"path" => "test.rb", "content" => "example content"})
209
211
  @config.should_receive(:system).with(/vim \/tmp\/shelly-edit/).and_return(true)
210
212
  @client.should_receive(:app_update_config).with("foo-staging", "path", "example content\n").and_return({"path" => "test.rb", "content" => "example content"})
211
- $stdout.should_receive(:puts).with(green "File 'test.rb' updated, it will be used after next code deploy")
213
+ $stdout.should_receive(:puts).with(green "File 'test.rb' updated.")
214
+ $stdout.should_receive(:puts).with("To make changes to running application redeploy it using:")
215
+ $stdout.should_receive(:puts).with("`shelly redeploy --cloud foo-staging`")
212
216
  invoke(@config, :edit, "path")
213
217
  end
214
218
 
@@ -286,7 +290,9 @@ describe Shelly::CLI::Config do
286
290
 
287
291
  it "should delete configuration file" do
288
292
  @client.should_receive(:app_delete_config).with("foo-staging", "path").and_return({})
289
- $stdout.should_receive(:puts).with(green "File deleted, redeploy your cloud to make changes")
293
+ $stdout.should_receive(:puts).with(green "File 'path' deleted.")
294
+ $stdout.should_receive(:puts).with("To make changes to running application redeploy it using:")
295
+ $stdout.should_receive(:puts).with("`shelly redeploy --cloud foo-staging`")
290
296
  fake_stdin(["y"]) do
291
297
  invoke(@config, :delete, "path")
292
298
  end
@@ -313,7 +319,9 @@ describe Shelly::CLI::Config do
313
319
 
314
320
  it "should use cloud specified by parameter" do
315
321
  @client.should_receive(:app_delete_config).with("foo-production", "path").and_return({})
316
- $stdout.should_receive(:puts).with(green "File deleted, redeploy your cloud to make changes")
322
+ $stdout.should_receive(:puts).with(green "File 'path' deleted.")
323
+ $stdout.should_receive(:puts).with("To make changes to running application redeploy it using:")
324
+ $stdout.should_receive(:puts).with("`shelly redeploy --cloud foo-production`")
317
325
  @config.options = {:cloud => "foo-production"}
318
326
  fake_stdin(["y"]) do
319
327
  invoke(@config, :delete, "path")
@@ -29,6 +29,7 @@ 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
33
  shelly help [TASK] # Describe available tasks or one specific task
33
34
  shelly ip # List cloud's IP addresses
34
35
  shelly list # List available clouds
@@ -916,6 +917,81 @@ OUT
916
917
  end
917
918
  end
918
919
 
920
+ describe "#execute" do
921
+ before do
922
+ FileUtils.mkdir_p("/projects/foo")
923
+ Dir.chdir("/projects/foo")
924
+ File.open("Cloudfile", 'w') {|f| f.write("foo-production:\n") }
925
+ @user = Shelly::User.new
926
+ @user.stub(:token)
927
+ Shelly::User.stub(:new).and_return(@user)
928
+ @client.stub(:apps).and_return([{"code_name" => "foo-production"},
929
+ {"code_name" => "foo-staging"}])
930
+ @app = Shelly::App.new
931
+ Shelly::App.stub(:new).and_return(@app)
932
+ File.open("to_execute.rb", 'w') {|f| f.write("User.count") }
933
+ end
934
+
935
+ it "should ensure user has logged in" do
936
+ hooks(@main, :execute).should include(:logged_in?)
937
+ end
938
+
939
+ context "single cloud in Cloudfile" do
940
+ it "should execute code for the cloud" do
941
+ @client.should_receive(:run).with("foo-production", "User.count").
942
+ and_return({"result" => "3"})
943
+ $stdout.should_receive(:puts).with("3")
944
+ invoke(@main, :execute, "to_execute.rb")
945
+ end
946
+ end
947
+
948
+ context "multiple clouds in Cloudfile" do
949
+ before do
950
+ File.open("Cloudfile", 'w') {|f|
951
+ f.write("foo-staging:\nfoo-production:\n") }
952
+ end
953
+
954
+ it "should show information to print logs for specific cloud and exit" do
955
+ $stdout.should_receive(:puts).
956
+ with(red "You have multiple clouds in Cloudfile.")
957
+ $stdout.should_receive(:puts).
958
+ with("Select cloud using `shelly execute --cloud foo-production`")
959
+ $stdout.should_receive(:puts).with("Available clouds:")
960
+ $stdout.should_receive(:puts).with(" * foo-production")
961
+ $stdout.should_receive(:puts).with(" * foo-staging")
962
+ lambda { invoke(@main, :execute, "to_execute.rb") }.should raise_error(SystemExit)
963
+ end
964
+
965
+ it "should fetch from command line which cloud to start" do
966
+ @client.should_receive(:run).with("foo-staging", "User.count").
967
+ and_return({"result" => "3"})
968
+ $stdout.should_receive(:puts).with("3")
969
+ @main.options = {:cloud => "foo-staging"}
970
+ invoke(@main, :execute, "to_execute.rb")
971
+ end
972
+
973
+ it "should run code when no file from parameter is found" do
974
+ @client.should_receive(:run).with("foo-staging", "2 + 2").
975
+ and_return({"result" => "4"})
976
+ $stdout.should_receive(:puts).with("4")
977
+ @main.options = {:cloud => "foo-staging"}
978
+ invoke(@main, :execute, "2 + 2")
979
+ end
980
+ end
981
+
982
+ context "cloud is not running" do
983
+ it "should print error" do
984
+ @client.should_receive(:run).with("foo-staging", "2 + 2").
985
+ and_raise(Shelly::Client::APIException.new(
986
+ {"message" => "App not running"}, 504))
987
+ $stdout.should_receive(:puts).
988
+ with(red "Cloud foo-staging is not running. Cannot run code.")
989
+ @main.options = {:cloud => "foo-staging"}
990
+ lambda { invoke(@main, :execute, "2 + 2") }.should raise_error(SystemExit)
991
+ end
992
+ end
993
+ end
994
+
919
995
  describe "#redeploy" do
920
996
  before do
921
997
  @user = Shelly::User.new
@@ -188,6 +188,15 @@ 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")
196
+ response.should == {"result" => "4"}
197
+ end
198
+ end
199
+
191
200
  describe "#send_invitation" do
192
201
  it "should send post with developer's email" do
193
202
  FakeWeb.register_uri(:post, api_url("apps/staging-foo/collaborations"), :body => {}.to_json)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shelly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.44.pre
4
+ version: 0.0.44.pre2
5
5
  prerelease: 7
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-08 00:00:00.000000000 Z
12
+ date: 2012-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70206898312780 !ruby/object:Gem::Requirement
16
+ requirement: &70274550076140 !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: *70206898312780
24
+ version_requirements: *70274550076140
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70206898266580 !ruby/object:Gem::Requirement
27
+ requirement: &70274550075720 !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: *70206898266580
35
+ version_requirements: *70274550075720
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: guard
38
- requirement: &70206898212380 !ruby/object:Gem::Requirement
38
+ requirement: &70274550075300 !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: *70206898212380
46
+ version_requirements: *70274550075300
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: guard-rspec
49
- requirement: &70206898169340 !ruby/object:Gem::Requirement
49
+ requirement: &70274550074880 !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: *70206898169340
57
+ version_requirements: *70274550074880
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: simplecov
60
- requirement: &70206898115120 !ruby/object:Gem::Requirement
60
+ requirement: &70274550074460 !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: *70206898115120
68
+ version_requirements: *70274550074460
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: ruby_gntp
71
- requirement: &70206898084560 !ruby/object:Gem::Requirement
71
+ requirement: &70274550074000 !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: *70206898084560
79
+ version_requirements: *70274550074000
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rb-fsevent
82
- requirement: &70206898037160 !ruby/object:Gem::Requirement
82
+ requirement: &70274554592480 !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: *70206898037160
90
+ version_requirements: *70274554592480
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: fakefs
93
- requirement: &70206898006080 !ruby/object:Gem::Requirement
93
+ requirement: &70274554592060 !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: *70206898006080
101
+ version_requirements: *70274554592060
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: fakeweb
104
- requirement: &70206897962100 !ruby/object:Gem::Requirement
104
+ requirement: &70274554591640 !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: *70206897962100
112
+ version_requirements: *70274554591640
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: wijet-thor
115
- requirement: &70206897912840 !ruby/object:Gem::Requirement
115
+ requirement: &70274554591140 !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: *70206897912840
123
+ version_requirements: *70274554591140
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: rest-client
126
- requirement: &70206897862480 !ruby/object:Gem::Requirement
126
+ requirement: &70274554590720 !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: *70206897862480
134
+ version_requirements: *70274554590720
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: json
137
- requirement: &70206897821420 !ruby/object:Gem::Requirement
137
+ requirement: &70274554590260 !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: *70206897821420
145
+ version_requirements: *70274554590260
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: wijet-launchy
148
- requirement: &70206897777600 !ruby/object:Gem::Requirement
148
+ requirement: &70274554589840 !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: *70206897777600
156
+ version_requirements: *70274554589840
157
157
  - !ruby/object:Gem::Dependency
158
158
  name: progressbar
159
- requirement: &70206897756220 !ruby/object:Gem::Requirement
159
+ requirement: &70274554589400 !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: *70206897756220
167
+ version_requirements: *70274554589400
168
168
  description: Tool for managing applications and clouds at shellycloud.com
169
169
  email:
170
170
  - support@shellycloud.com
@@ -234,6 +234,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
234
234
  - - ! '>='
235
235
  - !ruby/object:Gem::Version
236
236
  version: '0'
237
+ segments:
238
+ - 0
239
+ hash: 2757033815683066563
237
240
  required_rubygems_version: !ruby/object:Gem::Requirement
238
241
  none: false
239
242
  requirements:
@@ -242,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
242
245
  version: 1.3.1
243
246
  requirements: []
244
247
  rubyforge_project: shelly
245
- rubygems_version: 1.8.10
248
+ rubygems_version: 1.8.15
246
249
  signing_key:
247
250
  specification_version: 3
248
251
  summary: Shelly Cloud command line tool