r10k 1.3.5 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +1 -1
- data/CHANGELOG.mkd +210 -0
- data/CONTRIBUTING.mkd +105 -0
- data/Gemfile +2 -6
- data/README.mkd +97 -0
- data/doc/common-patterns.mkd +44 -0
- data/doc/dynamic-environments.mkd +12 -5
- data/doc/dynamic-environments/configuration.mkd +16 -1
- data/doc/dynamic-environments/{git-environments.markdown → git-environments.mkd} +13 -9
- data/doc/dynamic-environments/introduction.mkd +1 -2
- data/doc/dynamic-environments/master-configuration.mkd +70 -0
- data/doc/dynamic-environments/quickstart.mkd +241 -0
- data/doc/dynamic-environments/svn-environments.mkd +45 -0
- data/doc/dynamic-environments/usage.mkd +44 -5
- data/doc/dynamic-environments/workflow-guide.mkd +247 -0
- data/doc/faq.mkd +52 -0
- data/doc/puppetfile.mkd +203 -0
- data/lib/r10k/action/cri_runner.rb +75 -0
- data/lib/r10k/action/deploy.rb +9 -0
- data/lib/r10k/action/deploy/display.rb +104 -0
- data/lib/r10k/action/deploy/environment.rb +92 -0
- data/lib/r10k/action/deploy/module.rb +70 -0
- data/lib/r10k/action/puppetfile.rb +10 -0
- data/lib/r10k/action/puppetfile/check.rb +41 -0
- data/lib/r10k/action/puppetfile/cri_runner.rb +32 -0
- data/lib/r10k/action/puppetfile/install.rb +53 -0
- data/lib/r10k/action/puppetfile/purge.rb +37 -0
- data/lib/r10k/action/runner.rb +36 -0
- data/lib/r10k/action/visitor.rb +31 -0
- data/lib/r10k/cli/deploy.rb +14 -45
- data/lib/r10k/cli/puppetfile.rb +15 -53
- data/lib/r10k/deployment.rb +113 -58
- data/lib/r10k/deployment/basedir.rb +3 -38
- data/lib/r10k/deployment/config.rb +2 -1
- data/lib/r10k/deployment/source.rb +2 -0
- data/lib/r10k/environment/base.rb +40 -0
- data/lib/r10k/environment/git.rb +14 -17
- data/lib/r10k/environment/svn.rb +31 -15
- data/lib/r10k/errors.rb +33 -22
- data/lib/r10k/errors/formatting.rb +28 -0
- data/lib/r10k/execution.rb +2 -0
- data/lib/r10k/git/cache.rb +1 -6
- data/lib/r10k/git/errors.rb +1 -2
- data/lib/r10k/git/ref.rb +1 -1
- data/lib/r10k/module.rb +1 -1
- data/lib/r10k/module/base.rb +94 -2
- data/lib/r10k/module/forge.rb +33 -30
- data/lib/r10k/module/git.rb +13 -9
- data/lib/r10k/module/svn.rb +41 -28
- data/lib/r10k/puppetfile.rb +17 -1
- data/lib/r10k/semver.rb +2 -0
- data/lib/r10k/source/base.rb +8 -0
- data/lib/r10k/source/git.rb +1 -1
- data/lib/r10k/source/svn.rb +23 -5
- data/lib/r10k/svn/remote.rb +23 -3
- data/lib/r10k/svn/working_dir.rb +60 -9
- data/lib/r10k/task.rb +1 -0
- data/lib/r10k/task/deployment.rb +9 -1
- data/lib/r10k/task/environment.rb +2 -0
- data/lib/r10k/task/module.rb +1 -0
- data/lib/r10k/task/puppetfile.rb +3 -0
- data/lib/r10k/task_runner.rb +1 -0
- data/lib/r10k/util/attempt.rb +84 -0
- data/lib/r10k/util/basedir.rb +65 -0
- data/lib/r10k/util/purgeable.rb +55 -45
- data/lib/r10k/util/setopts.rb +53 -0
- data/lib/r10k/util/subprocess.rb +6 -30
- data/lib/r10k/util/subprocess/posix/runner.rb +29 -2
- data/lib/r10k/util/subprocess/result.rb +17 -4
- data/lib/r10k/util/subprocess/subprocess_error.rb +24 -0
- data/lib/r10k/version.rb +1 -1
- data/r10k.gemspec +7 -29
- data/spec/fixtures/unit/puppetfile/invalid-syntax/Puppetfile +1 -0
- data/spec/fixtures/unit/puppetfile/load-error/Puppetfile +1 -0
- data/spec/matchers/exit_with.rb +28 -0
- data/spec/r10k-mocks.rb +3 -0
- data/spec/r10k-mocks/mock_config.rb +28 -0
- data/spec/r10k-mocks/mock_env.rb +7 -0
- data/spec/r10k-mocks/mock_source.rb +10 -0
- data/spec/shared-examples/git-ref.rb +7 -7
- data/spec/spec_helper.rb +17 -5
- data/spec/unit/action/cri_runner_spec.rb +76 -0
- data/spec/unit/action/puppetfile/cri_action_spec.rb +65 -0
- data/spec/unit/action/runner_spec.rb +64 -0
- data/spec/unit/action/visitor_spec.rb +39 -0
- data/spec/unit/deployment_spec.rb +142 -0
- data/spec/unit/environment/base_spec.rb +38 -0
- data/spec/unit/environment/git_spec.rb +40 -10
- data/spec/unit/environment/svn_spec.rb +41 -4
- data/spec/unit/errors/formatting_spec.rb +84 -0
- data/spec/unit/git/alternates_spec.rb +1 -1
- data/spec/unit/git/head_spec.rb +1 -1
- data/spec/unit/git/ref_spec.rb +1 -1
- data/spec/unit/git/working_dir_spec.rb +1 -1
- data/spec/unit/module/base_spec.rb +72 -0
- data/spec/unit/module/forge_spec.rb +49 -8
- data/spec/unit/module/git_spec.rb +78 -0
- data/spec/unit/module/svn_spec.rb +40 -4
- data/spec/unit/module_spec.rb +3 -3
- data/spec/unit/puppetfile_spec.rb +84 -0
- data/spec/unit/settings/container_spec.rb +1 -1
- data/spec/unit/source/base_spec.rb +31 -0
- data/spec/unit/source/git_spec.rb +7 -7
- data/spec/unit/source/svn_spec.rb +1 -1
- data/spec/unit/svn/working_dir_spec.rb +56 -0
- data/spec/unit/util/attempt_spec.rb +82 -0
- data/spec/unit/util/setopts_spec.rb +59 -0
- data/spec/unit/util/subprocess/result_spec.rb +36 -0
- data/spec/unit/util/subprocess/subprocess_error_spec.rb +26 -0
- data/spec/unit/util/subprocess_spec.rb +2 -7
- metadata +83 -100
- data/.nodeset.yml +0 -7
- data/.rspec +0 -1
- data/README.markdown +0 -276
- data/Rakefile +0 -1
- data/doc/puppetfile.markdown +0 -87
- data/spec/rspec-system-r10k/puppetfile.rb +0 -24
- data/spec/rspec-system-r10k/tmpdir.rb +0 -32
- data/spec/system-provisioning/el.rb +0 -38
- data/spec/system/module/forge/install_spec.rb +0 -51
- data/spec/system/module/git/install_spec.rb +0 -117
- data/spec/system/module/svn/install_spec.rb +0 -51
- data/spec/system/module/svn/update_spec.rb +0 -38
- data/spec/system/spec_helper.rb +0 -60
- data/spec/system/system-helpers.rb +0 -4
- data/spec/system/version_spec.rb +0 -7
data/lib/r10k/module/forge.rb
CHANGED
@@ -16,31 +16,16 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
16
16
|
!!(name.match %r[\w+/\w+])
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
#
|
22
|
-
|
23
|
-
attr_reader :author
|
24
|
-
|
25
|
-
# @deprecated
|
26
|
-
def owner
|
27
|
-
logger.warn "#{self.inspect}#owner is deprecated; use #author instead"
|
28
|
-
@author
|
29
|
-
end
|
30
|
-
|
31
|
-
# @!attribute [r] full_name
|
32
|
-
# @return [String] The fully qualified module name
|
33
|
-
attr_reader :full_name
|
34
|
-
|
35
|
-
def initialize(full_name, basedir, args)
|
36
|
-
@full_name = full_name
|
37
|
-
@basedir = basedir
|
38
|
-
|
39
|
-
@author, @name = full_name.split('/')
|
19
|
+
# @!attribute [r] metadata
|
20
|
+
# @api private
|
21
|
+
# @return [R10K::Module::Metadata]
|
22
|
+
attr_reader :metadata
|
40
23
|
|
41
|
-
|
24
|
+
include R10K::Logging
|
42
25
|
|
43
|
-
|
26
|
+
def initialize(title, dirname, args)
|
27
|
+
super
|
28
|
+
@metadata = R10K::Module::Metadata.new(path + 'metadata.json')
|
44
29
|
|
45
30
|
if args.is_a? String
|
46
31
|
@expected_version = R10K::SemVer.new(args)
|
@@ -60,6 +45,14 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
60
45
|
end
|
61
46
|
end
|
62
47
|
|
48
|
+
def properties
|
49
|
+
{
|
50
|
+
:expected => expected_version,
|
51
|
+
:actual => current_version,
|
52
|
+
:type => :forge,
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
63
56
|
# @return [R10K::SemVer] The expected version that the module
|
64
57
|
def expected_version
|
65
58
|
if @expected_version == :latest
|
@@ -71,13 +64,14 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
71
64
|
|
72
65
|
# @return [R10K::SemVer] The version of the currently installed module
|
73
66
|
def current_version
|
67
|
+
@metadata.read
|
74
68
|
@metadata.version
|
75
69
|
end
|
76
70
|
|
77
71
|
alias version current_version
|
78
72
|
|
79
73
|
def exist?
|
80
|
-
|
74
|
+
path.exist?
|
81
75
|
end
|
82
76
|
|
83
77
|
def insync?
|
@@ -105,7 +99,7 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
105
99
|
# determine the state of the module.
|
106
100
|
@metadata.read
|
107
101
|
|
108
|
-
if not @
|
102
|
+
if not @owner == @metadata.author
|
109
103
|
# This is a forge module but the installed module is a different author
|
110
104
|
# than the expected author.
|
111
105
|
return :mismatched
|
@@ -121,12 +115,12 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
121
115
|
private
|
122
116
|
|
123
117
|
def install
|
124
|
-
FileUtils.mkdir @
|
118
|
+
FileUtils.mkdir @dirname unless File.directory? @dirname
|
125
119
|
cmd = []
|
126
120
|
cmd << 'install'
|
127
121
|
cmd << "--version=#{expected_version}" if expected_version
|
128
122
|
cmd << "--force"
|
129
|
-
cmd <<
|
123
|
+
cmd << title
|
130
124
|
pmt cmd
|
131
125
|
end
|
132
126
|
|
@@ -135,7 +129,7 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
135
129
|
cmd << 'upgrade'
|
136
130
|
cmd << "--version=#{expected_version}" if expected_version
|
137
131
|
cmd << "--force"
|
138
|
-
cmd <<
|
132
|
+
cmd << title
|
139
133
|
pmt cmd
|
140
134
|
end
|
141
135
|
|
@@ -154,7 +148,7 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
154
148
|
#
|
155
149
|
# @return [String] The stdout from the executed command
|
156
150
|
def pmt(argv)
|
157
|
-
argv = ['puppet', 'module', '--modulepath', @
|
151
|
+
argv = ['puppet', 'module', '--modulepath', @dirname, '--color', 'false'] + argv
|
158
152
|
|
159
153
|
subproc = R10K::Util::Subprocess.new(argv)
|
160
154
|
subproc.raise_on_fail = true
|
@@ -167,7 +161,16 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
167
161
|
|
168
162
|
def set_version_from_forge
|
169
163
|
repo = R10K::ModuleRepository::Forge.new
|
170
|
-
expected = repo.latest_version(
|
164
|
+
expected = repo.latest_version(title)
|
171
165
|
@expected_version = R10K::SemVer.new(expected)
|
172
166
|
end
|
167
|
+
|
168
|
+
# Override the base #parse_title to ensure we have a fully qualified name
|
169
|
+
def parse_title(title)
|
170
|
+
if (match = title.match(/\A(\w+)[-\/](\w+)\Z/))
|
171
|
+
[match[1], match[2]]
|
172
|
+
else
|
173
|
+
raise ArgumentError, "Forge module names must match 'owner/modulename'"
|
174
|
+
end
|
175
|
+
end
|
173
176
|
end
|
data/lib/r10k/module/git.rb
CHANGED
@@ -16,20 +16,24 @@ class R10K::Module::Git < R10K::Module::Base
|
|
16
16
|
# @return [R10K::Git::WorkingDir]
|
17
17
|
attr_reader :working_dir
|
18
18
|
|
19
|
-
def initialize(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@full_path = Pathname.new(File.join(basedir, name))
|
25
|
-
|
26
|
-
@working_dir = R10K::Git::WorkingDir.new(@ref, @remote, @basedir, @name)
|
19
|
+
def initialize(title, dirname, args)
|
20
|
+
super
|
21
|
+
parse_options(@args)
|
22
|
+
@working_dir = R10K::Git::WorkingDir.new(@ref, @remote, @dirname, @name)
|
27
23
|
end
|
28
24
|
|
29
25
|
def version
|
30
26
|
@ref
|
31
27
|
end
|
32
28
|
|
29
|
+
def properties
|
30
|
+
{
|
31
|
+
:expected => @ref,
|
32
|
+
:actual => (@working_dir.current.sha1 rescue "(unresolvable)"),
|
33
|
+
:type => :git,
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
33
37
|
def sync
|
34
38
|
case status
|
35
39
|
when :absent
|
@@ -65,7 +69,7 @@ class R10K::Module::Git < R10K::Module::Base
|
|
65
69
|
end
|
66
70
|
|
67
71
|
def uninstall
|
68
|
-
@
|
72
|
+
@path.rmtree
|
69
73
|
end
|
70
74
|
|
71
75
|
def parse_options(options)
|
data/lib/r10k/module/svn.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'r10k/module'
|
2
2
|
require 'r10k/execution'
|
3
3
|
require 'r10k/svn/working_dir'
|
4
|
+
require 'r10k/util/setopts'
|
4
5
|
|
5
6
|
class R10K::Module::SVN < R10K::Module::Base
|
6
7
|
|
@@ -15,22 +16,39 @@ class R10K::Module::SVN < R10K::Module::Base
|
|
15
16
|
attr_reader :expected_revision
|
16
17
|
alias expected_version expected_revision
|
17
18
|
|
18
|
-
# @!attribute [r] svn_path
|
19
|
-
# @return [String] The path inside of the SVN repository to have checked out
|
20
|
-
attr_reader :svn_path
|
21
|
-
|
22
19
|
# @!attribute [r] full_path
|
23
20
|
# @return [Pathname] The filesystem path to the SVN repo
|
24
21
|
attr_reader :full_path
|
25
22
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
23
|
+
# @!attribute [r] username
|
24
|
+
# @return [String, nil] The SVN username to be passed to the underlying SVN commands
|
25
|
+
# @api private
|
26
|
+
attr_reader :username
|
27
|
+
|
28
|
+
# @!attribute [r] password
|
29
|
+
# @return [String, nil] The SVN password to be passed to the underlying SVN commands
|
30
|
+
# @api private
|
31
|
+
attr_reader :password
|
32
|
+
|
33
|
+
# @!attribute [r] working_dir
|
34
|
+
# @return [R10K::SVN::WorkingDir]
|
35
|
+
# @api private
|
36
|
+
attr_reader :working_dir
|
37
|
+
|
38
|
+
include R10K::Util::Setopts
|
39
|
+
|
40
|
+
INITIALIZE_OPTS = {
|
41
|
+
:svn => :url,
|
42
|
+
:rev => :expected_revision,
|
43
|
+
:revision => :expected_revision,
|
44
|
+
:username => :self,
|
45
|
+
:password => :self
|
46
|
+
}
|
47
|
+
|
48
|
+
def initialize(name, dirname, opts)
|
49
|
+
super
|
50
|
+
setopts(opts, INITIALIZE_OPTS)
|
51
|
+
@working_dir = R10K::SVN::WorkingDir.new(@path, :username => @username, :password => @password)
|
34
52
|
end
|
35
53
|
|
36
54
|
def status
|
@@ -59,19 +77,27 @@ class R10K::Module::SVN < R10K::Module::Base
|
|
59
77
|
end
|
60
78
|
|
61
79
|
def exist?
|
62
|
-
|
80
|
+
path.exist?
|
81
|
+
end
|
82
|
+
|
83
|
+
def properties
|
84
|
+
{
|
85
|
+
:expected => expected_revision,
|
86
|
+
:actual => (@working_dir.revision rescue "(unresolvable)"),
|
87
|
+
:type => :svn,
|
88
|
+
}
|
63
89
|
end
|
64
90
|
|
65
91
|
private
|
66
92
|
|
67
93
|
def install
|
68
|
-
FileUtils.mkdir @
|
94
|
+
FileUtils.mkdir @dirname unless File.directory? @dirname
|
69
95
|
|
70
96
|
@working_dir.checkout(@url, @expected_revision)
|
71
97
|
end
|
72
98
|
|
73
99
|
def uninstall
|
74
|
-
|
100
|
+
path.rmtree
|
75
101
|
end
|
76
102
|
|
77
103
|
def reinstall
|
@@ -82,17 +108,4 @@ class R10K::Module::SVN < R10K::Module::Base
|
|
82
108
|
def update
|
83
109
|
@working_dir.update(@expected_revision)
|
84
110
|
end
|
85
|
-
|
86
|
-
def parse_options(hash)
|
87
|
-
hash.each_pair do |key, value|
|
88
|
-
case key
|
89
|
-
when :svn
|
90
|
-
@url = value
|
91
|
-
when :rev, :revision
|
92
|
-
@expected_revision = value
|
93
|
-
when :svn_path
|
94
|
-
@svn_path = value
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
111
|
end
|
data/lib/r10k/puppetfile.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
require 'pathname'
|
1
2
|
require 'r10k/module'
|
2
3
|
require 'r10k/util/purgeable'
|
4
|
+
require 'r10k/errors'
|
3
5
|
|
4
6
|
module R10K
|
5
7
|
class Puppetfile
|
@@ -49,6 +51,8 @@ class Puppetfile
|
|
49
51
|
def load!
|
50
52
|
dsl = R10K::Puppetfile::DSL.new(self)
|
51
53
|
dsl.instance_eval(puppetfile_contents, @puppetfile_path)
|
54
|
+
rescue SyntaxError, LoadError => e
|
55
|
+
raise R10K::Error.wrap(e, "Failed to evaluate #{@puppetfile_path}")
|
52
56
|
end
|
53
57
|
|
54
58
|
# @param [String] forge
|
@@ -58,7 +62,11 @@ class Puppetfile
|
|
58
62
|
|
59
63
|
# @param [String] moduledir
|
60
64
|
def set_moduledir(moduledir)
|
61
|
-
@moduledir = moduledir
|
65
|
+
@moduledir = if Pathname.new(moduledir).absolute?
|
66
|
+
moduledir
|
67
|
+
else
|
68
|
+
File.join(basedir, moduledir)
|
69
|
+
end
|
62
70
|
end
|
63
71
|
|
64
72
|
# @param [String] name
|
@@ -80,6 +88,14 @@ class Puppetfile
|
|
80
88
|
@modules.map { |mod| mod.name }
|
81
89
|
end
|
82
90
|
|
91
|
+
def accept(visitor)
|
92
|
+
visitor.visit(:puppetfile, self) do
|
93
|
+
modules.each do |mod|
|
94
|
+
mod.accept(visitor)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
83
99
|
private
|
84
100
|
|
85
101
|
def puppetfile_contents
|
data/lib/r10k/semver.rb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
# and instead use numeric comparisons (eg >, <, >=, <=)
|
5
5
|
# Ruby 1.8 already did this for all ranges, but Ruby 1.9 changed range include behavior
|
6
6
|
module R10K
|
7
|
+
# :nocov:
|
7
8
|
class SemVer < Numeric
|
8
9
|
include Comparable
|
9
10
|
|
@@ -123,4 +124,5 @@ class SemVer < Numeric
|
|
123
124
|
MAX.instance_variable_set(:@major, (1.0/0)) # => Infinity
|
124
125
|
MAX.instance_variable_set(:@vstring, 'vMAX')
|
125
126
|
end
|
127
|
+
# :nocov:
|
126
128
|
end
|
data/lib/r10k/source/base.rb
CHANGED
@@ -57,4 +57,12 @@ class R10K::Source::Base
|
|
57
57
|
def environments
|
58
58
|
raise NotImplementedError, "#{self.class} has not implemented method #{__method__}"
|
59
59
|
end
|
60
|
+
|
61
|
+
def accept(visitor)
|
62
|
+
visitor.visit(:source, self) do
|
63
|
+
environments.each do |env|
|
64
|
+
env.accept(visitor)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
60
68
|
end
|
data/lib/r10k/source/git.rb
CHANGED
@@ -63,7 +63,7 @@ class R10K::Source::Git < R10K::Source::Base
|
|
63
63
|
#
|
64
64
|
# @return [void]
|
65
65
|
def preload!
|
66
|
-
logger.
|
66
|
+
logger.debug "Determining current branches for Git source #{@remote.inspect}"
|
67
67
|
@cache.sync
|
68
68
|
end
|
69
69
|
alias fetch_remote preload!
|
data/lib/r10k/source/svn.rb
CHANGED
@@ -2,6 +2,7 @@ require 'r10k/svn'
|
|
2
2
|
require 'r10k/environment'
|
3
3
|
require 'r10k/util/purgeable'
|
4
4
|
require 'r10k/util/core_ext/hash_ext'
|
5
|
+
require 'r10k/util/setopts'
|
5
6
|
|
6
7
|
# This class implements a source for SVN environments.
|
7
8
|
#
|
@@ -27,6 +28,18 @@ class R10K::Source::SVN < R10K::Source::Base
|
|
27
28
|
# @return [R10K::SVN::Remote]
|
28
29
|
attr_reader :svn_remote
|
29
30
|
|
31
|
+
# @!attribute [r] username
|
32
|
+
# @return [String, nil] The SVN username to be passed to the underlying SVN commands
|
33
|
+
# @api private
|
34
|
+
attr_reader :username
|
35
|
+
|
36
|
+
# @!attribute [r] password
|
37
|
+
# @return [String, nil] The SVN password to be passed to the underlying SVN commands
|
38
|
+
# @api private
|
39
|
+
attr_reader :password
|
40
|
+
|
41
|
+
include R10K::Util::Setopts
|
42
|
+
|
30
43
|
# Initialize the given source.
|
31
44
|
#
|
32
45
|
# @param name [String] The identifier for this source.
|
@@ -36,13 +49,14 @@ class R10K::Source::SVN < R10K::Source::Base
|
|
36
49
|
# @option options [Boolean] :prefix Whether to prefix the source name to the
|
37
50
|
# environment directory names. Defaults to false.
|
38
51
|
# @option options [String] :remote The URL to the base directory of the SVN repository
|
52
|
+
# @option options [String] :username The SVN username
|
53
|
+
# @option options [String] :password The SVN password
|
39
54
|
def initialize(name, basedir, options = {})
|
40
55
|
super
|
41
56
|
|
42
|
-
|
57
|
+
setopts(options, {:remote => :self, :username => :self, :password => :self})
|
43
58
|
@environments = []
|
44
|
-
|
45
|
-
@svn_remote = R10K::SVN::Remote.new(@remote)
|
59
|
+
@svn_remote = R10K::SVN::Remote.new(@remote, :username => @username, :password => @password)
|
46
60
|
end
|
47
61
|
|
48
62
|
# Enumerate the environments associated with this SVN source.
|
@@ -67,8 +81,12 @@ class R10K::Source::SVN < R10K::Source::Base
|
|
67
81
|
def generate_environments
|
68
82
|
|
69
83
|
branch_names.map do |branch|
|
70
|
-
|
71
|
-
|
84
|
+
options = {
|
85
|
+
:remote => branch.remote,
|
86
|
+
:username => @username,
|
87
|
+
:password => @password
|
88
|
+
}
|
89
|
+
R10K::Environment::SVN.new(branch.name, @basedir, branch.dirname, options)
|
72
90
|
end
|
73
91
|
end
|
74
92
|
|
data/lib/r10k/svn/remote.rb
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
require 'r10k/util/subprocess'
|
2
|
+
require 'r10k/util/setopts'
|
2
3
|
|
4
|
+
# Inspect and interact with SVN remote repositories
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
# @since 1.3.0
|
3
8
|
class R10K::SVN::Remote
|
4
9
|
|
5
|
-
|
10
|
+
include R10K::Util::Setopts
|
11
|
+
|
12
|
+
def initialize(baseurl, opts = {})
|
6
13
|
@baseurl = baseurl
|
14
|
+
setopts(opts, {:username => :self, :password => :self})
|
7
15
|
end
|
8
16
|
|
9
17
|
# @todo validate that the path to trunk exists in the remote
|
@@ -13,7 +21,9 @@ class R10K::SVN::Remote
|
|
13
21
|
|
14
22
|
# @todo gracefully handle cases where no branches exist
|
15
23
|
def branches
|
16
|
-
|
24
|
+
argv = ['ls', "#{@baseurl}/branches"]
|
25
|
+
argv.concat(auth)
|
26
|
+
text = svn(argv)
|
17
27
|
text.lines.map do |line|
|
18
28
|
line.chomp!
|
19
29
|
line.gsub!(%r[/$], '')
|
@@ -23,6 +33,16 @@ class R10K::SVN::Remote
|
|
23
33
|
|
24
34
|
private
|
25
35
|
|
36
|
+
# Format authentication information for SVN command args, if applicable
|
37
|
+
def auth
|
38
|
+
auth = []
|
39
|
+
if @username
|
40
|
+
auth << "--username" << @username
|
41
|
+
auth << "--password" << @password
|
42
|
+
end
|
43
|
+
auth
|
44
|
+
end
|
45
|
+
|
26
46
|
include R10K::Logging
|
27
47
|
|
28
48
|
# Wrap SVN commands
|
@@ -34,7 +54,7 @@ class R10K::SVN::Remote
|
|
34
54
|
#
|
35
55
|
# @return [String] The stdout from the given command
|
36
56
|
def svn(argv, opts = {})
|
37
|
-
argv.unshift('svn')
|
57
|
+
argv.unshift('svn', '--non-interactive')
|
38
58
|
|
39
59
|
subproc = R10K::Util::Subprocess.new(argv)
|
40
60
|
subproc.raise_on_fail = true
|