shelly 0.0.1 → 0.0.2

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.
@@ -0,0 +1,5 @@
1
+ guard 'rspec', :cli => '--color --format doc' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/shelly/(.+)\.rb$}) { |m| "spec/shelly/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
@@ -0,0 +1,6 @@
1
+ # shelly: Shelly Cloud command line tool
2
+
3
+
4
+ ### Running tests
5
+
6
+ rake spec
data/Rakefile CHANGED
@@ -1 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ desc "Run specs"
5
+ RSpec::Core::RakeTask.new do |t|
6
+ t.rspec_opts = %w(-fs --color)
7
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require "shelly/cli"
3
+ Shelly::CLI.start
@@ -0,0 +1,5 @@
1
+ class Object
2
+ def blank?
3
+ respond_to?(:empty?) ? empty? : !self
4
+ end
5
+ end
@@ -1,5 +1,8 @@
1
- require "shelly/version"
1
+ require "rubygems"
2
+ require "thor"
3
+ require "core_ext/object"
2
4
 
3
5
  module Shelly
4
- # Your code goes here...
6
+ autoload :VERSION, "shelly/version"
7
+ autoload :Client, "shelly/client"
5
8
  end
@@ -0,0 +1,33 @@
1
+ require "shelly"
2
+
3
+ module Shelly
4
+ class CLI < Thor
5
+ include Thor::Actions
6
+ autoload :User, "shelly/user"
7
+
8
+ map %w(-v --version) => :version
9
+ desc "version", "Displays shelly version"
10
+ def version
11
+ say "shelly version #{Shelly::VERSION}"
12
+ end
13
+
14
+ desc "register", "Registers new user at Shelly Cloud"
15
+ def register
16
+ email_question = User.guess_email.blank? ? "Email:" : "Email (default #{User.guess_email}):"
17
+ email = ask(email_question)
18
+ email = User.guess_email if email.blank?
19
+ password = ask("Password:")
20
+
21
+ if email.blank? or password.blank?
22
+ say "Email and password can't be blank" and exit 1
23
+ end
24
+
25
+ user = User.new(email, password)
26
+ say "Check you mailbox for email confirmation" if user.register
27
+ rescue Client::APIError => e
28
+ if e.message == "Validation Failed"
29
+ e.errors.each { |error| say "#{error.first} #{error.last}" }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,78 @@
1
+ require "rest_client"
2
+ require "json"
3
+
4
+ module Shelly
5
+ class Client
6
+ class UnauthorizedException < Exception; end
7
+ class UnsupportedResponseException < Exception; end
8
+ class APIError < Exception
9
+ def initialize(response)
10
+ @response = response
11
+ end
12
+
13
+ def message
14
+ @response["message"]
15
+ end
16
+
17
+ def errors
18
+ @response["errors"]
19
+ end
20
+ end
21
+
22
+ def initialize(email = nil, password = nil)
23
+ @email = email
24
+ @password = password
25
+ end
26
+
27
+ def api_url
28
+ ENV["SHELLY_URL"] || "https://admin.winniecloud.com/apiv2"
29
+ end
30
+
31
+ def register_user(email, password)
32
+ post('/users', :user => {:email => email, :password => password})
33
+ end
34
+
35
+ def post(path, params = {})
36
+ request(path, :post, params)
37
+ end
38
+
39
+ def get(path)
40
+ request(path, :get)
41
+ end
42
+
43
+ def request(path, method, params = {})
44
+ unless @email.blank? or @password.blank?
45
+ params.merge!(:email => @email, :password => @password)
46
+ end
47
+
48
+ RestClient::Request.execute(
49
+ :method => method,
50
+ :url => "#{api_url}#{path}",
51
+ :headers => headers,
52
+ :payload => params.to_json
53
+ ) { |response, request| process_response(response) }
54
+ end
55
+
56
+ def process_response(response)
57
+ raise UnauthorizedException.new if response.code == 302
58
+ if [404, 422, 500].include?(response.code)
59
+ error_details = JSON.parse(response.body)
60
+ raise APIError.new(error_details)
61
+ end
62
+
63
+ begin
64
+ response.return!
65
+ JSON.parse(response.body)
66
+ rescue RestClient::RequestFailed => e
67
+ raise UnauthorizedException.new if e.http_code == 406
68
+ raise UnsupportedResponseException.new(e)
69
+ end
70
+ end
71
+
72
+ def headers
73
+ {:accept => :json,
74
+ :content_type => :json,
75
+ "shelly-version" => Shelly::VERSION}
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,47 @@
1
+ module Shelly
2
+ class User
3
+ attr_reader :email, :password
4
+ def initialize(email = nil, password = nil)
5
+ @email = email
6
+ @password = password
7
+ end
8
+
9
+ def register
10
+ client = Client.new
11
+ client.register_user(email, password)
12
+ save_credentials
13
+ end
14
+
15
+ def self.guess_email
16
+ @@guess_email ||= IO.popen("git config --get user.email").read.strip
17
+ end
18
+
19
+ def load_credentials
20
+ @email, @password = File.read(credentials_path).split("\n")
21
+ end
22
+
23
+ def save_credentials
24
+ FileUtils.mkdir_p(config_dir) unless credentials_exists?
25
+ File.open(credentials_path, 'w') { |file| file << "#{email}\n#{password}" }
26
+ set_credentials_permissions
27
+ end
28
+
29
+ protected
30
+ def config_dir
31
+ File.expand_path("~/.shelly")
32
+ end
33
+
34
+ def credentials_path
35
+ File.join(config_dir, "credentials")
36
+ end
37
+
38
+ def credentials_exists?
39
+ File.exists?(credentials_path)
40
+ end
41
+
42
+ def set_credentials_permissions
43
+ FileUtils.chmod(0700, config_dir)
44
+ FileUtils.chmod(0600, credentials_path)
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -12,13 +12,20 @@ Gem::Specification.new do |s|
12
12
  s.description = %q{Tool for managing applications and clouds at shellycloud.com}
13
13
 
14
14
  s.rubyforge_project = "shelly"
15
+ s.add_development_dependency "rspec"
16
+ s.add_development_dependency "guard"
17
+ s.add_development_dependency "guard-rspec"
18
+ if RUBY_PLATFORM =~ /darwin/
19
+ s.add_development_dependency "growl_notify"
20
+ s.add_development_dependency "rb-fsevent"
21
+ end
22
+ s.add_development_dependency "fakefs"
23
+ s.add_runtime_dependency "thor"
24
+ s.add_runtime_dependency "rest-client"
25
+ s.add_runtime_dependency "json"
15
26
 
16
27
  s.files = `git ls-files`.split("\n")
17
28
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
29
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
30
  s.require_paths = ["lib"]
20
-
21
- # specify any dependencies here; for example:
22
- # s.add_development_dependency "rspec"
23
- # s.add_runtime_dependency "rest-client"
24
31
  end
@@ -0,0 +1,7 @@
1
+ module RSpec
2
+ module Helpers
3
+ def fake_stdin(strings)
4
+ InputFaker.with_fake_input(strings) { yield }
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ class InputFaker
2
+ def initialize(strings)
3
+ @strings = strings
4
+ end
5
+
6
+ def gets
7
+ next_string = @strings.shift
8
+ # Uncomment the following line if you'd like to see the faked $stdin#gets
9
+ # puts "(DEBUG) Faking #gets with: #{next_string}"
10
+ next_string
11
+ end
12
+
13
+ def self.with_fake_input(strings)
14
+ $stdin = new(strings)
15
+ yield
16
+ ensure
17
+ $stdin = STDIN
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ class IO
2
+ def read_available_bytes
3
+ readpartial(100000)
4
+ end
5
+ end
@@ -0,0 +1,92 @@
1
+ require "spec_helper"
2
+ require "shelly/cli"
3
+ require "shelly/user"
4
+
5
+ describe Shelly::CLI do
6
+ before do
7
+ @client = mock
8
+ @cli = Shelly::CLI.new
9
+ Shelly::Client.stub(:new).and_return(@client)
10
+ $stdout.stub(:puts)
11
+ $stdout.stub(:print)
12
+ end
13
+
14
+ describe "#version" do
15
+ it "should return shelly's version" do
16
+ $stdout.should_receive(:puts).with("shelly version #{Shelly::VERSION}")
17
+ @cli.version
18
+ end
19
+ end
20
+
21
+ describe "#register" do
22
+ before do
23
+ Shelly::User.stub(:guess_email).and_return("")
24
+ @client.stub(:register_user)
25
+ end
26
+
27
+ it "should ask for email and password" do
28
+ $stdout.should_receive(:print).with("Email: ")
29
+ $stdout.should_receive(:print).with("Password: ")
30
+ fake_stdin(["better@example.com", "secret"]) do
31
+ @cli.register
32
+ end
33
+ end
34
+
35
+ it "should suggest email and use it if user enters blank email" do
36
+ Shelly::User.stub(:guess_email).and_return("kate@example.com")
37
+ $stdout.should_receive(:print).with("Email (default kate@example.com): ")
38
+ @client.should_receive(:register_user).with("kate@example.com", "secret")
39
+ fake_stdin(["", "secret"]) do
40
+ @cli.register
41
+ end
42
+ end
43
+
44
+ it "should use email provided by user" do
45
+ @client.should_receive(:register_user).with("better@example.com", "secret")
46
+ fake_stdin(["better@example.com", "secret"]) do
47
+ @cli.register
48
+ end
49
+ end
50
+
51
+ it "should exit with message if email is blank" do
52
+ Shelly::User.stub(:guess_email).and_return("")
53
+ $stdout.should_receive(:puts).with("Email and password can't be blank")
54
+ lambda do
55
+ fake_stdin(["", "only-pass"]) do
56
+ @cli.register
57
+ end
58
+ end.should raise_error(SystemExit)
59
+ end
60
+
61
+ it "should exit with message if password is blank" do
62
+ $stdout.should_receive(:puts).with("Email and password can't be blank")
63
+ lambda do
64
+ fake_stdin(["better@example.com", ""]) do
65
+ @cli.register
66
+ end
67
+ end.should raise_error(SystemExit)
68
+ end
69
+
70
+ context "on successful registration" do
71
+ it "should notify user about email verification" do
72
+ @client.stub(:register_user).and_return(true)
73
+ $stdout.should_receive(:puts).with("Check you mailbox for email confirmation")
74
+ fake_stdin(["kate@example.com", "pass"]) do
75
+ @cli.register
76
+ end
77
+ end
78
+ end
79
+
80
+ context "on unsuccessful registration" do
81
+ it "should notify user about errors" do
82
+ response = {"message" => "Validation Failed", "errors" => [["email", "has been already taken"]]}
83
+ exception = Shelly::Client::APIError.new(response)
84
+ @client.stub(:register_user).and_raise(exception)
85
+ $stdout.should_receive(:puts).with("email has been already taken")
86
+ fake_stdin(["kate@example.com", "pass"]) do
87
+ @cli.register
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,151 @@
1
+ require "spec_helper"
2
+
3
+ describe Shelly::Client do
4
+ before do
5
+ ENV['SHELLY_URL'] = nil
6
+ @client = Shelly::Client.new("bob@example.com", "secret")
7
+ RestClient::Request.stub!(:execute)
8
+ end
9
+
10
+ describe "#api_url" do
11
+ context "env SHELLY_URL is not set" do
12
+ it "should return default API URL" do
13
+ ENV['SHELLY_URL'].should be_nil
14
+ @client.api_url.should == "https://admin.winniecloud.com/apiv2"
15
+ end
16
+ end
17
+
18
+ context "env variable SHELLY_URL is set" do
19
+ it "should return value of env variable SHELLY_URL" do
20
+ ENV['SHELLY_URL'] = "https://example.com/api"
21
+ @client.api_url.should == "https://example.com/api"
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "#request" do
27
+ it "should make a request to given URL" do
28
+ RestClient::Request.should_receive(:execute).with(
29
+ request_parameters("/account", :get)
30
+ )
31
+ @client.request("/account", :get)
32
+ end
33
+
34
+ it "should include provided parameters in the request" do
35
+ RestClient::Request.should_receive(:execute).with(
36
+ request_parameters("/account", :post, {:name => "test"})
37
+ )
38
+ @client.request("/account", :post, :name => "test")
39
+ end
40
+
41
+ it "should include user credentials in the request parameters" do
42
+ @client = Shelly::Client.new("megan-fox@example.com", "secret")
43
+ RestClient::Request.should_receive(:execute).with(
44
+ request_parameters("/account", :get, {:email => "megan-fox@example.com", :password => "secret"})
45
+ )
46
+ @client.request("/account", :get)
47
+ end
48
+
49
+ it "should not include user credentials when they are blank" do
50
+ @client = Shelly::Client.new
51
+ RestClient::Request.should_receive(:execute).with(
52
+ :method => :get,
53
+ :url => "https://admin.winniecloud.com/apiv2/account",
54
+ :headers => {:accept => :json, :content_type => :json, "shelly-version" => Shelly::VERSION},
55
+ :payload => "{}"
56
+ )
57
+ @client.request("/account", :get)
58
+ end
59
+
60
+ it "should pass response to process_response method" do
61
+ response = mock(RestClient::Response)
62
+ request = mock(RestClient::Request)
63
+ @client.should_receive(:process_response).with(response)
64
+ RestClient::Request.should_receive(:execute).with(
65
+ request_parameters("/account", :get)
66
+ ).and_yield(response, request)
67
+
68
+ @client.request("/account", :get)
69
+ end
70
+
71
+ def request_parameters(path, method, payload = {})
72
+ {:method => method,
73
+ :url => "https://admin.winniecloud.com/apiv2#{path}",
74
+ :headers => {:accept => :json, :content_type => :json, "shelly-version" => Shelly::VERSION},
75
+ :payload => ({:email => "bob@example.com", :password => "secret"}.merge(payload)).to_json}
76
+ end
77
+ end
78
+
79
+ describe "#process_response" do
80
+ before do
81
+ @response = mock(RestClient::Response, :code => 200, :body => "{}", :return! => nil)
82
+ @request = mock(RestClient::Request)
83
+ RestClient::Request.stub(:execute).and_yield(@response, @request)
84
+ end
85
+
86
+ it "should not follow redirections" do
87
+ @response.should_receive(:return!)
88
+ @client.get('/account')
89
+ end
90
+
91
+ context "on 302 response code" do
92
+ it "should raise UnauthorizedException" do
93
+ @response.stub(:code).and_return(302)
94
+ lambda {
95
+ @client.get("/account")
96
+ }.should raise_error(Shelly::Client::UnauthorizedException)
97
+ end
98
+ end
99
+
100
+ context "on 406 response code" do
101
+ it "should raise UnauthorizedException" do
102
+ exception = RestClient::RequestFailed.new
103
+ exception.stub(:http_code).and_return(406)
104
+ @response.should_receive(:return!).and_raise(exception)
105
+
106
+ lambda {
107
+ @client.get("/account")
108
+ }.should raise_error(Shelly::Client::UnauthorizedException)
109
+ end
110
+ end
111
+
112
+ %w(404 422 500).each do |code|
113
+ context "on #{code} response code" do
114
+ it "should raise APIError" do
115
+ @response.stub(:code).and_return(code.to_i)
116
+ @response.stub(:body).and_return({"message" => "random error happened"}.to_json)
117
+
118
+ lambda {
119
+ @client.post("/api/apps/flower/command", :body => "puts User.count")
120
+ }.should raise_error(Shelly::Client::APIError, "random error happened")
121
+ end
122
+ end
123
+ end
124
+
125
+ context "on unsupported response code" do
126
+ it "should raise UnsupportedResponseException exception" do
127
+ exception = RestClient::RequestFailed.new
128
+ exception.stub(:http_code).and_return(409)
129
+ @response.should_receive(:return!).and_raise(exception)
130
+
131
+ lambda {
132
+ @client.get("/account")
133
+ }.should raise_error(Shelly::Client::UnsupportedResponseException)
134
+ end
135
+ end
136
+ end
137
+
138
+ describe "#get" do
139
+ it "should make GET request to given path" do
140
+ @client.should_receive(:request).with("/account", :get)
141
+ @client.get("/account")
142
+ end
143
+ end
144
+
145
+ describe "#post" do
146
+ it "should make POST request to given path with parameters" do
147
+ @client.should_receive(:request).with("/account", :post, :name => "pink-one")
148
+ @client.post("/account", :name => "pink-one")
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,70 @@
1
+ require "shelly/user"
2
+ require "spec_helper"
3
+
4
+ describe Shelly::User do
5
+ include FakeFS::SpecHelpers
6
+
7
+ before do
8
+ @client = mock
9
+ Shelly::Client.stub(:new).and_return(@client)
10
+ @user = Shelly::User.new("bob@example.com", "secret")
11
+ @user.stub(:set_credentials_permissions)
12
+ end
13
+
14
+ describe ".guess_email" do
15
+ it "should return user email fetched from git config" do
16
+ io = mock(:read => "boby@example.com\n")
17
+ IO.should_receive(:popen).with("git config --get user.email").and_return(io)
18
+ Shelly::User.guess_email.should == "boby@example.com"
19
+ end
20
+ end
21
+
22
+ describe "#register" do
23
+ before do
24
+ @client.stub(:register_user)
25
+ end
26
+
27
+ it "should register user at Shelly Cloud" do
28
+ @client.should_receive(:register_user).with("bob@example.com", "secret")
29
+ @user.register
30
+ end
31
+
32
+ it "should save credentials after successful registration" do
33
+ @user.should_receive(:save_credentials)
34
+ @user.register
35
+ end
36
+ end
37
+
38
+ describe "#save_credentials" do
39
+ it "should save credentials to file" do
40
+ File.exists?("~/.shelly/credentials").should be_false
41
+ @user.save_credentials
42
+ File.read("~/.shelly/credentials").should == "bob@example.com\nsecret"
43
+ end
44
+
45
+ it "should create config_dir if doesn't exist" do
46
+ File.exists?("~/.shelly").should be_false
47
+ @user.save_credentials
48
+ File.exists?("~/.shelly").should be_true
49
+ end
50
+
51
+ it "should set proper permissions on config_dir and credentials file" do
52
+ user = Shelly::User.new("bob@example.com", "secret")
53
+ FileUtils.should_receive(:chmod).with(0700, File.expand_path("~/.shelly"))
54
+ FileUtils.should_receive(:chmod).with(0600, File.expand_path("~/.shelly/credentials"))
55
+ user.save_credentials
56
+ end
57
+ end
58
+
59
+ describe "#load_credentials" do
60
+ it "should load credentials from file" do
61
+ config_dir = File.expand_path("~/.shelly")
62
+ FileUtils.mkdir_p(config_dir)
63
+ File.open(File.join(config_dir, "credentials"), "w") { |f| f << "superman@example.com\nkal-el" }
64
+ user = Shelly::User.new
65
+ user.load_credentials
66
+ user.email.should == "superman@example.com"
67
+ user.password.should == "kal-el"
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,11 @@
1
+ require "rspec"
2
+ require "helpers"
3
+ require "shelly"
4
+ require "io_ext"
5
+ require "input_faker"
6
+ require "fakefs/safe"
7
+ require "fakefs/spec_helpers"
8
+
9
+ RSpec.configure do |config|
10
+ config.include RSpec::Helpers
11
+ end
metadata CHANGED
@@ -1,8 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shelly
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.0.1
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
6
11
  platform: ruby
7
12
  authors:
8
13
  - Shelly Cloud team
@@ -10,14 +15,140 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2011-09-07 00:00:00 Z
14
- dependencies: []
15
-
18
+ date: 2011-09-13 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: guard
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: guard-rspec
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: growl_notify
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :development
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: rb-fsevent
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :development
90
+ version_requirements: *id005
91
+ - !ruby/object:Gem::Dependency
92
+ name: fakefs
93
+ prerelease: false
94
+ requirement: &id006 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ type: :development
104
+ version_requirements: *id006
105
+ - !ruby/object:Gem::Dependency
106
+ name: thor
107
+ prerelease: false
108
+ requirement: &id007 !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ type: :runtime
118
+ version_requirements: *id007
119
+ - !ruby/object:Gem::Dependency
120
+ name: rest-client
121
+ prerelease: false
122
+ requirement: &id008 !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ type: :runtime
132
+ version_requirements: *id008
133
+ - !ruby/object:Gem::Dependency
134
+ name: json
135
+ prerelease: false
136
+ requirement: &id009 !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ hash: 3
142
+ segments:
143
+ - 0
144
+ version: "0"
145
+ type: :runtime
146
+ version_requirements: *id009
16
147
  description: Tool for managing applications and clouds at shellycloud.com
17
148
  email:
18
149
  - support@shellycloud.com
19
- executables: []
20
-
150
+ executables:
151
+ - shelly
21
152
  extensions: []
22
153
 
23
154
  extra_rdoc_files: []
@@ -25,10 +156,25 @@ extra_rdoc_files: []
25
156
  files:
26
157
  - .gitignore
27
158
  - Gemfile
159
+ - Guardfile
160
+ - README.md
28
161
  - Rakefile
162
+ - bin/shelly
163
+ - lib/core_ext/object.rb
29
164
  - lib/shelly.rb
165
+ - lib/shelly/cli.rb
166
+ - lib/shelly/client.rb
167
+ - lib/shelly/user.rb
30
168
  - lib/shelly/version.rb
31
169
  - shelly.gemspec
170
+ - spec/helpers.rb
171
+ - spec/input_faker.rb
172
+ - spec/io_ext.rb
173
+ - spec/shelly/cli_spec.rb
174
+ - spec/shelly/client_spec.rb
175
+ - spec/shelly/user_spec.rb
176
+ - spec/spec_helper.rb
177
+ has_rdoc: true
32
178
  homepage: http://shellycloud.com
33
179
  licenses: []
34
180
 
@@ -42,19 +188,31 @@ required_ruby_version: !ruby/object:Gem::Requirement
42
188
  requirements:
43
189
  - - ">="
44
190
  - !ruby/object:Gem::Version
191
+ hash: 3
192
+ segments:
193
+ - 0
45
194
  version: "0"
46
195
  required_rubygems_version: !ruby/object:Gem::Requirement
47
196
  none: false
48
197
  requirements:
49
198
  - - ">="
50
199
  - !ruby/object:Gem::Version
200
+ hash: 3
201
+ segments:
202
+ - 0
51
203
  version: "0"
52
204
  requirements: []
53
205
 
54
206
  rubyforge_project: shelly
55
- rubygems_version: 1.8.6
207
+ rubygems_version: 1.3.7
56
208
  signing_key:
57
209
  specification_version: 3
58
210
  summary: Shelly Cloud command line tool
59
- test_files: []
60
-
211
+ test_files:
212
+ - spec/helpers.rb
213
+ - spec/input_faker.rb
214
+ - spec/io_ext.rb
215
+ - spec/shelly/cli_spec.rb
216
+ - spec/shelly/client_spec.rb
217
+ - spec/shelly/user_spec.rb
218
+ - spec/spec_helper.rb