shelly 0.0.12 → 0.0.13

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
@@ -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