r10k 3.5.0 → 3.8.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 +4 -4
- data/.github/pull_request_template.md +4 -1
- data/.github/workflows/docker.yml +25 -1
- data/.github/workflows/rspec_tests.yml +81 -0
- data/.travis.yml +14 -11
- data/CHANGELOG.mkd +42 -6
- data/CODEOWNERS +1 -1
- data/Gemfile +1 -1
- data/README.mkd +13 -4
- data/azure-pipelines.yml +2 -1
- data/doc/dynamic-environments/configuration.mkd +60 -3
- data/doc/dynamic-environments/usage.mkd +5 -4
- data/doc/faq.mkd +6 -1
- data/doc/puppetfile.mkd +2 -0
- data/docker/Makefile +16 -2
- data/docker/r10k/Dockerfile +17 -6
- data/docker/r10k/release.Dockerfile +23 -4
- data/integration/tests/git_source/git_source_repeated_remote.rb +68 -0
- data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +1 -1
- data/integration/tests/user_scenario/complex_workflow/multi_env_remove_re-add.rb +1 -1
- data/integration/tests/user_scenario/complex_workflow/multi_env_unamanaged.rb +1 -1
- data/lib/r10k/action/deploy/environment.rb +3 -0
- data/lib/r10k/action/deploy/module.rb +4 -1
- data/lib/r10k/action/runner.rb +34 -0
- data/lib/r10k/cli/deploy.rb +9 -4
- data/lib/r10k/cli/puppetfile.rb +5 -5
- data/lib/r10k/environment/base.rb +8 -1
- data/lib/r10k/environment/with_modules.rb +27 -19
- data/lib/r10k/forge/module_release.rb +2 -2
- data/lib/r10k/git.rb +1 -0
- data/lib/r10k/git/cache.rb +12 -4
- data/lib/r10k/git/rugged/credentials.rb +32 -2
- data/lib/r10k/git/stateful_repository.rb +4 -0
- data/lib/r10k/initializers.rb +2 -0
- data/lib/r10k/module/base.rb +8 -0
- data/lib/r10k/module/forge.rb +1 -1
- data/lib/r10k/module/git.rb +20 -3
- data/lib/r10k/puppetfile.rb +30 -12
- data/lib/r10k/settings.rb +24 -2
- data/lib/r10k/source/git.rb +22 -2
- data/lib/r10k/version.rb +1 -1
- data/locales/r10k.pot +60 -36
- data/spec/fixtures/unit/action/r10k_creds.yaml +9 -0
- data/spec/shared-examples/subprocess-runner.rb +11 -5
- data/spec/unit/action/deploy/environment_spec.rb +43 -2
- data/spec/unit/action/deploy/module_spec.rb +40 -1
- data/spec/unit/action/puppetfile/install_spec.rb +1 -0
- data/spec/unit/action/runner_spec.rb +48 -1
- data/spec/unit/environment/git_spec.rb +3 -2
- data/spec/unit/environment/with_modules_spec.rb +74 -0
- data/spec/unit/forge/module_release_spec.rb +14 -10
- data/spec/unit/git/cache_spec.rb +10 -0
- data/spec/unit/git/rugged/credentials_spec.rb +69 -2
- data/spec/unit/git_spec.rb +3 -3
- data/spec/unit/module/git_spec.rb +55 -0
- data/spec/unit/puppetfile_spec.rb +61 -7
- data/spec/unit/settings_spec.rb +12 -0
- data/spec/unit/source/git_spec.rb +49 -1
- metadata +6 -2
@@ -27,6 +27,7 @@ describe R10K::Action::Puppetfile::Install do
|
|
27
27
|
before do
|
28
28
|
allow(puppetfile).to receive(:purge!)
|
29
29
|
allow(puppetfile).to receive(:modules).and_return(modules)
|
30
|
+
allow(puppetfile).to receive(:modules_by_vcs_cachedir).and_return({none: modules})
|
30
31
|
end
|
31
32
|
|
32
33
|
it "syncs each module in the Puppetfile" do
|
@@ -10,11 +10,12 @@ describe R10K::Action::Runner do
|
|
10
10
|
Class.new do
|
11
11
|
attr_reader :opts
|
12
12
|
attr_reader :argv
|
13
|
+
attr_reader :settings
|
13
14
|
|
14
15
|
def initialize(opts, argv, settings = {})
|
15
16
|
@opts = opts
|
16
17
|
@argv = argv
|
17
|
-
@settings =
|
18
|
+
@settings = settings
|
18
19
|
end
|
19
20
|
|
20
21
|
def call
|
@@ -170,6 +171,52 @@ describe R10K::Action::Runner do
|
|
170
171
|
end
|
171
172
|
end
|
172
173
|
|
174
|
+
describe "configuring git credentials" do
|
175
|
+
it 'errors if both token and key paths are passed' do
|
176
|
+
runner = described_class.new({ 'oauth-token': '/nonexistent',
|
177
|
+
'private-key': '/also/fake' }, %w[args yes], action_class)
|
178
|
+
expect{ runner.call }.to raise_error(R10K::Error, /Cannot specify both/)
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'saves the sshkey path in settings hash' do
|
182
|
+
runner = described_class.new({ 'private-key': '/my/ssh/key' }, %w[args yes], action_class)
|
183
|
+
runner.call
|
184
|
+
expect(runner.instance.settings[:git][:private_key]).to eq('/my/ssh/key')
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'overrides per-repo sshkey in settings hash' do
|
188
|
+
runner = described_class.new({ config: "spec/fixtures/unit/action/r10k_creds.yaml",
|
189
|
+
'private-key': '/my/ssh/key' },
|
190
|
+
%w[args yes],
|
191
|
+
action_class)
|
192
|
+
runner.call
|
193
|
+
expect(runner.instance.settings[:git][:private_key]).to eq('/my/ssh/key')
|
194
|
+
expect(runner.instance.settings[:git][:repositories].count).to eq(2)
|
195
|
+
runner.instance.settings[:git][:repositories].each do |repo_settings|
|
196
|
+
expect(repo_settings[:private_key]).to eq('/my/ssh/key')
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'saves the token path in settings hash' do
|
201
|
+
runner = described_class.new({ 'oauth-token': '/my/token/path' }, %w[args yes], action_class)
|
202
|
+
runner.call
|
203
|
+
expect(runner.instance.settings[:git][:oauth_token]).to eq('/my/token/path')
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'overrides per-repo oauth token in settings hash' do
|
207
|
+
runner = described_class.new({ config: "spec/fixtures/unit/action/r10k_creds.yaml",
|
208
|
+
'oauth-token': '/my/token' },
|
209
|
+
%w[args yes],
|
210
|
+
action_class)
|
211
|
+
runner.call
|
212
|
+
expect(runner.instance.settings[:git][:oauth_token]).to eq('/my/token')
|
213
|
+
expect(runner.instance.settings[:git][:repositories].count).to eq(2)
|
214
|
+
runner.instance.settings[:git][:repositories].each do |repo_settings|
|
215
|
+
expect(repo_settings[:oauth_token]).to eq('/my/token')
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
173
220
|
describe "configuration authorization" do
|
174
221
|
context "when license is not present" do
|
175
222
|
before(:each) do
|
@@ -62,9 +62,10 @@ describe R10K::Environment::Git do
|
|
62
62
|
|
63
63
|
describe "enumerating modules" do
|
64
64
|
it "loads the Puppetfile and returns modules in that puppetfile" do
|
65
|
+
mod = double('A module', :name => 'dbl')
|
65
66
|
expect(subject.puppetfile).to receive(:load)
|
66
|
-
expect(subject.puppetfile).to receive(:modules).and_return [
|
67
|
-
expect(subject.modules).to eq([
|
67
|
+
expect(subject.puppetfile).to receive(:modules).and_return [mod]
|
68
|
+
expect(subject.modules).to eq([mod])
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r10k/environment'
|
3
|
+
|
4
|
+
describe R10K::Environment::WithModules do
|
5
|
+
subject do
|
6
|
+
described_class.new(
|
7
|
+
'release42',
|
8
|
+
'/some/nonexistent/environmentdir',
|
9
|
+
'prefix_release42',
|
10
|
+
{
|
11
|
+
:type => 'bare',
|
12
|
+
:modules => {
|
13
|
+
'puppetlabs-stdlib' => { local: true },
|
14
|
+
'puppetlabs-concat' => { local: true },
|
15
|
+
'puppetlabs-exec' => { local: true },
|
16
|
+
}
|
17
|
+
}.merge(subject_params)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Default no additional params
|
22
|
+
let(:subject_params) { {} }
|
23
|
+
|
24
|
+
describe "dealing with module conflicts" do
|
25
|
+
context "with no module conflicts" do
|
26
|
+
it "validates when there are no conflicts" do
|
27
|
+
mod = instance_double('R10K::Module::Base', name: 'nonconflict', origin: :puppetfile)
|
28
|
+
expect(subject.module_conflicts?(mod)).to eq false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "with module conflicts and default behavior" do
|
33
|
+
it "does not raise an error" do
|
34
|
+
mod = instance_double('R10K::Module::Base', name: 'stdlib', origin: :puppetfile)
|
35
|
+
expect(subject.logger).to receive(:warn).with(/Puppetfile.*both define.*ignored/i)
|
36
|
+
expect(subject.module_conflicts?(mod)).to eq true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with module conflicts and 'error' behavior" do
|
41
|
+
let(:subject_params) {{ :module_conflicts => 'error' }}
|
42
|
+
it "raises an error" do
|
43
|
+
mod = instance_double('R10K::Module::Base', name: 'stdlib', origin: :puppetfile)
|
44
|
+
expect { subject.module_conflicts?(mod) }.to raise_error(R10K::Error, /Puppetfile.*both define.*/i)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "with module conflicts and 'override' behavior" do
|
49
|
+
let(:subject_params) {{ :module_conflicts => 'override' }}
|
50
|
+
it "does not raise an error" do
|
51
|
+
mod = instance_double('R10K::Module::Base', name: 'stdlib', origin: :puppetfile)
|
52
|
+
expect(subject.logger).to receive(:debug).with(/Puppetfile.*both define.*ignored/i)
|
53
|
+
expect(subject.module_conflicts?(mod)).to eq true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with module conflicts and invalid configuration" do
|
58
|
+
let(:subject_params) {{ :module_conflicts => 'batman' }}
|
59
|
+
it "raises an error" do
|
60
|
+
mod = instance_double('R10K::Module::Base', name: 'stdlib', origin: :puppetfile)
|
61
|
+
expect { subject.module_conflicts?(mod) }.to raise_error(R10K::Error, /Unexpected value.*module_conflicts.*/i)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "modules method" do
|
67
|
+
it "returns the configured modules, and Puppetfile modules" do
|
68
|
+
puppetfile_mod = instance_double('R10K::Module::Base', name: 'zebra')
|
69
|
+
expect(subject.puppetfile).to receive(:modules).and_return [puppetfile_mod]
|
70
|
+
returned_modules = subject.modules
|
71
|
+
expect(returned_modules.map(&:name).sort).to eq(%w[concat exec stdlib zebra])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -166,33 +166,37 @@ describe R10K::Forge::ModuleRelease do
|
|
166
166
|
end
|
167
167
|
|
168
168
|
describe "#cleanup_unpack_path" do
|
169
|
-
it "ignores the unpack_path if
|
170
|
-
|
171
|
-
expect(
|
169
|
+
it "ignores the unpack_path if the parent doesn't exist" do
|
170
|
+
parent = instance_double('Pathname')
|
171
|
+
expect(parent).to receive(:exist?).and_return false
|
172
|
+
expect(parent).to_not receive(:rmtree)
|
173
|
+
expect(unpack_path).to receive(:parent).and_return(parent)
|
172
174
|
subject.cleanup_unpack_path
|
173
175
|
end
|
174
176
|
|
175
177
|
it "removes the containing directory of unpack_path if it exists" do
|
176
178
|
parent = instance_double('Pathname')
|
177
179
|
expect(parent).to receive(:rmtree)
|
178
|
-
expect(
|
179
|
-
expect(unpack_path).to receive(:parent).and_return(parent)
|
180
|
+
expect(parent).to receive(:exist?).and_return true
|
181
|
+
expect(unpack_path).to receive(:parent).and_return(parent).exactly(2).times
|
180
182
|
subject.cleanup_unpack_path
|
181
183
|
end
|
182
184
|
end
|
183
185
|
|
184
186
|
describe "#cleanup_download_path" do
|
185
|
-
it "ignores the download_path if
|
186
|
-
|
187
|
-
expect(
|
187
|
+
it "ignores the download_path if the parent doesn't exist" do
|
188
|
+
parent = instance_double('Pathname')
|
189
|
+
expect(parent).to receive(:exist?).and_return false
|
190
|
+
expect(parent).to_not receive(:rmtree)
|
191
|
+
expect(download_path).to receive(:parent).and_return(parent)
|
188
192
|
subject.cleanup_download_path
|
189
193
|
end
|
190
194
|
|
191
195
|
it "removes the containing directory of download_path if it exists" do
|
192
196
|
parent = instance_double('Pathname')
|
193
197
|
expect(parent).to receive(:rmtree)
|
194
|
-
expect(
|
195
|
-
expect(download_path).to receive(:parent).and_return(parent)
|
198
|
+
expect(parent).to receive(:exist?).and_return true
|
199
|
+
expect(download_path).to receive(:parent).and_return(parent).exactly(2).times
|
196
200
|
subject.cleanup_download_path
|
197
201
|
end
|
198
202
|
end
|
data/spec/unit/git/cache_spec.rb
CHANGED
@@ -3,6 +3,16 @@ require 'r10k/git/cache'
|
|
3
3
|
|
4
4
|
describe R10K::Git::Cache do
|
5
5
|
|
6
|
+
describe 'the default cache_root' do
|
7
|
+
it 'is in the right location in linux', unless: R10K::Util::Platform.windows? do
|
8
|
+
expect(described_class.defaults[:cache_root]).to match(/\.r10k\/git/)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'is in the right location for windows', if: R10K::Util::Platform.windows? do
|
12
|
+
expect(described_class.defaults[:cache_root]).to match(/[^.]r10k\/git/)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
6
16
|
let(:subclass) do
|
7
17
|
Class.new(described_class) do
|
8
18
|
def self.bare_repository
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe R10K::Git::Rugged::Credentials, :unless => R10K::Util::Platform.jruby? do
|
3
|
+
describe R10K::Git::Rugged::Credentials, :unless => R10K::Util::Platform.jruby? || R10K::Util::Platform.windows? do
|
4
4
|
before(:all) do
|
5
5
|
require 'r10k/git/rugged/credentials'
|
6
6
|
require 'rugged/credentials'
|
@@ -10,7 +10,7 @@ describe R10K::Git::Rugged::Credentials, :unless => R10K::Util::Platform.jruby?
|
|
10
10
|
|
11
11
|
subject { described_class.new(repo) }
|
12
12
|
|
13
|
-
after(:
|
13
|
+
after(:each) { R10K::Git.settings.reset! }
|
14
14
|
|
15
15
|
describe "determining the username" do
|
16
16
|
before { R10K::Git.settings[:username] = "moderns" }
|
@@ -39,6 +39,7 @@ describe R10K::Git::Rugged::Credentials, :unless => R10K::Util::Platform.jruby?
|
|
39
39
|
|
40
40
|
it "prefers a per-repository SSH private key" do
|
41
41
|
allow(File).to receive(:readable?).with("/etc/puppetlabs/r10k/ssh/tessier-ashpool-id_rsa").and_return true
|
42
|
+
R10K::Git.settings[:private_key] = "/etc/puppetlabs/r10k/ssh/id_rsa"
|
42
43
|
R10K::Git.settings[:repositories] = [{ remote: "ssh://git@tessier-ashpool.freeside/repo.git",
|
43
44
|
private_key: "/etc/puppetlabs/r10k/ssh/tessier-ashpool-id_rsa"}]
|
44
45
|
creds = subject.get_ssh_key_credentials("ssh://git@tessier-ashpool.freeside/repo.git", nil)
|
@@ -78,6 +79,72 @@ describe R10K::Git::Rugged::Credentials, :unless => R10K::Util::Platform.jruby?
|
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
82
|
+
describe "generating token credentials" do
|
83
|
+
it 'errors if token file does not exist' do
|
84
|
+
R10K::Git.settings[:oauth_token] = "/missing/token/file"
|
85
|
+
expect(File).to receive(:readable?).with("/missing/token/file").and_return false
|
86
|
+
R10K::Git.settings[:repositories] = [{remote: "https://tessier-ashpool.freeside/repo.git"}]
|
87
|
+
expect {
|
88
|
+
subject.get_plaintext_credentials("https://tessier-ashpool.freeside/repo.git", nil)
|
89
|
+
}.to raise_error(R10K::Git::GitError, /cannot load OAuth token/)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'errors if the token on stdin is not a valid OAuth token' do
|
93
|
+
allow($stdin).to receive(:read).and_return("<bad>token")
|
94
|
+
R10K::Git.settings[:oauth_token] = "-"
|
95
|
+
R10K::Git.settings[:repositories] = [{remote: "https://tessier-ashpool.freeside/repo.git"}]
|
96
|
+
expect {
|
97
|
+
subject.get_plaintext_credentials("https://tessier-ashpool.freeside/repo.git", nil)
|
98
|
+
}.to raise_error(R10K::Git::GitError, /invalid characters/)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'errors if the token in the file is not a valid OAuth token' do
|
102
|
+
token_file = Tempfile.new('token')
|
103
|
+
token_file.write('my bad \ntoken')
|
104
|
+
token_file.close
|
105
|
+
R10K::Git.settings[:oauth_token] = token_file.path
|
106
|
+
R10K::Git.settings[:repositories] = [{remote: "https://tessier-ashpool.freeside/repo.git"}]
|
107
|
+
expect {
|
108
|
+
subject.get_plaintext_credentials("https://tessier-ashpool.freeside/repo.git", nil)
|
109
|
+
}.to raise_error(R10K::Git::GitError, /invalid characters/)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'prefers per-repo token file' do
|
113
|
+
token_file = Tempfile.new('token')
|
114
|
+
token_file.write('my_token')
|
115
|
+
token_file.close
|
116
|
+
R10K::Git.settings[:oauth_token] = "/do/not/use"
|
117
|
+
R10K::Git.settings[:repositories] = [{remote: "https://tessier-ashpool.freeside/repo.git",
|
118
|
+
oauth_token: token_file.path }]
|
119
|
+
creds = subject.get_plaintext_credentials("https://tessier-ashpool.freeside/repo.git", nil)
|
120
|
+
expect(creds).to be_a_kind_of(Rugged::Credentials::UserPassword)
|
121
|
+
expect(creds.instance_variable_get(:@password)).to eq("my_token")
|
122
|
+
expect(creds.instance_variable_get(:@username)).to eq("x-oauth-token")
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'uses the token from a file as a password' do
|
126
|
+
token_file = Tempfile.new('token')
|
127
|
+
token_file.write('my_token')
|
128
|
+
token_file.close
|
129
|
+
R10K::Git.settings[:oauth_token] = token_file.path
|
130
|
+
R10K::Git.settings[:repositories] = [{remote: "https://tessier-ashpool.freeside/repo.git"}]
|
131
|
+
creds = subject.get_plaintext_credentials("https://tessier-ashpool.freeside/repo.git", nil)
|
132
|
+
expect(creds).to be_a_kind_of(Rugged::Credentials::UserPassword)
|
133
|
+
expect(creds.instance_variable_get(:@password)).to eq("my_token")
|
134
|
+
expect(creds.instance_variable_get(:@username)).to eq("x-oauth-token")
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'uses the token from stdin as a password' do
|
138
|
+
allow($stdin).to receive(:read).and_return("my_token")
|
139
|
+
R10K::Git.settings[:oauth_token] = '-'
|
140
|
+
R10K::Git.settings[:repositories] = [{remote: "https://tessier-ashpool.freeside/repo.git"}]
|
141
|
+
creds = subject.get_plaintext_credentials("https://tessier-ashpool.freeside/repo.git", nil)
|
142
|
+
expect(creds).to be_a_kind_of(Rugged::Credentials::UserPassword)
|
143
|
+
expect(creds.instance_variable_get(:@password)).to eq("my_token")
|
144
|
+
expect(creds.instance_variable_get(:@username)).to eq("x-oauth-token")
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
81
148
|
describe "generating default credentials" do
|
82
149
|
it "generates the rugged default credential type" do
|
83
150
|
creds = subject.get_default_credentials("https://azurediamond:hunter2@tessier-ashpool.freeside/repo.git", "azurediamond")
|
data/spec/unit/git_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe R10K::Git do
|
|
11
11
|
expect(described_class.default_name).to eq :shellgit
|
12
12
|
end
|
13
13
|
|
14
|
-
context 'under c-based rubies', :unless => R10K::Util::Platform.jruby? do
|
14
|
+
context 'under c-based rubies with rugged available', :unless => R10K::Util::Platform.jruby? || R10K::Util::Platform.windows? do
|
15
15
|
it 'returns rugged when the git executable is absent and the rugged library is present' do
|
16
16
|
expect(R10K::Features).to receive(:available?).with(:shellgit).and_return false
|
17
17
|
expect(R10K::Features).to receive(:available?).with(:rugged).and_return true
|
@@ -53,7 +53,7 @@ describe R10K::Git do
|
|
53
53
|
}.to raise_error(R10K::Error, "Git provider 'shellgit' is not functional.")
|
54
54
|
end
|
55
55
|
|
56
|
-
context 'under c-based rubies', :unless => R10K::Util::Platform.jruby? do
|
56
|
+
context 'under c-based rubies with rugged available', :unless => R10K::Util::Platform.jruby? || R10K::Util::Platform.windows? do
|
57
57
|
it "sets the current provider if the provider exists and is functional" do
|
58
58
|
expect(R10K::Features).to receive(:available?).with(:rugged).and_return true
|
59
59
|
described_class.provider = :rugged
|
@@ -71,7 +71,7 @@ describe R10K::Git do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
describe "retrieving the current provider" do
|
74
|
-
context 'under c-based rubies', :unless => R10K::Util::Platform.jruby? do
|
74
|
+
context 'under c-based rubies', :unless => R10K::Util::Platform.jruby? || R10K::Util::Platform.windows? do
|
75
75
|
it "uses the default if a provider has not been set" do
|
76
76
|
expect(described_class).to receive(:default_name).and_return :rugged
|
77
77
|
expect(described_class.provider).to eq(R10K::Git::Rugged)
|
@@ -268,6 +268,61 @@ describe R10K::Module::Git do
|
|
268
268
|
end
|
269
269
|
end
|
270
270
|
end
|
271
|
+
|
272
|
+
context "when using default_branch_override" do
|
273
|
+
before(:each) do
|
274
|
+
allow(mock_repo).to receive(:resolve).with(mock_env.ref).and_return(nil)
|
275
|
+
end
|
276
|
+
|
277
|
+
context "and the default branch override is resolvable" do
|
278
|
+
it "uses the override" do
|
279
|
+
expect(mock_repo).to receive(:resolve).with('default_override').and_return('5566aabb')
|
280
|
+
mod = test_module({branch: :control_branch,
|
281
|
+
default_branch: 'default',
|
282
|
+
default_branch_override: 'default_override'},
|
283
|
+
mock_env)
|
284
|
+
expect(mod.properties).to include(expected: 'default_override')
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context "and the default branch override is not resolvable" do
|
289
|
+
context "and default branch is provided" do
|
290
|
+
it "falls back to the default" do
|
291
|
+
expect(mock_repo).to receive(:resolve).with('default_override').and_return(nil)
|
292
|
+
expect(mock_repo).to receive(:resolve).with('default').and_return('5566aabb')
|
293
|
+
mod = test_module({branch: :control_branch,
|
294
|
+
default_branch: 'default',
|
295
|
+
default_branch_override: 'default_override'},
|
296
|
+
mock_env)
|
297
|
+
expect(mod.properties).to include(expected: 'default')
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
context "and default branch is not provided" do
|
302
|
+
it "raises the appropriate error" do
|
303
|
+
expect(mock_repo).to receive(:resolve).with('default_override').and_return(nil)
|
304
|
+
mod = test_module({branch: :control_branch,
|
305
|
+
default_branch_override: 'default_override'},
|
306
|
+
mock_env)
|
307
|
+
|
308
|
+
expect { mod.properties }.to raise_error(ArgumentError, /unable to manage.*or resolve the default branch override.*no default provided/i)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context "and default branch is not resolvable" do
|
313
|
+
it "raises the appropriate error" do
|
314
|
+
expect(mock_repo).to receive(:resolve).with('default_override').and_return(nil)
|
315
|
+
expect(mock_repo).to receive(:resolve).with('default').and_return(nil)
|
316
|
+
mod = test_module({branch: :control_branch,
|
317
|
+
default_branch: 'default',
|
318
|
+
default_branch_override: 'default_override'},
|
319
|
+
mock_env)
|
320
|
+
|
321
|
+
expect { mod.properties }.to raise_error(ArgumentError, /unable to manage.*or resolve the default branch override.*or resolve default/i)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
271
326
|
end
|
272
327
|
end
|
273
328
|
end
|
@@ -127,6 +127,17 @@ describe R10K::Puppetfile do
|
|
127
127
|
|
128
128
|
expect { subject.add_module('puppet/test_module', module_opts) }.to raise_error(R10K::Error, /cannot manage content.*is not within/i).and not_change { subject.modules }
|
129
129
|
end
|
130
|
+
|
131
|
+
it "should disable and not add modules that conflict with the environment" do
|
132
|
+
env = instance_double('R10K::Environment::Base')
|
133
|
+
mod = instance_double('R10K::Module::Base', name: 'conflict', origin: :puppetfile)
|
134
|
+
allow(mod).to receive(:origin=).and_return(nil)
|
135
|
+
allow(subject).to receive(:environment).and_return(env)
|
136
|
+
allow(env).to receive(:'module_conflicts?').with(mod).and_return(true)
|
137
|
+
|
138
|
+
allow(R10K::Module).to receive(:new).with('test', anything, anything, anything).and_return(mod)
|
139
|
+
expect { subject.add_module('test', {}) }.not_to change { subject.modules }
|
140
|
+
end
|
130
141
|
end
|
131
142
|
|
132
143
|
describe "#purge_exclusions" do
|
@@ -154,6 +165,26 @@ describe R10K::Puppetfile do
|
|
154
165
|
end
|
155
166
|
end
|
156
167
|
|
168
|
+
describe '#managed_directories' do
|
169
|
+
it 'returns an array of paths that can be purged' do
|
170
|
+
allow(R10K::Module).to receive(:new).with('puppet/test_module', subject.moduledir, '1.2.3', anything).and_call_original
|
171
|
+
|
172
|
+
subject.add_module('puppet/test_module', '1.2.3')
|
173
|
+
expect(subject.managed_directories).to match_array(["/some/nonexistent/basedir/modules"])
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'with a module with install_path == \'\'' do
|
177
|
+
it 'basedir isn\'t in the list of paths to purge' do
|
178
|
+
module_opts = { install_path: '', git: 'git@example.com:puppet/test_module.git' }
|
179
|
+
|
180
|
+
allow(R10K::Module).to receive(:new).with('puppet/test_module', subject.basedir, module_opts, anything).and_call_original
|
181
|
+
|
182
|
+
subject.add_module('puppet/test_module', module_opts)
|
183
|
+
expect(subject.managed_directories).to be_empty
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
157
188
|
describe "evaluating a Puppetfile" do
|
158
189
|
def expect_wrapped_error(orig, pf_path, wrapped_error)
|
159
190
|
expect(orig).to be_a_kind_of(R10K::Error)
|
@@ -244,7 +275,8 @@ describe R10K::Puppetfile do
|
|
244
275
|
default_branch_override = 'default_branch_override_name'
|
245
276
|
expect { subject.load!(default_branch_override) }.not_to raise_error
|
246
277
|
git_module = subject.modules[0]
|
247
|
-
expect(git_module.
|
278
|
+
expect(git_module.default_override_ref).to eq default_branch_override
|
279
|
+
expect(git_module.default_ref).to eq "here_lies_the_default_branch"
|
248
280
|
end
|
249
281
|
end
|
250
282
|
|
@@ -263,12 +295,12 @@ describe R10K::Puppetfile do
|
|
263
295
|
block.call
|
264
296
|
end
|
265
297
|
|
266
|
-
mod1 =
|
298
|
+
mod1 = instance_double('R10K::Module::Base', :cachedir => :none)
|
299
|
+
mod2 = instance_double('R10K::Module::Base', :cachedir => :none)
|
267
300
|
expect(mod1).to receive(:accept).with(visitor)
|
268
|
-
mod2 = spy('module')
|
269
301
|
expect(mod2).to receive(:accept).with(visitor)
|
270
|
-
|
271
302
|
expect(subject).to receive(:modules).and_return([mod1, mod2])
|
303
|
+
|
272
304
|
subject.accept(visitor)
|
273
305
|
end
|
274
306
|
|
@@ -284,11 +316,10 @@ describe R10K::Puppetfile do
|
|
284
316
|
block.call
|
285
317
|
end
|
286
318
|
|
287
|
-
mod1 =
|
319
|
+
mod1 = instance_double('R10K::Module::Base', :cachedir => :none)
|
320
|
+
mod2 = instance_double('R10K::Module::Base', :cachedir => :none)
|
288
321
|
expect(mod1).to receive(:accept).with(visitor)
|
289
|
-
mod2 = spy('module')
|
290
322
|
expect(mod2).to receive(:accept).with(visitor)
|
291
|
-
|
292
323
|
expect(subject).to receive(:modules).and_return([mod1, mod2])
|
293
324
|
|
294
325
|
expect(Thread).to receive(:new).exactly(pool_size).and_call_original
|
@@ -296,5 +327,28 @@ describe R10K::Puppetfile do
|
|
296
327
|
|
297
328
|
subject.accept(visitor)
|
298
329
|
end
|
330
|
+
|
331
|
+
it "Creates queues of modules grouped by cachedir" do
|
332
|
+
visitor = spy('visitor')
|
333
|
+
expect(visitor).to receive(:visit) do |type, other, &block|
|
334
|
+
expect(type).to eq :puppetfile
|
335
|
+
expect(other).to eq subject
|
336
|
+
block.call
|
337
|
+
end
|
338
|
+
|
339
|
+
m1 = instance_double('R10K::Module::Base', :cachedir => '/dev/null/A')
|
340
|
+
m2 = instance_double('R10K::Module::Base', :cachedir => '/dev/null/B')
|
341
|
+
m3 = instance_double('R10K::Module::Base', :cachedir => '/dev/null/C')
|
342
|
+
m4 = instance_double('R10K::Module::Base', :cachedir => '/dev/null/C')
|
343
|
+
m5 = instance_double('R10K::Module::Base', :cachedir => '/dev/null/D')
|
344
|
+
m6 = instance_double('R10K::Module::Base', :cachedir => '/dev/null/D')
|
345
|
+
|
346
|
+
expect(subject).to receive(:modules).and_return([m1, m2, m3, m4, m5, m6])
|
347
|
+
|
348
|
+
queue = subject.modules_queue(visitor)
|
349
|
+
expect(queue.length).to be 4
|
350
|
+
queue_array = 4.times.map { queue.pop }
|
351
|
+
expect(queue_array).to match_array([[m1], [m2], [m3, m4], [m5, m6]])
|
352
|
+
end
|
299
353
|
end
|
300
354
|
end
|