shelly 0.1.24.pre2 → 0.1.24
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +3 -1
- data/README.md +0 -4
- data/lib/shelly/app.rb +1 -1
- data/lib/shelly/cli/backup.rb +2 -2
- data/lib/shelly/cli/command.rb +0 -1
- data/lib/shelly/cli/config.rb +1 -2
- data/lib/shelly/cli/deploys.rb +7 -1
- data/lib/shelly/cli/main.rb +14 -45
- data/lib/shelly/cloudfile.rb +17 -4
- data/lib/shelly/helpers.rb +1 -1
- data/lib/shelly/version.rb +1 -1
- data/lib/shelly.rb +0 -1
- data/lib/thor/options.rb +2 -3
- data/lib/thor/thor.rb +38 -4
- data/shelly.gemspec +1 -3
- data/spec/shelly/cli/backup_spec.rb +1 -3
- data/spec/shelly/cli/deploys_spec.rb +8 -4
- data/spec/shelly/cli/files_spec.rb +0 -1
- data/spec/shelly/cli/main_spec.rb +1 -57
- data/spec/shelly/cli/user_spec.rb +2 -3
- data/spec/shelly/cloudfile_spec.rb +26 -62
- data/spec/spec_helper.rb +0 -1
- metadata +9 -97
- data/Guardfile +0 -6
- data/lib/shelly/cloud.rb +0 -49
- data/lib/thor/basic.rb +0 -9
- data/spec/shelly/cloud_spec.rb +0 -57
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
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
|
121
121
|
if clouds.grep(/staging/).present?
|
122
122
|
guessed = "production"
|
123
123
|
production_clouds = clouds.grep(/production/)
|
data/lib/shelly/cli/backup.rb
CHANGED
@@ -32,7 +32,7 @@ module Shelly
|
|
32
32
|
|
33
33
|
say "Available backups:", :green
|
34
34
|
say_new_line
|
35
|
-
print_table(to_display, :
|
35
|
+
print_table(to_display, :indent => 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.
|
73
|
+
app.request_backup(kind || cloudfile.backup_databases(app))
|
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
|
data/lib/shelly/cli/command.rb
CHANGED
data/lib/shelly/cli/config.rb
CHANGED
@@ -79,8 +79,7 @@ module Shelly
|
|
79
79
|
end
|
80
80
|
|
81
81
|
desc "delete PATH", "Delete configuration file"
|
82
|
-
def delete(path
|
83
|
-
say_error "No configuration file specified" unless path
|
82
|
+
def delete(path)
|
84
83
|
app = multiple_clouds(options[:cloud], "delete #{path}")
|
85
84
|
answer = yes?("Are you sure you want to delete 'path' (yes/no): ")
|
86
85
|
if answer
|
data/lib/shelly/cli/deploys.rb
CHANGED
@@ -17,7 +17,13 @@ module Shelly
|
|
17
17
|
unless logs.empty?
|
18
18
|
say "Available deploy logs", :green
|
19
19
|
logs.each do |log|
|
20
|
-
log[
|
20
|
+
if log['author'].present? && log['commit_sha'].present?
|
21
|
+
log_line = " * #{log['created_at']} #{log['commit_sha'][0..6]} by #{log['author']}"
|
22
|
+
else
|
23
|
+
log_line = " * #{log['created_at']}"
|
24
|
+
end
|
25
|
+
message = log["failed"] ? "#{log_line} (failed)" : log_line
|
26
|
+
say(message, nil, true)
|
21
27
|
end
|
22
28
|
else
|
23
29
|
say "No deploy logs available"
|
data/lib/shelly/cli/main.rb
CHANGED
@@ -19,7 +19,6 @@ 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
|
23
22
|
before_hook :logged_in?, :only => [:add, :status, :list, :start, :stop, :logs, :delete, :info, :ip, :logout, :execute, :rake, :setup, :console, :dbconsole]
|
24
23
|
before_hook :inside_git_repository?, :only => [:add, :setup, :check]
|
25
24
|
|
@@ -134,7 +133,7 @@ module Shelly
|
|
134
133
|
end
|
135
134
|
[app["code_name"], "| #{state.humanize}#{msg}"]
|
136
135
|
end
|
137
|
-
print_table(apps_table, :
|
136
|
+
print_table(apps_table, :indent => 2)
|
138
137
|
else
|
139
138
|
say "You have no clouds yet", :green
|
140
139
|
end
|
@@ -149,21 +148,21 @@ module Shelly
|
|
149
148
|
" (deployment log: `shelly deploys show last -c #{app}`)"
|
150
149
|
end
|
151
150
|
say "Cloud #{app}:", msg.present? ? :red : :green
|
152
|
-
print_wrapped "State: #{app.state}#{msg}", :
|
151
|
+
print_wrapped "State: #{app.state}#{msg}", :indent => 2
|
153
152
|
say_new_line
|
154
|
-
print_wrapped "Deployed commit sha: #{app.git_info["deployed_commit_sha"]}", :
|
155
|
-
print_wrapped "Deployed commit message: #{app.git_info["deployed_commit_message"]}", :
|
156
|
-
print_wrapped "Deployed by: #{app.git_info["deployed_push_author"]}", :
|
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
|
157
156
|
say_new_line
|
158
|
-
print_wrapped "Repository URL: #{app.git_info["repository_url"]}", :
|
159
|
-
print_wrapped "Web server IP: #{app.web_server_ip}", :
|
157
|
+
print_wrapped "Repository URL: #{app.git_info["repository_url"]}", :indent => 2
|
158
|
+
print_wrapped "Web server IP: #{app.web_server_ip}", :indent => 2
|
160
159
|
say_new_line
|
161
160
|
if app.statistics.present?
|
162
|
-
print_wrapped "Statistics:", :
|
161
|
+
print_wrapped "Statistics:", :indent => 2
|
163
162
|
app.statistics.each do |stat|
|
164
|
-
print_wrapped "#{stat['name']}:", :
|
165
|
-
print_wrapped "Load average: 1m: #{stat['load']['avg01']}, 5m: #{stat['load']['avg05']}, 15m: #{stat['load']['avg15']}", :
|
166
|
-
print_wrapped "CPU: #{stat['cpu']['wait']}%, MEM: #{stat['memory']['percent']}%, SWAP: #{stat['swap']['percent']}%", :
|
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
|
167
166
|
end
|
168
167
|
end
|
169
168
|
rescue Client::GatewayTimeoutException
|
@@ -385,10 +384,6 @@ We have been notified about it. We will be adding new resources shortly}
|
|
385
384
|
"Gemfile.lock is missing in git repository",
|
386
385
|
:show_fulfilled => verbose)
|
387
386
|
|
388
|
-
print_check(structure.config_ru?, "File config.ru is present",
|
389
|
-
"File config.ru is missing",
|
390
|
-
:show_fulfilled => verbose)
|
391
|
-
|
392
387
|
print_check(structure.gem?("shelly-dependencies"),
|
393
388
|
"Gem 'shelly-dependencies' is present",
|
394
389
|
"Gem 'shelly-dependencies' is missing, we recommend to install it\n See more at https://shellycloud.com/documentation/requirements#shelly-dependencies",
|
@@ -400,35 +395,9 @@ We have been notified about it. We will be adding new resources shortly}
|
|
400
395
|
print_check(structure.gem?("rake"), "Gem 'rake' is present",
|
401
396
|
"Gem 'rake' is missing in the Gemfile", :show_fulfilled => verbose)
|
402
397
|
|
403
|
-
|
404
|
-
|
405
|
-
|
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
|
398
|
+
print_check(structure.config_ru?, "File config.ru is present",
|
399
|
+
"File config.ru is missing",
|
400
|
+
:show_fulfilled => verbose)
|
432
401
|
|
433
402
|
print_check(!structure.gem?("mysql") && !structure.gem?("mysql2"),"",
|
434
403
|
"mysql driver present in the Gemfile (not supported on Shelly Cloud)",
|
data/lib/shelly/cloudfile.rb
CHANGED
@@ -16,10 +16,7 @@ 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
|
20
|
-
Shelly::Cloud.new("code_name" => code_name,
|
21
|
-
"content" => content[code_name.to_s])
|
22
|
-
end if content
|
19
|
+
content.keys.sort if content
|
23
20
|
end
|
24
21
|
|
25
22
|
# Public: Generate example Cloudfile based on object attributes
|
@@ -38,6 +35,22 @@ module Shelly
|
|
38
35
|
File.open(path, "a+") { |f| f << generate }
|
39
36
|
end
|
40
37
|
|
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
|
+
|
41
54
|
# Internal: Load and parse Cloudfile
|
42
55
|
def content
|
43
56
|
return unless present?
|
data/lib/shelly/helpers.rb
CHANGED
data/lib/shelly/version.rb
CHANGED
data/lib/shelly.rb
CHANGED
@@ -14,7 +14,6 @@ require "shelly/model"
|
|
14
14
|
module Shelly
|
15
15
|
autoload :App, "shelly/app"
|
16
16
|
autoload :Cloudfile, "shelly/cloudfile"
|
17
|
-
autoload :Cloud, "shelly/cloud"
|
18
17
|
autoload :Client, "shelly/client"
|
19
18
|
autoload :StructureValidator, "shelly/structure_validator"
|
20
19
|
autoload :User, "shelly/user"
|
data/lib/thor/options.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
class Thor
|
2
2
|
class Options < Arguments
|
3
|
-
|
4
3
|
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
|
7
|
+
"Try 'shelly --help' for more information" unless unknown.empty?
|
8
8
|
end
|
9
|
-
|
10
9
|
end
|
11
10
|
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] = options
|
5
|
+
@hook[method] = {:only => Array(options[:only])}
|
6
6
|
end
|
7
7
|
|
8
8
|
def hooks
|
@@ -28,12 +28,46 @@ 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)
|
31
37
|
end
|
32
38
|
|
33
|
-
# We overwrite this method so namespace is
|
39
|
+
# We overwrite this method so namespace is shown
|
34
40
|
# shelly *backup* restore FILENAME
|
35
|
-
def handle_argument_error(task, error)
|
36
|
-
|
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 || [])
|
37
71
|
end
|
38
72
|
end
|
39
73
|
end
|
data/shelly.gemspec
CHANGED
@@ -14,8 +14,6 @@ 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"
|
19
17
|
s.add_development_dependency "simplecov"
|
20
18
|
if RUBY_PLATFORM =~ /darwin/
|
21
19
|
s.add_development_dependency "ruby_gntp"
|
@@ -23,7 +21,7 @@ Gem::Specification.new do |s|
|
|
23
21
|
end
|
24
22
|
s.add_development_dependency "fakefs"
|
25
23
|
s.add_development_dependency "fakeweb"
|
26
|
-
s.add_runtime_dependency "
|
24
|
+
s.add_runtime_dependency "thor", "~> 0.15.4"
|
27
25
|
s.add_runtime_dependency "rest-client"
|
28
26
|
s.add_runtime_dependency "json"
|
29
27
|
s.add_runtime_dependency "progressbar"
|
@@ -135,9 +135,7 @@ describe Shelly::CLI::Backup do
|
|
135
135
|
FileUtils.mkdir_p("/projects/foo")
|
136
136
|
Dir.chdir("/projects/foo")
|
137
137
|
$stdout.stub(:puts)
|
138
|
-
@
|
139
|
-
Shelly::Cloud.stub(:new).and_return(@cloud)
|
140
|
-
@cloudfile = mock(:present? => true, :clouds => [@cloud])
|
138
|
+
@cloudfile = mock(:backup_databases => ['postgresql', 'mongodb'], :clouds => ['foo-staging'])
|
141
139
|
Shelly::Cloudfile.stub(:new).and_return(@cloudfile)
|
142
140
|
end
|
143
141
|
|
@@ -35,11 +35,15 @@ describe Shelly::CLI::Deploys do
|
|
35
35
|
|
36
36
|
it "should display available logs" do
|
37
37
|
@client.should_receive(:deploy_logs).with("foo-staging").and_return([
|
38
|
-
{"failed" => false, "created_at" => "2011-12-12-14-14-59"},
|
39
|
-
|
38
|
+
{"failed" => false, "created_at" => "2011-12-12-14-14-59", "author" => "wijet", "commit_sha" => "69fb7a9b5101969f284db15b937ea23e579b3d4d"},
|
39
|
+
{"failed" => true, "created_at" => "2011-12-12-15-14-59", "author" => "sabcio", "commit_sha" => "ac37e1993fea54ddbadaf7654b7ab0fa381d202b"},
|
40
|
+
{"failed" => false, "created_at" => "2011-12-12-16-14-59", "author" => nil, "commit_sha" => nil},
|
41
|
+
{"failed" => true, "created_at" => "2011-12-12-17-14-59", "author" => nil, "commit_sha" => nil}])
|
40
42
|
$stdout.should_receive(:puts).with(green "Available deploy logs")
|
41
|
-
$stdout.should_receive(:puts).with(" * 2011-12-12-14-14-59")
|
42
|
-
$stdout.should_receive(:puts).with(" * 2011-12-12-15-14-59 (failed)")
|
43
|
+
$stdout.should_receive(:puts).with(" * 2011-12-12-14-14-59 69fb7a9 by wijet")
|
44
|
+
$stdout.should_receive(:puts).with(" * 2011-12-12-15-14-59 ac37e19 by sabcio (failed)")
|
45
|
+
$stdout.should_receive(:puts).with(" * 2011-12-12-16-14-59")
|
46
|
+
$stdout.should_receive(:puts).with(" * 2011-12-12-17-14-59 (failed)")
|
43
47
|
invoke(@deploys, :list)
|
44
48
|
end
|
45
49
|
end
|
@@ -29,7 +29,6 @@ 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
|
-
|
33
32
|
$stdout.should_receive(:puts).with(red "You need to install rsync in order to upload and download files")
|
34
33
|
lambda { invoke(@cli_files, :upload, "some/path") }.should raise_error(SystemExit)
|
35
34
|
end
|
@@ -1275,7 +1275,7 @@ We have been notified about it. We will be adding new resources shortly")
|
|
1275
1275
|
before do
|
1276
1276
|
Shelly::App.stub(:inside_git_repository?).and_return(true)
|
1277
1277
|
Bundler::Definition.stub_chain(:build, :specs, :map) \
|
1278
|
-
.and_return(["thin"
|
1278
|
+
.and_return(["thin"])
|
1279
1279
|
Shelly::StructureValidator.any_instance.stub(:repo_paths) \
|
1280
1280
|
.and_return(["config.ru", "Gemfile", "Gemfile.lock"])
|
1281
1281
|
end
|
@@ -1344,62 +1344,6 @@ We have been notified about it. We will be adding new resources shortly")
|
|
1344
1344
|
end
|
1345
1345
|
end
|
1346
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
|
-
|
1403
1347
|
context "when mysql gem exists" do
|
1404
1348
|
it "should show that mysql gem is not supported by Shelly Cloud" do
|
1405
1349
|
Bundler::Definition.stub_chain(:build, :specs, :map).and_return(["mysql"])
|
@@ -8,6 +8,7 @@ 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("")
|
11
12
|
$stdout.stub(:puts)
|
12
13
|
$stdout.stub(:print)
|
13
14
|
@client.stub(:token).and_return("abc")
|
@@ -15,8 +16,6 @@ describe Shelly::CLI::User do
|
|
15
16
|
Dir.chdir("/projects/foo")
|
16
17
|
@app = Shelly::App.new("foo-staging")
|
17
18
|
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)
|
20
19
|
end
|
21
20
|
|
22
21
|
describe "#help" do
|
@@ -48,7 +47,7 @@ describe Shelly::CLI::User do
|
|
48
47
|
context "on success" do
|
49
48
|
it "should display clouds and users" do
|
50
49
|
@client.stub(:collaborations).and_return(response)
|
51
|
-
$stdout.should_receive(:puts).with("Cloud
|
50
|
+
$stdout.should_receive(:puts).with("Cloud foo-staging:")
|
52
51
|
$stdout.should_receive(:puts).with(" user@example.com")
|
53
52
|
$stdout.should_receive(:puts).with(" auser2@example2.com (invited)")
|
54
53
|
invoke(@cli_user, :list)
|
@@ -5,6 +5,7 @@ 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"}}
|
8
9
|
@client = mock
|
9
10
|
Shelly::Client.stub(:new).and_return(@client)
|
10
11
|
@cloudfile = Shelly::Cloudfile.new
|
@@ -21,68 +22,6 @@ describe Shelly::Cloudfile do
|
|
21
22
|
yaml.should == {"domains" => ["*.example.com", "example.com"]}
|
22
23
|
end
|
23
24
|
|
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
|
-
|
86
25
|
describe "#generate" do
|
87
26
|
before do
|
88
27
|
@cloudfile.code_name = "foo-staging"
|
@@ -149,6 +88,31 @@ config
|
|
149
88
|
end
|
150
89
|
end
|
151
90
|
|
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
|
+
|
152
116
|
describe "#create" do
|
153
117
|
before do
|
154
118
|
@cloudfile.stub(:generate).and_return("foo-staging:")
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shelly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.24
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.24
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Shelly Cloud team
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -43,38 +43,6 @@ 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'
|
78
46
|
- !ruby/object:Gem::Dependency
|
79
47
|
name: simplecov
|
80
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,38 +59,6 @@ dependencies:
|
|
91
59
|
- - ! '>='
|
92
60
|
- !ruby/object:Gem::Version
|
93
61
|
version: '0'
|
94
|
-
- !ruby/object:Gem::Dependency
|
95
|
-
name: ruby_gntp
|
96
|
-
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
|
-
requirements:
|
99
|
-
- - ! '>='
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version: '0'
|
102
|
-
type: :development
|
103
|
-
prerelease: false
|
104
|
-
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
|
-
requirements:
|
107
|
-
- - ! '>='
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: '0'
|
110
|
-
- !ruby/object:Gem::Dependency
|
111
|
-
name: rb-fsevent
|
112
|
-
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
|
-
requirements:
|
115
|
-
- - ! '>='
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
|
-
requirements:
|
123
|
-
- - ! '>='
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version: '0'
|
126
62
|
- !ruby/object:Gem::Dependency
|
127
63
|
name: fakefs
|
128
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -156,13 +92,13 @@ dependencies:
|
|
156
92
|
- !ruby/object:Gem::Version
|
157
93
|
version: '0'
|
158
94
|
- !ruby/object:Gem::Dependency
|
159
|
-
name:
|
95
|
+
name: thor
|
160
96
|
requirement: !ruby/object:Gem::Requirement
|
161
97
|
none: false
|
162
98
|
requirements:
|
163
99
|
- - ~>
|
164
100
|
- !ruby/object:Gem::Version
|
165
|
-
version: 0.
|
101
|
+
version: 0.15.4
|
166
102
|
type: :runtime
|
167
103
|
prerelease: false
|
168
104
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -170,7 +106,7 @@ dependencies:
|
|
170
106
|
requirements:
|
171
107
|
- - ~>
|
172
108
|
- !ruby/object:Gem::Version
|
173
|
-
version: 0.
|
109
|
+
version: 0.15.4
|
174
110
|
- !ruby/object:Gem::Dependency
|
175
111
|
name: rest-client
|
176
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -279,7 +215,6 @@ files:
|
|
279
215
|
- .travis.yml
|
280
216
|
- CHANGELOG.md
|
281
217
|
- Gemfile
|
282
|
-
- Guardfile
|
283
218
|
- README.md
|
284
219
|
- Rakefile
|
285
220
|
- bin/shelly
|
@@ -298,7 +233,6 @@ files:
|
|
298
233
|
- lib/shelly/cli/runner.rb
|
299
234
|
- lib/shelly/cli/user.rb
|
300
235
|
- lib/shelly/client.rb
|
301
|
-
- lib/shelly/cloud.rb
|
302
236
|
- lib/shelly/cloudfile.rb
|
303
237
|
- lib/shelly/download_progress_bar.rb
|
304
238
|
- lib/shelly/helpers.rb
|
@@ -308,7 +242,6 @@ files:
|
|
308
242
|
- lib/shelly/user.rb
|
309
243
|
- lib/shelly/version.rb
|
310
244
|
- lib/thor/arguments.rb
|
311
|
-
- lib/thor/basic.rb
|
312
245
|
- lib/thor/options.rb
|
313
246
|
- lib/thor/thor.rb
|
314
247
|
- scrolls/shellycloud.rb
|
@@ -325,7 +258,6 @@ files:
|
|
325
258
|
- spec/shelly/cli/runner_spec.rb
|
326
259
|
- spec/shelly/cli/user_spec.rb
|
327
260
|
- spec/shelly/client_spec.rb
|
328
|
-
- spec/shelly/cloud_spec.rb
|
329
261
|
- spec/shelly/cloudfile_spec.rb
|
330
262
|
- spec/shelly/download_progress_bar_spec.rb
|
331
263
|
- spec/shelly/model_spec.rb
|
@@ -348,33 +280,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
348
280
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
349
281
|
none: false
|
350
282
|
requirements:
|
351
|
-
- - ! '
|
283
|
+
- - ! '>='
|
352
284
|
- !ruby/object:Gem::Version
|
353
|
-
version:
|
285
|
+
version: '0'
|
354
286
|
requirements: []
|
355
287
|
rubyforge_project: shelly
|
356
288
|
rubygems_version: 1.8.24
|
357
289
|
signing_key:
|
358
290
|
specification_version: 3
|
359
291
|
summary: Shelly Cloud command line tool
|
360
|
-
test_files:
|
361
|
-
- spec/helpers.rb
|
362
|
-
- spec/input_faker.rb
|
363
|
-
- spec/shelly/app_spec.rb
|
364
|
-
- spec/shelly/backup_spec.rb
|
365
|
-
- spec/shelly/cli/backup_spec.rb
|
366
|
-
- spec/shelly/cli/config_spec.rb
|
367
|
-
- spec/shelly/cli/deploys_spec.rb
|
368
|
-
- spec/shelly/cli/files_spec.rb
|
369
|
-
- spec/shelly/cli/main_spec.rb
|
370
|
-
- spec/shelly/cli/runner_spec.rb
|
371
|
-
- spec/shelly/cli/user_spec.rb
|
372
|
-
- spec/shelly/client_spec.rb
|
373
|
-
- spec/shelly/cloud_spec.rb
|
374
|
-
- spec/shelly/cloudfile_spec.rb
|
375
|
-
- spec/shelly/download_progress_bar_spec.rb
|
376
|
-
- spec/shelly/model_spec.rb
|
377
|
-
- spec/shelly/structure_validator_spec.rb
|
378
|
-
- spec/shelly/user_spec.rb
|
379
|
-
- spec/spec_helper.rb
|
380
|
-
- spec/thor/options_spec.rb
|
292
|
+
test_files: []
|
data/Guardfile
DELETED
data/lib/shelly/cloud.rb
DELETED
@@ -1,49 +0,0 @@
|
|
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
|
data/lib/thor/basic.rb
DELETED
data/spec/shelly/cloud_spec.rb
DELETED
@@ -1,57 +0,0 @@
|
|
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
|