engineyard 1.4.29 → 1.7.0.pre2
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.
- 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
|