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 +5 -11
- data/lib/shelly/cli/main.rb +15 -5
- data/lib/shelly/client.rb +11 -5
- data/lib/shelly/user.rb +4 -0
- data/lib/shelly/version.rb +1 -1
- data/spec/shelly/app_spec.rb +25 -23
- data/spec/shelly/cli/main_spec.rb +13 -4
- data/spec/shelly/client_spec.rb +38 -0
- data/spec/shelly/user_spec.rb +7 -0
- metadata +24 -24
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 =>
|
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
|
data/lib/shelly/cli/main.rb
CHANGED
@@ -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.
|
28
|
-
e.errors.each
|
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.
|
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(
|
8
|
-
@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
|
-
|
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
data/lib/shelly/version.rb
CHANGED
data/spec/shelly/app_spec.rb
CHANGED
@@ -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
|
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
|
-
|
119
|
+
attributes = {
|
112
120
|
:code_name => "fooo",
|
113
121
|
:name => "fooo",
|
114
|
-
:environment => "
|
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 {
|
data/spec/shelly/client_spec.rb
CHANGED
@@ -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 = {
|
data/spec/shelly/user_spec.rb
CHANGED
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.
|
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-
|
12
|
+
date: 2011-10-13 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
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: *
|
24
|
+
version_requirements: *2160815840
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
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: *
|
35
|
+
version_requirements: *2160815420
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: guard
|
38
|
-
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: *
|
46
|
+
version_requirements: *2160814660
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: guard-rspec
|
49
|
-
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: *
|
57
|
+
version_requirements: *2160813620
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: growl_notify
|
60
|
-
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: *
|
68
|
+
version_requirements: *2160811840
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rb-fsevent
|
71
|
-
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: *
|
79
|
+
version_requirements: *2160810620
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: fakefs
|
82
|
-
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: *
|
90
|
+
version_requirements: *2160809600
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: thor
|
93
|
-
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: *
|
101
|
+
version_requirements: *2160809060
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: rest-client
|
104
|
-
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: *
|
112
|
+
version_requirements: *2160795800
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: json
|
115
|
-
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: *
|
123
|
+
version_requirements: *2160795340
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: launchy
|
126
|
-
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: *
|
134
|
+
version_requirements: *2160794900
|
135
135
|
description: Tool for managing applications and clouds at shellycloud.com
|
136
136
|
email:
|
137
137
|
- support@shellycloud.com
|