engineyard 1.4.29 → 1.7.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +139 -4
- data/bin/ey +1 -7
- data/lib/engineyard.rb +1 -22
- data/lib/engineyard/cli.rb +192 -94
- data/lib/engineyard/cli/#recipes.rb# +32 -0
- data/lib/engineyard/cli/api.rb +42 -28
- data/lib/engineyard/cli/recipes.rb +13 -6
- data/lib/engineyard/cli/ui.rb +103 -42
- data/lib/engineyard/cli/web.rb +16 -10
- data/lib/engineyard/config.rb +92 -18
- data/lib/engineyard/deploy_config.rb +66 -0
- data/lib/engineyard/deploy_config/migrate.rb +125 -0
- data/lib/engineyard/deploy_config/ref.rb +56 -0
- data/lib/engineyard/error.rb +38 -78
- data/lib/engineyard/repo.rb +75 -27
- data/lib/engineyard/serverside_runner.rb +133 -0
- data/lib/engineyard/thor.rb +110 -18
- data/lib/engineyard/version.rb +1 -1
- data/spec/engineyard/cli/api_spec.rb +10 -16
- data/spec/engineyard/cli_spec.rb +0 -11
- data/spec/engineyard/config_spec.rb +1 -8
- data/spec/engineyard/deploy_config_spec.rb +203 -0
- data/spec/engineyard/eyrc_spec.rb +2 -0
- data/spec/engineyard/repo_spec.rb +57 -34
- data/spec/ey/deploy_spec.rb +102 -52
- data/spec/ey/list_environments_spec.rb +69 -14
- data/spec/ey/login_spec.rb +11 -7
- data/spec/ey/logout_spec.rb +4 -4
- data/spec/ey/logs_spec.rb +6 -6
- data/spec/ey/recipes/apply_spec.rb +1 -1
- data/spec/ey/recipes/download_spec.rb +1 -1
- data/spec/ey/recipes/upload_spec.rb +6 -6
- data/spec/ey/rollback_spec.rb +3 -3
- data/spec/ey/ssh_spec.rb +9 -9
- data/spec/ey/status_spec.rb +2 -2
- data/spec/ey/whoami_spec.rb +9 -8
- data/spec/spec_helper.rb +18 -15
- data/spec/support/{fake_awsm.rb → git_repos.rb} +0 -14
- data/spec/support/helpers.rb +84 -28
- data/spec/support/matchers.rb +0 -16
- data/spec/support/shared_behavior.rb +83 -103
- metadata +65 -51
- data/lib/engineyard/api.rb +0 -117
- data/lib/engineyard/collection.rb +0 -7
- data/lib/engineyard/collection/abstract.rb +0 -71
- data/lib/engineyard/collection/apps.rb +0 -8
- data/lib/engineyard/collection/environments.rb +0 -8
- data/lib/engineyard/model.rb +0 -12
- data/lib/engineyard/model/account.rb +0 -8
- data/lib/engineyard/model/api_struct.rb +0 -33
- data/lib/engineyard/model/app.rb +0 -32
- data/lib/engineyard/model/deployment.rb +0 -90
- data/lib/engineyard/model/environment.rb +0 -194
- data/lib/engineyard/model/instance.rb +0 -166
- data/lib/engineyard/model/log.rb +0 -9
- data/lib/engineyard/model/user.rb +0 -6
- data/lib/engineyard/resolver.rb +0 -134
- data/lib/engineyard/rest_client_ext.rb +0 -9
- data/lib/engineyard/ruby_ext.rb +0 -9
- data/spec/engineyard/api_spec.rb +0 -39
- data/spec/engineyard/collection/apps_spec.rb +0 -16
- data/spec/engineyard/collection/environments_spec.rb +0 -16
- data/spec/engineyard/model/api_struct_spec.rb +0 -41
- data/spec/engineyard/model/environment_spec.rb +0 -198
- data/spec/engineyard/model/instance_spec.rb +0 -27
- data/spec/engineyard/resolver_spec.rb +0 -112
- data/spec/support/fake_awsm.ru +0 -245
- data/spec/support/scenarios.rb +0 -417
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'escape'
|
2
|
+
require 'net/ssh'
|
3
|
+
require 'engineyard-serverside-adapter'
|
4
|
+
|
5
|
+
module EY
|
6
|
+
class ServersideRunner
|
7
|
+
def initialize(bridge, app, environment, verbose)
|
8
|
+
@verbose = verbose || ENV['DEBUG']
|
9
|
+
@adapter = load_adapter(bridge, app, environment)
|
10
|
+
@username = environment.username
|
11
|
+
@hostname = bridge
|
12
|
+
@command = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def deploy(&block)
|
16
|
+
@command = @adapter.deploy(&block)
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def rollback(&block)
|
21
|
+
@command = @adapter.rollback(&block)
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def put_up_maintenance_page(&block)
|
26
|
+
@command = @adapter.enable_maintenance_page(&block)
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def take_down_maintenance_page(&block)
|
31
|
+
@command = @adapter.disable_maintenance_page(&block)
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(out, err)
|
36
|
+
raise "No command!" unless @command
|
37
|
+
@command.call do |cmd|
|
38
|
+
run cmd, out, err
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def load_adapter(bridge, app, environment)
|
45
|
+
EY::Serverside::Adapter.new("/usr/local/ey_resin/ruby/bin") do |args|
|
46
|
+
args.app = app.name
|
47
|
+
args.repo = app.repository_uri
|
48
|
+
args.instances = instances_data(environment.deploy_to_instances, bridge)
|
49
|
+
args.stack = environment.app_server_stack_name
|
50
|
+
args.framework_env = environment.framework_env
|
51
|
+
args.environment_name = environment.name
|
52
|
+
args.account_name = app.account.name
|
53
|
+
args.verbose = @verbose
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# If we tell engineyard-serverside to use 'localhost', it'll run
|
58
|
+
# commands on the instance directly (#system). If we give it the
|
59
|
+
# instance's actual hostname, it'll SSH to itself.
|
60
|
+
#
|
61
|
+
# Using 'localhost' instead of its EC2 hostname speeds up
|
62
|
+
# deploys on solos and single-app-server clusters significantly.
|
63
|
+
def instances_data(instances, bridge)
|
64
|
+
instances.map do |i|
|
65
|
+
{
|
66
|
+
:hostname => i.hostname == bridge ? 'localhost' : i.hostname,
|
67
|
+
:roles => [i.role],
|
68
|
+
:name => i.name,
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def run(remote_command, out, err)
|
74
|
+
cmd = Escape.shell_command(['bash', '-lc', remote_command])
|
75
|
+
|
76
|
+
if cmd.respond_to?(:encoding) && cmd.respond_to?(:force_encoding)
|
77
|
+
out << "Encoding: #{cmd.encoding.name}" if @verbose
|
78
|
+
cmd.force_encoding('binary')
|
79
|
+
out << " => #{cmd.encoding.name}; __ENCODING__: #{__ENCODING__.name}; LANG: #{ENV['LANG']}; LC_CTYPE: #{ENV['LC_CTYPE']}\n" if @verbose
|
80
|
+
end
|
81
|
+
|
82
|
+
out << "Running command on #{@username}@#{@hostname}.\n"
|
83
|
+
out << cmd << "\n" if @verbose
|
84
|
+
|
85
|
+
if ENV["NO_SSH"]
|
86
|
+
out << "NO_SSH is set. No output.\n"
|
87
|
+
true
|
88
|
+
else
|
89
|
+
begin
|
90
|
+
ssh(cmd, @hostname, @username, out, err)
|
91
|
+
rescue Net::SSH::AuthenticationFailed
|
92
|
+
raise EY::Error, "Authentication Failed: Please add your environment's ssh key with: ssh-add path/to/key"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def ssh(cmd, hostname, username, out, err)
|
98
|
+
exit_code = 1
|
99
|
+
options_for_ssh = {:paranoid => false}
|
100
|
+
options_for_ssh[:verbose] = ENV["DEBUG"].downcase.to_sym if ENV["DEBUG"]
|
101
|
+
Net::SSH.start(hostname, username, options_for_ssh) do |net_ssh|
|
102
|
+
net_ssh.open_channel do |channel|
|
103
|
+
channel.exec cmd do |_, success|
|
104
|
+
unless success
|
105
|
+
err << "Remote command execution failed"
|
106
|
+
return false
|
107
|
+
end
|
108
|
+
|
109
|
+
channel.on_data do |_, data|
|
110
|
+
out << data
|
111
|
+
end
|
112
|
+
|
113
|
+
channel.on_extended_data do |_, _, data|
|
114
|
+
err << data
|
115
|
+
end
|
116
|
+
|
117
|
+
channel.on_request("exit-status") do |_, data|
|
118
|
+
exit_code = data.read_long
|
119
|
+
end
|
120
|
+
|
121
|
+
channel.on_request("exit-signal") do |_, data|
|
122
|
+
exit_code = 255
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
net_ssh.loop
|
128
|
+
end
|
129
|
+
exit_code.zero?
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
data/lib/engineyard/thor.rb
CHANGED
@@ -4,33 +4,125 @@ module EY
|
|
4
4
|
module UtilityMethods
|
5
5
|
protected
|
6
6
|
def api
|
7
|
-
@api ||= EY::CLI::API.new
|
7
|
+
@api ||= EY::CLI::API.new(config.endpoint, ui)
|
8
|
+
end
|
9
|
+
|
10
|
+
def config
|
11
|
+
@config ||= EY::Config.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def ui
|
15
|
+
@ui ||= load_ui
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_ui
|
19
|
+
Thor::Base.shell = EY::CLI::UI
|
20
|
+
EY::CLI::UI.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def in_repo?
|
24
|
+
EY::Repo.exist?
|
8
25
|
end
|
9
26
|
|
10
27
|
def repo
|
11
28
|
@repo ||= EY::Repo.new
|
12
29
|
end
|
13
30
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
31
|
+
def serverside_runner(app_env, verbose)
|
32
|
+
ServersideRunner.new(app_env.environment.bridge!.hostname, app_env.app, app_env.environment, verbose)
|
33
|
+
end
|
34
|
+
|
35
|
+
def use_default_environment
|
36
|
+
if env = config.default_environment
|
37
|
+
ui.say "Using default environment #{config.default_environment.inspect} from ey.yml."
|
38
|
+
env
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def fetch_environment(environment_name, account_name)
|
43
|
+
environment_name ||= use_default_environment
|
44
|
+
remotes = repo.remotes if in_repo?
|
45
|
+
constraints = {
|
17
46
|
:environment_name => environment_name,
|
18
|
-
:account_name
|
47
|
+
:account_name => account_name,
|
48
|
+
:remotes => remotes,
|
19
49
|
}
|
20
|
-
|
21
|
-
api.
|
50
|
+
|
51
|
+
resolver = api.resolve_environments(constraints)
|
52
|
+
|
53
|
+
resolver.one_match { |match| return match }
|
54
|
+
|
55
|
+
resolver.no_matches do |errors, suggestions|
|
56
|
+
raise_no_matches(errors, suggestions)
|
57
|
+
end
|
58
|
+
|
59
|
+
resolver.many_matches do |matches|
|
60
|
+
if environment_name
|
61
|
+
message = "Multiple environments possible, please be more specific:\n\n"
|
62
|
+
matches.each do |env|
|
63
|
+
message << "\t#{env.name.ljust(25)} # ey <command> --environment='#{env.name}' --account='#{env.account.name}'\n"
|
64
|
+
end
|
65
|
+
raise EY::MultipleMatchesError.new(message)
|
66
|
+
else
|
67
|
+
raise EY::AmbiguousEnvironmentGitUriError.new(matches)
|
68
|
+
end
|
69
|
+
end
|
22
70
|
end
|
23
71
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
72
|
+
def fetch_app_environment(app_name, environment_name, account_name)
|
73
|
+
environment_name ||= use_default_environment
|
74
|
+
remotes = repo.remotes if in_repo?
|
75
|
+
constraints = {
|
76
|
+
:app_name => app_name,
|
27
77
|
:environment_name => environment_name,
|
28
|
-
:account_name
|
78
|
+
:account_name => account_name,
|
79
|
+
:remotes => remotes,
|
29
80
|
}
|
30
|
-
|
31
|
-
|
81
|
+
|
82
|
+
if constraints.all? { |k,v| v.nil? || v.empty? || v.to_s.empty? }
|
83
|
+
raise EY::NoMatchesError.new <<-ERROR
|
84
|
+
Unable to find application without a git remote URI or app name.
|
85
|
+
|
86
|
+
Please specify --app app_name or add this application at #{config.endpoint}"
|
87
|
+
ERROR
|
88
|
+
end
|
89
|
+
|
90
|
+
resolver = api.resolve_app_environments(constraints)
|
91
|
+
|
92
|
+
resolver.one_match { |match| return match }
|
93
|
+
resolver.no_matches do |errors, suggestions|
|
94
|
+
raise_no_matches(errors, suggestions)
|
95
|
+
end
|
96
|
+
resolver.many_matches do |app_envs|
|
97
|
+
raise EY::MultipleMatchesError.new(too_many_app_environments_error(app_envs))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def raise_no_matches(errors, suggestions)
|
102
|
+
message = "We found the following suggestions:\n" if suggestions.any?
|
103
|
+
|
104
|
+
suggestions.each do |suggest|
|
105
|
+
message << " # ey <command> --account='#{suggest['account_name']}' --app='#{suggest['app_name']}' --environment='#{suggest['env_name']}'\n"
|
106
|
+
end
|
107
|
+
|
108
|
+
raise EY::NoMatchesError.new([errors,message].compact.join("\n").strip)
|
32
109
|
end
|
33
110
|
|
111
|
+
def too_many_app_environments_error(app_envs)
|
112
|
+
message = "Multiple application environments possible, please be more specific:\n\n"
|
113
|
+
|
114
|
+
app_envs.group_by do |app_env|
|
115
|
+
[app_env.account_name, app_env.app_name]
|
116
|
+
end.sort_by { |k,v| k.join }.each do |(account_name, app_name), grouped_app_envs|
|
117
|
+
message << "\n"
|
118
|
+
message << account_name << "/" << app_name << "\n"
|
119
|
+
grouped_app_envs.map { |ae| ae.environment_name }.uniq.sort.each do |env_name|
|
120
|
+
message << "\t#{env_name.ljust(25)}"
|
121
|
+
message << " # ey <command> --account='#{account_name}' --app='#{app_name}' --environment='#{env_name}'\n"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
message
|
125
|
+
end
|
34
126
|
end # UtilityMethods
|
35
127
|
|
36
128
|
class Thor < ::Thor
|
@@ -44,13 +136,13 @@ module EY
|
|
44
136
|
class_eval <<-RUBY
|
45
137
|
def help(*args)
|
46
138
|
if args.empty?
|
47
|
-
|
48
|
-
|
139
|
+
ui.say "usage: #{banner_base} #{cmd} COMMAND"
|
140
|
+
ui.say
|
49
141
|
subcommands = self.class.printable_tasks.sort_by{|s| s[0] }
|
50
142
|
subcommands.reject!{|t| t[0] =~ /#{cmd} help$/}
|
51
|
-
|
52
|
-
|
53
|
-
|
143
|
+
ui.print_help(subcommands)
|
144
|
+
ui.say self.class.send(:class_options_help, ui)
|
145
|
+
ui.say "See #{banner_base} #{cmd} help COMMAND" +
|
54
146
|
" for more information on a specific subcommand." if args.empty?
|
55
147
|
else
|
56
148
|
super
|
data/lib/engineyard/version.rb
CHANGED
@@ -2,42 +2,36 @@ require 'spec_helper'
|
|
2
2
|
require 'engineyard/cli'
|
3
3
|
|
4
4
|
describe EY::CLI::API do
|
5
|
-
before(:all) do
|
6
|
-
EY.ui = EY::CLI::UI.new
|
7
|
-
end
|
8
|
-
|
9
|
-
after(:all) do
|
10
|
-
EY.ui = EY::UI.new
|
11
|
-
end
|
12
|
-
|
13
5
|
it "gets the api token from ~/.eyrc if possible" do
|
14
6
|
write_eyrc({"api_token" => "asdf"})
|
15
|
-
EY::CLI::API.new.
|
7
|
+
EY::CLI::API.new('http://fake.local', EY::CLI::UI.new).token.should == "asdf"
|
8
|
+
clean_eyrc
|
16
9
|
end
|
17
10
|
|
18
11
|
it "uses the token from $ENGINEYARD_API_TOKEN if set" do
|
19
12
|
ENV['ENGINEYARD_API_TOKEN'] = 'envtoken'
|
20
|
-
EY::CLI::API.new.token.should == 'envtoken'
|
13
|
+
EY::CLI::API.new('http://fake.local', EY::CLI::UI.new).token.should == 'envtoken'
|
21
14
|
ENV.delete('ENGINEYARD_API_TOKEN')
|
22
15
|
end
|
23
16
|
|
24
17
|
context "without saved api token" do
|
25
18
|
before(:each) do
|
26
|
-
|
19
|
+
clean_eyrc
|
20
|
+
FakeWeb.register_uri(:post, "http://fake.local/api/v2/authenticate", :body => %|{"api_token": "asdf"}|, :content_type => 'application/json')
|
27
21
|
|
28
22
|
EY::CLI::UI::Prompter.enable_mock!
|
29
|
-
EY::CLI::UI::Prompter.
|
30
|
-
EY::CLI::UI::Prompter.
|
23
|
+
EY::CLI::UI::Prompter.add_answer "my@email.example.com"
|
24
|
+
EY::CLI::UI::Prompter.add_answer "secret"
|
31
25
|
|
32
|
-
@api = EY::CLI::API.new
|
26
|
+
@api = EY::CLI::API.new('http://fake.local', EY::CLI::UI.new)
|
33
27
|
end
|
34
28
|
|
35
29
|
it "asks you for your credentials" do
|
36
|
-
EY::CLI::UI::Prompter.
|
30
|
+
EY::CLI::UI::Prompter.questions.should == ["Email: ","Password: "]
|
37
31
|
end
|
38
32
|
|
39
33
|
it "gets the api token" do
|
40
|
-
@api.should ==
|
34
|
+
@api.token.should == "asdf"
|
41
35
|
end
|
42
36
|
|
43
37
|
it "saves the api token to ~/.eyrc" do
|
data/spec/engineyard/cli_spec.rb
CHANGED
@@ -3,15 +3,6 @@ require 'engineyard/cli'
|
|
3
3
|
|
4
4
|
describe EY::CLI do
|
5
5
|
|
6
|
-
it "sets up EY.ui" do
|
7
|
-
EY.instance_eval{ @ui = nil }
|
8
|
-
EY.ui.should be_an(EY::UI)
|
9
|
-
capture_stdout do
|
10
|
-
EY::CLI.start(["help"])
|
11
|
-
end
|
12
|
-
EY.ui.should be_an(EY::CLI::UI)
|
13
|
-
end
|
14
|
-
|
15
6
|
it "provides help" do
|
16
7
|
out = capture_stdout do
|
17
8
|
EY::CLI.start(["help"])
|
@@ -31,8 +22,6 @@ describe EY::CLI do
|
|
31
22
|
end
|
32
23
|
|
33
24
|
it "provides error classes" do
|
34
|
-
EY::EnvironmentError.should be
|
35
|
-
EY::BranchMismatchError.should be
|
36
25
|
EY::DeployArgumentError.should be
|
37
26
|
end
|
38
27
|
|
@@ -23,14 +23,7 @@ describe EY::Config do
|
|
23
23
|
|
24
24
|
it "loads the endpoint from $CLOUD_URL" do
|
25
25
|
ENV['CLOUD_URL'] = "http://fake.local/"
|
26
|
-
EY::Config.new.endpoint.should ==
|
27
|
-
ENV.delete('CLOUD_URL')
|
28
|
-
end
|
29
|
-
|
30
|
-
it "raises on an invalid endpoint" do
|
31
|
-
ENV['CLOUD_URL'] = "non/absolute"
|
32
|
-
lambda { EY::Config.new.endpoint }.
|
33
|
-
should raise_error(EY::Config::ConfigurationError)
|
26
|
+
EY::Config.new.endpoint.should == 'http://fake.local/'
|
34
27
|
ENV.delete('CLOUD_URL')
|
35
28
|
end
|
36
29
|
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EY::DeployConfig::Migrate do
|
4
|
+
before do
|
5
|
+
@parent = mock('parent config mock')
|
6
|
+
@parent.stub!(:set_environment_option)
|
7
|
+
@parent.stub!(:path).and_return('path')
|
8
|
+
@ui = EY::CLI::UI.new
|
9
|
+
EY::CLI::UI::Prompter.enable_mock!
|
10
|
+
@repo = mock('repo')
|
11
|
+
end
|
12
|
+
|
13
|
+
def env_config(opts=nil)
|
14
|
+
@env_config ||= EY::Config::EnvironmentConfig.new(opts, 'envname', @parent)
|
15
|
+
end
|
16
|
+
|
17
|
+
def deploy_config(cli_options)
|
18
|
+
EY::DeployConfig.new(cli_options, env_config, @repo, @ui)
|
19
|
+
end
|
20
|
+
|
21
|
+
context "inside a repository" do
|
22
|
+
context "no migrate options set (interactive)" do
|
23
|
+
it "prompts migrate and command by default" do
|
24
|
+
EY::CLI::UI::Prompter.add_answer "" # default
|
25
|
+
EY::CLI::UI::Prompter.add_answer ""
|
26
|
+
@parent.should_receive(:set_environment_option).with('envname', 'migrate', true)
|
27
|
+
@parent.should_receive(:set_environment_option).with('envname', 'migration_command', 'rake db:migrate')
|
28
|
+
dc = deploy_config({})
|
29
|
+
dc.migrate.should be_true
|
30
|
+
dc.migrate_command.should == 'rake db:migrate'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "prompts migration_command if first answer is yes" do
|
34
|
+
EY::CLI::UI::Prompter.add_answer "yes" # default
|
35
|
+
EY::CLI::UI::Prompter.add_answer "ruby script/migrate"
|
36
|
+
@parent.should_receive(:set_environment_option).with('envname', 'migrate', true)
|
37
|
+
@parent.should_receive(:set_environment_option).with('envname', 'migration_command', 'ruby script/migrate')
|
38
|
+
dc = deploy_config({})
|
39
|
+
dc.migrate.should be_true
|
40
|
+
dc.migrate_command.should == 'ruby script/migrate'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "doesn't prompt migration_command if first answer is no" do
|
44
|
+
EY::CLI::UI::Prompter.add_answer "no" # default
|
45
|
+
@parent.should_receive(:set_environment_option).with('envname', 'migrate', false)
|
46
|
+
dc = deploy_config({})
|
47
|
+
dc.migrate.should be_false
|
48
|
+
dc.migrate_command.should be_nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with the migrate cli option" do
|
53
|
+
it "returns the default migration command when is true" do
|
54
|
+
dc = deploy_config({'migrate' => true})
|
55
|
+
dc.migrate.should be_true
|
56
|
+
dc.migrate_command.should == 'rake db:migrate'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns false when nil" do
|
60
|
+
dc = deploy_config({'migrate' => nil})
|
61
|
+
dc.migrate.should be_false
|
62
|
+
dc.migrate_command.should be_nil
|
63
|
+
end
|
64
|
+
|
65
|
+
it "return the custom migration command when is a string" do
|
66
|
+
dc = deploy_config({'migrate' => 'foo migrate'})
|
67
|
+
dc.migrate.should be_true
|
68
|
+
dc.migrate_command.should == 'foo migrate'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with the migrate option in the global configuration" do
|
73
|
+
it "return the default migration command when the option is true" do
|
74
|
+
env_config('migrate' => true, 'migration_command' => 'bar migrate')
|
75
|
+
dc = deploy_config({})
|
76
|
+
dc.migrate.should be_true
|
77
|
+
dc.migrate_command.should == 'bar migrate'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "return the false when migrate is false" do
|
81
|
+
env_config('migrate' => false, 'migration_command' => 'bar migrate')
|
82
|
+
dc = deploy_config({})
|
83
|
+
dc.migrate.should be_false
|
84
|
+
dc.migrate_command.should be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it "return the default migration command when the option is true" do
|
88
|
+
env_config('migrate' => true)
|
89
|
+
dc = deploy_config({})
|
90
|
+
dc.migrate.should be_true
|
91
|
+
dc.migrate_command.should == 'rake db:migrate'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "return the ey.yml migration_command when command line option --migrate is passed" do
|
95
|
+
env_config('migrate' => false, 'migration_command' => 'bar migrate')
|
96
|
+
dc = deploy_config({'migrate' => true})
|
97
|
+
dc.migrate.should be_true
|
98
|
+
dc.migrate_command.should == 'bar migrate'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "ref" do
|
103
|
+
it "returns the passed ref" do
|
104
|
+
deploy_config({'ref' => 'master'}).ref.should == 'master'
|
105
|
+
end
|
106
|
+
|
107
|
+
it "returns the passed force_ref" do
|
108
|
+
deploy_config({'force_ref' => 'force'}).ref.should == 'force'
|
109
|
+
end
|
110
|
+
|
111
|
+
it "returns the ref if force_ref is true" do
|
112
|
+
deploy_config({'ref' => 'master', 'force_ref' => true}).ref.should == 'master'
|
113
|
+
end
|
114
|
+
|
115
|
+
it "overrides the ref if force_ref is set to a string" do
|
116
|
+
deploy_config({'ref' => 'master', 'force_ref' => 'force'}).ref.should == 'force'
|
117
|
+
end
|
118
|
+
|
119
|
+
context "with a default branch" do
|
120
|
+
before { env_config('branch' => 'default') }
|
121
|
+
|
122
|
+
it "uses the configured default if ref is not passed" do
|
123
|
+
deploy_config({}).ref.should == 'default'
|
124
|
+
end
|
125
|
+
|
126
|
+
it "raises if a default is set and --ref is passed on the cli (and they don't match)" do
|
127
|
+
lambda { deploy_config({'ref' => 'master'}).ref }.should raise_error(EY::BranchMismatchError)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "returns the default if a default is set and --ref is the same" do
|
131
|
+
deploy_config({'ref' => 'default'}).ref.should == 'default'
|
132
|
+
end
|
133
|
+
|
134
|
+
it "returns the ref if force_ref is set" do
|
135
|
+
deploy_config({'ref' => 'master', 'force_ref' => true}).ref.should == 'master'
|
136
|
+
end
|
137
|
+
|
138
|
+
it "returns the ref if force_ref is a branch" do
|
139
|
+
deploy_config({'force_ref' => 'master'}).ref.should == 'master'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "no options, no default" do
|
144
|
+
it "uses the repo's current branch" do
|
145
|
+
@repo.should_receive(:current_branch).and_return('current')
|
146
|
+
deploy_config({}).ref.should == 'current'
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context "when outside of a repo" do
|
153
|
+
describe "migrate" do
|
154
|
+
it "returns the default migration command when migrate is true" do
|
155
|
+
dc = deploy_config({'app' => 'app', 'migrate' => true})
|
156
|
+
dc.migrate.should be_true
|
157
|
+
dc.migrate_command.should == 'rake db:migrate'
|
158
|
+
end
|
159
|
+
|
160
|
+
it "returns false when nil" do
|
161
|
+
dc = deploy_config({'app' => 'app', 'migrate' => nil})
|
162
|
+
dc.migrate.should be_false
|
163
|
+
dc.migrate_command.should be_nil
|
164
|
+
end
|
165
|
+
|
166
|
+
it "return the custom migration command when is a string" do
|
167
|
+
dc = deploy_config({'app' => 'app', 'migrate' => 'foo migrate'})
|
168
|
+
dc.migrate.should be_true
|
169
|
+
dc.migrate_command.should == 'foo migrate'
|
170
|
+
end
|
171
|
+
|
172
|
+
it "raises if migrate is not passed" do
|
173
|
+
lambda { deploy_config({'app' => 'app'}).migrate }.should raise_error(EY::RefAndMigrateRequiredOutsideRepo)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "ref" do
|
178
|
+
it "returns the passed ref" do
|
179
|
+
dc = deploy_config({'app' => 'app', 'ref' => 'master'})
|
180
|
+
dc.ref.should == 'master'
|
181
|
+
end
|
182
|
+
|
183
|
+
it "returns the passed force_ref" do
|
184
|
+
dc = deploy_config({'app' => 'app', 'force_ref' => 'force'})
|
185
|
+
dc.ref.should == 'force'
|
186
|
+
end
|
187
|
+
|
188
|
+
it "returns the ref if force_ref is true" do
|
189
|
+
dc = deploy_config({'app' => 'app', 'ref' => 'master', 'force_ref' => true})
|
190
|
+
dc.ref.should == 'master'
|
191
|
+
end
|
192
|
+
|
193
|
+
it "overrides the ref if force_ref is set to a string" do
|
194
|
+
dc = deploy_config({'app' => 'app', 'ref' => 'master', 'force_ref' => 'force'})
|
195
|
+
dc.ref.should == 'force'
|
196
|
+
end
|
197
|
+
|
198
|
+
it "raises if ref is not passed" do
|
199
|
+
lambda { deploy_config({'app' => 'app'}).ref }.should raise_error(EY::RefAndMigrateRequiredOutsideRepo)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|