config_curator 0.0.0 → 0.0.1
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/.travis.yml +2 -1
- data/CHANGELOG.md +2 -2
- data/Guardfile +10 -0
- data/README.md +1 -1
- data/Rakefile +2 -0
- data/bin/curate +5 -0
- data/config_curator.gemspec +3 -0
- data/lib/config_curator.rb +8 -0
- data/lib/config_curator/cli.rb +71 -0
- data/lib/config_curator/collection.rb +137 -0
- data/lib/config_curator/package_lookup.rb +77 -0
- data/lib/config_curator/unit.rb +122 -0
- data/lib/config_curator/units/component.rb +76 -0
- data/lib/config_curator/units/config_file.rb +76 -0
- data/lib/config_curator/units/symlink.rb +31 -0
- data/lib/config_curator/version.rb +2 -1
- data/spec/cli_spec.rb +69 -0
- data/spec/collection_spec.rb +280 -0
- data/spec/package_lookup_spec.rb +59 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/unit_spec.rb +190 -0
- data/spec/units/component_spec.rb +59 -0
- data/spec/units/config_file_spec.rb +84 -0
- data/spec/units/symlink_spec.rb +46 -0
- metadata +55 -3
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ConfigCurator::PackageLookup do
|
4
|
+
|
5
|
+
subject(:lookup) { ConfigCurator::PackageLookup.new }
|
6
|
+
|
7
|
+
describe ".new" do
|
8
|
+
|
9
|
+
it "sets the package tool" do
|
10
|
+
lookup = ConfigCurator::PackageLookup.new tool: :dpkg
|
11
|
+
expect(lookup.tool).to eq :dpkg
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#tools" do
|
16
|
+
|
17
|
+
it "uses the default list of tools" do
|
18
|
+
expect(lookup.tools).to eq ConfigCurator::PackageLookup::TOOLS
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#tool" do
|
23
|
+
|
24
|
+
context "when tool is set" do
|
25
|
+
|
26
|
+
it "returns the tool" do
|
27
|
+
lookup.tool = :pacman
|
28
|
+
expect(lookup.tool).to eq :pacman
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when tool not set" do
|
33
|
+
|
34
|
+
it "returns the first avaible tool" do
|
35
|
+
allow(lookup).to receive(:command?).with(:dpkg).and_return(true)
|
36
|
+
lookup.tools = %i(dpkg pacman)
|
37
|
+
expect(lookup.tool).to eq :dpkg
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#installed?" do
|
43
|
+
|
44
|
+
it "calls the corresponding private lookup method" do
|
45
|
+
lookup.tool = :dpkg
|
46
|
+
expect(lookup).to receive(:dpkg).with('rsync')
|
47
|
+
lookup.installed? 'rsync'
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when no package tool found" do
|
51
|
+
|
52
|
+
it "fails" do
|
53
|
+
lookup.tools = %i(dpkg)
|
54
|
+
allow(lookup).to receive(:command?).with(:dpkg).and_return(false)
|
55
|
+
expect { lookup.installed? 'rsync' }.to raise_error ConfigCurator::PackageLookup::LookupFailed
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -12,4 +12,17 @@ SimpleCov.start
|
|
12
12
|
|
13
13
|
RSpec.configure do |c|
|
14
14
|
c.expect_with(:rspec) { |e| e.syntax = :expect }
|
15
|
+
|
16
|
+
stderr = $stderr
|
17
|
+
stdout = $stdout
|
18
|
+
c.before(:all) do
|
19
|
+
$stderr = File.open File::NULL, 'w'
|
20
|
+
$stdout = File.open File::NULL, 'w'
|
21
|
+
end
|
22
|
+
c.after(:all) do
|
23
|
+
$stderr = stderr
|
24
|
+
$stdout = stdout
|
25
|
+
end
|
26
|
+
|
27
|
+
c.before(:each) { allow(FileUtils).to receive(:remove_entry_secure).with(anything) }
|
15
28
|
end
|
data/spec/unit_spec.rb
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ConfigCurator::Unit do
|
4
|
+
|
5
|
+
subject(:unit) { ConfigCurator::Unit.new }
|
6
|
+
|
7
|
+
describe ".new" do
|
8
|
+
|
9
|
+
it "sets the logger" do
|
10
|
+
logger = Logger.new(STDOUT)
|
11
|
+
unit = ConfigCurator::Unit.new logger: logger
|
12
|
+
expect(unit.logger).to be logger
|
13
|
+
end
|
14
|
+
|
15
|
+
it "sets default options" do
|
16
|
+
expect(unit.options).to eq ConfigCurator::Unit::DEFAULT_OPTIONS
|
17
|
+
end
|
18
|
+
|
19
|
+
it "merges default options" do
|
20
|
+
unit = ConfigCurator::Unit.new options: {root: '/home/user'}
|
21
|
+
expect(unit.options).to eq ConfigCurator::Unit::DEFAULT_OPTIONS.merge(root: '/home/user')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#logger" do
|
26
|
+
|
27
|
+
it "makes a new logger" do
|
28
|
+
expect(unit.logger).to be_a Logger
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#options" do
|
33
|
+
|
34
|
+
it "merges with default options" do
|
35
|
+
unit.options[:root] = '/home/user'
|
36
|
+
expect(unit.options).to eq ConfigCurator::Unit::DEFAULT_OPTIONS.merge(root: '/home/user')
|
37
|
+
end
|
38
|
+
|
39
|
+
it "can be called twice and merge options" do
|
40
|
+
unit.options[:root] = '/home/user'
|
41
|
+
unit.options[:perm] = 0600
|
42
|
+
expect(unit.options).to eq ConfigCurator::Unit::DEFAULT_OPTIONS.merge(root: '/home/user', perm: 0600)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#source_path" do
|
47
|
+
|
48
|
+
it "expands the path" do
|
49
|
+
unit.source = 'path/../src_name'
|
50
|
+
expect(unit.source_path).to eq File.expand_path('path/../src_name')
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when no source given" do
|
54
|
+
|
55
|
+
it "returns nil" do
|
56
|
+
expect(unit.source_path).to eq nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#destination_path" do
|
62
|
+
|
63
|
+
it "expands the path" do
|
64
|
+
unit.destination = 'path/../dest_name'
|
65
|
+
unit.options[:root] = '/tmp'
|
66
|
+
expect(unit.destination_path).to eq '/tmp/dest_name'
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when no destination given" do
|
70
|
+
|
71
|
+
it "returns nil" do
|
72
|
+
expect(unit.destination_path).to eq nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#hosts" do
|
78
|
+
|
79
|
+
it "is empty by default" do
|
80
|
+
expect(unit.hosts).to be_a Array
|
81
|
+
expect(unit.hosts).to be_empty
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#packages" do
|
86
|
+
|
87
|
+
it "is empty by default" do
|
88
|
+
expect(unit.packages).to be_a Array
|
89
|
+
expect(unit.packages).to be_empty
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#package_lookup" do
|
94
|
+
|
95
|
+
it "returns a PackageLookup object" do
|
96
|
+
expect(unit.package_lookup).to be_a ConfigCurator::PackageLookup
|
97
|
+
end
|
98
|
+
|
99
|
+
it "sets the correct package tool" do
|
100
|
+
unit.options[:package_tool] = :pkg_tool
|
101
|
+
expect(unit.package_lookup.tool).to eq :pkg_tool
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#install" do
|
106
|
+
|
107
|
+
context "when unit should be installed" do
|
108
|
+
|
109
|
+
it "returns true" do
|
110
|
+
expect(unit).to receive(:install?).and_return(true)
|
111
|
+
expect(unit.install).to be true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when unit should not be installed" do
|
116
|
+
|
117
|
+
it "returns false" do
|
118
|
+
expect(unit).to receive(:install?).and_return(false)
|
119
|
+
expect(unit.install).to be false
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "#install?" do
|
125
|
+
|
126
|
+
it "checks if host is allowed" do
|
127
|
+
expect(unit).to receive(:allowed_host?)
|
128
|
+
unit.install?
|
129
|
+
end
|
130
|
+
|
131
|
+
it "checks if package requirements are met" do
|
132
|
+
expect(unit).to receive(:packages_installed?)
|
133
|
+
unit.install?
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#allowed_host?" do
|
138
|
+
|
139
|
+
context "when hosts are given" do
|
140
|
+
|
141
|
+
it "allows host if host is listed" do
|
142
|
+
allow(unit).to receive(:hostname).and_return('test_hostname')
|
143
|
+
unit.hosts = %w(some_host test_hostname)
|
144
|
+
expect(unit.allowed_host?).to eq true
|
145
|
+
end
|
146
|
+
|
147
|
+
it "does not allow unlisted host" do
|
148
|
+
allow(unit).to receive(:hostname).and_return('bad_test_hostname')
|
149
|
+
unit.hosts = %w(some_host test_hostname)
|
150
|
+
expect(unit.allowed_host?).to eq false
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "when no hosts are given" do
|
155
|
+
|
156
|
+
it "allows any host" do
|
157
|
+
unit.hosts = []
|
158
|
+
expect(unit.allowed_host?).to eq true
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "#packages_installed?" do
|
164
|
+
|
165
|
+
context "when packages listed" do
|
166
|
+
|
167
|
+
it "meets package requirements if no missing packages" do
|
168
|
+
allow(unit).to receive(:pkg_exists?).with('good_pkg_1').and_return(true)
|
169
|
+
allow(unit).to receive(:pkg_exists?).with('good_pkg_2').and_return(true)
|
170
|
+
unit.packages = %w(good_pkg_1 good_pkg_2)
|
171
|
+
expect(unit.packages_installed?).to eq true
|
172
|
+
end
|
173
|
+
|
174
|
+
it "does not meet package requirements if missing packages" do
|
175
|
+
allow(unit).to receive(:pkg_exists?).with('good_pkg').and_return(true)
|
176
|
+
allow(unit).to receive(:pkg_exists?).with('bad_pkg').and_return(false)
|
177
|
+
unit.packages = %w(good_pkg bad_pkg)
|
178
|
+
expect(unit.packages_installed?).to eq false
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "when no packages listed" do
|
183
|
+
|
184
|
+
it "meets package requirements" do
|
185
|
+
unit.packages = []
|
186
|
+
expect(unit.packages_installed?).to eq true
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ConfigCurator::Component do
|
4
|
+
|
5
|
+
subject(:component) { ConfigCurator::Component.new }
|
6
|
+
|
7
|
+
describe "#install" do
|
8
|
+
|
9
|
+
context "when component should be installed" do
|
10
|
+
|
11
|
+
it "installs the component and returns true" do
|
12
|
+
expect(component).to receive(:install?).and_return(true)
|
13
|
+
expect(component).to receive(:install_component)
|
14
|
+
expect(component).to receive(:set_mode)
|
15
|
+
expect(component).to receive(:set_owner)
|
16
|
+
expect(component.install).to be true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when component should not be installed" do
|
21
|
+
|
22
|
+
it "does not install the component and returns false" do
|
23
|
+
expect(component).to receive(:install?).and_return(false)
|
24
|
+
expect(component).to_not receive(:install_component)
|
25
|
+
expect(component).to_not receive(:set_mode)
|
26
|
+
expect(component).to_not receive(:set_owner)
|
27
|
+
expect(component.install).to be false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#install?" do
|
33
|
+
|
34
|
+
context "when source not given" do
|
35
|
+
|
36
|
+
it "fails" do
|
37
|
+
component.destination = 'inst_path'
|
38
|
+
expect { component.install? }.to raise_error ConfigCurator::Symlink::InstallFailed
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when destination not given" do
|
43
|
+
|
44
|
+
it "fails" do
|
45
|
+
component.source = 'dir'
|
46
|
+
expect { component.install? }.to raise_error ConfigCurator::Symlink::InstallFailed
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when source does not exist" do
|
51
|
+
|
52
|
+
it "fails" do
|
53
|
+
component.destination = 'inst_path'
|
54
|
+
component.source = 'dir/that/does/not/exist'
|
55
|
+
expect { component.install? }.to raise_error ConfigCurator::Symlink::InstallFailed
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ConfigCurator::ConfigFile do
|
4
|
+
|
5
|
+
subject(:config_file) { ConfigCurator::ConfigFile.new }
|
6
|
+
|
7
|
+
describe "#destination" do
|
8
|
+
|
9
|
+
it "uses the source path to set the destination" do
|
10
|
+
config_file.source = 'path/to/file'
|
11
|
+
expect(config_file.destination).to eq 'path/to/file'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#source" do
|
16
|
+
|
17
|
+
context "when host-specific file not found" do
|
18
|
+
|
19
|
+
let(:source) { 'path/../src_name.ext' }
|
20
|
+
|
21
|
+
it "returns the source path" do
|
22
|
+
config_file.source = source
|
23
|
+
allow(config_file).to receive(:search_for_host_specific_file).with(source)
|
24
|
+
.and_return(nil)
|
25
|
+
expect(config_file.source).to eq source
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when host-specific file found" do
|
30
|
+
|
31
|
+
let(:source) { 'path/../src_name.ext' }
|
32
|
+
|
33
|
+
it "returns the host-specific source path" do
|
34
|
+
config_file.source = source
|
35
|
+
allow(config_file).to receive(:search_for_host_specific_file).with(source)
|
36
|
+
.and_return('path/../src_name.hostname.ext')
|
37
|
+
expect(config_file.source).to eq 'path/../src_name.hostname.ext'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#install" do
|
43
|
+
|
44
|
+
context "when config file should be installed" do
|
45
|
+
|
46
|
+
it "installs the config file and returns true" do
|
47
|
+
expect(config_file).to receive(:install?).and_return(true)
|
48
|
+
expect(config_file).to receive(:install_file)
|
49
|
+
expect(config_file).to receive(:set_mode)
|
50
|
+
expect(config_file).to receive(:set_owner)
|
51
|
+
expect(config_file.install).to be true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when config file should not be installed" do
|
56
|
+
|
57
|
+
it "does not install the config file and returns false" do
|
58
|
+
expect(config_file).to receive(:install?).and_return(false)
|
59
|
+
expect(config_file).to_not receive(:install_file)
|
60
|
+
expect(config_file).to_not receive(:set_mode)
|
61
|
+
expect(config_file).to_not receive(:set_owner)
|
62
|
+
expect(config_file.install).to be false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#install?" do
|
68
|
+
|
69
|
+
context "when source not given" do
|
70
|
+
|
71
|
+
it "fails" do
|
72
|
+
expect { config_file.install? }.to raise_error ConfigCurator::Symlink::InstallFailed
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when source does not exist" do
|
77
|
+
|
78
|
+
it "fails" do
|
79
|
+
config_file.source = 'dir/that/does/not/exist'
|
80
|
+
expect { config_file.install? }.to raise_error ConfigCurator::Symlink::InstallFailed
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ConfigCurator::Symlink do
|
4
|
+
|
5
|
+
subject(:symlink) { ConfigCurator::Symlink.new }
|
6
|
+
|
7
|
+
describe "#install" do
|
8
|
+
|
9
|
+
context "when symbolic link should be installed" do
|
10
|
+
|
11
|
+
it "installs the symbolic link and returns true" do
|
12
|
+
expect(symlink).to receive(:install?).and_return true
|
13
|
+
expect(symlink).to receive(:install_symlink)
|
14
|
+
expect(symlink.install).to be true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when symbolic link should not be installed" do
|
19
|
+
|
20
|
+
it "does not install the symbolic link and returns false" do
|
21
|
+
expect(symlink).to receive(:install?).and_return false
|
22
|
+
expect(symlink).to_not receive(:install_symlink)
|
23
|
+
expect(symlink.install).to be false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#install?" do
|
29
|
+
|
30
|
+
context "when source not given" do
|
31
|
+
|
32
|
+
it "fails" do
|
33
|
+
symlink.destination = 'link_path'
|
34
|
+
expect { symlink.install? }.to raise_error ConfigCurator::Symlink::InstallFailed
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when destination not given" do
|
39
|
+
|
40
|
+
it "fails" do
|
41
|
+
symlink.source = 'file'
|
42
|
+
expect { symlink.install? }.to raise_error ConfigCurator::Symlink::InstallFailed
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|