shelly 0.1.24.pre → 0.1.24.pre2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,4 @@
1
+ * [feature] `shelly check` checks gems based on Cloudfile
1
2
  * [feature] Option --help [-h] added to all tasks
2
3
 
3
4
  ## 0.1.23 / 2012-08-08
data/Guardfile ADDED
@@ -0,0 +1,6 @@
1
+ guard 'rspec', :cli => '--color --format doc' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch('lib/shelly/helpers.rb') { "spec" }
4
+ watch(%r{^lib/shelly/(.+)\.rb$}) { |m| "spec/shelly/#{m[1]}_spec.rb" }
5
+ watch('spec/spec_helper.rb') { "spec" }
6
+ end
data/README.md CHANGED
@@ -13,3 +13,7 @@
13
13
  ## Running tests
14
14
 
15
15
  bundle exec rake
16
+
17
+ or
18
+
19
+ guard
data/lib/shelly.rb CHANGED
@@ -14,6 +14,7 @@ require "shelly/model"
14
14
  module Shelly
15
15
  autoload :App, "shelly/app"
16
16
  autoload :Cloudfile, "shelly/cloudfile"
17
+ autoload :Cloud, "shelly/cloud"
17
18
  autoload :Client, "shelly/client"
18
19
  autoload :StructureValidator, "shelly/structure_validator"
19
20
  autoload :User, "shelly/user"
data/lib/shelly/app.rb CHANGED
@@ -117,7 +117,7 @@ module Shelly
117
117
  guessed = nil
118
118
  cloudfile = Cloudfile.new
119
119
  if cloudfile.present?
120
- clouds = cloudfile.clouds
120
+ clouds = cloudfile.clouds.map(&:code_name)
121
121
  if clouds.grep(/staging/).present?
122
122
  guessed = "production"
123
123
  production_clouds = clouds.grep(/production/)
@@ -32,7 +32,7 @@ module Shelly
32
32
 
33
33
  say "Available backups:", :green
34
34
  say_new_line
35
- print_table(to_display, :indent => 2)
35
+ print_table(to_display, :ident => 2)
36
36
  else
37
37
  say "No database backups available"
38
38
  end
@@ -70,7 +70,7 @@ module Shelly
70
70
  say_error "Cloudfile must be present in current working directory or specify database kind with:", :with_exit => false
71
71
  say_error "`shelly backup create DB_KIND`"
72
72
  end
73
- app.request_backup(kind || cloudfile.backup_databases(app))
73
+ app.request_backup(kind || cloudfile.clouds.find { |c| c.code_name == app.to_s }.backup_databases)
74
74
  say "Backup requested. It can take up to several minutes for " +
75
75
  "the backup process to finish.", :green
76
76
  rescue Client::ValidationException => e
@@ -4,6 +4,7 @@ require "thor/thor"
4
4
  require "thor/group"
5
5
  require "thor/options"
6
6
  require "thor/arguments"
7
+ require "thor/basic"
7
8
 
8
9
  module Shelly
9
10
  module CLI
@@ -79,7 +79,8 @@ module Shelly
79
79
  end
80
80
 
81
81
  desc "delete PATH", "Delete configuration file"
82
- def delete(path)
82
+ def delete(path = nil)
83
+ say_error "No configuration file specified" unless path
83
84
  app = multiple_clouds(options[:cloud], "delete #{path}")
84
85
  answer = yes?("Are you sure you want to delete 'path' (yes/no): ")
85
86
  if answer
@@ -19,6 +19,7 @@ module Shelly
19
19
 
20
20
  check_unknown_options!(:except => :rake)
21
21
 
22
+ # FIXME: it should be possible to pass single symbol, instead of one element array
22
23
  before_hook :logged_in?, :only => [:add, :status, :list, :start, :stop, :logs, :delete, :info, :ip, :logout, :execute, :rake, :setup, :console, :dbconsole]
23
24
  before_hook :inside_git_repository?, :only => [:add, :setup, :check]
24
25
 
@@ -133,7 +134,7 @@ module Shelly
133
134
  end
134
135
  [app["code_name"], "| #{state.humanize}#{msg}"]
135
136
  end
136
- print_table(apps_table, :indent => 2)
137
+ print_table(apps_table, :ident => 2)
137
138
  else
138
139
  say "You have no clouds yet", :green
139
140
  end
@@ -148,21 +149,21 @@ module Shelly
148
149
  " (deployment log: `shelly deploys show last -c #{app}`)"
149
150
  end
150
151
  say "Cloud #{app}:", msg.present? ? :red : :green
151
- print_wrapped "State: #{app.state}#{msg}", :indent => 2
152
+ print_wrapped "State: #{app.state}#{msg}", :ident => 2
152
153
  say_new_line
153
- print_wrapped "Deployed commit sha: #{app.git_info["deployed_commit_sha"]}", :indent => 2
154
- print_wrapped "Deployed commit message: #{app.git_info["deployed_commit_message"]}", :indent => 2
155
- print_wrapped "Deployed by: #{app.git_info["deployed_push_author"]}", :indent => 2
154
+ print_wrapped "Deployed commit sha: #{app.git_info["deployed_commit_sha"]}", :ident => 2
155
+ print_wrapped "Deployed commit message: #{app.git_info["deployed_commit_message"]}", :ident => 2
156
+ print_wrapped "Deployed by: #{app.git_info["deployed_push_author"]}", :ident => 2
156
157
  say_new_line
157
- print_wrapped "Repository URL: #{app.git_info["repository_url"]}", :indent => 2
158
- print_wrapped "Web server IP: #{app.web_server_ip}", :indent => 2
158
+ print_wrapped "Repository URL: #{app.git_info["repository_url"]}", :ident => 2
159
+ print_wrapped "Web server IP: #{app.web_server_ip}", :ident => 2
159
160
  say_new_line
160
161
  if app.statistics.present?
161
- print_wrapped "Statistics:", :indent => 2
162
+ print_wrapped "Statistics:", :ident => 2
162
163
  app.statistics.each do |stat|
163
- print_wrapped "#{stat['name']}:", :indent => 4
164
- print_wrapped "Load average: 1m: #{stat['load']['avg01']}, 5m: #{stat['load']['avg05']}, 15m: #{stat['load']['avg15']}", :indent => 6
165
- print_wrapped "CPU: #{stat['cpu']['wait']}%, MEM: #{stat['memory']['percent']}%, SWAP: #{stat['swap']['percent']}%", :indent => 6
164
+ print_wrapped "#{stat['name']}:", :ident => 4
165
+ print_wrapped "Load average: 1m: #{stat['load']['avg01']}, 5m: #{stat['load']['avg05']}, 15m: #{stat['load']['avg15']}", :ident => 6
166
+ print_wrapped "CPU: #{stat['cpu']['wait']}%, MEM: #{stat['memory']['percent']}%, SWAP: #{stat['swap']['percent']}%", :ident => 6
166
167
  end
167
168
  end
168
169
  rescue Client::GatewayTimeoutException
@@ -384,6 +385,10 @@ We have been notified about it. We will be adding new resources shortly}
384
385
  "Gemfile.lock is missing in git repository",
385
386
  :show_fulfilled => verbose)
386
387
 
388
+ print_check(structure.config_ru?, "File config.ru is present",
389
+ "File config.ru is missing",
390
+ :show_fulfilled => verbose)
391
+
387
392
  print_check(structure.gem?("shelly-dependencies"),
388
393
  "Gem 'shelly-dependencies' is present",
389
394
  "Gem 'shelly-dependencies' is missing, we recommend to install it\n See more at https://shellycloud.com/documentation/requirements#shelly-dependencies",
@@ -395,9 +400,35 @@ We have been notified about it. We will be adding new resources shortly}
395
400
  print_check(structure.gem?("rake"), "Gem 'rake' is present",
396
401
  "Gem 'rake' is missing in the Gemfile", :show_fulfilled => verbose)
397
402
 
398
- print_check(structure.config_ru?, "File config.ru is present",
399
- "File config.ru is missing",
400
- :show_fulfilled => verbose)
403
+
404
+ print_check(structure.gem?("rake"), "Gem 'rake' is present",
405
+ "Gem 'rake' is missing in the Gemfile", :show_fulfilled => verbose)
406
+
407
+ cloudfile = Cloudfile.new
408
+ if cloudfile.present?
409
+ cloudfile.clouds.each do |cloud|
410
+ if cloud.databases.include?('postgresql')
411
+ print_check(structure.gem?("pg") || structure.gem?("postgres"),
412
+ "Postgresql driver is present for '#{cloud}' cloud",
413
+ "Postgresql driver is missing in the Gemfile for '#{cloud}' cloud,\n we recommend adding 'pg' gem to Gemfile",
414
+ :show_fulfilled => verbose)
415
+ end
416
+
417
+ if cloud.delayed_job?
418
+ print_check(structure.gem?("delayed_job"),
419
+ "Gem 'delayed_job' is present for '#{cloud}' cloud",
420
+ "Gem 'delayed_job' is missing in the Gemfile for '#{cloud}' cloud",
421
+ :show_fulfilled => verbose)
422
+ end
423
+
424
+ if cloud.whenever?
425
+ print_check(structure.gem?("whenever"),
426
+ "Gem 'whenever' is present for '#{cloud}' cloud",
427
+ "Gem 'whenever' is missing in the Gemfile for '#{cloud}' cloud",
428
+ :show_fulfilled => verbose)
429
+ end
430
+ end
431
+ end
401
432
 
402
433
  print_check(!structure.gem?("mysql") && !structure.gem?("mysql2"),"",
403
434
  "mysql driver present in the Gemfile (not supported on Shelly Cloud)",
@@ -0,0 +1,49 @@
1
+ require "yaml"
2
+
3
+ module Shelly
4
+ class Cloud < Model
5
+ attr_accessor :code_name, :content
6
+
7
+ def initialize(attributes = {})
8
+ @code_name = attributes["code_name"]
9
+ @content = attributes["content"]
10
+ end
11
+
12
+ # Public: Return databases for given Cloud in Cloudfile
13
+ # Returns Array of databases
14
+ def databases
15
+ content["servers"].map do |server, settings|
16
+ settings["databases"]
17
+ end.flatten.uniq
18
+ end
19
+
20
+ # Public: Delayed job enabled?
21
+ # Returns true if delayed job is present
22
+ def delayed_job?
23
+ option?("delayed_job")
24
+ end
25
+
26
+ # Public: Whenever enabled?
27
+ # Returns true if whenever is present
28
+ def whenever?
29
+ option?("whenever")
30
+ end
31
+
32
+ # Public: Return databases to backup for given Cloud in Cloudfile
33
+ # Returns Array of databases, except redis db
34
+ def backup_databases
35
+ databases - ['redis']
36
+ end
37
+
38
+ def to_s
39
+ code_name
40
+ end
41
+
42
+ private
43
+
44
+ # Internal: Checks if specified option is present
45
+ def option?(option)
46
+ content["servers"].any? {|_, settings| settings.has_key?(option)}
47
+ end
48
+ end
49
+ end
@@ -16,7 +16,10 @@ module Shelly
16
16
  # Returns Array of clouds names from Cloudfile
17
17
  # nil if there is no cloudfile
18
18
  def clouds
19
- content.keys.sort if content
19
+ content.keys.sort.map do |code_name|
20
+ Shelly::Cloud.new("code_name" => code_name,
21
+ "content" => content[code_name.to_s])
22
+ end if content
20
23
  end
21
24
 
22
25
  # Public: Generate example Cloudfile based on object attributes
@@ -35,22 +38,6 @@ module Shelly
35
38
  File.open(path, "a+") { |f| f << generate }
36
39
  end
37
40
 
38
- # Public: Return databases for given Cloud in Cloudfile
39
- # Returns Array of databases
40
- def databases(cloud)
41
- content[cloud.to_s]["servers"].map do |server, settings|
42
- settings["databases"]
43
- end.flatten.uniq
44
- end
45
-
46
- # Public: Return databases to backup for given Cloud in Cloudfile
47
- # Returns Array of databases, except redis db
48
- def backup_databases(cloud)
49
- databases(cloud) - ['redis']
50
- end
51
-
52
- private
53
-
54
41
  # Internal: Load and parse Cloudfile
55
42
  def content
56
43
  return unless present?
@@ -61,7 +61,11 @@ module Shelly
61
61
  end
62
62
 
63
63
  def inside_git_repository?
64
- say_error "Must be run inside your project git repository" unless App.inside_git_repository?
64
+ unless App.inside_git_repository?
65
+ say_error %q{Current directory is not a git repository.
66
+ You need to initialize repository with `git init`.
67
+ More info at http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository}
68
+ end
65
69
  end
66
70
 
67
71
  def cloudfile_present?
@@ -112,7 +116,7 @@ module Shelly
112
116
  end
113
117
 
114
118
  app = Shelly::App.new
115
- app.code_name = cloud || clouds.first
119
+ app.code_name = cloud || clouds.first.code_name
116
120
  app
117
121
  end
118
122
 
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.1.24.pre"
2
+ VERSION = "0.1.24.pre2"
3
3
  end
data/lib/thor/basic.rb ADDED
@@ -0,0 +1,9 @@
1
+ class Thor
2
+ module Shell
3
+
4
+ def print_wrapped(*args)
5
+ shell.print_wrapped(*args)
6
+ end
7
+
8
+ end
9
+ end
data/lib/thor/options.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  class Thor
2
2
  class Options < Arguments
3
+
3
4
  def check_unknown!
4
- unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
5
5
  raise UnknownArgumentError, "shelly: unrecognized option '#{@unknown.join(', ')}'\n" +
6
6
  "Usage: shelly [COMMAND]... [OPTIONS]\n" +
7
- "Try 'shelly --help' for more information" unless unknown.empty?
7
+ "Try 'shelly --help' for more information" unless @unknown.empty?
8
8
  end
9
+
9
10
  end
10
11
  end
data/lib/thor/thor.rb CHANGED
@@ -2,7 +2,7 @@ class Thor
2
2
  class << self
3
3
  def before_hook(method, options = {})
4
4
  @hook = {} unless @hook
5
- @hook[method] = {:only => Array(options[:only])}
5
+ @hook[method] = options
6
6
  end
7
7
 
8
8
  def hooks
@@ -28,46 +28,12 @@ class Thor
28
28
  rescue Thor::Error => e
29
29
  ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
30
30
  exit(1) if exit_on_failure?
31
- rescue Errno::EPIPE
32
- # This happens if a thor task is piped to something like `head`,
33
- # which closes the pipe when it's done reading. This will also
34
- # mean that if the pipe is closed, further unnecessary
35
- # computation will not occur.
36
- exit(0)
37
31
  end
38
32
 
39
- # We overwrite this method so namespace is shown
33
+ # We overwrite this method so namespace is show
40
34
  # shelly *backup* restore FILENAME
41
- def handle_argument_error(task, error, arity = nil)
42
- banner = self.banner(task, nil, self.to_s != 'Shelly::CLI::Main')
43
- raise InvocationError, "#{task.name.inspect} was called incorrectly. Call as `#{banner}`"
44
- end
45
-
46
- protected
47
- # this has to overwritten so that in tests args are passed correctly
48
- # only change is the commented line
49
- # its for some edge cases when boolean options are passed in some
50
- # strange order
51
- def dispatch(meth, given_args, given_opts, config) #:nodoc:
52
- meth ||= retrieve_task_name(given_args)
53
- task = all_tasks[normalize_task_name(meth)]
54
-
55
- if task
56
- args, opts = Thor::Options.split(given_args)
57
- else
58
- args, opts = given_args, nil
59
- task = Thor::DynamicTask.new(meth)
60
- end
61
-
62
- opts = given_opts || opts || []
63
- config.merge!(:current_task => task, :task_options => task.options)
64
-
65
- instance = new(args, opts, config)
66
- yield instance if block_given?
67
- # args = instance.args
68
- trailing = args[Range.new(arguments.size, -1)]
69
-
70
- instance.invoke_task(task, trailing || [])
35
+ def handle_argument_error(task, error)
36
+ raise InvocationError, "#{task.name.inspect} was called incorrectly. Call as #{self.banner(task, nil, self.to_s != 'Shelly::CLI::Main').inspect}."
71
37
  end
72
38
  end
73
39
  end
data/shelly.gemspec CHANGED
@@ -14,6 +14,8 @@ Gem::Specification.new do |s|
14
14
  s.rubyforge_project = "shelly"
15
15
  s.add_development_dependency "rspec", "~> 2.11.0"
16
16
  s.add_development_dependency "rake"
17
+ s.add_development_dependency "guard"
18
+ s.add_development_dependency "guard-rspec"
17
19
  s.add_development_dependency "simplecov"
18
20
  if RUBY_PLATFORM =~ /darwin/
19
21
  s.add_development_dependency "ruby_gntp"
@@ -21,7 +23,7 @@ Gem::Specification.new do |s|
21
23
  end
22
24
  s.add_development_dependency "fakefs"
23
25
  s.add_development_dependency "fakeweb"
24
- s.add_runtime_dependency "thor", "~> 0.15.4"
26
+ s.add_runtime_dependency "wijet-thor", "~> 0.14.7"
25
27
  s.add_runtime_dependency "rest-client"
26
28
  s.add_runtime_dependency "json"
27
29
  s.add_runtime_dependency "progressbar"
@@ -135,7 +135,9 @@ describe Shelly::CLI::Backup do
135
135
  FileUtils.mkdir_p("/projects/foo")
136
136
  Dir.chdir("/projects/foo")
137
137
  $stdout.stub(:puts)
138
- @cloudfile = mock(:backup_databases => ['postgresql', 'mongodb'], :clouds => ['foo-staging'])
138
+ @cloud = mock(:backup_databases => ['postgresql', 'mongodb'], :code_name => "foo-staging")
139
+ Shelly::Cloud.stub(:new).and_return(@cloud)
140
+ @cloudfile = mock(:present? => true, :clouds => [@cloud])
139
141
  Shelly::Cloudfile.stub(:new).and_return(@cloudfile)
140
142
  end
141
143
 
@@ -29,6 +29,7 @@ describe Shelly::CLI::Files do
29
29
 
30
30
  it "should exit if rsync isn't installed" do
31
31
  FakeFS::File.stub(:executable?).and_return(false)
32
+
32
33
  $stdout.should_receive(:puts).with(red "You need to install rsync in order to upload and download files")
33
34
  lambda { invoke(@cli_files, :upload, "some/path") }.should raise_error(SystemExit)
34
35
  end
@@ -299,7 +299,9 @@ describe Shelly::CLI::Main do
299
299
  # This spec tests inside_git_repository? hook
300
300
  it "should exit with message if command run outside git repository" do
301
301
  Shelly::App.stub(:inside_git_repository?).and_return(false)
302
- $stdout.should_receive(:puts).with("\e[31mMust be run inside your project git repository\e[0m")
302
+ $stdout.should_receive(:puts).with("\e[31mCurrent directory is not a git repository.
303
+ You need to initialize repository with `git init`.
304
+ More info at http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository\e[0m")
303
305
  lambda {
304
306
  fake_stdin(["", ""]) do
305
307
  invoke(@main, :add)
@@ -1273,7 +1275,7 @@ We have been notified about it. We will be adding new resources shortly")
1273
1275
  before do
1274
1276
  Shelly::App.stub(:inside_git_repository?).and_return(true)
1275
1277
  Bundler::Definition.stub_chain(:build, :specs, :map) \
1276
- .and_return(["thin"])
1278
+ .and_return(["thin", "pg", "delayed_job", "whenever"])
1277
1279
  Shelly::StructureValidator.any_instance.stub(:repo_paths) \
1278
1280
  .and_return(["config.ru", "Gemfile", "Gemfile.lock"])
1279
1281
  end
@@ -1342,6 +1344,62 @@ We have been notified about it. We will be adding new resources shortly")
1342
1344
  end
1343
1345
  end
1344
1346
 
1347
+ context "cloudfile" do
1348
+ before do
1349
+ cloud = mock(:code_name => "foo-staging", :databases => ["postgresql"],
1350
+ :whenever? => true, :delayed_job? => true, :to_s => "foo-staging")
1351
+ cloudfile = mock(:clouds => [cloud])
1352
+
1353
+ Shelly::Cloudfile.stub(:new).and_return(cloudfile)
1354
+ end
1355
+
1356
+ context "whenever is enabled" do
1357
+ it "should show that necessary gem doesn't exist" do
1358
+ Bundler::Definition.stub_chain(:build, :specs, :map).and_return([])
1359
+ $stdout.should_receive(:puts).with(" #{red("✗")} Gem 'whenever' is missing in the Gemfile for 'foo-staging' cloud")
1360
+ invoke(@main, :check)
1361
+ end
1362
+
1363
+ it "should show that necessary gem exists" do
1364
+ $stdout.should_receive(:puts).with(" #{green("✓")} Gem 'whenever' is present for 'foo-staging' cloud")
1365
+ invoke(@main, :check)
1366
+ end
1367
+ end
1368
+
1369
+ context "delayed_job is enabled" do
1370
+ it "should show that necessary gem doesn't exist" do
1371
+ Bundler::Definition.stub_chain(:build, :specs, :map).and_return([])
1372
+ $stdout.should_receive(:puts).with(" #{red("✗")} Gem 'delayed_job' is missing in the Gemfile for 'foo-staging' cloud")
1373
+ invoke(@main, :check)
1374
+ end
1375
+
1376
+ it "should show that necessary gem exists" do
1377
+ $stdout.should_receive(:puts).with(" #{green("✓")} Gem 'delayed_job' is present for 'foo-staging' cloud")
1378
+ invoke(@main, :check)
1379
+ end
1380
+ end
1381
+
1382
+ context "postgresql is enabled" do
1383
+ it "should show that necessary gem doesn't exist" do
1384
+ Bundler::Definition.stub_chain(:build, :specs, :map).and_return([])
1385
+ $stdout.should_receive(:puts).with(" #{red("✗")} Postgresql driver is missing in the Gemfile for 'foo-staging' cloud,\n we recommend adding 'pg' gem to Gemfile")
1386
+ invoke(@main, :check)
1387
+ end
1388
+
1389
+ it "should show that necessary gem exists - postgres" do
1390
+ Bundler::Definition.stub_chain(:build, :specs, :map).and_return(["postgres"])
1391
+ $stdout.should_receive(:puts).with(" #{green("✓")} Postgresql driver is present for 'foo-staging' cloud")
1392
+ invoke(@main, :check)
1393
+ end
1394
+
1395
+ it "should show that necessary gem exists - pg" do
1396
+ Bundler::Definition.stub_chain(:build, :specs, :map).and_return(["pg"])
1397
+ $stdout.should_receive(:puts).with(" #{green("✓")} Postgresql driver is present for 'foo-staging' cloud")
1398
+ invoke(@main, :check)
1399
+ end
1400
+ end
1401
+ end
1402
+
1345
1403
  context "when mysql gem exists" do
1346
1404
  it "should show that mysql gem is not supported by Shelly Cloud" do
1347
1405
  Bundler::Definition.stub_chain(:build, :specs, :map).and_return(["mysql"])
@@ -8,7 +8,6 @@ describe Shelly::CLI::User do
8
8
  Shelly::CLI::User.stub(:new).and_return(@cli_user)
9
9
  @client = mock
10
10
  Shelly::Client.stub(:new).and_return(@client)
11
- Shelly::User.stub(:guess_email).and_return("")
12
11
  $stdout.stub(:puts)
13
12
  $stdout.stub(:print)
14
13
  @client.stub(:token).and_return("abc")
@@ -16,6 +15,8 @@ describe Shelly::CLI::User do
16
15
  Dir.chdir("/projects/foo")
17
16
  @app = Shelly::App.new("foo-staging")
18
17
  File.open("Cloudfile", 'w') {|f| f.write("foo-staging:\n") }
18
+ @cloud = Shelly::Cloud.new("code_name" => 'foo-staging')
19
+ Shelly::Cloud.stub(:new).and_return(@cloud)
19
20
  end
20
21
 
21
22
  describe "#help" do
@@ -47,7 +48,7 @@ describe Shelly::CLI::User do
47
48
  context "on success" do
48
49
  it "should display clouds and users" do
49
50
  @client.stub(:collaborations).and_return(response)
50
- $stdout.should_receive(:puts).with("Cloud foo-staging:")
51
+ $stdout.should_receive(:puts).with("Cloud #{@cloud}:")
51
52
  $stdout.should_receive(:puts).with(" user@example.com")
52
53
  $stdout.should_receive(:puts).with(" auser2@example2.com (invited)")
53
54
  invoke(@cli_user, :list)
@@ -0,0 +1,57 @@
1
+ require "spec_helper"
2
+ require "shelly/cloudfile"
3
+ require "shelly/cloud"
4
+
5
+ describe Shelly::Cloud do
6
+ before do
7
+ FileUtils.mkdir_p("/projects/foo")
8
+ Dir.chdir("/projects/foo")
9
+ @client = mock
10
+ Shelly::Client.stub(:new).and_return(@client)
11
+ @cloud = Shelly::Cloud.new("code_name" => "foo-staging", "content" => {})
12
+ end
13
+
14
+ describe "#databases" do
15
+ before do
16
+ content = {"servers" => {"app1" => {"databases" => ["postgresql", "redis"]},
17
+ "app2" => {"databases" => ["mongodb"]}}}
18
+ @cloud.stub(:content).and_return(content)
19
+ end
20
+
21
+ it "should return databases in cloudfile" do
22
+ @cloud.databases.should =~ ['redis', 'mongodb', 'postgresql']
23
+ end
24
+
25
+ it "should return databases except for redis" do
26
+ @cloud.backup_databases.should =~ ['postgresql', 'mongodb']
27
+ end
28
+ end
29
+
30
+ describe "#delayed_job?" do
31
+ it "should return true if present" do
32
+ content = {"servers" => {"app1" => {"delayed_job" => 1}}}
33
+ @cloud.stub(:content).and_return(content)
34
+ @cloud.delayed_job?.should be_true
35
+ end
36
+
37
+ it "should retrun false if not present" do
38
+ content = {"servers" => {"app1" => {"size" => "small"}}}
39
+ @cloud.stub(:content).and_return(content)
40
+ @cloud.delayed_job?.should be_false
41
+ end
42
+ end
43
+
44
+ describe "#whenever?" do
45
+ it "should return true if present" do
46
+ content = {"servers" => {"app1" => {"whenever" => true}}}
47
+ @cloud.stub(:content).and_return(content)
48
+ @cloud.whenever?.should be_true
49
+ end
50
+
51
+ it "should return false if not present" do
52
+ content = {"servers" => {"app1" => {"size" => "small"}}}
53
+ @cloud.stub(:content).and_return(content)
54
+ @cloud.whenever?.should be_false
55
+ end
56
+ end
57
+ end
@@ -5,7 +5,6 @@ describe Shelly::Cloudfile do
5
5
  before do
6
6
  FileUtils.mkdir_p("/projects/foo")
7
7
  Dir.chdir("/projects/foo")
8
- @hash = {:code_name => {:code => "test"}}
9
8
  @client = mock
10
9
  Shelly::Client.stub(:new).and_return(@client)
11
10
  @cloudfile = Shelly::Cloudfile.new
@@ -22,6 +21,68 @@ describe Shelly::Cloudfile do
22
21
  yaml.should == {"domains" => ["*.example.com", "example.com"]}
23
22
  end
24
23
 
24
+ describe "#content" do
25
+ it "should fetch and parse file content" do
26
+ content = <<-config
27
+ foo-staging:
28
+ ruby_version: 1.9.3
29
+ environment: production
30
+ monitoring_email: bob@example.com
31
+ domains:
32
+ - foo-staging.winniecloud.com
33
+ servers:
34
+ app1:
35
+ size: small
36
+ thin: 2
37
+ whenever: on
38
+ delayed_job: 1
39
+ databases:
40
+ - postgresql
41
+ config
42
+ File.open("/projects/foo/Cloudfile", "w") { |f| f << content }
43
+ @cloudfile.content.should == {"foo-staging" => {
44
+ "ruby_version" => "1.9.3",
45
+ "environment" => "production",
46
+ "monitoring_email" => "bob@example.com",
47
+ "domains" => ["foo-staging.winniecloud.com"],
48
+ "servers" => { "app1" =>
49
+ {"size" => "small",
50
+ "thin" => 2,
51
+ "whenever" => true,
52
+ "delayed_job" => 1,
53
+ "databases" => ["postgresql"]}
54
+ }
55
+ }
56
+ }
57
+ end
58
+ end
59
+
60
+ describe "#clouds" do
61
+ it "should create Cloud objects" do
62
+ content = <<-config
63
+ foo-staging:
64
+ ruby_version: 1.9.3
65
+ servers:
66
+ app1:
67
+ size: small
68
+ foo-production:
69
+ environment: production
70
+ servers:
71
+ app1:
72
+ thin: 2
73
+ config
74
+ File.open("/projects/foo/Cloudfile", "w") { |f| f << content }
75
+ cloud1 = Shelly::Cloud.should_receive(:new).with({"code_name"=>"foo-staging",
76
+ "content"=>{"ruby_version"=>"1.9.3",
77
+ "servers"=>{"app1"=>{"size"=>"small"}}}})
78
+ cloud2 = Shelly::Cloud.should_receive(:new).with({"code_name"=>"foo-production",
79
+ "content"=>{"environment"=>"production",
80
+ "servers"=>{"app1"=>{"thin"=>2}}}})
81
+
82
+ @cloudfile.clouds
83
+ end
84
+ end
85
+
25
86
  describe "#generate" do
26
87
  before do
27
88
  @cloudfile.code_name = "foo-staging"
@@ -88,31 +149,6 @@ config
88
149
  end
89
150
  end
90
151
 
91
- describe "#databases" do
92
- before do
93
- content = <<-config
94
- foo-staging:
95
- servers:
96
- app1:
97
- databases:
98
- - postgresql
99
- - redis
100
- app2:
101
- databases:
102
- - mongodb
103
- config
104
- File.open("Cloudfile", 'w') {|f| f.write(content) }
105
- end
106
-
107
- it "should return databases in cloudfile" do
108
- @cloudfile.databases("foo-staging").should =~ ['redis', 'mongodb', 'postgresql']
109
- end
110
-
111
- it "should return databases except for redis" do
112
- @cloudfile.backup_databases("foo-staging").should =~ ['postgresql', 'mongodb']
113
- end
114
- end
115
-
116
152
  describe "#create" do
117
153
  before do
118
154
  @cloudfile.stub(:generate).and_return("foo-staging:")
data/spec/spec_helper.rb CHANGED
@@ -9,6 +9,7 @@ require "helpers"
9
9
  require "input_faker"
10
10
  require "fakefs/spec_helpers"
11
11
  require "fakeweb"
12
+ require "launchy"
12
13
 
13
14
  ENV['THOR_COLUMNS'] = "180"
14
15
  FakeWeb.allow_net_connect = false
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.1.24.pre
4
+ version: 0.1.24.pre2
5
5
  prerelease: 7
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-14 00:00:00.000000000 Z
12
+ date: 2012-09-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -43,6 +43,38 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: guard
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: guard-rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
46
78
  - !ruby/object:Gem::Dependency
47
79
  name: simplecov
48
80
  requirement: !ruby/object:Gem::Requirement
@@ -124,13 +156,13 @@ dependencies:
124
156
  - !ruby/object:Gem::Version
125
157
  version: '0'
126
158
  - !ruby/object:Gem::Dependency
127
- name: thor
159
+ name: wijet-thor
128
160
  requirement: !ruby/object:Gem::Requirement
129
161
  none: false
130
162
  requirements:
131
163
  - - ~>
132
164
  - !ruby/object:Gem::Version
133
- version: 0.15.4
165
+ version: 0.14.7
134
166
  type: :runtime
135
167
  prerelease: false
136
168
  version_requirements: !ruby/object:Gem::Requirement
@@ -138,7 +170,7 @@ dependencies:
138
170
  requirements:
139
171
  - - ~>
140
172
  - !ruby/object:Gem::Version
141
- version: 0.15.4
173
+ version: 0.14.7
142
174
  - !ruby/object:Gem::Dependency
143
175
  name: rest-client
144
176
  requirement: !ruby/object:Gem::Requirement
@@ -247,6 +279,7 @@ files:
247
279
  - .travis.yml
248
280
  - CHANGELOG.md
249
281
  - Gemfile
282
+ - Guardfile
250
283
  - README.md
251
284
  - Rakefile
252
285
  - bin/shelly
@@ -265,6 +298,7 @@ files:
265
298
  - lib/shelly/cli/runner.rb
266
299
  - lib/shelly/cli/user.rb
267
300
  - lib/shelly/client.rb
301
+ - lib/shelly/cloud.rb
268
302
  - lib/shelly/cloudfile.rb
269
303
  - lib/shelly/download_progress_bar.rb
270
304
  - lib/shelly/helpers.rb
@@ -274,6 +308,7 @@ files:
274
308
  - lib/shelly/user.rb
275
309
  - lib/shelly/version.rb
276
310
  - lib/thor/arguments.rb
311
+ - lib/thor/basic.rb
277
312
  - lib/thor/options.rb
278
313
  - lib/thor/thor.rb
279
314
  - scrolls/shellycloud.rb
@@ -290,6 +325,7 @@ files:
290
325
  - spec/shelly/cli/runner_spec.rb
291
326
  - spec/shelly/cli/user_spec.rb
292
327
  - spec/shelly/client_spec.rb
328
+ - spec/shelly/cloud_spec.rb
293
329
  - spec/shelly/cloudfile_spec.rb
294
330
  - spec/shelly/download_progress_bar_spec.rb
295
331
  - spec/shelly/model_spec.rb
@@ -334,6 +370,7 @@ test_files:
334
370
  - spec/shelly/cli/runner_spec.rb
335
371
  - spec/shelly/cli/user_spec.rb
336
372
  - spec/shelly/client_spec.rb
373
+ - spec/shelly/cloud_spec.rb
337
374
  - spec/shelly/cloudfile_spec.rb
338
375
  - spec/shelly/download_progress_bar_spec.rb
339
376
  - spec/shelly/model_spec.rb