shelly 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,4 +2,8 @@ class Object
2
2
  def blank?
3
3
  respond_to?(:empty?) ? empty? : !self
4
4
  end
5
+
6
+ def present?
7
+ not blank?
8
+ end
5
9
  end
data/lib/shelly/base.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require "yaml"
2
+
1
3
  module Shelly
2
4
  class Base
3
5
  def current_user
@@ -6,8 +8,20 @@ module Shelly
6
8
  @user
7
9
  end
8
10
 
11
+ def config
12
+ @config ||= if File.exists?(config_file_path)
13
+ YAML::load(File.read(config_file_path))
14
+ else
15
+ {}
16
+ end
17
+ end
18
+
19
+ def config_file_path
20
+ File.join(current_user.config_dir, "config.yml")
21
+ end
22
+
9
23
  def shelly
10
- @shelly ||= Client.new(current_user.email, current_user.password)
24
+ @shelly ||= Client.new(current_user.email, current_user.password, config)
11
25
  end
12
26
  end
13
27
  end
@@ -6,26 +6,20 @@ module Shelly
6
6
  namespace :account
7
7
  include Helpers
8
8
 
9
- desc "register", "Registers new user account on Shelly Cloud"
10
- def register
11
- email = ask_for_email
12
- password = ask_for_password
13
-
14
- # FIXME: ask user in loop, until he enters valid values
15
- if email.blank? or password.blank?
16
- say "Email and password can't be blank" and exit 1
17
- end
18
-
19
- user = User.new(email, password)
9
+ desc "register [EMAIL]", "Registers new user account on Shelly Cloud"
10
+ def register(email = nil)
11
+ say "Registering with email: #{email}" if email
12
+ user = User.new(email || ask_for_email, ask_for_password)
20
13
  user.register
21
14
  if user.ssh_key_exists?
22
15
  say "Uploading your public SSH key from #{user.ssh_key_path}"
23
16
  end
24
17
  say "Successfully registered!"
25
- say "Check you mailbox for email confirmation"
18
+ say "Check you mailbox for email address confirmation"
26
19
  rescue Client::APIError => e
27
20
  if e.message == "Validation Failed"
28
21
  e.errors.each { |error| say "#{error.first} #{error.last}" }
22
+ exit 1
29
23
  end
30
24
  end
31
25
 
@@ -40,15 +34,26 @@ module Shelly
40
34
  def ask_for_email
41
35
  email_question = User.guess_email.blank? ? "Email:" : "Email (#{User.guess_email} - default):"
42
36
  email = ask(email_question)
43
- email.blank? ? User.guess_email : email
37
+ email = email.blank? ? User.guess_email : email
38
+ return email if email.present?
39
+ say_error "Email can't be blank, please try again"
44
40
  end
45
41
 
46
42
  def ask_for_password
47
- say "Password: "
48
- echo_off
49
- password = $stdin.gets.strip
50
- echo_on
51
- password
43
+ loop do
44
+ say "Password: "
45
+ password = echo_disabled { $stdin.gets.strip }
46
+ say_new_line
47
+ say "Password confirmation: "
48
+ password_confirmation = echo_disabled { $stdin.gets.strip }
49
+ say_new_line
50
+ if password.present?
51
+ return password if password == password_confirmation
52
+ say "Password and password confirmation don't match, please type them again"
53
+ else
54
+ say "Password can't be blank"
55
+ end
56
+ end
52
57
  end
53
58
  end
54
59
  end
@@ -13,13 +13,17 @@ module Shelly
13
13
  @app.databases = ask_for_databases
14
14
  @app.add_git_remote
15
15
  @app.create_cloudfile
16
- @app.open_billing_page
17
-
16
+ open_billing_page
18
17
  info_adding_cloudfile_to_repository
19
18
  info_deploying_to_shellycloud
20
19
  end
21
20
 
22
21
  no_tasks do
22
+ def open_billing_page
23
+ say "Provide billing details. Opening browser..."
24
+ @app.open_billing_page
25
+ end
26
+
23
27
  def ask_for_purpose
24
28
  purpose = ask("How will you use this system (production - default,staging):")
25
29
  purpose.blank? ? "production" : purpose
@@ -16,9 +16,9 @@ module Shelly
16
16
  say "shelly version #{Shelly::VERSION}"
17
17
  end
18
18
 
19
- desc "register", "Registers new user account on Shelly Cloud"
20
- def register
21
- invoke "account:register"
19
+ desc "register [EMAIL]", "Registers new user account on Shelly Cloud"
20
+ def register(email = nil)
21
+ invoke "account:register", email
22
22
  end
23
23
 
24
24
  desc "add", "Adds new application to Shelly Cloud"
data/lib/shelly/client.rb CHANGED
@@ -19,13 +19,14 @@ module Shelly
19
19
  end
20
20
  end
21
21
 
22
- def initialize(email = nil, password = nil)
22
+ def initialize(email = nil, password = nil, options = {})
23
23
  @email = email
24
24
  @password = password
25
+ @options = options
25
26
  end
26
27
 
27
28
  def api_url
28
- ENV["SHELLY_URL"] || "https://admin.winniecloud.com/apiv2"
29
+ @options["shelly_url"] || ENV["SHELLY_URL"] || "https://admin.winniecloud.com/apiv2"
29
30
  end
30
31
 
31
32
  def register_user(email, password, ssh_key)
@@ -1,11 +1,19 @@
1
1
  module Shelly
2
2
  module Helpers
3
- def echo_off
3
+ def echo_disabled
4
4
  system "stty -echo"
5
+ value = yield
6
+ system "stty echo"
7
+ value
5
8
  end
6
9
 
7
- def echo_on
8
- system "stty echo"
10
+ def say_new_line
11
+ say "\n"
12
+ end
13
+
14
+ def say_error(message)
15
+ say message
16
+ exit 1
9
17
  end
10
18
  end
11
19
  end
@@ -1,5 +1,6 @@
1
1
  <%= @code_name %>:
2
- ruby: 1.9.2
2
+ ruby: 1.9.2 # 1.9.2 or ree
3
+ environment: production # RAILS_ENV
3
4
  monitoring_email:
4
5
  - <%= @email %>
5
6
  domains:
@@ -7,14 +8,12 @@
7
8
  servers:
8
9
  app1:
9
10
  size: large
10
- web:
11
- type: thin
12
- count: 3
13
- clock:
14
- type: cron
15
- <%- @databases.each_with_index do |kind, index| -%>
16
- <%= "#{kind}#{index}" %>:
11
+ thin: 4
12
+ # whenever: on
13
+ # delayed_job: 1
14
+ <%- @databases.each do |kind| -%>
15
+ <%= kind %>:
17
16
  size: large
18
17
  database:
19
- type: <%= kind %>
18
+ - <%= kind %>
20
19
  <%- end -%>
data/lib/shelly/user.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  module Shelly
2
2
  class User < Base
3
3
  attr_reader :email, :password
4
+
4
5
  def initialize(email = nil, password = nil)
5
6
  @email = email
6
7
  @password = password
@@ -39,11 +40,11 @@ module Shelly
39
40
  @@guess_email ||= IO.popen("git config --get user.email").read.strip
40
41
  end
41
42
 
42
- protected
43
- def config_dir
44
- File.expand_path("~/.shelly")
45
- end
43
+ def config_dir
44
+ File.expand_path("~/.shelly")
45
+ end
46
46
 
47
+ protected
47
48
  def credentials_path
48
49
  File.join(config_dir, "credentials")
49
50
  end
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
@@ -31,7 +31,8 @@ describe Shelly::App do
31
31
  FakeFS.deactivate!
32
32
  expected = <<-config
33
33
  foo-staging:
34
- ruby: 1.9.2
34
+ ruby: 1.9.2 # 1.9.2 or ree
35
+ environment: production # RAILS_ENV
35
36
  monitoring_email:
36
37
  - bob@example.com
37
38
  domains:
@@ -39,19 +40,17 @@ foo-staging:
39
40
  servers:
40
41
  app1:
41
42
  size: large
42
- web:
43
- type: thin
44
- count: 3
45
- clock:
46
- type: cron
47
- postgresql0:
43
+ thin: 4
44
+ # whenever: on
45
+ # delayed_job: 1
46
+ postgresql:
48
47
  size: large
49
48
  database:
50
- type: postgresql
51
- mongodb1:
49
+ - postgresql
50
+ mongodb:
52
51
  size: large
53
52
  database:
54
- type: mongodb
53
+ - mongodb
55
54
  config
56
55
  @app.generate_cloudfile.should == expected
57
56
  end
@@ -83,7 +82,7 @@ config
83
82
 
84
83
  describe "#open_billing_page" do
85
84
  it "should open browser window" do
86
- user = mock(:token => "abc", :email => nil, :password => nil)
85
+ user = mock(:token => "abc", :email => nil, :password => nil, :config_dir => "~/.shelly")
87
86
  @app.stub(:current_user).and_return(user)
88
87
  url = "#{@app.shelly.api_url}/apps/foo-staging/edit_billing?api_key=abc"
89
88
  Launchy.should_receive(:open).with(url)
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ describe Shelly::Base do
4
+ before do
5
+ config_dir = File.expand_path("~/.shelly")
6
+ FileUtils.mkdir_p(config_dir)
7
+ end
8
+
9
+ describe "#current_user" do
10
+ it "should return user with loaded credentials" do
11
+ File.open(File.join("~/.shelly/credentials"), "w") { |f| f << "superman@example.com\nthe-kal-el" }
12
+ base = Shelly::Base.new
13
+ user = base.current_user
14
+ user.email.should == "superman@example.com"
15
+ user.password.should == "the-kal-el"
16
+ end
17
+ end
18
+
19
+ describe "#config" do
20
+ context "config file exists" do
21
+ it "should return loaded config as a Hash" do
22
+ File.open("~/.shelly/config.yml", "w") { |f| f << "shelly_url: http://api.example.com/v4/\n" }
23
+ base = Shelly::Base.new
24
+ base.config.should == {"shelly_url" => "http://api.example.com/v4/"}
25
+ end
26
+ end
27
+
28
+ context "config file doesn't exist" do
29
+ it "should return an empty Hash" do
30
+ base = Shelly::Base.new
31
+ base.config.should == {}
32
+ end
33
+ end
34
+ end
35
+ end
@@ -18,10 +18,11 @@ describe Shelly::CLI::Account do
18
18
  @key_path = File.expand_path("~/.ssh/id_rsa.pub")
19
19
  end
20
20
 
21
- it "should ask for email and password" do
21
+ it "should ask for email, password and password confirmation" do
22
22
  $stdout.should_receive(:print).with("Email: ")
23
23
  $stdout.should_receive(:print).with("Password: ")
24
- fake_stdin(["better@example.com", "secret"]) do
24
+ $stdout.should_receive(:print).with("Password confirmation: ")
25
+ fake_stdin(["better@example.com", "secret", "secret"]) do
25
26
  @account.register
26
27
  end
27
28
  end
@@ -30,77 +31,97 @@ describe Shelly::CLI::Account do
30
31
  Shelly::User.stub(:guess_email).and_return("kate@example.com")
31
32
  $stdout.should_receive(:print).with("Email (kate@example.com - default): ")
32
33
  @client.should_receive(:register_user).with("kate@example.com", "secret", nil)
33
- fake_stdin(["", "secret"]) do
34
+ fake_stdin(["", "secret", "secret"]) do
34
35
  @account.register
35
36
  end
36
37
  end
37
38
 
38
39
  it "should use email provided by user" do
39
40
  @client.should_receive(:register_user).with("better@example.com", "secret", nil)
40
- fake_stdin(["better@example.com", "secret"]) do
41
+ fake_stdin(["better@example.com", "secret", "secret"]) do
41
42
  @account.register
42
43
  end
43
44
  end
44
45
 
45
- it "should exit with message if email is blank" do
46
- Shelly::User.stub(:guess_email).and_return("")
47
- $stdout.should_receive(:puts).with("Email and password can't be blank")
48
- lambda do
49
- fake_stdin(["", "only-pass"]) do
46
+ it "should not ask about email if it's provided as argument" do
47
+ $stdout.should_receive(:puts).with("Registering with email: kate@example.com")
48
+ fake_stdin(["secret", "secret"]) do
49
+ @account.register("kate@example.com")
50
+ end
51
+ end
52
+
53
+ context "when user enters blank email" do
54
+ it "should show error message and exit with 1" do
55
+ Shelly::User.stub(:guess_email).and_return("")
56
+ $stdout.should_receive(:puts).with("Email can't be blank, please try again")
57
+ lambda {
58
+ fake_stdin(["", "bob@example.com", "only-pass", "only-pass"]) do
59
+ @account.register
60
+ end
61
+ }.should raise_error(SystemExit)
62
+ end
63
+ end
64
+
65
+ context "when user enters blank password" do
66
+ it "should ask for it again" do
67
+ $stdout.should_receive(:puts).with("Password can't be blank")
68
+ fake_stdin(["better@example.com", "", "", "secret", "secret"]) do
50
69
  @account.register
51
70
  end
52
- end.should raise_error(SystemExit)
71
+ end
53
72
  end
54
73
 
55
- it "should exit with message if password is blank" do
56
- $stdout.should_receive(:puts).with("Email and password can't be blank")
57
- lambda do
58
- fake_stdin(["better@example.com", ""]) do
74
+ context "when user enters password and password confirmation which don't match each other" do
75
+ it "should ask for them again" do
76
+ $stdout.should_receive(:puts).with("Password and password confirmation don't match, please type them again")
77
+ fake_stdin(["better@example.com", "secret", "sec-TYPO-ret", "secret", "secret"]) do
59
78
  @account.register
60
79
  end
61
- end.should raise_error(SystemExit)
80
+ end
62
81
  end
63
82
 
64
- context "ssh key exists" do
65
- it "should register with ssh-key" do
83
+ context "public SSH key exists" do
84
+ it "should register with the public SSH key" do
66
85
  FileUtils.mkdir_p("~/.ssh")
67
86
  File.open(@key_path, "w") { |f| f << "key" }
68
87
  $stdout.should_receive(:puts).with("Uploading your public SSH key from #{@key_path}")
69
- fake_stdin(["kate@example.com", "secret"]) do
88
+ fake_stdin(["kate@example.com", "secret", "secret"]) do
70
89
  @account.register
71
90
  end
72
91
  end
73
92
  end
74
93
 
75
- context "ssh key doesn't exist" do
76
- it "should register user without the ssh key" do
94
+ context "public SSH key doesn't exist" do
95
+ it "should register user without the public SSH key" do
77
96
  $stdout.should_not_receive(:puts).with("Uploading your public SSH key from #{@key_path}")
78
- fake_stdin(["kate@example.com", "secret"]) do
97
+ fake_stdin(["kate@example.com", "secret", "secret"]) do
79
98
  @account.register
80
99
  end
81
100
  end
82
101
  end
83
102
 
84
103
  context "on successful registration" do
85
- it "should display message about registration and email confirmation" do
104
+ it "should display message about registration and email address confirmation" do
86
105
  @client.stub(:register_user).and_return(true)
87
106
  $stdout.should_receive(:puts).with("Successfully registered!")
88
- $stdout.should_receive(:puts).with("Check you mailbox for email confirmation")
89
- fake_stdin(["kate@example.com", "pass"]) do
107
+ $stdout.should_receive(:puts).with("Check you mailbox for email address confirmation")
108
+ fake_stdin(["kate@example.com", "pass", "pass"]) do
90
109
  @account.register
91
110
  end
92
111
  end
93
112
  end
94
113
 
95
114
  context "on unsuccessful registration" do
96
- it "should display errors" do
115
+ it "should display errors and exit with 1" do
97
116
  response = {"message" => "Validation Failed", "errors" => [["email", "has been already taken"]]}
98
117
  exception = Shelly::Client::APIError.new(response)
99
118
  @client.stub(:register_user).and_raise(exception)
100
119
  $stdout.should_receive(:puts).with("email has been already taken")
101
- fake_stdin(["kate@example.com", "pass"]) do
102
- @account.register
103
- end
120
+ lambda {
121
+ fake_stdin(["kate@example.com", "pass", "pass"]) do
122
+ @account.register
123
+ end
124
+ }.should raise_error(SystemExit)
104
125
  end
105
126
  end
106
127
  end
@@ -97,6 +97,7 @@ describe Shelly::CLI::Apps do
97
97
  end
98
98
 
99
99
  it "should browser window with link to edit billing information" do
100
+ $stdout.should_receive(:puts).with("Provide billing details. Opening browser...")
100
101
  @app.should_receive(:open_billing_page)
101
102
  fake_stdin(["staging", "foooo", ""]) do
102
103
  @apps.add
@@ -15,8 +15,8 @@ describe Shelly::CLI::Main do
15
15
 
16
16
  describe "#register" do
17
17
  it "should invoke account:register command" do
18
- @main.should_receive(:invoke).with("account:register")
19
- @main.register
18
+ @main.should_receive(:invoke).with("account:register", "kate@example.com")
19
+ @main.register("kate@example.com")
20
20
  end
21
21
  end
22
22
 
@@ -27,8 +27,6 @@ describe Shelly::CLI::Main do
27
27
  end
28
28
  end
29
29
 
30
-
31
-
32
30
  describe "#help" do
33
31
  it "should display available commands" do
34
32
  expected = <<-OUT
@@ -37,7 +35,7 @@ Tasks:
37
35
  shelly add # Adds new application to Shelly Cloud
38
36
  shelly apps <command> # Manages your applications
39
37
  shelly help [TASK] # Describe available tasks or one specific task
40
- shelly register # Registers new user account on Shelly Cloud
38
+ shelly register [EMAIL] # Registers new user account on Shelly Cloud
41
39
  shelly version # Displays shelly version
42
40
  OUT
43
41
  out = IO.popen("bin/shelly").read.strip
@@ -8,6 +8,13 @@ describe Shelly::Client do
8
8
  end
9
9
 
10
10
  describe "#api_url" do
11
+ context "API URL passed with options hash" do
12
+ it "should use provided value" do
13
+ client = Shelly::Client.new("bob@example.com", "secret", "shelly_url" => "https://api2.example.com")
14
+ client.api_url.should == "https://api2.example.com"
15
+ end
16
+ end
17
+
11
18
  context "env SHELLY_URL is not set" do
12
19
  it "should return default API URL" do
13
20
  ENV['SHELLY_URL'].should be_nil
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shelly
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ - 7
10
+ version: 0.0.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Shelly Cloud team
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-20 00:00:00 +02:00
18
+ date: 2011-10-03 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -205,6 +205,7 @@ files:
205
205
  - spec/helpers.rb
206
206
  - spec/input_faker.rb
207
207
  - spec/shelly/app_spec.rb
208
+ - spec/shelly/base_spec.rb
208
209
  - spec/shelly/cli/account_spec.rb
209
210
  - spec/shelly/cli/apps_spec.rb
210
211
  - spec/shelly/cli/main_spec.rb
@@ -249,6 +250,7 @@ test_files:
249
250
  - spec/helpers.rb
250
251
  - spec/input_faker.rb
251
252
  - spec/shelly/app_spec.rb
253
+ - spec/shelly/base_spec.rb
252
254
  - spec/shelly/cli/account_spec.rb
253
255
  - spec/shelly/cli/apps_spec.rb
254
256
  - spec/shelly/cli/main_spec.rb