shelly 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
data/lib/shelly/app.rb CHANGED
@@ -4,10 +4,11 @@ require 'launchy'
4
4
  module Shelly
5
5
  class App < Base
6
6
  DATABASE_KINDS = %w(postgresql mongodb redis none)
7
- attr_accessor :purpose, :code_name, :databases, :ruby_version, :environment
7
+ attr_accessor :purpose, :code_name, :databases, :ruby_version, :environment, :git_url
8
8
 
9
9
  def initialize
10
10
  @ruby_version = "MRI-1.9.2"
11
+ @environment = "production"
11
12
  end
12
13
 
13
14
  def add_git_remote(force = false)
@@ -19,14 +20,6 @@ module Shelly
19
20
  IO.popen("git remote").read.split("\n").include?(purpose)
20
21
  end
21
22
 
22
- def git_host
23
- ENV["SHELLY_GIT_HOST"] || "git.shellycloud.com"
24
- end
25
-
26
- def git_url
27
- "git@#{git_host}:#{code_name}.git"
28
- end
29
-
30
23
  def generate_cloudfile
31
24
  @email = current_user.email
32
25
  @databases = databases
@@ -43,11 +36,12 @@ module Shelly
43
36
  attributes = {
44
37
  :name => code_name,
45
38
  :code_name => code_name,
46
- :environment => purpose,
39
+ :environment => environment,
47
40
  :ruby_version => ruby_version,
48
41
  :domain_name => "#{code_name}.shellycloud.com"
49
42
  }
50
- shelly.create_app(attributes)
43
+ response = shelly.create_app(attributes)
44
+ self.git_url = response["git_url"]
51
45
  end
52
46
 
53
47
  def create_cloudfile
@@ -24,8 +24,10 @@ module Shelly
24
24
  say "Successfully registered!"
25
25
  say "Check you mailbox for email address confirmation"
26
26
  rescue Client::APIError => e
27
- if e.message == "Validation Failed"
28
- e.errors.each { |error| say "#{error.first} #{error.last}" }
27
+ if e.validation?
28
+ e.errors.each do |error|
29
+ say "#{error.first} #{error.last}"
30
+ end
29
31
  exit 1
30
32
  end
31
33
  end
@@ -37,9 +39,18 @@ module Shelly
37
39
  say "Login successful"
38
40
  say "Uploading your public SSH key"
39
41
  user.upload_ssh_key
42
+ say "You have following applications available:", :green
43
+ user.apps.each do |app|
44
+ say " #{app["code_name"]}"
45
+ end
40
46
  rescue RestClient::Unauthorized
41
47
  say "Wrong email or password or your email is unconfirmend"
42
48
  exit 1
49
+ rescue Client::APIError
50
+ if e.validation?
51
+ e.errors.each { |error| say "#{error.first} #{error.last}" }
52
+ exit 1
53
+ end
43
54
  end
44
55
 
45
56
  desc "add", "Adds new application to Shelly Cloud"
@@ -71,13 +82,12 @@ module Shelly
71
82
  info_adding_cloudfile_to_repository
72
83
  info_deploying_to_shellycloud
73
84
  rescue Client::APIError => e
74
- if e.message == "Validation Failed"
85
+ if e.validation?
75
86
  e.errors.each { |error| say "#{error.first} #{error.last}" }
76
87
  exit 1
77
88
  end
78
89
  end
79
90
 
80
-
81
91
  # FIXME: move to helpers
82
92
  no_tasks do
83
93
  def ask_for_email
@@ -121,7 +131,7 @@ module Shelly
121
131
  kinds = Shelly::App::DATABASE_KINDS
122
132
  databases = ask("Which database do you want to use #{kinds.join(", ")} (postgresql - default):")
123
133
  begin
124
- databases = databases.split(/[\s,]/)
134
+ databases = databases.split(/[\s,]/).reject(&:blank?)
125
135
  valid = databases.all? { |kind| kinds.include?(kind) }
126
136
  break if valid
127
137
  databases = ask("Unknown database kind. Supported are: #{kinds.join(", ")}:")
data/lib/shelly/client.rb CHANGED
@@ -4,8 +4,8 @@ require "json"
4
4
  module Shelly
5
5
  class Client
6
6
  class APIError < Exception
7
- def initialize(response)
8
- @response = response
7
+ def initialize(response_body)
8
+ @response = JSON.parse(response_body)
9
9
  end
10
10
 
11
11
  def message
@@ -15,6 +15,10 @@ module Shelly
15
15
  def errors
16
16
  @response["errors"]
17
17
  end
18
+
19
+ def validation?
20
+ message == "Validation Failed"
21
+ end
18
22
  end
19
23
 
20
24
  def initialize(email = nil, password = nil)
@@ -42,6 +46,10 @@ module Shelly
42
46
  put("/ssh_key", :ssh_key => ssh_key)
43
47
  end
44
48
 
49
+ def apps
50
+ get("/apps")
51
+ end
52
+
45
53
  def post(path, params = {})
46
54
  request(path, :post, params)
47
55
  end
@@ -81,9 +89,7 @@ module Shelly
81
89
 
82
90
  def process_response(response)
83
91
  if [404, 422, 500].include?(response.code)
84
- # FIXME: move parsing JSON to APIError class
85
- error_details = JSON.parse(response.body)
86
- raise APIError.new(error_details)
92
+ raise APIError.new(response.body)
87
93
  end
88
94
 
89
95
  response.return!
data/lib/shelly/user.rb CHANGED
@@ -7,6 +7,10 @@ module Shelly
7
7
  @password = password
8
8
  end
9
9
 
10
+ def apps
11
+ shelly.apps
12
+ end
13
+
10
14
  def register
11
15
  ssh_key = File.read(ssh_key_path) if ssh_key_exists?
12
16
  shelly.register_user(email, password, ssh_key)
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.0.12"
2
+ VERSION = "0.0.13"
3
3
  end
@@ -12,6 +12,16 @@ describe Shelly::App do
12
12
  @app.code_name = "foo-staging"
13
13
  end
14
14
 
15
+ describe "being initialized" do
16
+ it "should have default ruby_version: MRI-1.9.2" do
17
+ @app.ruby_version.should == "MRI-1.9.2"
18
+ end
19
+
20
+ it "should have default environment: production" do
21
+ @app.environment.should == "production"
22
+ end
23
+ end
24
+
15
25
  describe ".guess_code_name" do
16
26
  it "should return name of current working directory" do
17
27
  Shelly::App.guess_code_name.should == "foo"
@@ -19,7 +29,11 @@ describe Shelly::App do
19
29
  end
20
30
 
21
31
  describe "#add_git_remote" do
22
- before { @app.stub(:system) }
32
+ before do
33
+ @app.stub(:git_url).and_return("git@git.shellycloud.com:foo-staging.git")
34
+ @app.stub(:system)
35
+ end
36
+
23
37
  it "should add git remote with proper name and git repository" do
24
38
  @app.should_receive(:system).with("git remote add staging git@git.shellycloud.com:foo-staging.git")
25
39
  @app.add_git_remote
@@ -98,25 +112,26 @@ config
98
112
  end
99
113
  end
100
114
 
101
- describe "#git_url" do
102
- it "should return URL to git repository on shelly" do
103
- @app.git_url.should == "git@git.shellycloud.com:foo-staging.git"
104
- end
105
- end
106
-
107
115
  describe "#create" do
108
116
  it "should create the app on shelly cloud via API client" do
109
117
  @app.purpose = "dev"
110
118
  @app.code_name = "fooo"
111
- @client.should_receive(:create_app).with({
119
+ attributes = {
112
120
  :code_name => "fooo",
113
121
  :name => "fooo",
114
- :environment => "dev",
122
+ :environment => "production",
115
123
  :ruby_version => "MRI-1.9.2",
116
124
  :domain_name => "fooo.shellycloud.com"
117
- })
125
+ }
126
+ @client.should_receive(:create_app).with(attributes).and_return("git_url" => "git@git.shellycloud.com:fooo.git")
118
127
  @app.create
119
128
  end
129
+
130
+ it "should assign returned git_url" do
131
+ @client.stub(:create_app).and_return("git_url" => "git@git.example.com:fooo.git")
132
+ @app.create
133
+ @app.git_url.should == "git@git.example.com:fooo.git"
134
+ end
120
135
  end
121
136
 
122
137
  describe "#remote_exists?" do
@@ -136,17 +151,4 @@ config
136
151
  end
137
152
  end
138
153
  end
139
-
140
- describe "#git_host" do
141
- it "should return default git host" do
142
- @app.git_host.should == "git.shellycloud.com"
143
- end
144
-
145
- context "SHELLY_GIT_HOST set" do
146
- it "should return value of SHELLY_GIT_HOST env variable" do
147
- ENV['SHELLY_GIT_HOST'] = "git.example.com"
148
- @app.git_host.should == "git.example.com"
149
- end
150
- end
151
- end
152
154
  end
@@ -137,7 +137,7 @@ OUT
137
137
  context "on unsuccessful registration" do
138
138
  it "should display errors and exit with 1" do
139
139
  response = {"message" => "Validation Failed", "errors" => [["email", "has been already taken"]]}
140
- exception = Shelly::Client::APIError.new(response)
140
+ exception = Shelly::Client::APIError.new(response.to_json)
141
141
  @client.stub(:register_user).and_raise(exception)
142
142
  $stdout.should_receive(:puts).with("email has been already taken")
143
143
  lambda {
@@ -154,6 +154,7 @@ OUT
154
154
  @user = Shelly::User.new
155
155
  @user.stub(:upload_ssh_key)
156
156
  @client.stub(:token).and_return("abc")
157
+ @client.stub(:apps).and_return([{"code_name" => "abc"}, {"code_name" => "fooo"}])
157
158
  Shelly::User.stub(:new).and_return(@user)
158
159
  end
159
160
 
@@ -179,7 +180,14 @@ OUT
179
180
  end
180
181
  end
181
182
 
182
- it "should display list of applications to which user has access"
183
+ it "should display list of applications to which user has access" do
184
+ $stdout.should_receive(:puts).with("\e[32mYou have following applications available:\e[0m")
185
+ $stdout.should_receive(:puts).with(" abc")
186
+ $stdout.should_receive(:puts).with(" fooo")
187
+ fake_stdin(["megan@example.com", "secret"]) do
188
+ @main.login
189
+ end
190
+ end
183
191
  end
184
192
 
185
193
  context "on unauthorized user" do
@@ -206,6 +214,7 @@ OUT
206
214
  @app.stub(:generate_cloudfile).and_return("Example Cloudfile")
207
215
  @app.stub(:open_billing_page)
208
216
  @app.stub(:remote_exists?).and_return(false)
217
+ @app.stub(:git_url).and_return("git@git.shellycloud.com:foooo.git")
209
218
  Shelly::App.stub(:inside_git_repository?).and_return(true)
210
219
  Shelly::App.stub(:new).and_return(@app)
211
220
  end
@@ -260,7 +269,7 @@ OUT
260
269
  it "should use database provided by user (separated by comma or space)" do
261
270
  $stdout.should_receive(:print).with("Which database do you want to use postgresql, mongodb, redis, none (postgresql - default): ")
262
271
  @app.should_receive(:databases=).with(["postgresql", "mongodb", "redis"])
263
- fake_stdin(["staging", "", "postgresql,mongodb redis"]) do
272
+ fake_stdin(["staging", "", "postgresql ,mongodb redis"]) do
264
273
  @main.add
265
274
  end
266
275
  end
@@ -291,7 +300,7 @@ OUT
291
300
 
292
301
  it "should display validation errors if they are any" do
293
302
  response = {"message" => "Validation Failed", "errors" => [["code_name", "has been already taken"]]}
294
- exception = Shelly::Client::APIError.new(response)
303
+ exception = Shelly::Client::APIError.new(response.to_json)
295
304
  @app.should_receive(:create).and_raise(exception)
296
305
  $stdout.should_receive(:puts).with("code_name has been already taken")
297
306
  lambda {
@@ -1,5 +1,36 @@
1
1
  require "spec_helper"
2
2
 
3
+ describe Shelly::Client::APIError do
4
+ before do
5
+ body = {"message" => "something went wrong", "errors" => [{"first" => "foo"}]}
6
+ @error = Shelly::Client::APIError.new(body.to_json)
7
+ end
8
+
9
+ it "should return error message" do
10
+ @error.message.should == "something went wrong"
11
+ end
12
+
13
+ it "should return list of errors" do
14
+ @error.errors.should == [{"first" => "foo"}]
15
+ end
16
+
17
+ describe "#validation?" do
18
+ context "when error is caused by validation errors" do
19
+ it "should return true" do
20
+ body = {"message" => "Validation Failed"}
21
+ error = Shelly::Client::APIError.new(body.to_json)
22
+ error.should be_validation
23
+ end
24
+ end
25
+
26
+ context "when error is not caused by validation errors" do
27
+ it "should return false" do
28
+ @error.should_not be_validation
29
+ end
30
+ end
31
+ end
32
+ end
33
+
3
34
  describe Shelly::Client do
4
35
  before do
5
36
  ENV['SHELLY_URL'] = nil
@@ -52,6 +83,13 @@ describe Shelly::Client do
52
83
  end
53
84
  end
54
85
 
86
+ describe "#apps" do
87
+ it "should send get requests for user's applications list" do
88
+ @client.should_receive(:get).with("/apps")
89
+ @client.apps
90
+ end
91
+ end
92
+
55
93
  describe "#request_parameters" do
56
94
  it "should return hash of resquest parameters" do
57
95
  expected = {
@@ -140,4 +140,11 @@ describe Shelly::User do
140
140
  end
141
141
  end
142
142
  end
143
+
144
+ describe "#apps" do
145
+ it "should fetch list of apps via API client" do
146
+ @client.should_receive(:apps)
147
+ @user.apps
148
+ end
149
+ end
143
150
  end
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.12
4
+ version: 0.0.13
5
5
  prerelease:
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: 2011-10-11 00:00:00.000000000Z
12
+ date: 2011-10-13 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2161489060 !ruby/object:Gem::Requirement
16
+ requirement: &2160815840 !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: *2161489060
24
+ version_requirements: *2160815840
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &2161488640 !ruby/object:Gem::Requirement
27
+ requirement: &2160815420 !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: *2161488640
35
+ version_requirements: *2160815420
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: guard
38
- requirement: &2161488220 !ruby/object:Gem::Requirement
38
+ requirement: &2160814660 !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: *2161488220
46
+ version_requirements: *2160814660
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: guard-rspec
49
- requirement: &2161487780 !ruby/object:Gem::Requirement
49
+ requirement: &2160813620 !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: *2161487780
57
+ version_requirements: *2160813620
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: growl_notify
60
- requirement: &2161487280 !ruby/object:Gem::Requirement
60
+ requirement: &2160811840 !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: *2161487280
68
+ version_requirements: *2160811840
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rb-fsevent
71
- requirement: &2161486760 !ruby/object:Gem::Requirement
71
+ requirement: &2160810620 !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: *2161486760
79
+ version_requirements: *2160810620
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: fakefs
82
- requirement: &2161486240 !ruby/object:Gem::Requirement
82
+ requirement: &2160809600 !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: *2161486240
90
+ version_requirements: *2160809600
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: thor
93
- requirement: &2161481240 !ruby/object:Gem::Requirement
93
+ requirement: &2160809060 !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: :runtime
100
100
  prerelease: false
101
- version_requirements: *2161481240
101
+ version_requirements: *2160809060
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: rest-client
104
- requirement: &2161480620 !ruby/object:Gem::Requirement
104
+ requirement: &2160795800 !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: :runtime
111
111
  prerelease: false
112
- version_requirements: *2161480620
112
+ version_requirements: *2160795800
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: json
115
- requirement: &2161479960 !ruby/object:Gem::Requirement
115
+ requirement: &2160795340 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: '0'
121
121
  type: :runtime
122
122
  prerelease: false
123
- version_requirements: *2161479960
123
+ version_requirements: *2160795340
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: launchy
126
- requirement: &2161479400 !ruby/object:Gem::Requirement
126
+ requirement: &2160794900 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ! '>='
@@ -131,7 +131,7 @@ dependencies:
131
131
  version: '0'
132
132
  type: :runtime
133
133
  prerelease: false
134
- version_requirements: *2161479400
134
+ version_requirements: *2160794900
135
135
  description: Tool for managing applications and clouds at shellycloud.com
136
136
  email:
137
137
  - support@shellycloud.com