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/spec/unit/module_spec.rb
CHANGED
@@ -5,19 +5,19 @@ describe R10K::Module do
|
|
5
5
|
describe 'delegating to R10K::Module::Git' do
|
6
6
|
it "accepts args {:git => 'git url}" do
|
7
7
|
obj = R10K::Module.new('foo', '/modulepath', :git => 'git url')
|
8
|
-
obj.
|
8
|
+
expect(obj).to be_a_kind_of(R10K::Module::Git)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
describe 'delegating to R10K::Module::Git' do
|
13
13
|
it "accepts name matching 'username/modulename' and no args" do
|
14
14
|
obj = R10K::Module.new('bar/quux', '/modulepath', [])
|
15
|
-
obj.
|
15
|
+
expect(obj).to be_a_kind_of(R10K::Module::Forge)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "accepts name matching 'username/modulename' and a semver argument" do
|
19
19
|
obj = R10K::Module.new('bar/quux', '/modulepath', '10.0.0')
|
20
|
-
obj.
|
20
|
+
expect(obj).to be_a_kind_of(R10K::Module::Forge)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r10k/puppetfile'
|
3
|
+
|
4
|
+
describe R10K::Puppetfile do
|
5
|
+
|
6
|
+
subject do
|
7
|
+
described_class.new(
|
8
|
+
'/some/nonexistent/basedir'
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "the default moduledir" do
|
13
|
+
it "is the basedir joined with '/modules' path" do
|
14
|
+
expect(subject.moduledir).to eq '/some/nonexistent/basedir/modules'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "setting moduledir" do
|
19
|
+
it "changes to given moduledir if it is an absolute path" do
|
20
|
+
subject.set_moduledir('/absolute/path/moduledir')
|
21
|
+
expect(subject.moduledir).to eq '/absolute/path/moduledir'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "joins the basedir with the given moduledir if it is a relative path" do
|
25
|
+
subject.set_moduledir('relative/moduledir')
|
26
|
+
expect(subject.moduledir).to eq '/some/nonexistent/basedir/relative/moduledir'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "evaluating a Puppetfile" do
|
31
|
+
def expect_wrapped_error(orig, pf_path, wrapped_error)
|
32
|
+
expect(orig).to be_a_kind_of(R10K::Error)
|
33
|
+
expect(orig.message).to eq("Failed to evaluate #{pf_path}")
|
34
|
+
expect(orig.original).to be_a_kind_of(wrapped_error)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "wraps and re-raises syntax errors" do
|
38
|
+
path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'invalid-syntax')
|
39
|
+
pf_path = File.join(path, 'Puppetfile')
|
40
|
+
subject = described_class.new(path)
|
41
|
+
expect {
|
42
|
+
subject.load!
|
43
|
+
}.to raise_error do |e|
|
44
|
+
expect_wrapped_error(e, pf_path, SyntaxError)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "wraps and re-raises load errors" do
|
49
|
+
path = File.join(PROJECT_ROOT, 'spec', 'fixtures', 'unit', 'puppetfile', 'load-error')
|
50
|
+
pf_path = File.join(path, 'Puppetfile')
|
51
|
+
subject = described_class.new(path)
|
52
|
+
expect {
|
53
|
+
subject.load!
|
54
|
+
}.to raise_error do |e|
|
55
|
+
expect_wrapped_error(e, pf_path, LoadError)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "accepting a visitor" do
|
61
|
+
it "passes itself to the visitor" do
|
62
|
+
visitor = spy('visitor')
|
63
|
+
expect(visitor).to receive(:visit).with(:puppetfile, subject)
|
64
|
+
subject.accept(visitor)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "passes the visitor to each module if the visitor yields" do
|
68
|
+
visitor = spy('visitor')
|
69
|
+
expect(visitor).to receive(:visit) do |type, other, &block|
|
70
|
+
expect(type).to eq :puppetfile
|
71
|
+
expect(other).to eq subject
|
72
|
+
block.call
|
73
|
+
end
|
74
|
+
|
75
|
+
mod1 = spy('module')
|
76
|
+
expect(mod1).to receive(:accept).with(visitor)
|
77
|
+
mod2 = spy('module')
|
78
|
+
expect(mod2).to receive(:accept).with(visitor)
|
79
|
+
|
80
|
+
expect(subject).to receive(:modules).and_return([mod1, mod2])
|
81
|
+
subject.accept(visitor)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r10k/source'
|
3
|
+
|
4
|
+
describe R10K::Source::Base do
|
5
|
+
subject { described_class.new('base', '/some/nonexistent/path') }
|
6
|
+
|
7
|
+
describe "accepting a visitor" do
|
8
|
+
it "passes itself to the visitor" do
|
9
|
+
visitor = spy('visitor')
|
10
|
+
expect(visitor).to receive(:visit).with(:source, subject)
|
11
|
+
subject.accept(visitor)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "passes the visitor to each environment if the visitor yields" do
|
15
|
+
visitor = spy('visitor')
|
16
|
+
expect(visitor).to receive(:visit) do |type, other, &block|
|
17
|
+
expect(type).to eq :source
|
18
|
+
expect(other).to eq subject
|
19
|
+
block.call
|
20
|
+
end
|
21
|
+
|
22
|
+
env1 = spy('environment')
|
23
|
+
expect(env1).to receive(:accept).with(visitor)
|
24
|
+
env2 = spy('environment')
|
25
|
+
expect(env2).to receive(:accept).with(visitor)
|
26
|
+
|
27
|
+
expect(subject).to receive(:environments).and_return([env1, env2])
|
28
|
+
subject.accept(visitor)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -32,14 +32,14 @@ describe R10K::Source::Git do
|
|
32
32
|
it "generates environments when the cache is present and environments have not been loaded" do
|
33
33
|
allow(subject.cache).to receive(:cached?).and_return true
|
34
34
|
allow(subject).to receive(:generate_environments).and_return %w[hi]
|
35
|
-
expect(subject.environments).to
|
35
|
+
expect(subject.environments.size).to eq(1)
|
36
36
|
end
|
37
37
|
|
38
38
|
it "doesn't recreate environments if they have already been loaded" do
|
39
39
|
allow(subject.cache).to receive(:cached?).and_return true
|
40
40
|
allow(subject).to receive(:generate_environments).once.and_return %w[hi]
|
41
|
-
expect(subject.environments).to
|
42
|
-
expect(subject.environments).to
|
41
|
+
expect(subject.environments.size).to eq(1)
|
42
|
+
expect(subject.environments.size).to eq(1)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -51,7 +51,7 @@ describe R10K::Source::Git do
|
|
51
51
|
let(:master_env) { subject.generate_environments.first }
|
52
52
|
|
53
53
|
it "creates an environment for each branch" do
|
54
|
-
expect(subject.generate_environments).to
|
54
|
+
expect(subject.generate_environments.size).to eq(1)
|
55
55
|
end
|
56
56
|
|
57
57
|
it "copies the source remote to the environment" do
|
@@ -79,7 +79,7 @@ describe R10K::Source::Git, "handling invalid branch names" do
|
|
79
79
|
end
|
80
80
|
|
81
81
|
it "creates an environment for each branch" do
|
82
|
-
expect(subject.generate_environments).to
|
82
|
+
expect(subject.generate_environments.size).to eq(2)
|
83
83
|
end
|
84
84
|
|
85
85
|
it "removes invalid characters from branch names" do
|
@@ -102,7 +102,7 @@ describe R10K::Source::Git, "handling invalid branch names" do
|
|
102
102
|
end
|
103
103
|
|
104
104
|
it "only creates an environment for valid branches" do
|
105
|
-
expect(subject.generate_environments).to
|
105
|
+
expect(subject.generate_environments.size).to eq(1)
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
@@ -130,7 +130,7 @@ describe R10K::Source::Git, 'when prefixing is enabled' do
|
|
130
130
|
let(:environments) { subject.environments }
|
131
131
|
|
132
132
|
it "creates an environment for each branch" do
|
133
|
-
expect(subject.environments).to
|
133
|
+
expect(subject.environments.size).to eq(2)
|
134
134
|
end
|
135
135
|
|
136
136
|
it "prefixes the source name to environments when prefixing is enabled" do
|
@@ -83,7 +83,7 @@ describe R10K::Source::SVN, 'when prefixing is enabled' do
|
|
83
83
|
let(:environments) { subject.generate_environments }
|
84
84
|
|
85
85
|
it "creates an environment for each branch and the trunk" do
|
86
|
-
expect(environments).to
|
86
|
+
expect(environments.size).to eq(4)
|
87
87
|
end
|
88
88
|
|
89
89
|
it "prefixes the source name to environments" do
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r10k/svn/working_dir'
|
3
|
+
|
4
|
+
describe R10K::SVN::WorkingDir, "initializing" do
|
5
|
+
let(:pathname) { Pathname.new("/some/imaginary/path") }
|
6
|
+
it "stores the provided path" do
|
7
|
+
subject = described_class.new(pathname)
|
8
|
+
expect(subject.path).to eq Pathname.new("/some/imaginary/path")
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "when auth is provided" do
|
12
|
+
it "raises an error when only the username is provided" do
|
13
|
+
expect {
|
14
|
+
described_class.new(pathname, :username => "root")
|
15
|
+
}.to raise_error(ArgumentError, "Both username and password must be specified")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "raises an error when only the password is provided" do
|
19
|
+
expect {
|
20
|
+
described_class.new(pathname, :password => "hunter2")
|
21
|
+
}.to raise_error(ArgumentError, "Both username and password must be specified")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "does not raise an error when both username and password are provided" do
|
25
|
+
o = described_class.new(pathname, :username => "root", :password => "hunter2")
|
26
|
+
expect(o.username).to eq("root")
|
27
|
+
expect(o.password).to eq("hunter2")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe R10K::SVN::WorkingDir, "when authentication credentials are given" do
|
33
|
+
let(:pathname) { Pathname.new("/some/imaginary/path") }
|
34
|
+
subject { described_class.new(pathname, :username => "root", :password => "hunter2") }
|
35
|
+
|
36
|
+
def check_args(args)
|
37
|
+
expect(args).to include("--username")
|
38
|
+
expect(args).to include("root")
|
39
|
+
expect(args).to include("--password")
|
40
|
+
expect(args).to include("hunter2")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "invokes 'svn checkout' with the given credentials" do
|
44
|
+
expect(subject).to receive(:svn) do |args, _|
|
45
|
+
check_args(args)
|
46
|
+
end
|
47
|
+
subject.checkout('https://some.svn.url/trunk')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "invokes 'svn update' with the given credentials" do
|
51
|
+
expect(subject).to receive(:svn) do |args, _|
|
52
|
+
check_args(args)
|
53
|
+
end
|
54
|
+
subject.update
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r10k/util/attempt'
|
3
|
+
|
4
|
+
describe R10K::Util::Attempt do
|
5
|
+
|
6
|
+
describe "with a single truthy value" do
|
7
|
+
subject(:attempt) { described_class.new("hello") }
|
8
|
+
|
9
|
+
it "invokes the next action with the value" do
|
10
|
+
value = nil
|
11
|
+
attempt.try { |inner| value = inner }
|
12
|
+
attempt.run
|
13
|
+
expect(attempt).to be_ok
|
14
|
+
expect(value).to eq "hello"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns the resulting value from the block" do
|
18
|
+
attempt.try { |inner| inner + " world" }
|
19
|
+
result = attempt.run
|
20
|
+
expect(attempt).to be_ok
|
21
|
+
expect(result).to eq "hello world"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "with a false value" do
|
26
|
+
subject(:attempt) { described_class.new(nil) }
|
27
|
+
|
28
|
+
it "does not evaluate the block" do
|
29
|
+
value = "outside of block"
|
30
|
+
attempt.try { |inner| value = "ran block" }
|
31
|
+
attempt.run
|
32
|
+
expect(attempt).to be_ok
|
33
|
+
expect(value).to eq "outside of block"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "does not continue execution" do
|
37
|
+
attempt.try { |_| "something" }.try { raise }
|
38
|
+
expect(attempt.run).to be_nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "with an array" do
|
43
|
+
subject(:attempt) { described_class.new([1, 2, 3, 4, 5]) }
|
44
|
+
|
45
|
+
it "runs the block for each element in the array" do
|
46
|
+
sum = 0
|
47
|
+
attempt.try { |inner| sum += inner }
|
48
|
+
attempt.run
|
49
|
+
expect(attempt).to be_ok
|
50
|
+
expect(sum).to eq 15
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns the result of the operation on each array member" do
|
54
|
+
sum = 0
|
55
|
+
attempt.try { |inner| sum += inner }
|
56
|
+
result = attempt.run
|
57
|
+
expect(result).to eq([1, 3, 6, 10, 15])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "when an exception is raised" do
|
62
|
+
subject(:attempt) { described_class.new("initial") }
|
63
|
+
|
64
|
+
it "returns the exception" do
|
65
|
+
attempt.try { |_| raise RuntimeError }
|
66
|
+
result = attempt.run
|
67
|
+
expect(attempt).to_not be_ok
|
68
|
+
expect(result).to be_a_kind_of RuntimeError
|
69
|
+
end
|
70
|
+
|
71
|
+
it "does not continue execution" do
|
72
|
+
attempt.try { |_| raise RuntimeError }.try { |_| "This should not be run" }
|
73
|
+
result = attempt.run
|
74
|
+
expect(result).to be_a_kind_of RuntimeError
|
75
|
+
end
|
76
|
+
|
77
|
+
it "only rescues descendants of StandardError" do
|
78
|
+
attempt.try { |_| raise Exception }
|
79
|
+
expect { attempt.run }.to raise_error
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r10k/util/setopts'
|
3
|
+
|
4
|
+
describe R10K::Util::Setopts do
|
5
|
+
let(:klass) do
|
6
|
+
Class.new do
|
7
|
+
include R10K::Util::Setopts
|
8
|
+
|
9
|
+
attr_reader :valid, :alsovalid, :truthyvalid
|
10
|
+
|
11
|
+
def initialize(opts = {})
|
12
|
+
setopts(opts, {
|
13
|
+
:valid => :self, :alsovalid => :self, :truthyvalid => true,
|
14
|
+
:validalias => :valid,
|
15
|
+
:ignoreme => nil
|
16
|
+
})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can handle an empty hash of options" do
|
22
|
+
o = klass.new()
|
23
|
+
expect(o.valid).to be_nil
|
24
|
+
expect(o.alsovalid).to be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "can handle a single valid option" do
|
28
|
+
o = klass.new(:valid => 'yep')
|
29
|
+
expect(o.valid).to eq 'yep'
|
30
|
+
expect(o.alsovalid).to be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can handle multiple valid options" do
|
34
|
+
o = klass.new(:valid => 'yep', :alsovalid => 'yarp')
|
35
|
+
expect(o.valid).to eq 'yep'
|
36
|
+
expect(o.alsovalid).to eq 'yarp'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "can handle options marked with TrueClass" do
|
40
|
+
o = klass.new(:truthyvalid => 'so truthy')
|
41
|
+
expect(o.truthyvalid).to eq 'so truthy'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "can handle aliases marked with :self" do
|
45
|
+
o = klass.new(:validalias => 'yuuup')
|
46
|
+
expect(o.valid).to eq 'yuuup'
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
it "raises an error when given an unhandled option" do
|
51
|
+
expect {
|
52
|
+
klass.new(:valid => 'yep', :notvalid => 'newp')
|
53
|
+
}.to raise_error(ArgumentError, /cannot handle option 'notvalid'/)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "ignores values that are marked as unhandled" do
|
57
|
+
klass.new(:ignoreme => "IGNORE ME!")
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r10k/util/subprocess'
|
3
|
+
|
4
|
+
describe R10K::Util::Subprocess::Result do
|
5
|
+
describe "formatting" do
|
6
|
+
it "includes the exit code" do
|
7
|
+
result = described_class.new(%w[/usr/bin/gti --zoom], '', '', 42)
|
8
|
+
expect(result.format).to match(%r[Exit code: 42])
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "stdout" do
|
12
|
+
it "is omitted when empty" do
|
13
|
+
result = described_class.new(%w[/usr/bin/gti --zoom], '', '', 42)
|
14
|
+
expect(result.format).to_not match(%r[Stdout])
|
15
|
+
end
|
16
|
+
it "is included when non-empty" do
|
17
|
+
result = described_class.new(%w[/usr/bin/gti --zoom], 'stuff here', '', 42)
|
18
|
+
expect(result.format).to match(%r[Stdout:])
|
19
|
+
expect(result.format).to match(%r[stuff here])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "stderr" do
|
24
|
+
it "is omitted when empty" do
|
25
|
+
result = described_class.new(%w[/usr/bin/gti --zoom], '', '', 42)
|
26
|
+
expect(result.format).to_not match(%r[Stderr])
|
27
|
+
end
|
28
|
+
|
29
|
+
it "is included when non-empty" do
|
30
|
+
result = described_class.new(%w[/usr/bin/gti --zoom], '', 'other stuff', 42)
|
31
|
+
expect(result.format).to match(%r[Stderr:])
|
32
|
+
expect(result.format).to match(%r[other stuff])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|