r10k 3.10.0 → 3.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -10
  3. data/CHANGELOG.mkd +9 -0
  4. data/README.mkd +6 -0
  5. data/doc/dynamic-environments/configuration.mkd +14 -0
  6. data/doc/puppetfile.mkd +15 -1
  7. data/integration/Rakefile +2 -0
  8. data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +15 -13
  9. data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +3 -3
  10. data/integration/tests/user_scenario/complex_workflow/multi_env_remove_re-add.rb +3 -3
  11. data/integration/tests/user_scenario/complex_workflow/multi_env_unamanaged.rb +3 -3
  12. data/lib/r10k/action/deploy/environment.rb +6 -1
  13. data/lib/r10k/action/deploy/module.rb +31 -5
  14. data/lib/r10k/action/runner.rb +34 -4
  15. data/lib/r10k/cli/deploy.rb +4 -0
  16. data/lib/r10k/git.rb +3 -0
  17. data/lib/r10k/git/rugged/credentials.rb +77 -0
  18. data/lib/r10k/git/stateful_repository.rb +1 -0
  19. data/lib/r10k/initializers.rb +3 -0
  20. data/lib/r10k/module/base.rb +37 -0
  21. data/lib/r10k/module/forge.rb +1 -0
  22. data/lib/r10k/module/git.rb +1 -0
  23. data/lib/r10k/module/svn.rb +1 -0
  24. data/lib/r10k/module_loader/puppetfile.rb +15 -4
  25. data/lib/r10k/puppetfile.rb +10 -11
  26. data/lib/r10k/settings.rb +44 -2
  27. data/lib/r10k/settings/definition.rb +1 -1
  28. data/lib/r10k/version.rb +1 -1
  29. data/locales/r10k.pot +106 -38
  30. data/r10k.gemspec +2 -0
  31. data/spec/unit/action/deploy/environment_spec.rb +16 -0
  32. data/spec/unit/action/deploy/module_spec.rb +178 -0
  33. data/spec/unit/action/runner_spec.rb +80 -0
  34. data/spec/unit/git/rugged/credentials_spec.rb +29 -0
  35. data/spec/unit/git/stateful_repository_spec.rb +5 -0
  36. data/spec/unit/module/base_spec.rb +46 -0
  37. data/spec/unit/module/forge_spec.rb +19 -0
  38. data/spec/unit/module/git_spec.rb +17 -0
  39. data/spec/unit/module/svn_spec.rb +18 -0
  40. data/spec/unit/module_loader/puppetfile_spec.rb +16 -3
  41. data/spec/unit/module_spec.rb +12 -1
  42. data/spec/unit/puppetfile_spec.rb +31 -1
  43. data/spec/unit/settings_spec.rb +18 -0
  44. metadata +16 -2
@@ -89,6 +89,23 @@ describe R10K::Module::Git do
89
89
  end
90
90
  end
91
91
 
92
+ describe 'syncing the repo' do
93
+ let(:module_org) { "coolorg" }
94
+ let(:module_name) { "coolmod" }
95
+ let(:title) { "#{module_org}-#{module_name}" }
96
+ let(:dirname) { Pathname.new(Dir.mktmpdir) }
97
+ let(:spec_path) { dirname + module_name + 'spec' }
98
+ subject { described_class.new(title, dirname, {}) }
99
+
100
+ it 'defaults to keeping the spec dir' do
101
+ FileUtils.mkdir_p(spec_path)
102
+ allow(mock_repo).to receive(:resolve).with('master').and_return('abc123')
103
+ allow(mock_repo).to receive(:sync)
104
+ subject.sync
105
+ expect(Dir.exist?(spec_path)).to eq true
106
+ end
107
+ end
108
+
92
109
  describe "determining the status" do
93
110
  subject do
94
111
  described_class.new(
@@ -119,6 +119,24 @@ describe R10K::Module::SVN do
119
119
  end
120
120
  end
121
121
 
122
+ describe 'the default spec dir' do
123
+ let(:module_org) { "coolorg" }
124
+ let(:module_name) { "coolmod" }
125
+ let(:title) { "#{module_org}-#{module_name}" }
126
+ let(:dirname) { Pathname.new(Dir.mktmpdir) }
127
+ let(:spec_path) { dirname + module_name + 'spec' }
128
+ subject { described_class.new(title, dirname, {}) }
129
+
130
+ it 'is kept by default' do
131
+
132
+ FileUtils.mkdir_p(spec_path)
133
+ expect(subject).to receive(:status).and_return(:absent)
134
+ expect(subject).to receive(:install).and_return(nil)
135
+ subject.sync
136
+ expect(Dir.exist?(spec_path)).to eq true
137
+ end
138
+ end
139
+
122
140
  describe "synchronizing" do
123
141
 
124
142
  subject { described_class.new('foo', '/moduledir', :svn => 'https://github.com/adrienthebo/r10k-fixture-repo', :rev => 123) }
@@ -37,13 +37,13 @@ describe R10K::ModuleLoader::Puppetfile do
37
37
  it 'respects absolute paths' do
38
38
  absolute_options = options.merge({puppetfile: '/opt/puppetlabs/special/Puppetfile'})
39
39
  puppetfile = R10K::ModuleLoader::Puppetfile.new(**absolute_options)
40
- expect(puppetfile.instance_variable_get(:@puppetfile)).to eq('/opt/puppetlabs/special/Puppetfile')
40
+ expect(puppetfile.instance_variable_get(:@puppetfile_path)).to eq('/opt/puppetlabs/special/Puppetfile')
41
41
  end
42
42
 
43
43
  it 'roots the Puppetfile in the basepath if a relative path is specified' do
44
44
  relative_options = options.merge({puppetfile: 'Puppetfile.global'})
45
45
  puppetfile = R10K::ModuleLoader::Puppetfile.new(**relative_options)
46
- expect(puppetfile.instance_variable_get(:@puppetfile)).to eq('/test/basedir/env/Puppetfile.global')
46
+ expect(puppetfile.instance_variable_get(:@puppetfile_path)).to eq('/test/basedir/env/Puppetfile.global')
47
47
  end
48
48
  end
49
49
 
@@ -68,7 +68,7 @@ describe R10K::ModuleLoader::Puppetfile do
68
68
  end
69
69
 
70
70
  it 'has a Puppetfile rooted in the basedir' do
71
- expect(subject.instance_variable_get(:@puppetfile)).to eq('/test/basedir/Puppetfile')
71
+ expect(subject.instance_variable_get(:@puppetfile_path)).to eq('/test/basedir/Puppetfile')
72
72
  end
73
73
 
74
74
  it 'uses the public forge' do
@@ -107,6 +107,18 @@ describe R10K::ModuleLoader::Puppetfile do
107
107
  expect(subject.modules.collect(&:name)).not_to include('test_module')
108
108
  end
109
109
 
110
+ it 'should set :spec_deletable to true for modules in the basedir' do
111
+ module_opts = { git: 'git@example.com:puppet/test_module.git' }
112
+ subject.add_module('puppet/test_module', module_opts)
113
+ expect(subject.modules[0].spec_deletable).to be true
114
+ end
115
+
116
+ it 'should set :spec_deletable to false for modules outside the basedir' do
117
+ module_opts = { git: 'git@example.com:puppet/test_module.git', install_path: 'some/path' }
118
+ subject.add_module('puppet/test_module', module_opts)
119
+ expect(subject.modules[0].spec_deletable).to be false
120
+ end
121
+
110
122
  it 'should accept non-Forge modules with a hash arg' do
111
123
  module_opts = { git: 'git@example.com:puppet/test_module.git' }
112
124
 
@@ -165,6 +177,7 @@ describe R10K::ModuleLoader::Puppetfile do
165
177
  mod = instance_double('R10K::Module::Base', name: 'conflict', origin: :puppetfile, 'origin=': nil)
166
178
  loader = R10K::ModuleLoader::Puppetfile.new(basedir: basedir, environment: env)
167
179
  allow(env).to receive(:'module_conflicts?').with(mod).and_return(true)
180
+ allow(mod).to receive(:spec_deletable=)
168
181
 
169
182
  expect(R10K::Module).to receive(:new).with('conflict', anything, anything, anything).and_return(mod)
170
183
  expect { loader.add_module('conflict', {}) }.not_to change { loader.modules }
@@ -77,7 +77,7 @@ describe R10K::Module do
77
77
  }.to raise_error RuntimeError, /doesn't have an implementation/
78
78
  end
79
79
 
80
- describe 'when a user passes a `default_branch_override`' do
80
+ describe 'Given a set of initialization parameters for R10K::Module' do
81
81
  [ ['name', {git: 'git url'}],
82
82
  ['name', {type: 'git', source: 'git url'}],
83
83
  ['name', {svn: 'svn url'}],
@@ -91,6 +91,17 @@ describe R10K::Module do
91
91
  expect(obj).to be_a_kind_of(R10K::Module::Base)
92
92
  }.not_to raise_error
93
93
  end
94
+ describe 'the exclude_spec setting' do
95
+ it 'sets the exclude_spec instance variable' do
96
+ obj = R10K::Module.new(name, '/modulepath', options.merge({exclude_spec: true}))
97
+ expect(obj.instance_variable_get("@exclude_spec")).to eq(true)
98
+ end
99
+ it 'can be overridden by the overrides map' do
100
+ options = options.merge({exclude_spec: false, overrides: {modules: {exclude_spec: true}}})
101
+ obj = R10K::Module.new(name, '/modulepath', options)
102
+ expect(obj.instance_variable_get("@exclude_spec")).to eq(true)
103
+ end
104
+ end
94
105
  end
95
106
  end
96
107
  end
@@ -10,7 +10,7 @@ describe R10K::Puppetfile do
10
10
  )
11
11
  end
12
12
 
13
- describe "a custom puppetfile Puppetfile.r10k" do
13
+ describe "a custom puppetfile_name" do
14
14
  it "is the basedir joined with '/Puppetfile.r10k' path" do
15
15
  expect(subject.puppetfile_path).to eq '/some/nonexistent/basedir/Puppetfile.r10k'
16
16
  end
@@ -18,6 +18,25 @@ describe R10K::Puppetfile do
18
18
 
19
19
  end
20
20
 
21
+ describe R10K::Puppetfile do
22
+
23
+ describe "a custom relative puppetfile_path" do
24
+ it "is the basedir joined with the puppetfile_path" do
25
+ relative_subject = described_class.new('/some/nonexistent/basedir',
26
+ {puppetfile_path: 'relative/Puppetfile'})
27
+ expect(relative_subject.puppetfile_path).to eq '/some/nonexistent/basedir/relative/Puppetfile'
28
+ end
29
+ end
30
+
31
+ describe "a custom absolute puppetfile_path" do
32
+ it "is the puppetfile_path as given" do
33
+ absolute_subject = described_class.new('/some/nonexistent/basedir',
34
+ {puppetfile_path: '/some/absolute/custom/Puppetfile'})
35
+ expect(absolute_subject.puppetfile_path).to eq '/some/absolute/custom/Puppetfile'
36
+ end
37
+ end
38
+ end
39
+
21
40
  describe R10K::Puppetfile do
22
41
 
23
42
  subject do
@@ -80,6 +99,17 @@ describe R10K::Puppetfile do
80
99
  expect(has_some_data).to be true
81
100
  end
82
101
 
102
+ it "handles a relative basedir" do
103
+ path = File.join('spec', 'fixtures', 'unit', 'puppetfile', 'valid-forge-with-version')
104
+ subject = described_class.new(path, {})
105
+
106
+ loaded_content = subject.load
107
+ expect(loaded_content).to be_an_instance_of(Hash)
108
+
109
+ has_some_data = loaded_content.values.none?(&:empty?)
110
+ expect(has_some_data).to be true
111
+ end
112
+
83
113
  it "is idempotent" do
84
114
  path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'valid-forge-with-version')
85
115
  subject = described_class.new(path, {})
@@ -95,6 +95,24 @@ describe R10K::Settings do
95
95
  describe "deploy settings" do
96
96
  subject { described_class.deploy_settings }
97
97
 
98
+ describe 'exclude_spec' do
99
+ it 'is false by default' do
100
+ expect(subject.evaluate({})[:exclude_spec]).to eq(false)
101
+ end
102
+ it 'can be set to true' do
103
+ expect(subject.evaluate({"exclude_spec" => true})[:exclude_spec]).to eq(true)
104
+ end
105
+ it "raises an error for non-boolean values" do
106
+ expect {
107
+ subject.evaluate({"exclude_spec" => 'invalid_string'})
108
+ }.to raise_error do |err|
109
+ expect(err.message).to match(/Validation failed for 'deploy' settings group/)
110
+ expect(err.errors.size).to eq 1
111
+ expect(err.errors[:exclude_spec]).to be_a_kind_of(ArgumentError)
112
+ expect(err.errors[:exclude_spec].message).to match(/`exclude_spec` can only be a boolean value, not 'invalid_string'/)
113
+ end
114
+ end
115
+ end
98
116
  describe "write_lock" do
99
117
  it "accepts a string with a reason for the write lock" do
100
118
  output = subject.evaluate("write_lock" => "No maintenance window active, code freeze till 2038-01-19")
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: 3.10.0
4
+ version: 3.11.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: 2021-07-15 00:00:00.000000000 Z
11
+ date: 2021-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colored2
@@ -128,6 +128,20 @@ dependencies:
128
128
  - - "<"
129
129
  - !ruby/object:Gem::Version
130
130
  version: 3.3.0
131
+ - !ruby/object:Gem::Dependency
132
+ name: jwt
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: 2.2.3
138
+ type: :runtime
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: 2.2.3
131
145
  - !ruby/object:Gem::Dependency
132
146
  name: rspec
133
147
  requirement: !ruby/object:Gem::Requirement