r10k 2.5.5 → 2.6.0
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.
- checksums.yaml +13 -5
- data/.travis.yml +1 -0
- data/CHANGELOG.mkd +20 -0
- data/doc/dynamic-environments/configuration.mkd +26 -0
- data/doc/puppetfile.mkd +1 -1
- data/integration/lib/r10k_utils.rb +11 -0
- data/integration/tests/git_source/HTTP_proxy_and_git_source.rb +1 -3
- data/lib/r10k/action/deploy/environment.rb +6 -2
- data/lib/r10k/action/deploy/module.rb +13 -2
- data/lib/r10k/action/puppetfile/cri_runner.rb +7 -1
- data/lib/r10k/action/puppetfile/install.rb +4 -3
- data/lib/r10k/cli/deploy.rb +1 -0
- data/lib/r10k/cli/puppetfile.rb +1 -2
- data/lib/r10k/forge/module_release.rb +98 -14
- data/lib/r10k/initializers.rb +1 -0
- data/lib/r10k/module/forge.rb +2 -2
- data/lib/r10k/puppetfile.rb +8 -1
- data/lib/r10k/settings.rb +4 -0
- data/lib/r10k/source/git.rb +24 -2
- data/lib/r10k/source/svn.rb +24 -4
- data/lib/r10k/util/setopts.rb +4 -2
- data/lib/r10k/version.rb +1 -1
- data/r10k.gemspec +1 -2
- data/spec/shared-examples/puppetfile-action.rb +22 -0
- data/spec/unit/action/deploy/environment_spec.rb +12 -0
- data/spec/unit/action/deploy/module_spec.rb +13 -0
- data/spec/unit/action/puppetfile/install_spec.rb +19 -5
- data/spec/unit/forge/module_release_spec.rb +80 -10
- data/spec/unit/source/git_spec.rb +34 -0
- data/spec/unit/source/svn_spec.rb +28 -0
- metadata +29 -43
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NTZjY2UzMDMyMTJlNjIzZmQzNzk4MGViMGMzMjM0Yzc2MzdkZjg2MQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YTE1ZjhkYzBiZjY1YTFiOGUyMTliM2Q2MDAzNzg3YzA4NjUyN2Q0Ng==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NDRiNTI5NDA3NGQzNmVjODZjN2NlNmMyYjVjMjVjM2ZkYjNiMmY0ZWUyMjNj
|
10
|
+
NWI1NjExNTk2NDJhM2M0NjFlN2ExZTVmNGU5MzRmNjJjYWY1NzliMGY2Mzgy
|
11
|
+
NmUyN2FlNzZjMDAwMWFhMTdmZDA4ZTY4NThiZTBlMmM5MWZjOGE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MmM4YzFlNTBmNTYyMzMxYjA0Zjc2YWU0OTJlMzQ1YzFmM2E2NDEzZGM2MWZi
|
14
|
+
NTczNzVhODdhNTc0Yjg0OWVhYjIxOTUwY2NkOTUyYmY0MzMyY2FhNDc1Mzhj
|
15
|
+
YWNlYTVjMGMwYjJmNjUwMDIxMTFiOTg4NTE4Yjk3ODVlNjg3Mzg=
|
data/.travis.yml
CHANGED
data/CHANGELOG.mkd
CHANGED
@@ -1,6 +1,26 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
=========
|
3
3
|
|
4
|
+
2.6.0
|
5
|
+
-----
|
6
|
+
|
7
|
+
### New Features
|
8
|
+
|
9
|
+
(RK-307) Branches can now be ignored by prefixes during deployment.
|
10
|
+
|
11
|
+
(RK-305) Add --no-force to deploy action to avoid overwriting local module changes.
|
12
|
+
|
13
|
+
(RK-264) Add --force action to puppetfile install to force overwriting local
|
14
|
+
module changes.
|
15
|
+
|
16
|
+
(RK-291) (RK-304) Add caching of forge modules.
|
17
|
+
|
18
|
+
### Changes
|
19
|
+
|
20
|
+
(RK-306) Remove the dependency on semantic_puppet.
|
21
|
+
|
22
|
+
(RK-161) Deprecate the usage of PUPPETFILE and PUPPETFILE_DIR environment variables.
|
23
|
+
|
4
24
|
2.5.5
|
5
25
|
-----
|
6
26
|
|
@@ -356,6 +356,32 @@ sources:
|
|
356
356
|
* if `false` (default) environment folder will not be prefixed
|
357
357
|
* if `String` environment folder will be prefixed with the `prefix` value.
|
358
358
|
|
359
|
+
### ignore_branch_prefixes
|
360
|
+
|
361
|
+
The 'ignore_branch_prefixes' setting causes environments to be ignored which match in part or whole
|
362
|
+
to any of the prefixes listed in the setting.
|
363
|
+
The setting is a list of strings. Each branch in
|
364
|
+
the 'git' repo will have its name tested against all prefixes and, if the prefix
|
365
|
+
is found, then an environment will not be deployed for this branch.
|
366
|
+
If no 'ignore_branch_prefixes' is specified, then all branches in the 'git' repo will
|
367
|
+
be deployed (default behavior).
|
368
|
+
|
369
|
+
#### ignore_branch_prefixes behaviour
|
370
|
+
* if empty, deploy environments for all branches
|
371
|
+
* for each branch in git repo
|
372
|
+
** if `branch.name` has a prefix found in `ignore_branch_prefixes`, then do not deploy an environment for branch
|
373
|
+
|
374
|
+
Example: do not deploy branches with names starting with (or completely named) 'test' or 'dev'.
|
375
|
+
```yaml
|
376
|
+
---
|
377
|
+
sources:
|
378
|
+
mysource:
|
379
|
+
basedir: '/etc/puppet/environments'
|
380
|
+
ignore_branch_prefixes:
|
381
|
+
- 'test'
|
382
|
+
- 'dev'
|
383
|
+
```
|
384
|
+
|
359
385
|
Examples
|
360
386
|
--------
|
361
387
|
|
data/doc/puppetfile.mkd
CHANGED
@@ -306,7 +306,7 @@ The given 'install\_path' can be an absolute path or a path relative to the base
|
|
306
306
|
the environment. Note that r10k will exit with an error if you attempt to set the
|
307
307
|
'path' option to a directory outside of the environment.
|
308
308
|
|
309
|
-
## Environment variables
|
309
|
+
## Environment variables (**DEPRECATED** as of 2.5.6)
|
310
310
|
|
311
311
|
It is possible to set an alternate name/location for your `Puppetfile` and
|
312
312
|
`modules` directory. This is useful if you want to control multiple environments
|
@@ -76,6 +76,10 @@ def r10k_revert_environment(host, commit_sha, git_repo_path)
|
|
76
76
|
#Force push changes to remote.
|
77
77
|
git_on(host, 'push origin --mirror --force', git_repo_path)
|
78
78
|
git_on(host, 'push origin --mirror --force', git_repo_path)
|
79
|
+
|
80
|
+
#Remove r10k cache
|
81
|
+
cachedir = '/var/cache/r10k'
|
82
|
+
on(master, "rm -rf #{cachedir}")
|
79
83
|
end
|
80
84
|
|
81
85
|
# Clean-up the r10k environment on the master to bring it back to a known good state.
|
@@ -102,6 +106,13 @@ def clean_up_r10k(master, commit_sha, git_repo_path)
|
|
102
106
|
step 'Reset Git Repo to Known Good State'
|
103
107
|
r10k_revert_environment(master, commit_sha, git_repo_path)
|
104
108
|
|
109
|
+
# RK-297 workaround. Without this, tests will fail with an error like the following:
|
110
|
+
# [2017-06-02 11:11:46 - ERROR] Object not found - no match for id (60e4ea82c9fdf86974a13f78b839a497325de04b)
|
111
|
+
# This cleanup should not be necessary when RK-297 has been resolved.
|
112
|
+
#
|
113
|
+
step 'Remove git directories from codedir to prevent cache errors'
|
114
|
+
on(master, "find #{environment_path } -name .git -type d -print0 | xargs -r0 -- rm -r")
|
115
|
+
|
105
116
|
step 'Restore Original "production" Environment'
|
106
117
|
on(master, "#{r10k_fqp} deploy environment -v")
|
107
118
|
|
@@ -66,7 +66,5 @@ git_add_commit_push(master, 'production', 'add Puppetfile', git_environments_pat
|
|
66
66
|
on(master, "#{r10k_fqp} deploy environment -p", :accept_all_exit_codes => true) do |r|
|
67
67
|
regex = /proxy.*ilovecatvideos\.com/
|
68
68
|
assert(r.exit_code == 1, 'expected error code was not observed')
|
69
|
-
|
70
|
-
assert_match(regex, r.stderr, 'The expected error message was not observed' )
|
71
|
-
end
|
69
|
+
assert_match(regex, r.stderr, 'The expected error message was not observed' )
|
72
70
|
end
|
@@ -13,6 +13,8 @@ module R10K
|
|
13
13
|
|
14
14
|
include R10K::Action::Deploy::DeployHelpers
|
15
15
|
|
16
|
+
attr_reader :force
|
17
|
+
|
16
18
|
def initialize(opts, argv, settings = nil)
|
17
19
|
settings ||= {}
|
18
20
|
@purge_levels = settings.fetch(:deploy, {}).fetch(:purge_levels, [])
|
@@ -20,6 +22,8 @@ module R10K
|
|
20
22
|
|
21
23
|
super
|
22
24
|
|
25
|
+
# @force here is used to make it easier to reason about
|
26
|
+
@force = !@no_force
|
23
27
|
@argv = @argv.map { |arg| arg.gsub(/\W/,'_') }
|
24
28
|
end
|
25
29
|
|
@@ -117,7 +121,7 @@ module R10K
|
|
117
121
|
|
118
122
|
def visit_module(mod)
|
119
123
|
logger.info _("Deploying Puppetfile content %{mod_path}") % {mod_path: mod.path}
|
120
|
-
mod.sync
|
124
|
+
mod.sync(force: @force)
|
121
125
|
end
|
122
126
|
|
123
127
|
def write_environment_info!(environment, started_at, success)
|
@@ -142,7 +146,7 @@ module R10K
|
|
142
146
|
end
|
143
147
|
|
144
148
|
def allowed_initialize_opts
|
145
|
-
super.merge(puppetfile: :self, cachedir: :self)
|
149
|
+
super.merge(puppetfile: :self, cachedir: :self, :'no-force' => :self)
|
146
150
|
end
|
147
151
|
end
|
148
152
|
end
|
@@ -10,6 +10,17 @@ module R10K
|
|
10
10
|
|
11
11
|
include R10K::Action::Deploy::DeployHelpers
|
12
12
|
|
13
|
+
attr_reader :force
|
14
|
+
|
15
|
+
def initialize(opts, argv, settings = nil)
|
16
|
+
settings ||= {}
|
17
|
+
|
18
|
+
super
|
19
|
+
|
20
|
+
# @force here is used to make it easier to reason about
|
21
|
+
@force = !@no_force
|
22
|
+
end
|
23
|
+
|
13
24
|
def call
|
14
25
|
@visit_ok = true
|
15
26
|
|
@@ -50,14 +61,14 @@ module R10K
|
|
50
61
|
def visit_module(mod)
|
51
62
|
if @argv.include?(mod.name)
|
52
63
|
logger.info _("Deploying module %{mod_path}") % {mod_path: mod.path}
|
53
|
-
mod.sync
|
64
|
+
mod.sync(force: @force)
|
54
65
|
else
|
55
66
|
logger.debug1(_("Only updating modules %{modules}, skipping module %{mod_name}") % {modules: @argv.inspect, mod_name: mod.name})
|
56
67
|
end
|
57
68
|
end
|
58
69
|
|
59
70
|
def allowed_initialize_opts
|
60
|
-
super.merge(environment: true)
|
71
|
+
super.merge(environment: true, :'no-force' => :self)
|
61
72
|
end
|
62
73
|
end
|
63
74
|
end
|
@@ -8,10 +8,16 @@ module R10K
|
|
8
8
|
#
|
9
9
|
# @api private
|
10
10
|
# @deprecated The use of these environment variables is deprecated and
|
11
|
-
# will be removed in
|
11
|
+
# will be removed in 3.0.0.
|
12
12
|
class CriRunner < R10K::Action::CriRunner
|
13
|
+
|
14
|
+
include R10K::Logging
|
15
|
+
|
13
16
|
def handle_opts(opts)
|
14
17
|
opts[:root] ||= wd
|
18
|
+
if env['PUPPETFILE_DIR'] || env['PUPPETFILE']
|
19
|
+
logger.warn _("The use of the PUPPETFILE and PUPPETFILE_DIR environment variables is deprecated.")
|
20
|
+
end
|
15
21
|
opts[:moduledir] ||= env['PUPPETFILE_DIR']
|
16
22
|
opts[:puppetfile] ||= env['PUPPETFILE']
|
17
23
|
super(opts)
|
@@ -10,7 +10,7 @@ module R10K
|
|
10
10
|
|
11
11
|
def call
|
12
12
|
@visit_ok = true
|
13
|
-
pf = R10K::Puppetfile.new(@root, @moduledir, @puppetfile)
|
13
|
+
pf = R10K::Puppetfile.new(@root, @moduledir, @puppetfile, nil , @force)
|
14
14
|
pf.accept(self)
|
15
15
|
@visit_ok
|
16
16
|
end
|
@@ -26,17 +26,18 @@ module R10K
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def visit_module(mod)
|
29
|
+
@force ||= false
|
29
30
|
logger.info _("Updating module %{mod_path}") % {mod_path: mod.path}
|
30
31
|
|
31
32
|
if mod.respond_to?(:desired_ref) && mod.desired_ref == :control_branch
|
32
33
|
logger.warn _("Cannot track control repo branch for content '%{name}' when not part of a 'deploy' action, will use default if available." % {name: mod.name})
|
33
34
|
end
|
34
35
|
|
35
|
-
mod.sync(force:
|
36
|
+
mod.sync(force: @force)
|
36
37
|
end
|
37
38
|
|
38
39
|
def allowed_initialize_opts
|
39
|
-
super.merge(root: :self, puppetfile: :self, moduledir: :self)
|
40
|
+
super.merge(root: :self, puppetfile: :self, moduledir: :self, force: :self )
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
data/lib/r10k/cli/deploy.rb
CHANGED
@@ -22,6 +22,7 @@ module R10K::CLI
|
|
22
22
|
DESCRIPTION
|
23
23
|
|
24
24
|
required nil, :cachedir, 'Specify a cachedir, overriding the value in config'
|
25
|
+
flag nil, :'no-force', 'Prevent the overwriting of local module modifications'
|
25
26
|
|
26
27
|
run do |opts, args, cmd|
|
27
28
|
puts cmd.help(:verbose => opts[:verbose])
|
data/lib/r10k/cli/puppetfile.rb
CHANGED
@@ -30,10 +30,9 @@ Puppetfile (http://bombasticmonkey.com/librarian-puppet/).
|
|
30
30
|
name 'install'
|
31
31
|
usage 'install'
|
32
32
|
summary 'Install all modules from a Puppetfile'
|
33
|
-
|
34
33
|
required nil, :moduledir, 'Path to install modules to'
|
35
34
|
required nil, :puppetfile, 'Path to puppetfile'
|
36
|
-
|
35
|
+
flag nil, :force, 'Force locally changed files to be overwritten'
|
37
36
|
runner R10K::Action::Puppetfile::CriRunner.wrap(R10K::Action::Puppetfile::Install)
|
38
37
|
end
|
39
38
|
end
|
@@ -13,6 +13,7 @@ module R10K
|
|
13
13
|
|
14
14
|
def_setting_attr :proxy
|
15
15
|
def_setting_attr :baseurl
|
16
|
+
def_setting_attr :cache_root, File.expand_path(ENV['HOME'] ? '~/.r10k/cache': '/root/.r10k/cache')
|
16
17
|
|
17
18
|
include R10K::Logging
|
18
19
|
|
@@ -27,6 +28,18 @@ module R10K
|
|
27
28
|
# @return [Pathname] Where the module tarball will be downloaded to.
|
28
29
|
attr_accessor :download_path
|
29
30
|
|
31
|
+
# @!attribute [rw] tarball_cache_path
|
32
|
+
# @return [Pathname] Where the module tarball will be cached to.
|
33
|
+
attr_accessor :tarball_cache_path
|
34
|
+
|
35
|
+
# @!attribute [rw] tarball_cache_root
|
36
|
+
# @return [Pathname] Directory where the module tarball will be cached to.
|
37
|
+
attr_accessor :tarball_cache_root
|
38
|
+
|
39
|
+
# @!attribute [rw] md5_file_path
|
40
|
+
# @return [Pathname] Where the md5 of the cached tarball is stored.
|
41
|
+
attr_accessor :md5_file_path
|
42
|
+
|
30
43
|
# @!attribute [rw] unpack_path
|
31
44
|
# @return [Pathname] Where the module will be unpacked to.
|
32
45
|
attr_accessor :unpack_path
|
@@ -41,9 +54,17 @@ module R10K
|
|
41
54
|
# objects are created in the class instances and thus are not shared with
|
42
55
|
# subclasses.
|
43
56
|
PuppetForge::V3::Release.conn = PuppetForge::V3::Base.conn
|
57
|
+
|
44
58
|
@forge_release = PuppetForge::V3::Release.new({ :name => @full_name, :version => @version, :slug => "#{@full_name}-#{@version}" })
|
45
59
|
|
46
|
-
|
60
|
+
tarball_name = @forge_release.slug + '.tar.gz'
|
61
|
+
@download_path = Pathname.new(Dir.mktmpdir) + (tarball_name)
|
62
|
+
@tarball_cache_root = Pathname.new(settings[:cache_root]) + (@forge_release.slug + "/tarball/")
|
63
|
+
@tarball_cache_path = @tarball_cache_root + tarball_name
|
64
|
+
|
65
|
+
md5_filename = @forge_release.slug + '.md5'
|
66
|
+
@md5_file_path = @tarball_cache_root + md5_filename
|
67
|
+
|
47
68
|
@unpack_path = Pathname.new(Dir.mktmpdir) + @forge_release.slug
|
48
69
|
end
|
49
70
|
|
@@ -65,34 +86,83 @@ module R10K
|
|
65
86
|
cleanup
|
66
87
|
end
|
67
88
|
|
68
|
-
# Download the module release to {#download_path}
|
89
|
+
# Download the module release to {#download_path} and cache to {#tarball_cache_path}
|
69
90
|
#
|
70
91
|
# @return [void]
|
71
92
|
def download
|
72
|
-
|
73
|
-
|
93
|
+
if @tarball_cache_path.exist?
|
94
|
+
logger.debug1 "Using cached copy of #{@forge_release.slug} tarball"
|
95
|
+
else
|
96
|
+
logger.debug1 "Downloading #{@forge_release.slug} from #{PuppetForge::Release.conn.url_prefix} to #{@download_path}"
|
97
|
+
@forge_release.download(download_path)
|
98
|
+
FileUtils::mkdir_p(@tarball_cache_root)
|
99
|
+
FileUtils::mv(@download_path, @tarball_cache_path)
|
100
|
+
end
|
74
101
|
end
|
75
102
|
|
76
|
-
# Verify the module release
|
77
|
-
# module release checksum given by the Puppet Forge
|
103
|
+
# Verify the module release cached in {#tarball_cache_path} against the
|
104
|
+
# module release checksum given by the Puppet Forge. On mismatch, remove
|
105
|
+
# the cached copy.
|
78
106
|
#
|
79
|
-
# @raise [PuppetForge::V3::Release::ChecksumMismatch] The
|
80
|
-
# downloaded module release checksum doesn't match the expected Forge
|
81
|
-
# module release checksum.
|
82
107
|
# @return [void]
|
83
108
|
def verify
|
84
|
-
logger.debug1 "Verifying that #{
|
85
|
-
|
109
|
+
logger.debug1 "Verifying that #{@tarball_cache_path} matches checksum"
|
110
|
+
|
111
|
+
md5_of_tarball = Digest::MD5.hexdigest(File.read(@tarball_cache_path))
|
112
|
+
|
113
|
+
if @md5_file_path.exist?
|
114
|
+
verify_from_md5_file(md5_of_tarball)
|
115
|
+
else
|
116
|
+
verify_from_forge(md5_of_tarball)
|
117
|
+
end
|
86
118
|
end
|
87
119
|
|
88
|
-
#
|
120
|
+
# Verify the md5 of the cached tarball against the
|
121
|
+
# module release checksum stored in the cache as well.
|
122
|
+
# On mismatch, remove the cached copy of both files.
|
123
|
+
#
|
124
|
+
# @raise [PuppetForge::V3::Release::ChecksumMismatch] The
|
125
|
+
# cached module release checksum doesn't match the cached checksum.
|
126
|
+
#
|
127
|
+
# @return [void]
|
128
|
+
def verify_from_md5_file(md5_of_tarball)
|
129
|
+
md5_from_file = File.read(@md5_file_path).strip
|
130
|
+
if md5_of_tarball != md5_from_file
|
131
|
+
logger.error "MD5 of #{@tarball_cache_path} (#{md5_of_tarball}) does not match checksum #{md5_from_file} in #{@md5_file_path}. Removing both files."
|
132
|
+
cleanup_cached_tarball_path
|
133
|
+
cleanup_md5_file_path
|
134
|
+
raise PuppetForge::V3::Release::ChecksumMismatch.new
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Verify the md5 of the cached tarball against the
|
139
|
+
# module release checksum from the forge.
|
140
|
+
# On mismatch, remove the cached copy of the tarball.
|
141
|
+
#
|
142
|
+
# @raise [PuppetForge::V3::Release::ChecksumMismatch] The
|
143
|
+
# cached module release checksum doesn't match the forge checksum.
|
144
|
+
#
|
145
|
+
# @return [void]
|
146
|
+
def verify_from_forge(md5_of_tarball)
|
147
|
+
md5_from_forge = @forge_release.file_md5
|
148
|
+
#compare file_md5 to md5_of_tarball
|
149
|
+
if md5_of_tarball != md5_from_forge
|
150
|
+
logger.debug1 "MD5 of #{@tarball_cache_path} (#{md5_of_tarball}) does not match checksum #{md5_from_forge} found on the forge. Removing tarball."
|
151
|
+
cleanup_cached_tarball_path
|
152
|
+
raise PuppetForge::V3::Release::ChecksumMismatch.new
|
153
|
+
else
|
154
|
+
File.write(@md5_file_path, md5_from_forge)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Unpack the module release at {#tarball_cache_path} into the given target_dir
|
89
159
|
#
|
90
160
|
# @param target_dir [Pathname] The final path where the module release
|
91
161
|
# should be unpacked/installed into.
|
92
162
|
# @return [void]
|
93
163
|
def unpack(target_dir)
|
94
|
-
logger.debug1 _("Unpacking %{
|
95
|
-
file_lists = PuppetForge::Unpacker.unpack(
|
164
|
+
logger.debug1 _("Unpacking %{tarball_cache_path} to %{target_dir} (with tmpdir %{tmp_path})") % {tarball_cache_path: tarball_cache_path, target_dir: target_dir, tmp_path: unpack_path}
|
165
|
+
file_lists = PuppetForge::Unpacker.unpack(tarball_cache_path.to_s, target_dir.to_s, unpack_path.to_s)
|
96
166
|
logger.debug2 _("Valid files unpacked: %{valid_files}") % {valid_files: file_lists[:valid]}
|
97
167
|
if !file_lists[:invalid].empty?
|
98
168
|
logger.debug1 _("These files existed in the module's tar file, but are invalid filetypes and were not unpacked: %{invalid_files}") % {invalid_files: file_lists[:invalid]}
|
@@ -121,6 +191,20 @@ module R10K
|
|
121
191
|
download_path.delete
|
122
192
|
end
|
123
193
|
end
|
194
|
+
|
195
|
+
# Remove the cached module release.
|
196
|
+
def cleanup_cached_tarball_path
|
197
|
+
if tarball_cache_path.exist?
|
198
|
+
tarball_cache_path.delete
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Remove the module release md5.
|
203
|
+
def cleanup_md5_file_path
|
204
|
+
if md5_file_path.exist?
|
205
|
+
md5_file_path.delete
|
206
|
+
end
|
207
|
+
end
|
124
208
|
end
|
125
209
|
end
|
126
210
|
end
|
data/lib/r10k/initializers.rb
CHANGED
@@ -31,6 +31,7 @@ module R10K
|
|
31
31
|
end
|
32
32
|
|
33
33
|
with_setting(:cachedir) { |value| R10K::Git::Cache.settings[:cache_root] = value }
|
34
|
+
with_setting(:cachedir) { |value| R10K::Forge::ModuleRelease.settings[:cache_root] = value }
|
34
35
|
|
35
36
|
with_setting(:git) { |value| GitInitializer.new(value).call }
|
36
37
|
with_setting(:forge) { |value| ForgeInitializer.new(value).call }
|
data/lib/r10k/module/forge.rb
CHANGED
@@ -6,7 +6,7 @@ require 'r10k/forge/module_release'
|
|
6
6
|
|
7
7
|
require 'pathname'
|
8
8
|
require 'fileutils'
|
9
|
-
require 'puppet_forge'
|
9
|
+
require 'puppet_forge/util'
|
10
10
|
|
11
11
|
class R10K::Module::Forge < R10K::Module::Base
|
12
12
|
|
@@ -17,7 +17,7 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.valid_version?(expected_version)
|
20
|
-
expected_version == :latest || expected_version.nil? ||
|
20
|
+
expected_version == :latest || expected_version.nil? || PuppetForge::Util.version_valid?(expected_version)
|
21
21
|
end
|
22
22
|
|
23
23
|
# @!attribute [r] metadata
|
data/lib/r10k/puppetfile.rb
CHANGED
@@ -33,11 +33,18 @@ class Puppetfile
|
|
33
33
|
# @return [R10K::Environment] Optional R10K::Environment that this Puppetfile belongs to.
|
34
34
|
attr_accessor :environment
|
35
35
|
|
36
|
+
# @!attribute [rw] force
|
37
|
+
# @return [Boolean] Overwrite any locally made changes
|
38
|
+
attr_accessor :force
|
39
|
+
|
36
40
|
# @param [String] basedir
|
37
41
|
# @param [String] moduledir The directory to install the modules, default to #{basedir}/modules
|
38
42
|
# @param [String] puppetfile_path The path to the Puppetfile, default to #{basedir}/Puppetfile
|
39
|
-
|
43
|
+
# @param [String] puppetfile_name The name of the Puppetfile, default to 'Puppetfile'
|
44
|
+
# @param [Boolean] force Shall we overwrite locally made changes?
|
45
|
+
def initialize(basedir, moduledir = nil, puppetfile_path = nil, puppetfile_name = nil, force = nil )
|
40
46
|
@basedir = basedir
|
47
|
+
@force = force || false
|
41
48
|
@moduledir = moduledir || File.join(basedir, 'modules')
|
42
49
|
@puppetfile_path = puppetfile_path || File.join(basedir, 'Puppetfile')
|
43
50
|
|
data/lib/r10k/settings.rb
CHANGED
@@ -51,6 +51,10 @@ module R10K
|
|
51
51
|
:desc => "An optional proxy server to use when interacting with Git sources via HTTP(S).",
|
52
52
|
:default => :inherit,
|
53
53
|
}),
|
54
|
+
|
55
|
+
Definition.new(:ignore_branch_prefixes, {
|
56
|
+
:desc => "Array of strings used to prefix branch names that will not be deployed as environments.",
|
57
|
+
}),
|
54
58
|
])
|
55
59
|
},
|
56
60
|
{
|
data/lib/r10k/source/git.rb
CHANGED
@@ -36,6 +36,11 @@ class R10K::Source::Git < R10K::Source::Base
|
|
36
36
|
# Puppet environments will be handled.
|
37
37
|
attr_reader :invalid_branches
|
38
38
|
|
39
|
+
# @!attribute [r] ignore_branch_prefixes
|
40
|
+
# @return [Array<String>] Array of strings used to remove repository branches
|
41
|
+
# that will be deployed as environments.
|
42
|
+
attr_reader :ignore_branch_prefixes
|
43
|
+
|
39
44
|
# Initialize the given source.
|
40
45
|
#
|
41
46
|
# @param name [String] The identifier for this source.
|
@@ -53,8 +58,9 @@ class R10K::Source::Git < R10K::Source::Base
|
|
53
58
|
|
54
59
|
@environments = []
|
55
60
|
|
56
|
-
@remote
|
61
|
+
@remote = options[:remote]
|
57
62
|
@invalid_branches = (options[:invalid_branches] || 'correct_and_warn')
|
63
|
+
@ignore_branch_prefixes = options[:ignore_branch_prefixes]
|
58
64
|
|
59
65
|
@cache = R10K::Git.cache.generate(@remote)
|
60
66
|
end
|
@@ -109,11 +115,27 @@ class R10K::Source::Git < R10K::Source::Base
|
|
109
115
|
environments.map {|env| env.dirname }
|
110
116
|
end
|
111
117
|
|
118
|
+
def filter_branches(branches, ignore_prefixes)
|
119
|
+
filter = Regexp.new("^#{Regexp.union(ignore_prefixes)}")
|
120
|
+
branches = branches.reject do |branch|
|
121
|
+
result = filter.match(branch)
|
122
|
+
if result
|
123
|
+
logger.warn _("Branch %{branch} filtered out by ignore_branch_prefixes %{ibp}") % {branch: branch, ibp: @ignore_branch_prefixes}
|
124
|
+
end
|
125
|
+
result
|
126
|
+
end
|
127
|
+
branches
|
128
|
+
end
|
129
|
+
|
112
130
|
private
|
113
131
|
|
114
132
|
def branch_names
|
115
133
|
opts = {:prefix => @prefix, :invalid => @invalid_branches, :source => @name}
|
116
|
-
@cache.branches
|
134
|
+
branches = @cache.branches
|
135
|
+
if @ignore_branch_prefixes && !@ignore_branch_prefixes.empty?
|
136
|
+
branches = filter_branches(branches, @ignore_branch_prefixes)
|
137
|
+
end
|
138
|
+
branches.map do |branch|
|
117
139
|
R10K::Environment::Name.new(branch, opts)
|
118
140
|
end
|
119
141
|
end
|
data/lib/r10k/source/svn.rb
CHANGED
@@ -37,6 +37,11 @@ class R10K::Source::SVN < R10K::Source::Base
|
|
37
37
|
# @api private
|
38
38
|
attr_reader :password
|
39
39
|
|
40
|
+
# @!attribute [r] ignore_branch_prefixes
|
41
|
+
# @return [Array<String>] Array of strings used to remove repository branches
|
42
|
+
# that will be deployed as environments.
|
43
|
+
attr_reader :ignore_branch_prefixes
|
44
|
+
|
40
45
|
include R10K::Util::Setopts
|
41
46
|
|
42
47
|
# Initialize the given source.
|
@@ -56,6 +61,7 @@ class R10K::Source::SVN < R10K::Source::Base
|
|
56
61
|
setopts(options, {:remote => :self, :username => :self, :password => :self})
|
57
62
|
@environments = []
|
58
63
|
@svn_remote = R10K::SVN::Remote.new(@remote, :username => @username, :password => @password)
|
64
|
+
@ignore_branch_prefixes = options[:ignore_branch_prefixes]
|
59
65
|
end
|
60
66
|
|
61
67
|
# Enumerate the environments associated with this SVN source.
|
@@ -97,18 +103,32 @@ class R10K::Source::SVN < R10K::Source::Base
|
|
97
103
|
|
98
104
|
include R10K::Logging
|
99
105
|
|
106
|
+
def filter_branches(branches, ignore_prefixes)
|
107
|
+
filter = Regexp.new("^(#{ignore_prefixes.join('|')})")
|
108
|
+
branches = branches.reject do |branch|
|
109
|
+
result = filter.match(branch)
|
110
|
+
if result
|
111
|
+
logger.warn _("Branch %{branch} filtered out by ignore_branch_prefixes %{ibp}") % {branch: branch, ibp: @ignore_branch_prefixes}
|
112
|
+
end
|
113
|
+
result
|
114
|
+
end
|
115
|
+
branches
|
116
|
+
end
|
117
|
+
|
100
118
|
private
|
101
119
|
|
102
120
|
def names_and_paths
|
103
121
|
branches = []
|
104
|
-
|
105
122
|
opts = {:prefix => @prefix, :correct => false, :validate => false, :source => @name}
|
106
|
-
|
107
123
|
branches << [R10K::Environment::Name.new('production', opts), "#{@remote}/trunk"]
|
108
|
-
@svn_remote.branches
|
109
|
-
|
124
|
+
additional_branch_names = @svn_remote.branches
|
125
|
+
if @ignore_branch_prefixes && !@ignore_branch_prefixes.empty?
|
126
|
+
additional_branch_names = filter_branches(additional_branch_names, @ignore_branch_prefixes)
|
110
127
|
end
|
111
128
|
|
129
|
+
additional_branch_names.each do |branch|
|
130
|
+
branches << [R10K::Environment::Name.new(branch, opts), "#{@remote}/branches/#{branch}"]
|
131
|
+
end
|
112
132
|
branches
|
113
133
|
end
|
114
134
|
end
|
data/lib/r10k/util/setopts.rb
CHANGED
@@ -39,9 +39,11 @@ module R10K
|
|
39
39
|
when NilClass, FalseClass
|
40
40
|
# Ignore nil options
|
41
41
|
when :self, TrueClass
|
42
|
-
|
42
|
+
# tr here is because instance variables cannot have hyphens in their names.
|
43
|
+
instance_variable_set("@#{key}".tr('-','_').to_sym, value)
|
43
44
|
else
|
44
|
-
|
45
|
+
# tr here same as previous
|
46
|
+
instance_variable_set("@#{rhs}".tr('-','_').to_sym, value)
|
45
47
|
end
|
46
48
|
else
|
47
49
|
raise ArgumentError, _("%{class_name} cannot handle option '%{key}'") % {class_name: self.class.name, key: key}
|
data/lib/r10k/version.rb
CHANGED
data/r10k.gemspec
CHANGED
@@ -28,8 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.add_dependency 'log4r', '1.1.10'
|
29
29
|
s.add_dependency 'multi_json', '~> 1.10'
|
30
30
|
|
31
|
-
s.add_dependency 'puppet_forge', '~> 2.2'
|
32
|
-
s.add_dependency 'semantic_puppet', '~> 0.1.0'
|
31
|
+
s.add_dependency 'puppet_forge', '~> 2.2.8'
|
33
32
|
|
34
33
|
s.add_dependency 'gettext-setup', '~> 0.5'
|
35
34
|
|
@@ -13,5 +13,27 @@ shared_examples_for "a puppetfile action" do
|
|
13
13
|
it "accepts the :moduledir option" do
|
14
14
|
described_class.new({moduledir: "/some/nonexistent/path/modules"}, [])
|
15
15
|
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
shared_examples_for "a puppetfile install action" do
|
21
|
+
describe "initializing" do
|
22
|
+
it "accepts the :root option" do
|
23
|
+
described_class.new({root: "/some/nonexistent/path"}, [])
|
24
|
+
end
|
25
|
+
|
26
|
+
it "accepts the :puppetfile option" do
|
27
|
+
described_class.new({puppetfile: "/some/nonexistent/path/Puppetfile"}, [])
|
28
|
+
end
|
29
|
+
|
30
|
+
it "accepts the :moduledir option" do
|
31
|
+
described_class.new({moduledir: "/some/nonexistent/path/modules"}, [])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "accepts the :force option" do
|
35
|
+
described_class.new({force: true}, [])
|
36
|
+
end
|
37
|
+
|
16
38
|
end
|
17
39
|
end
|
@@ -19,6 +19,10 @@ describe R10K::Action::Deploy::Environment do
|
|
19
19
|
described_class.new({puppetfile: true}, [])
|
20
20
|
end
|
21
21
|
|
22
|
+
it "can accept a no-force option" do
|
23
|
+
described_class.new({:'no-force' => true}, [])
|
24
|
+
end
|
25
|
+
|
22
26
|
it "normalizes environment names in the arg vector"
|
23
27
|
end
|
24
28
|
|
@@ -53,6 +57,14 @@ describe R10K::Action::Deploy::Environment do
|
|
53
57
|
end
|
54
58
|
end
|
55
59
|
|
60
|
+
describe "with no-force" do
|
61
|
+
subject { described_class.new({ config: "/some/nonexistent/path", puppetfile: true, :'no-force' => true}, %w[first]) }
|
62
|
+
|
63
|
+
it "tries to preserve local modifications" do
|
64
|
+
expect(subject.force).to equal(false)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
56
68
|
describe "purge_levels" do
|
57
69
|
let(:settings) { { deploy: { purge_levels: purge_levels } } }
|
58
70
|
|
@@ -13,5 +13,18 @@ describe R10K::Action::Deploy::Module do
|
|
13
13
|
it "accepts an environment option" do
|
14
14
|
described_class.new({environment: "production"}, [])
|
15
15
|
end
|
16
|
+
|
17
|
+
it "can accept a no-force option" do
|
18
|
+
described_class.new({:'no-force' => true}, [])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "with no-force" do
|
23
|
+
|
24
|
+
subject { described_class.new({ config: "/some/nonexistent/path", :'no-force' => true}, [] )}
|
25
|
+
|
26
|
+
it "tries to preserve local modifications" do
|
27
|
+
expect(subject.force).to equal(false)
|
28
|
+
end
|
16
29
|
end
|
17
30
|
end
|
@@ -7,11 +7,12 @@ describe R10K::Action::Puppetfile::Install do
|
|
7
7
|
|
8
8
|
let(:puppetfile) { R10K::Puppetfile.new('/some/nonexistent/path', nil, nil) }
|
9
9
|
|
10
|
-
before do
|
11
|
-
allow(
|
10
|
+
before(:each) do
|
11
|
+
allow(puppetfile).to receive(:load!).and_return(nil)
|
12
|
+
allow(R10K::Puppetfile).to receive(:new).with("/some/nonexistent/path", nil, nil, nil, nil).and_return(puppetfile)
|
12
13
|
end
|
13
14
|
|
14
|
-
it_behaves_like "a puppetfile action"
|
15
|
+
it_behaves_like "a puppetfile install action"
|
15
16
|
|
16
17
|
describe "installing modules" do
|
17
18
|
let(:modules) do
|
@@ -55,14 +56,27 @@ describe R10K::Action::Puppetfile::Install do
|
|
55
56
|
|
56
57
|
it "can use a custom puppetfile path" do
|
57
58
|
subject = described_class.new({root: "/some/nonexistent/path", puppetfile: "/some/other/path/Puppetfile"}, [])
|
58
|
-
expect(R10K::Puppetfile).to receive(:new).with("/some/nonexistent/path", nil, "/some/other/path/Puppetfile").and_return(puppetfile)
|
59
|
+
expect(R10K::Puppetfile).to receive(:new).with("/some/nonexistent/path", nil, "/some/other/path/Puppetfile", nil, nil).and_return(puppetfile)
|
59
60
|
subject.call
|
60
61
|
end
|
61
62
|
|
62
63
|
it "can use a custom moduledir path" do
|
63
64
|
subject = described_class.new({root: "/some/nonexistent/path", moduledir: "/some/other/path/site-modules"}, [])
|
64
|
-
expect(R10K::Puppetfile).to receive(:new).with("/some/nonexistent/path", "/some/other/path/site-modules", nil).and_return(puppetfile)
|
65
|
+
expect(R10K::Puppetfile).to receive(:new).with("/some/nonexistent/path", "/some/other/path/site-modules", nil, nil, nil).and_return(puppetfile)
|
65
66
|
subject.call
|
66
67
|
end
|
67
68
|
end
|
69
|
+
|
70
|
+
describe "forcing to overwrite local changes" do
|
71
|
+
before do
|
72
|
+
allow(puppetfile).to receive(:modules).and_return([])
|
73
|
+
end
|
74
|
+
|
75
|
+
it "can use the force overwrite option" do
|
76
|
+
subject = described_class.new({root: "/some/nonexistent/path", force: true}, [])
|
77
|
+
expect(R10K::Puppetfile).to receive(:new).with("/some/nonexistent/path", nil, nil, nil, true).and_return(puppetfile)
|
78
|
+
subject.call
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
68
82
|
end
|
@@ -7,35 +7,105 @@ describe R10K::Forge::ModuleRelease do
|
|
7
7
|
subject { described_class.new('branan-eight_hundred', '8.0.0') }
|
8
8
|
|
9
9
|
let(:forge_release_class) { PuppetForge::V3::Release }
|
10
|
+
let(:md5_digest_class) { Digest::MD5 }
|
10
11
|
|
11
12
|
let(:download_path) { instance_double('Pathname') }
|
13
|
+
let(:tarball_cache_path) { instance_double('Pathname') }
|
14
|
+
let(:tarball_cache_root) { instance_double('Pathname') }
|
12
15
|
let(:unpack_path) { instance_double('Pathname') }
|
13
16
|
let(:target_dir) { instance_double('Pathname') }
|
17
|
+
let(:md5_file_path) { instance_double('Pathname') }
|
18
|
+
|
14
19
|
let(:file_lists) { {:valid=>['valid_ex'], :invalid=>[], :symlinks=>['symlink_ex']} }
|
15
20
|
|
21
|
+
let(:file_contents) { "skeletor's closet" }
|
22
|
+
let(:md5_of_tarball) { "something_hexy" }
|
23
|
+
let(:good_md5) { md5_of_tarball }
|
24
|
+
let(:bad_md5) { "different_hexy_thing" }
|
25
|
+
|
16
26
|
before do
|
17
27
|
subject.download_path = download_path
|
28
|
+
subject.tarball_cache_path = tarball_cache_path
|
29
|
+
subject.tarball_cache_root = tarball_cache_root
|
18
30
|
subject.unpack_path = unpack_path
|
31
|
+
subject.md5_file_path = md5_file_path
|
32
|
+
end
|
33
|
+
|
34
|
+
context "no cached tarball" do
|
35
|
+
describe '#download' do
|
36
|
+
it "downloads the module from the forge into `download_path`" do
|
37
|
+
expect(tarball_cache_path).to receive(:exist?).and_return(false)
|
38
|
+
expect(subject.forge_release).to receive(:download).with(download_path)
|
39
|
+
allow(FileUtils).to receive(:mkdir_p).with(tarball_cache_root)
|
40
|
+
expect(FileUtils).to receive(:mv).with(download_path, tarball_cache_path)
|
41
|
+
subject.download
|
42
|
+
end
|
43
|
+
end
|
19
44
|
end
|
20
45
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
46
|
+
context "with cached tarball" do
|
47
|
+
describe '#download' do
|
48
|
+
it "does not download a new tarball" do
|
49
|
+
expect(tarball_cache_path).to receive(:exist?).and_return(true)
|
50
|
+
expect(subject.forge_release).not_to receive(:download).with(download_path)
|
51
|
+
subject.download
|
52
|
+
end
|
25
53
|
end
|
26
54
|
end
|
27
55
|
|
28
56
|
describe '#verify' do
|
29
|
-
|
30
|
-
|
31
|
-
|
57
|
+
|
58
|
+
it "verifies using the file md5, if that exists" do
|
59
|
+
allow(File).to receive(:read).and_return(file_contents)
|
60
|
+
allow(md5_digest_class).to receive(:hexdigest).and_return(md5_of_tarball)
|
61
|
+
allow(md5_file_path).to receive(:exist?).and_return(true)
|
62
|
+
expect(subject).to receive(:verify_from_md5_file).with(md5_of_tarball)
|
32
63
|
subject.verify
|
33
64
|
end
|
65
|
+
|
66
|
+
it "verifies using the forge file_md5, if no md5 file exists" do
|
67
|
+
allow(File).to receive(:read).and_return(file_contents)
|
68
|
+
allow(md5_digest_class).to receive(:hexdigest).and_return(md5_of_tarball)
|
69
|
+
allow(md5_file_path).to receive(:exist?).and_return(false)
|
70
|
+
expect(subject).to receive(:verify_from_forge).with(md5_of_tarball)
|
71
|
+
subject.verify
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#verify_from_md5_file' do
|
76
|
+
|
77
|
+
it "does nothing when the checksums match" do
|
78
|
+
expect(File).to receive(:read).with(md5_file_path).and_return(good_md5)
|
79
|
+
expect(subject).not_to receive(:cleanup_cached_tarball_path)
|
80
|
+
subject.verify_from_md5_file(md5_of_tarball)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "raises an error and cleans up when the checksums do not match" do
|
84
|
+
expect(File).to receive(:read).with(md5_file_path).and_return(bad_md5)
|
85
|
+
expect(subject).to receive(:cleanup_cached_tarball_path)
|
86
|
+
expect(subject).to receive(:cleanup_md5_file_path)
|
87
|
+
expect { subject.verify_from_md5_file(md5_of_tarball) }.to raise_error(PuppetForge::V3::Release::ChecksumMismatch)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#verify_from_forge' do
|
92
|
+
it "write the md5 to file when the checksums match" do
|
93
|
+
expect(subject.forge_release).to receive(:file_md5).and_return(good_md5)
|
94
|
+
expect(subject).not_to receive(:cleanup_cached_tarball_path)
|
95
|
+
expect(File).to receive(:write).with(md5_file_path, good_md5)
|
96
|
+
subject.verify_from_forge(md5_of_tarball)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "raises an error and cleans up when the checksums do not match" do
|
100
|
+
expect(subject.forge_release).to receive(:file_md5).and_return(bad_md5)
|
101
|
+
expect(subject).to receive(:cleanup_cached_tarball_path)
|
102
|
+
expect { subject.verify_from_forge(md5_of_tarball) }.to raise_error(PuppetForge::V3::Release::ChecksumMismatch)
|
103
|
+
end
|
34
104
|
end
|
35
105
|
|
36
106
|
describe '#unpack' do
|
37
|
-
it "unpacks the module tarball in `
|
38
|
-
expect(PuppetForge::Unpacker).to receive(:unpack).with(
|
107
|
+
it "unpacks the module tarball in `tarball_cache_path` into the provided target path" do
|
108
|
+
expect(PuppetForge::Unpacker).to receive(:unpack).with(tarball_cache_path.to_s, target_dir.to_s, unpack_path.to_s).\
|
39
109
|
and_return({:valid=>["extractedmodule/metadata.json"], :invalid=>[], :symlinks=>[]})
|
40
110
|
subject.unpack(target_dir)
|
41
111
|
end
|
@@ -52,7 +122,7 @@ describe R10K::Forge::ModuleRelease do
|
|
52
122
|
end
|
53
123
|
|
54
124
|
describe "#cleanup" do
|
55
|
-
it "cleans up the
|
125
|
+
it "cleans up the unpack paths" do
|
56
126
|
expect(subject).to receive(:cleanup_unpack_path)
|
57
127
|
expect(subject).to receive(:cleanup_download_path)
|
58
128
|
subject.cleanup
|
@@ -62,6 +62,40 @@ describe R10K::Source::Git do
|
|
62
62
|
expect(master_env.dirname).to eq 'master'
|
63
63
|
end
|
64
64
|
end
|
65
|
+
|
66
|
+
describe "generate_environments respects ignore_branch_prefixes setting" do
|
67
|
+
before do
|
68
|
+
allow(subject.cache).to receive(:branches).and_return ['master', 'development', 'production', 'not_dev_test_me', 'dev_test', 'dev', 'test_2']
|
69
|
+
subject.instance_variable_set(:@ignore_branch_prefixes, ['dev', 'test'])
|
70
|
+
end
|
71
|
+
|
72
|
+
let(:environments) { subject.generate_environments }
|
73
|
+
|
74
|
+
it "creates an environment for each branch not in ignore_branch_prefixes" do
|
75
|
+
expect(subject.generate_environments.size).to eq(3)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "copies the source remote to the environment" do
|
79
|
+
expect(environments[0].remote).to eq subject.remote
|
80
|
+
expect(environments[1].remote).to eq subject.remote
|
81
|
+
expect(environments[2].remote).to eq subject.remote
|
82
|
+
end
|
83
|
+
|
84
|
+
it "uses the branch name as the directory by default" do
|
85
|
+
expect(environments[0].dirname).to eq 'master'
|
86
|
+
expect(environments[1].dirname).to eq 'production'
|
87
|
+
expect(environments[2].dirname).to eq 'not_dev_test_me'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "filtering branches with ignore prefixes" do
|
92
|
+
let(:branches) { ['master', 'development', 'production', 'not_dev_test_me', 'dev_test', 'dev', 'test_2'] }
|
93
|
+
let(:ignore_prefixes) { ['dev', 'test'] }
|
94
|
+
|
95
|
+
it "filters branches" do
|
96
|
+
expect(subject.filter_branches(branches, ignore_prefixes)).to eq(['master', 'production', 'not_dev_test_me'])
|
97
|
+
end
|
98
|
+
end
|
65
99
|
end
|
66
100
|
|
67
101
|
describe R10K::Source::Git, "handling invalid branch names" do
|
@@ -61,6 +61,34 @@ describe R10K::Source::SVN do
|
|
61
61
|
expect(environments[3].dirname).to eq 'robobutler'
|
62
62
|
end
|
63
63
|
end
|
64
|
+
|
65
|
+
describe "generate_environments respects ignore_branch_prefixes setting" do
|
66
|
+
before do
|
67
|
+
allow(subject.svn_remote).to receive(:branches).and_return ['master', 'development', 'not_dev_test_me', 'dev_test', 'dev', 'test_2']
|
68
|
+
subject.instance_variable_set(:@ignore_branch_prefixes, ['dev', 'test'])
|
69
|
+
end
|
70
|
+
|
71
|
+
let(:environments) { subject.generate_environments }
|
72
|
+
|
73
|
+
it "creates an environment for each branch not in ignore_branch_prefixes" do
|
74
|
+
expect(subject.generate_environments.size).to eq(3)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "uses the branch name as the directory by default" do
|
78
|
+
expect(environments[0].name).to eq 'production'
|
79
|
+
expect(environments[1].name).to eq 'master'
|
80
|
+
expect(environments[2].name).to eq 'not_dev_test_me'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "filtering branches with ignore prefixes" do
|
85
|
+
let(:branches) { ['master', 'development', 'production', 'not_dev_test_me', 'dev_test', 'dev', 'test_2'] }
|
86
|
+
let(:ignore_prefixes) { ['dev', 'test'] }
|
87
|
+
|
88
|
+
it "filters branches" do
|
89
|
+
expect(subject.filter_branches(branches, ignore_prefixes)).to eq(['master', 'production', 'not_dev_test_me'])
|
90
|
+
end
|
91
|
+
end
|
64
92
|
end
|
65
93
|
|
66
94
|
describe R10K::Source::SVN, 'when prefixing is enabled' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: r10k
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrien Thebo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colored
|
@@ -28,14 +28,14 @@ dependencies:
|
|
28
28
|
name: cri
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 2.6.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 2.6.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -56,126 +56,111 @@ dependencies:
|
|
56
56
|
name: multi_json
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '1.10'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.10'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: puppet_forge
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ~>
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 2.2.8
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ~>
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: semantic_puppet
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 0.1.0
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 0.1.0
|
82
|
+
version: 2.2.8
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: gettext-setup
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
|
-
- -
|
87
|
+
- - ~>
|
102
88
|
- !ruby/object:Gem::Version
|
103
89
|
version: '0.5'
|
104
90
|
type: :runtime
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
|
-
- -
|
94
|
+
- - ~>
|
109
95
|
- !ruby/object:Gem::Version
|
110
96
|
version: '0.5'
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: rspec
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - ~>
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '3.1'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
107
|
requirements:
|
122
|
-
- -
|
108
|
+
- - ~>
|
123
109
|
- !ruby/object:Gem::Version
|
124
110
|
version: '3.1'
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
112
|
name: rake
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
128
114
|
requirements:
|
129
|
-
- -
|
115
|
+
- - ! '>='
|
130
116
|
- !ruby/object:Gem::Version
|
131
117
|
version: '0'
|
132
118
|
type: :development
|
133
119
|
prerelease: false
|
134
120
|
version_requirements: !ruby/object:Gem::Requirement
|
135
121
|
requirements:
|
136
|
-
- -
|
122
|
+
- - ! '>='
|
137
123
|
- !ruby/object:Gem::Version
|
138
124
|
version: '0'
|
139
125
|
- !ruby/object:Gem::Dependency
|
140
126
|
name: yard
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
142
128
|
requirements:
|
143
|
-
- -
|
129
|
+
- - ~>
|
144
130
|
- !ruby/object:Gem::Version
|
145
131
|
version: 0.8.7.3
|
146
132
|
type: :development
|
147
133
|
prerelease: false
|
148
134
|
version_requirements: !ruby/object:Gem::Requirement
|
149
135
|
requirements:
|
150
|
-
- -
|
136
|
+
- - ~>
|
151
137
|
- !ruby/object:Gem::Version
|
152
138
|
version: 0.8.7.3
|
153
139
|
- !ruby/object:Gem::Dependency
|
154
140
|
name: minitar
|
155
141
|
requirement: !ruby/object:Gem::Requirement
|
156
142
|
requirements:
|
157
|
-
- -
|
143
|
+
- - ~>
|
158
144
|
- !ruby/object:Gem::Version
|
159
145
|
version: 0.6.1
|
160
146
|
type: :development
|
161
147
|
prerelease: false
|
162
148
|
version_requirements: !ruby/object:Gem::Requirement
|
163
149
|
requirements:
|
164
|
-
- -
|
150
|
+
- - ~>
|
165
151
|
- !ruby/object:Gem::Version
|
166
152
|
version: 0.6.1
|
167
|
-
description:
|
168
|
-
|
169
|
-
|
170
|
-
dynamic environments.
|
153
|
+
description: ! " R10K provides a general purpose toolset for deploying Puppet environments
|
154
|
+
and modules.\n It implements the Puppetfile format and provides a native implementation
|
155
|
+
of Puppet\n dynamic environments.\n"
|
171
156
|
email: adrien@somethingsinistral.net
|
172
157
|
executables:
|
173
158
|
- r10k
|
174
159
|
extensions: []
|
175
160
|
extra_rdoc_files: []
|
176
161
|
files:
|
177
|
-
-
|
178
|
-
-
|
162
|
+
- .gitignore
|
163
|
+
- .travis.yml
|
179
164
|
- CHANGELOG.mkd
|
180
165
|
- CONTRIBUTING.mkd
|
181
166
|
- Gemfile
|
@@ -515,18 +500,19 @@ require_paths:
|
|
515
500
|
- lib
|
516
501
|
required_ruby_version: !ruby/object:Gem::Requirement
|
517
502
|
requirements:
|
518
|
-
- -
|
503
|
+
- - ! '>='
|
519
504
|
- !ruby/object:Gem::Version
|
520
505
|
version: 1.9.3
|
521
506
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
522
507
|
requirements:
|
523
|
-
- -
|
508
|
+
- - ! '>='
|
524
509
|
- !ruby/object:Gem::Version
|
525
510
|
version: '0'
|
526
511
|
requirements: []
|
527
512
|
rubyforge_project:
|
528
|
-
rubygems_version: 2.
|
513
|
+
rubygems_version: 2.4.8
|
529
514
|
signing_key:
|
530
515
|
specification_version: 4
|
531
516
|
summary: Puppet environment and module deployment
|
532
517
|
test_files: []
|
518
|
+
has_rdoc:
|