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,66 @@
|
|
1
|
+
module EY
|
2
|
+
class DeployConfig
|
3
|
+
def initialize(cli_opts, env_config, repo, ui)
|
4
|
+
@cli_opts = cli_opts
|
5
|
+
@env_config = env_config
|
6
|
+
@repo = repo
|
7
|
+
@ui = ui
|
8
|
+
end
|
9
|
+
|
10
|
+
def ref
|
11
|
+
@ref ||= decide_ref
|
12
|
+
end
|
13
|
+
|
14
|
+
def migrate
|
15
|
+
decide_migrate
|
16
|
+
@migrate
|
17
|
+
end
|
18
|
+
|
19
|
+
def migrate_command
|
20
|
+
decide_migrate
|
21
|
+
@migrate_command
|
22
|
+
end
|
23
|
+
|
24
|
+
def verbose
|
25
|
+
@cli_opts.fetch('verbose') { in_repo? && @env_config.verbose }
|
26
|
+
end
|
27
|
+
|
28
|
+
def extra_config
|
29
|
+
extras = @cli_opts.fetch('extra_deploy_hook_options', {})
|
30
|
+
if in_repo?
|
31
|
+
extras = @env_config.merge(extras)
|
32
|
+
end
|
33
|
+
extras
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# passing an app means we assume PWD is not the app.
|
39
|
+
def in_repo?
|
40
|
+
@cli_opts['app'].nil? || @cli_opts['app'] == ''
|
41
|
+
end
|
42
|
+
|
43
|
+
def decide_ref
|
44
|
+
ref_decider = EY::DeployConfig::Ref.new(@cli_opts, @env_config, @repo, @ui)
|
45
|
+
if in_repo?
|
46
|
+
ref_decider.when_inside_repo
|
47
|
+
else
|
48
|
+
ref_decider.when_outside_repo
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def decide_migrate
|
53
|
+
return if @migrate_decider
|
54
|
+
@migrate_decider = EY::DeployConfig::Migrate.new(@cli_opts, @env_config, @ui)
|
55
|
+
@migrate, @migrate_command =
|
56
|
+
if in_repo?
|
57
|
+
@migrate_decider.when_inside_repo
|
58
|
+
else
|
59
|
+
@migrate_decider.when_outside_repo
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
require 'engineyard/deploy_config/migrate'
|
66
|
+
require 'engineyard/deploy_config/ref'
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module EY
|
2
|
+
class DeployConfig
|
3
|
+
class Migrate
|
4
|
+
|
5
|
+
DEFAULT = 'rake db:migrate'
|
6
|
+
|
7
|
+
def initialize(cli_opts, env_config, ui)
|
8
|
+
@cli_opts = cli_opts
|
9
|
+
@env_config = env_config
|
10
|
+
@ui = ui
|
11
|
+
|
12
|
+
@perform = nil
|
13
|
+
@command = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns an array of [perform_migration, migrate_command] on success.
|
17
|
+
# Yields the block if no migrate options are set.
|
18
|
+
def when_outside_repo
|
19
|
+
if perform_from_cli_opts
|
20
|
+
if @perform
|
21
|
+
@command ||= command_from_opts || DEFAULT
|
22
|
+
else
|
23
|
+
@command = nil
|
24
|
+
end
|
25
|
+
[@perform, @command]
|
26
|
+
else
|
27
|
+
raise RefAndMigrateRequiredOutsideRepo.new(@cli_opts)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns an array of [perform_migration, migrate_command] on success.
|
32
|
+
# Should always return successfully.
|
33
|
+
def when_inside_repo
|
34
|
+
if perform_from_cli_opts || perform_from_config || perform_from_interaction
|
35
|
+
if @perform
|
36
|
+
@command ||= command_from_opts || command_from_config || DEFAULT
|
37
|
+
else
|
38
|
+
@command = nil
|
39
|
+
end
|
40
|
+
[@perform, @command]
|
41
|
+
else
|
42
|
+
raise MigrateRequired.new(@cli_opts)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :cli_opts, :env_config, :ui
|
49
|
+
|
50
|
+
def command_from_opts
|
51
|
+
cli_migrate = cli_opts.fetch('migrate', nil)
|
52
|
+
cli_migrate.respond_to?(:to_str) && cli_migrate.to_str
|
53
|
+
end
|
54
|
+
|
55
|
+
def command_from_config
|
56
|
+
env_config.migrate_command
|
57
|
+
end
|
58
|
+
|
59
|
+
def perform_from_cli_opts
|
60
|
+
@perform = !!cli_opts.fetch('migrate') { return false } # yields on not found
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
64
|
+
def perform_from_config
|
65
|
+
@perform = !!env_config.migrate { return perform_implied_via_command_in_config }
|
66
|
+
if @perform
|
67
|
+
unless command_from_config
|
68
|
+
env_config.migration_command = DEFAULT
|
69
|
+
end
|
70
|
+
end
|
71
|
+
true
|
72
|
+
end
|
73
|
+
|
74
|
+
# if the command is set in ey.yml and perform isn't explicitly turned off,
|
75
|
+
# then we'll write out the old default of migrating always, since that's
|
76
|
+
# probably what is expected.
|
77
|
+
def perform_implied_via_command_in_config
|
78
|
+
if @perfom.nil? && @command = command_from_config
|
79
|
+
@perform = true
|
80
|
+
env_config.migrate = @perform
|
81
|
+
ui.warn "********************************************************************************"
|
82
|
+
ui.info "#{env_config.path} config for #{env_config.name} has been updated to"
|
83
|
+
ui.info "migrate by default to maintain previous expected default behavior."
|
84
|
+
ui.warn "********************************************************************************"
|
85
|
+
ui.say "It's a good idea to git commit #{env_config.path} with these new changes."
|
86
|
+
true
|
87
|
+
else
|
88
|
+
false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def perform_from_interaction
|
93
|
+
ui.warn "********************************************************************************"
|
94
|
+
ui.warn "No default migrate choice for environment: #{env_config.name}"
|
95
|
+
ui.warn "Migrate can be toggled per-deploy using --migrate or --no-migrate."
|
96
|
+
ui.warn "Let's set a default migration choice."
|
97
|
+
ui.warn "********************************************************************************"
|
98
|
+
@perform = ui.agree('Migrate every deploy by default? ', true)
|
99
|
+
env_config.migrate = @perform
|
100
|
+
if @perform
|
101
|
+
command_from_interaction
|
102
|
+
end
|
103
|
+
ui.say "#{env_config.path}: migrate settings saved for #{env_config.name}."
|
104
|
+
ui.say "It's a good idea to git commit #{env_config.path} with these new changes."
|
105
|
+
true
|
106
|
+
rescue Timeout::Error
|
107
|
+
@perform = nil
|
108
|
+
@command = nil
|
109
|
+
ui.error "Timeout when waiting for input. This is not a terminal."
|
110
|
+
ui.error "ey deploy no longer migrates when no default is set in ey.yml."
|
111
|
+
ui.error "Run interactively for step-by-step ey.yml migration setup."
|
112
|
+
return false
|
113
|
+
end
|
114
|
+
|
115
|
+
# only interactively request a command if we interactively requested the perform setting.
|
116
|
+
# don't call this outside of the interactive setting (otherwise, why even have a default?)
|
117
|
+
def command_from_interaction
|
118
|
+
default = env_config.migration_command || DEFAULT
|
119
|
+
@command = ui.ask("Migration command? ", false, default)
|
120
|
+
env_config.migration_command = @command
|
121
|
+
@command
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'engineyard/error'
|
2
|
+
|
3
|
+
module EY
|
4
|
+
class DeployConfig
|
5
|
+
class Ref
|
6
|
+
|
7
|
+
def initialize(cli_opts, env_config, repo, ui)
|
8
|
+
@cli_opts = cli_opts
|
9
|
+
@default = env_config.branch
|
10
|
+
@repo = repo
|
11
|
+
@force_ref = @cli_opts.fetch('force_ref', false)
|
12
|
+
@ui = ui
|
13
|
+
|
14
|
+
if @force_ref.kind_of?(String)
|
15
|
+
@ref, @force_ref = @force_ref, true
|
16
|
+
else
|
17
|
+
@ref = @cli_opts.fetch('ref', nil)
|
18
|
+
@ref = nil if @ref == ''
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def when_inside_repo
|
23
|
+
if !@force_ref && @ref && @default && @ref != @default
|
24
|
+
raise BranchMismatchError.new(@default, @ref)
|
25
|
+
elsif @force_ref && @ref && @default
|
26
|
+
@ui.say "Default ref overridden with #{@ref.inspect}."
|
27
|
+
end
|
28
|
+
|
29
|
+
@ref || use_default || use_current_branch || raise(RefRequired.new(@cli_opts))
|
30
|
+
end
|
31
|
+
|
32
|
+
def use_default
|
33
|
+
if @default
|
34
|
+
@ui.say "Using default branch #{@default.inspect} from ey.yml."
|
35
|
+
@default
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def use_current_branch
|
40
|
+
if current = @repo.current_branch
|
41
|
+
@ui.say "Using current HEAD branch #{current.inspect}."
|
42
|
+
current
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# a.k.a. not in the correct repo
|
47
|
+
#
|
48
|
+
# returns the ref if it was passed in the cli opts.
|
49
|
+
# or raise
|
50
|
+
def when_outside_repo
|
51
|
+
@ref or raise RefAndMigrateRequiredOutsideRepo.new(@cli_opts)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/engineyard/error.rb
CHANGED
@@ -1,78 +1,24 @@
|
|
1
1
|
module EY
|
2
2
|
class Error < RuntimeError
|
3
|
-
def ambiguous(type, name, matches, desc="")
|
4
|
-
pretty_names = matches.map {|x| "'#{x}'"}.join(', ')
|
5
|
-
"The name '#{name}' is ambiguous; it matches all of the following #{type} names: #{pretty_names}.\n" +
|
6
|
-
"Please use a longer, unambiguous substring or the entire #{type} name." + desc
|
7
|
-
end
|
8
3
|
end
|
9
4
|
|
10
|
-
class ResolveError < EY::Error; end
|
11
|
-
class NoMatchesError < ResolveError; end
|
12
|
-
class MultipleMatchesError < ResolveError; end
|
13
|
-
|
14
5
|
class NoCommandError < EY::Error
|
15
6
|
def initialize
|
16
7
|
super "Must specify a command to run via ssh"
|
17
8
|
end
|
18
9
|
end
|
19
10
|
|
20
|
-
class NoRemotesError < EY::Error
|
21
|
-
def initialize(path)
|
22
|
-
super "fatal: No git remotes found in #{path}"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class NoAppError < Error
|
27
|
-
def initialize(repo)
|
28
|
-
super <<-ERROR
|
29
|
-
There is no application configured for any of the following remotes:
|
30
|
-
\t#{repo ? repo.urls.join("\n\t") : "No remotes found."}
|
31
|
-
You can add this application at #{EY.config.endpoint}
|
32
|
-
ERROR
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
class InvalidAppError < Error
|
37
|
-
def initialize(name)
|
38
|
-
super %|There is no app configured with the name "#{name}"|
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class AmbiguousAppNameError < EY::Error
|
43
|
-
def initialize(name, matches, desc="")
|
44
|
-
super ambiguous("app", name, matches, desc)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
class NoAppMasterError < EY::Error
|
49
|
-
def initialize(env_name)
|
50
|
-
super "The environment '#{env_name}' does not have a master instance."
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
11
|
class NoInstancesError < EY::Error
|
55
12
|
def initialize(env_name)
|
56
13
|
super "The environment '#{env_name}' does not have any matching instances."
|
57
14
|
end
|
58
15
|
end
|
59
16
|
|
60
|
-
class
|
61
|
-
|
62
|
-
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
class EnvironmentError < EY::Error
|
67
|
-
end
|
17
|
+
class ResolverError < Error; end
|
18
|
+
class NoMatchesError < ResolverError; end
|
19
|
+
class MultipleMatchesError < ResolverError; end
|
68
20
|
|
69
|
-
class
|
70
|
-
def initialize(name, matches, desc="")
|
71
|
-
super ambiguous("environment", name, matches, desc)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
class AmbiguousEnvironmentGitUriError < EY::EnvironmentError
|
21
|
+
class AmbiguousEnvironmentGitUriError < ResolverError
|
76
22
|
def initialize(environments)
|
77
23
|
message = "The repository url in this directory is ambiguous.\n"
|
78
24
|
message << "Please use -e <envname> to specify one of the following environments:\n"
|
@@ -87,36 +33,50 @@ You can add this application at #{EY.config.endpoint}
|
|
87
33
|
end
|
88
34
|
end
|
89
35
|
|
90
|
-
class NoSingleEnvironmentError < EY::EnvironmentError
|
91
|
-
def initialize(app)
|
92
|
-
size = app.environments.size
|
93
|
-
super "Unable to determine a single environment for the current application (found #{size} environments)"
|
94
|
-
end
|
95
|
-
end
|
96
36
|
|
97
|
-
class
|
98
|
-
|
99
|
-
|
37
|
+
class DeployArgumentError < EY::Error; end
|
38
|
+
class BranchMismatchError < DeployArgumentError
|
39
|
+
def initialize(default, ref)
|
40
|
+
super <<-ERR
|
41
|
+
Your default branch is set to #{default.inspect} in ey.yml.
|
42
|
+
To deploy #{ref.inspect} you can:
|
43
|
+
* Delete the line 'branch: #{default}' in ey.yml
|
44
|
+
OR
|
45
|
+
* Use the -R [REF] or --force-ref [REF] options as follows:
|
46
|
+
Usage: ey deploy -R #{ref}
|
47
|
+
ey deploy --force-ref #{ref}
|
48
|
+
ERR
|
100
49
|
end
|
101
50
|
end
|
102
51
|
|
103
|
-
class
|
104
|
-
def initialize(
|
105
|
-
super
|
52
|
+
class RefAndMigrateRequiredOutsideRepo < DeployArgumentError
|
53
|
+
def initialize(options)
|
54
|
+
super <<-ERR
|
55
|
+
Because defaults are stored in a file in your application dir, when specifying
|
56
|
+
--app you must also specify the --ref and the --migrate or --no-migrate options.
|
57
|
+
Usage: ey deploy --app #{options[:app]} --ref [ref] --migrate [COMMAND]
|
58
|
+
ey deploy --app #{options[:app]} --ref [branch] --no-migrate
|
59
|
+
ERR
|
106
60
|
end
|
107
61
|
end
|
108
62
|
|
109
|
-
class
|
110
|
-
def initialize(
|
111
|
-
super
|
112
|
-
|
63
|
+
class RefRequired < DeployArgumentError
|
64
|
+
def initialize(options)
|
65
|
+
super <<-ERR
|
66
|
+
Unable to determine the branch or ref to deploy
|
67
|
+
Usage: ey deploy --ref [ref]
|
68
|
+
ERR
|
113
69
|
end
|
114
70
|
end
|
115
71
|
|
116
|
-
class
|
117
|
-
def initialize
|
118
|
-
super
|
119
|
-
|
72
|
+
class MigrateRequired < DeployArgumentError
|
73
|
+
def initialize(options)
|
74
|
+
super <<-ERR
|
75
|
+
Unable to determine migration choice. ey deploy no longer migrates by default.
|
76
|
+
Usage: ey deploy --migrate
|
77
|
+
ey deploy --no-migrate
|
78
|
+
ERR
|
120
79
|
end
|
121
80
|
end
|
81
|
+
|
122
82
|
end
|
data/lib/engineyard/repo.rb
CHANGED
@@ -1,55 +1,103 @@
|
|
1
1
|
require 'engineyard/error'
|
2
|
-
require 'escape'
|
3
2
|
require 'pathname'
|
4
3
|
|
5
4
|
module EY
|
6
5
|
class Repo
|
6
|
+
class NotAGitRepository < EY::Error
|
7
|
+
attr_reader :dir
|
8
|
+
def initialize(output)
|
9
|
+
@dir = File.expand_path(ENV['GIT_DIR'] || ENV['GIT_WORK_TREE'] || '.')
|
10
|
+
super("#{output} (#{@dir})")
|
11
|
+
end
|
12
|
+
end
|
7
13
|
|
8
|
-
|
14
|
+
class NoRemotesError < EY::Error
|
15
|
+
def initialize(path)
|
16
|
+
super "fatal: No git remotes found in #{path}"
|
17
|
+
end
|
18
|
+
end
|
9
19
|
|
10
|
-
def
|
11
|
-
|
20
|
+
def self.exist?
|
21
|
+
system("git rev-parse --git-dir > /dev/null 2>&1")
|
12
22
|
end
|
13
23
|
|
14
|
-
|
15
|
-
|
24
|
+
attr_reader :root
|
25
|
+
|
26
|
+
# $GIT_DIR is what git uses to override the location of the .git dir.
|
27
|
+
# $GIT_WORK_TREE is the working tree for git, which we'll use after $GIT_DIR.
|
28
|
+
#
|
29
|
+
# We use this to specify which repo we should look at, since it would also
|
30
|
+
# specify where any git commands are directed, thus fooling commands we
|
31
|
+
# run anyway.
|
32
|
+
def initialize
|
16
33
|
end
|
17
34
|
|
18
|
-
def
|
19
|
-
|
35
|
+
def root
|
36
|
+
@root ||= begin
|
37
|
+
out = `git rev-parse --show-toplevel 2>&1`.strip
|
38
|
+
|
39
|
+
if $?.success? && !out.empty?
|
40
|
+
Pathname.new(out)
|
41
|
+
else
|
42
|
+
raise EY::Repo::NotAGitRepository.new(out)
|
43
|
+
end
|
44
|
+
end
|
20
45
|
end
|
21
46
|
|
22
|
-
def
|
23
|
-
|
24
|
-
head
|
25
|
-
else
|
26
|
-
nil
|
27
|
-
end
|
47
|
+
def ensure_repository!
|
48
|
+
root
|
28
49
|
end
|
29
50
|
|
30
|
-
def
|
31
|
-
|
51
|
+
def has_committed_file?(file)
|
52
|
+
ensure_repository!
|
53
|
+
`git ls-files --full-name #{file}`.strip == file && $?.success?
|
32
54
|
end
|
33
55
|
|
34
|
-
def
|
35
|
-
|
56
|
+
def has_file?(file)
|
57
|
+
ensure_repository!
|
58
|
+
has_committed_file?(file) || root.join(file).exist?
|
36
59
|
end
|
37
60
|
|
38
|
-
|
39
|
-
|
40
|
-
|
61
|
+
# Read the committed version at HEAD (or ref) of a file using the git working tree relative filename.
|
62
|
+
# If the file is not committed, but does exist, a warning will be displayed
|
63
|
+
# and the file will be read anyway.
|
64
|
+
# If the file does not exist, returns nil.
|
65
|
+
#
|
66
|
+
# Example:
|
67
|
+
#
|
68
|
+
# read_file('config/ey.yml') # will read $GIT_WORK_TREE/config/ey.yml
|
69
|
+
#
|
70
|
+
def read_file(file, ref = 'HEAD')
|
71
|
+
ensure_repository!
|
72
|
+
if has_committed_file?(file)
|
73
|
+
# TODO warn if there are unstaged changes.
|
74
|
+
`git show #{ref}:#{file}`
|
75
|
+
else
|
76
|
+
EY.ui.warn <<-WARN
|
77
|
+
Warn: #{file} is not committed to this git repository:
|
78
|
+
\t#{root}
|
79
|
+
This can prevent ey deploy from loading this file for certain server side
|
80
|
+
deploy-time operations. Commit this file to fix this warning.
|
81
|
+
WARN
|
82
|
+
root.join(file).read
|
41
83
|
end
|
42
84
|
end
|
43
85
|
|
44
|
-
|
86
|
+
def current_branch
|
87
|
+
ensure_repository!
|
88
|
+
branch = `git symbolic-ref -q HEAD`.chomp.gsub("refs/heads/", "")
|
89
|
+
branch.empty? ? nil : branch
|
90
|
+
end
|
45
91
|
|
46
|
-
def
|
47
|
-
|
92
|
+
def remotes
|
93
|
+
ensure_repository!
|
94
|
+
@remotes ||= `git remote -v`.scan(/\t[^\s]+\s/).map { |c| c.strip }.uniq
|
48
95
|
end
|
49
96
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
97
|
+
def fail_on_no_remotes!
|
98
|
+
if remotes.empty?
|
99
|
+
raise EY::Repo::NoRemotesError.new(root)
|
100
|
+
end
|
53
101
|
end
|
54
102
|
|
55
103
|
end # Repo
|