config_curator 0.1.1 → 0.2.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/.rubocop.yml +17 -0
- data/.travis.yml +7 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +6 -1
- data/Guardfile +20 -7
- data/README.md +44 -8
- data/Rakefile +18 -4
- data/config_curator.gemspec +17 -11
- data/lib/.rubocop.yml +4 -0
- data/lib/config_curator.rb +0 -4
- data/lib/config_curator/cli.rb +35 -30
- data/lib/config_curator/collection.rb +75 -48
- data/lib/config_curator/package_lookup.rb +8 -12
- data/lib/config_curator/unit.rb +5 -8
- data/lib/config_curator/units/component.rb +19 -20
- data/lib/config_curator/units/config_file.rb +10 -8
- data/lib/config_curator/units/symlink.rb +2 -5
- data/lib/config_curator/utils.rb +1 -4
- data/lib/config_curator/version.rb +2 -1
- data/spec/.rubocop.yml +7 -0
- data/spec/cli_spec.rb +6 -6
- data/spec/spec_helper.rb +6 -4
- metadata +94 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cc743eac4dc51e37ac3c8c373868ed9b099853e
|
4
|
+
data.tar.gz: c5857e0fc09a20c537069875c4515b706b8d3ebc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 815a4f93e970b6cdeeb9e0fa848d7d6d2c50ed192d20ea4c973b2a885d1900732532418126f52ddc0d9d0c16034e3547c223387b707ee64f0f98d34f376cf4ee
|
7
|
+
data.tar.gz: d0cb7b9cff4ac26b07d1405942871a51ce04f388387736e6bca432d32e16321fc1cd93d88174ed2b50b8177dc00a70b6527831b73f0d4c6409f7eb638fc2693d
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
AllCops:
|
2
|
+
Include:
|
3
|
+
- Gemfile
|
4
|
+
- Guardfile
|
5
|
+
- Rakefile
|
6
|
+
|
7
|
+
Style/PercentLiteralDelimiters:
|
8
|
+
PreferredDelimiters:
|
9
|
+
'%q': '{}'
|
10
|
+
'%Q': '{}'
|
11
|
+
|
12
|
+
Style/RegexpLiteral:
|
13
|
+
Exclude:
|
14
|
+
- Guardfile
|
15
|
+
|
16
|
+
Style/SpaceInsideHashLiteralBraces:
|
17
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/.yardopts
CHANGED
data/CHANGELOG.md
CHANGED
data/Guardfile
CHANGED
@@ -1,10 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
scope groups: [:doc, :lint, :unit]
|
2
|
+
|
3
|
+
group :doc do
|
4
|
+
guard :yard do
|
5
|
+
watch(%r{^lib/(.+)\.rb$})
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
group :lint do
|
10
|
+
guard :rubocop do
|
11
|
+
watch(%r{.+\.rb$})
|
12
|
+
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
|
13
|
+
end
|
6
14
|
end
|
7
15
|
|
8
|
-
|
9
|
-
|
16
|
+
group :unit do
|
17
|
+
guard :rspec, cmd: 'bundle exec rspec --color --format Fuubar' do
|
18
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
19
|
+
watch(%r{^lib/config_curator/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
20
|
+
watch(%r{^spec/.+_spec\.rb$})
|
21
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
22
|
+
end
|
10
23
|
end
|
data/README.md
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
# Config Curator
|
2
2
|
|
3
|
-
by Evan Boyd Sosenko.
|
4
|
-
|
5
|
-
_Simple and intelligent configuration file management._
|
6
|
-
|
7
3
|
[](https://rubygems.org/gems/config_curator)
|
8
4
|
[](./LICENSE.txt)
|
9
5
|
[](https://gemnasium.com/razor-x/config_curator)
|
@@ -11,6 +7,12 @@ _Simple and intelligent configuration file management._
|
|
11
7
|
[](https://coveralls.io/r/razor-x/config_curator)
|
12
8
|
[](https://codeclimate.com/github/razor-x/config_curator)
|
13
9
|
|
10
|
+
by Evan Boyd Sosenko.
|
11
|
+
|
12
|
+
_Simple and intelligent configuration file management._
|
13
|
+
|
14
|
+
## Description
|
15
|
+
|
14
16
|
## Installation
|
15
17
|
|
16
18
|
Add this line to your application's Gemfile:
|
@@ -48,7 +50,9 @@ Config Curator is fully scriptable for easy inclusion into other Ruby programs.
|
|
48
50
|
The API is well documented for this purpose
|
49
51
|
(see [Documentation](#documentation) above).
|
50
52
|
|
51
|
-
##
|
53
|
+
## Development and Testing
|
54
|
+
|
55
|
+
### Source Code
|
52
56
|
|
53
57
|
The [Config Curator source](https://github.com/razor-x/config_curator)
|
54
58
|
is hosted on GitHub.
|
@@ -58,6 +62,37 @@ To clone the project run
|
|
58
62
|
$ git clone https://github.com/razor-x/config_curator.git
|
59
63
|
````
|
60
64
|
|
65
|
+
### Rake
|
66
|
+
|
67
|
+
Run `rake -T` to see all Rake tasks.
|
68
|
+
|
69
|
+
````
|
70
|
+
rake all # Run all tasks
|
71
|
+
rake build # Build config_curator-0.0.0.gem into the pkg directory
|
72
|
+
rake bump:current # Show current gem version
|
73
|
+
rake bump:major # Bump major part of gem version
|
74
|
+
rake bump:minor # Bump minor part of gem version
|
75
|
+
rake bump:patch # Bump patch part of gem version
|
76
|
+
rake bump:pre # Bump pre part of gem version
|
77
|
+
rake bump:set # Sets the version number using the VERSION environment variable
|
78
|
+
rake install # Build and install config_curator-0.0.0.gem into system gems
|
79
|
+
rake release # Create tag v0.0.0 and build and push config_curator-0.0.0.gem to Rubygems
|
80
|
+
rake rubocop # Run RuboCop
|
81
|
+
rake rubocop:auto_correct # Auto-correct RuboCop offenses
|
82
|
+
rake spec # Run RSpec code examples
|
83
|
+
rake yard # Generate YARD Documentation
|
84
|
+
````
|
85
|
+
|
86
|
+
### Guard
|
87
|
+
|
88
|
+
Guard tasks have been separated into the following groups:
|
89
|
+
|
90
|
+
- `doc`
|
91
|
+
- `lint`
|
92
|
+
- `unit`
|
93
|
+
|
94
|
+
By default, Guard will generate documentation, lint, and run unit tests.
|
95
|
+
|
61
96
|
## Contributing
|
62
97
|
|
63
98
|
Please submit and comment on bug reports and feature requests.
|
@@ -66,9 +101,10 @@ To submit a patch:
|
|
66
101
|
|
67
102
|
1. Fork it (https://github.com/razor-x/config_curator/fork).
|
68
103
|
2. Create your feature branch (`git checkout -b my-new-feature`).
|
69
|
-
3.
|
70
|
-
4.
|
71
|
-
5.
|
104
|
+
3. Make changes. Write and run tests.
|
105
|
+
4. Commit your changes (`git commit -am 'Add some feature'`).
|
106
|
+
5. Push to the branch (`git push origin my-new-feature`).
|
107
|
+
6. Create a new Pull Request.
|
72
108
|
|
73
109
|
## License
|
74
110
|
|
data/Rakefile
CHANGED
@@ -1,9 +1,23 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
1
|
require 'bump/tasks'
|
2
|
+
require 'bundler/gem_tasks'
|
3
3
|
require 'rspec/core/rake_task'
|
4
|
+
require 'rubocop/rake_task'
|
5
|
+
require 'yard'
|
6
|
+
|
7
|
+
task default: [:yard, :rubocop, :spec]
|
8
|
+
task travis: [:rubocop, :spec]
|
9
|
+
|
10
|
+
desc 'Run all tasks'
|
11
|
+
task all: [:yard, :rubocop, :spec]
|
4
12
|
|
5
|
-
|
13
|
+
YARD::Config.load_plugin 'redcarpet-ext'
|
14
|
+
YARD::Rake::YardocTask.new do |t|
|
15
|
+
t.files = ['**/*.rb', '-', 'README.md', 'CHANGELOG.md', 'LICENSE.txt']
|
16
|
+
t.options = ['--markup-provider=redcarpet', '--markup=markdown']
|
17
|
+
end
|
6
18
|
|
7
|
-
|
19
|
+
RuboCop::RakeTask.new do |t|
|
20
|
+
t.formatters = ['progress']
|
21
|
+
end
|
8
22
|
|
9
|
-
|
23
|
+
RSpec::Core::RakeTask.new
|
data/config_curator.gemspec
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
lib = File.expand_path('../lib', __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'config_curator/version'
|
@@ -8,14 +7,14 @@ Gem::Specification.new do |spec|
|
|
8
7
|
spec.version = ConfigCurator::VERSION
|
9
8
|
spec.authors = ['Evan Boyd Sosenko']
|
10
9
|
spec.email = ['razorx@evansosenko.com']
|
11
|
-
spec.summary = %q{Simple and intelligent configuration file management.}
|
12
10
|
spec.description = %q{}
|
11
|
+
spec.summary = %q{Simple and intelligent configuration file management.}
|
13
12
|
spec.homepage = 'https://github.com/razor-x/config_curator'
|
14
13
|
spec.license = 'MIT'
|
15
14
|
|
16
|
-
spec.files = `git ls-files
|
15
|
+
spec.files = `git ls-files`.split($/)
|
17
16
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
spec.test_files = spec.files.grep(%r{^(
|
17
|
+
spec.test_files = spec.files.grep(%r{^(features|spec|test)/})
|
19
18
|
spec.require_paths = ['lib']
|
20
19
|
|
21
20
|
spec.required_ruby_version = '>= 2.0.0'
|
@@ -24,17 +23,24 @@ Gem::Specification.new do |spec|
|
|
24
23
|
spec.add_dependency 'thor', '~> 0.19.1'
|
25
24
|
|
26
25
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
27
|
-
spec.add_development_dependency 'rake', '~> 10.3.1'
|
28
26
|
spec.add_development_dependency 'bump', '~> 0.5.0'
|
29
27
|
|
30
|
-
spec.add_development_dependency 'yard', '0.8.7.4'
|
31
|
-
spec.add_development_dependency 'redcarpet', '
|
28
|
+
spec.add_development_dependency 'yard', '~> 0.8.7.4'
|
29
|
+
spec.add_development_dependency 'yard-redcarpet-ext', '~> 0.0.3'
|
30
|
+
spec.add_development_dependency 'redcarpet', '~> 3.1.2'
|
32
31
|
spec.add_development_dependency 'github-markup', '1.2.1'
|
33
32
|
|
34
|
-
spec.add_development_dependency '
|
33
|
+
spec.add_development_dependency 'rubocop', '~> 0.23.0'
|
34
|
+
|
35
|
+
spec.add_development_dependency 'rake', '~> 10.3.2'
|
36
|
+
|
37
|
+
spec.add_development_dependency 'guard', '~> 2.6.1'
|
38
|
+
spec.add_development_dependency 'guard-yard', '~> 2.1.0'
|
39
|
+
spec.add_development_dependency 'guard-rubocop', '~> 1.1.0'
|
40
|
+
spec.add_development_dependency 'guard-rspec', '~> 4.2.9'
|
41
|
+
|
42
|
+
spec.add_development_dependency 'rspec', '~> 3.0.0'
|
35
43
|
spec.add_development_dependency 'simplecov', '~> 0.8.2'
|
36
44
|
spec.add_development_dependency 'coveralls', '~> 0.7.0'
|
37
|
-
spec.add_development_dependency 'fuubar', '~>
|
38
|
-
spec.add_development_dependency 'guard-rspec', '~> 4.2.8'
|
39
|
-
spec.add_development_dependency 'guard-yard', '~> 2.1.1'
|
45
|
+
spec.add_development_dependency 'fuubar', '~> 2.0.0.rc1'
|
40
46
|
end
|
data/lib/.rubocop.yml
ADDED
data/lib/config_curator.rb
CHANGED
data/lib/config_curator/cli.rb
CHANGED
@@ -2,10 +2,8 @@ require 'logger'
|
|
2
2
|
require 'thor'
|
3
3
|
|
4
4
|
module ConfigCurator
|
5
|
-
|
6
5
|
# Thor class for the `curate` command.
|
7
6
|
class CLI < Thor
|
8
|
-
|
9
7
|
default_task :install
|
10
8
|
|
11
9
|
class_option :verbose, type: :boolean, aliases: %i(v)
|
@@ -15,11 +13,12 @@ module ConfigCurator
|
|
15
13
|
# Installs the collection.
|
16
14
|
# @param manifest [String] path to the manifest file to use
|
17
15
|
# @return [Boolean] value of {Collection#install} or {Collection#install?}
|
18
|
-
desc
|
19
|
-
option :dryrun,
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
desc 'install', 'Installs all units in collection.'
|
17
|
+
option :dryrun,
|
18
|
+
type: :boolean, aliases: %i(n),
|
19
|
+
desc: %q{Only simulate the install. Don't make any actual changes.}
|
20
|
+
def install(manifest = 'manifest.yml')
|
21
|
+
unless File.exist? manifest
|
23
22
|
logger.fatal { "Manifest file '#{manifest}' does not exist." }
|
24
23
|
return false
|
25
24
|
end
|
@@ -27,21 +26,12 @@ module ConfigCurator
|
|
27
26
|
collection.load_manifest manifest
|
28
27
|
result = options[:dryrun] ? collection.install? : collection.install
|
29
28
|
|
30
|
-
msg =
|
31
|
-
|
32
|
-
|
33
|
-
elsif result.nil?
|
34
|
-
'failed.'
|
35
|
-
else
|
36
|
-
'failed. No changes were made.'
|
37
|
-
end
|
38
|
-
|
39
|
-
if result then logger.info msg else logger.error msg end
|
40
|
-
return result
|
29
|
+
msg = install_message(result, options[:dryrun])
|
30
|
+
result ? logger.info(msg) : logger.error(msg)
|
31
|
+
result
|
41
32
|
end
|
42
33
|
|
43
34
|
no_commands do
|
44
|
-
|
45
35
|
# Makes a collection object to use for the instance.
|
46
36
|
# @return [Collection] the collection object
|
47
37
|
def collection
|
@@ -56,19 +46,34 @@ module ConfigCurator
|
|
56
46
|
log.formatter = proc do |severity, _, _, msg|
|
57
47
|
"#{severity} -- #{msg}\n"
|
58
48
|
end
|
59
|
-
log.level =
|
60
|
-
if options[:debug]
|
61
|
-
Logger::DEBUG
|
62
|
-
elsif options[:verbose]
|
63
|
-
Logger::INFO
|
64
|
-
elsif options[:quiet]
|
65
|
-
Logger::FATAL
|
66
|
-
else
|
67
|
-
Logger::WARN
|
68
|
-
end
|
49
|
+
log.level = log_level(options)
|
69
50
|
end
|
70
51
|
end
|
71
52
|
end
|
72
|
-
end
|
73
53
|
|
54
|
+
private
|
55
|
+
|
56
|
+
def log_level(options)
|
57
|
+
if options[:debug]
|
58
|
+
Logger::DEBUG
|
59
|
+
elsif options[:verbose]
|
60
|
+
Logger::INFO
|
61
|
+
elsif options[:quiet]
|
62
|
+
Logger::FATAL
|
63
|
+
else
|
64
|
+
Logger::WARN
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def install_message(result, dryrun)
|
69
|
+
"Install #{'simulation ' if dryrun}" + \
|
70
|
+
if result
|
71
|
+
'completed without error.'
|
72
|
+
elsif result.nil?
|
73
|
+
'failed.'
|
74
|
+
else
|
75
|
+
'failed. No changes were made.'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
74
79
|
end
|
@@ -3,30 +3,28 @@ require 'logger'
|
|
3
3
|
require 'yaml'
|
4
4
|
|
5
5
|
module ConfigCurator
|
6
|
-
|
7
6
|
# Manages collections of units.
|
8
7
|
# @example Load a list of units and install them
|
9
8
|
# Collection.new(manifest_path: 'manifest.yml').install
|
10
9
|
class Collection
|
11
|
-
|
12
10
|
# Supported unit types.
|
13
11
|
UNIT_TYPES = %i(unit component config_file symlink)
|
14
12
|
|
15
13
|
# The possible attributes specific to each unit type.
|
16
14
|
# This should not include generic attributes
|
17
15
|
# such as {Unit#source} and {Unit#destination}.
|
18
|
-
|
16
|
+
UNIT_ATTRIBUTES = {
|
19
17
|
unit: %i(hosts packages),
|
20
18
|
component: %i(hosts packages fmode dmode owner group),
|
21
19
|
config_file: %i(hosts packages fmode owner group),
|
22
|
-
symlink: %i(hosts packages)
|
20
|
+
symlink: %i(hosts packages)
|
23
21
|
}
|
24
22
|
|
25
23
|
attr_accessor :logger, :manifest, :units
|
26
24
|
|
27
|
-
def initialize
|
25
|
+
def initialize(manifest_path: nil, logger: nil)
|
28
26
|
self.logger = logger unless logger.nil?
|
29
|
-
|
27
|
+
load_manifest manifest_path unless manifest_path.nil?
|
30
28
|
end
|
31
29
|
|
32
30
|
# Logger instance to use.
|
@@ -40,7 +38,7 @@ module ConfigCurator
|
|
40
38
|
# Loads the manifest from file.
|
41
39
|
# @param file [Hash] the yaml file to load
|
42
40
|
# @return [Hash] the loaded manifest
|
43
|
-
def load_manifest
|
41
|
+
def load_manifest(file)
|
44
42
|
self.manifest = YAML.load_file file
|
45
43
|
end
|
46
44
|
|
@@ -52,32 +50,22 @@ module ConfigCurator
|
|
52
50
|
k = type.to_s.pluralize.to_sym
|
53
51
|
u[k] = []
|
54
52
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
53
|
+
next unless manifest
|
54
|
+
next if manifest[k].nil?
|
55
|
+
|
56
|
+
manifest[k].each { |v| u[k] << create_unit(type, attributes: v) }
|
60
57
|
end
|
61
58
|
end
|
62
59
|
end
|
63
60
|
|
64
61
|
# Installs all units from the manifest.
|
65
|
-
# @return [Boolean, nil] if units were installed or nil
|
62
|
+
# @return [Boolean, nil] if units were installed or nil if fails mid-install
|
66
63
|
def install
|
67
64
|
return false unless install? quiet: !(logger.level == Logger::DEBUG)
|
68
65
|
|
69
|
-
UNIT_TYPES.each do |
|
70
|
-
|
71
|
-
|
72
|
-
units[t.to_s.pluralize.to_sym].each do |unit|
|
73
|
-
begin
|
74
|
-
if unit.install
|
75
|
-
logger.info { "Installed #{type_name}: #{unit.source} ⇨ #{unit.destination_path}" }
|
76
|
-
end
|
77
|
-
rescue Unit::InstallFailed => e
|
78
|
-
logger.fatal { "Halting install! Install attempt failed for #{type_name}: #{e}" }
|
79
|
-
return nil
|
80
|
-
end
|
66
|
+
UNIT_TYPES.each do |type|
|
67
|
+
units[type.to_s.pluralize.to_sym].each do |unit|
|
68
|
+
return nil unless install_unit(unit, type)
|
81
69
|
end
|
82
70
|
end
|
83
71
|
true
|
@@ -86,20 +74,11 @@ module ConfigCurator
|
|
86
74
|
# Checks all units in the manifest for any detectable install issues.
|
87
75
|
# @param quiet [Boolean] suppress some {#logger} output
|
88
76
|
# @return [Boolean] if units can be installed
|
89
|
-
def install?
|
77
|
+
def install?(quiet: false)
|
90
78
|
result = true
|
91
|
-
UNIT_TYPES.each do |
|
92
|
-
|
93
|
-
|
94
|
-
units[t.to_s.pluralize.to_sym].each do |unit|
|
95
|
-
begin
|
96
|
-
if unit.install?
|
97
|
-
logger.info { "Testing install for #{type_name}: #{unit.source} ⇨ #{unit.destination_path}" }
|
98
|
-
end unless quiet
|
99
|
-
rescue Unit::InstallFailed => e
|
100
|
-
result = false
|
101
|
-
logger.error { "Cannot install #{type_name}: #{e}" }
|
102
|
-
end
|
79
|
+
UNIT_TYPES.each do |type|
|
80
|
+
units[type.to_s.pluralize.to_sym].each do |unit|
|
81
|
+
result = install_unit?(unit, type, quiet) ? result : false
|
103
82
|
end
|
104
83
|
end
|
105
84
|
result
|
@@ -107,21 +86,16 @@ module ConfigCurator
|
|
107
86
|
|
108
87
|
# Creates a new unit object for the collection.
|
109
88
|
# @param type [Symbol] a unit type in {UNIT_TYPES}
|
110
|
-
# @param attributes [Hash] attributes for the unit from {
|
89
|
+
# @param attributes [Hash] attributes for the unit from {UNIT_ATTRIBUTES}
|
111
90
|
# @return [Unit] the unit object of the appropriate subclass
|
112
|
-
def create_unit
|
113
|
-
options = {}
|
114
|
-
%i(root package_tool).each do |k|
|
115
|
-
options[k] = manifest[k] unless manifest[k].nil?
|
116
|
-
end if manifest
|
117
|
-
|
91
|
+
def create_unit(type, attributes: {})
|
118
92
|
"#{self.class.name.split('::').first}::#{type.to_s.camelize}".constantize
|
119
|
-
.new(options:
|
93
|
+
.new(options: unit_options, logger: logger).tap do |unit|
|
120
94
|
{src: :source, dst: :destination}.each do |k, v|
|
121
95
|
unit.send "#{v}=".to_sym, attributes[k] unless attributes[k].nil?
|
122
96
|
end
|
123
97
|
|
124
|
-
|
98
|
+
UNIT_ATTRIBUTES[type].each do |v|
|
125
99
|
unit.send "#{v}=".to_sym, defaults[v] unless defaults[v].nil?
|
126
100
|
unit.send "#{v}=".to_sym, attributes[v] unless attributes[v].nil?
|
127
101
|
end
|
@@ -130,11 +104,64 @@ module ConfigCurator
|
|
130
104
|
|
131
105
|
private
|
132
106
|
|
107
|
+
# Formats a unit type for display.
|
108
|
+
# @param type [Symbol] the unit type
|
109
|
+
# @return [String] formatted unit type
|
110
|
+
def type_name(type)
|
111
|
+
type.to_s.humanize capitalize: false
|
112
|
+
end
|
113
|
+
|
133
114
|
# Hash of any defaults given in the manifest.
|
115
|
+
# @return [Hash] the defaults
|
134
116
|
def defaults
|
135
117
|
return {} unless manifest
|
136
118
|
manifest[:defaults].nil? ? {} : manifest[:defaults]
|
137
119
|
end
|
138
|
-
end
|
139
120
|
|
121
|
+
# Load basic unit options from the manifest.
|
122
|
+
# @return [Hash] the options
|
123
|
+
def unit_options
|
124
|
+
options = {}
|
125
|
+
return options unless manifest
|
126
|
+
%i(root package_tool).each do |k|
|
127
|
+
options[k] = manifest[k] unless manifest[k].nil?
|
128
|
+
end
|
129
|
+
options
|
130
|
+
end
|
131
|
+
|
132
|
+
# Installs a unit.
|
133
|
+
# @param unit [Unit] the unit to install
|
134
|
+
# @param type [Symbol] the unit type
|
135
|
+
# @param quiet [Boolean] suppress some {#logger} output
|
136
|
+
# @return [Boolean] if unit was installed
|
137
|
+
def install_unit(unit, type, quiet = false)
|
138
|
+
unit.install
|
139
|
+
logger.info do
|
140
|
+
"Installed #{type_name(type)}: #{unit.source} ⇨ #{unit.destination_path}"
|
141
|
+
end unless quiet
|
142
|
+
return true
|
143
|
+
|
144
|
+
rescue Unit::InstallFailed => e
|
145
|
+
logger.fatal { "Halting install! Install attempt failed for #{type_name(type)}: #{e}" }
|
146
|
+
return false
|
147
|
+
end
|
148
|
+
|
149
|
+
# Checks if a unit can be installed.
|
150
|
+
# @param unit [Unit] the unit to check
|
151
|
+
# @param type [Symbol] the unit type
|
152
|
+
# @param quiet [Boolean] suppress some {#logger} output
|
153
|
+
# @return [Boolean] if unit can be installed
|
154
|
+
def install_unit?(unit, type, quiet = false)
|
155
|
+
unit.install?
|
156
|
+
logger.info do
|
157
|
+
"Testing install for #{type_name(type)}:" \
|
158
|
+
" #{unit.source} ⇨ #{unit.destination_path}"
|
159
|
+
end unless quiet
|
160
|
+
return true
|
161
|
+
|
162
|
+
rescue Unit::InstallFailed => e
|
163
|
+
logger.error { "Cannot install #{type_name(type)}: #{e}" }
|
164
|
+
return false
|
165
|
+
end
|
166
|
+
end
|
140
167
|
end
|
@@ -2,7 +2,6 @@ require 'mkmf'
|
|
2
2
|
require 'open3'
|
3
3
|
|
4
4
|
module ConfigCurator
|
5
|
-
|
6
5
|
# Lookup if a package is installed on the system.
|
7
6
|
# See {TOOLS} for supported package tools.
|
8
7
|
# If {#tool} is not explicitly set, it will try and choose one automatically.
|
@@ -11,7 +10,6 @@ module ConfigCurator
|
|
11
10
|
# @example Lookup a package using `pacman`
|
12
11
|
# PackageLookup.new(tool: :pacman).installed? 'ruby' #=> true
|
13
12
|
class PackageLookup
|
14
|
-
|
15
13
|
include Utils
|
16
14
|
|
17
15
|
# Error when a package lookup cannot be completed.
|
@@ -22,12 +20,12 @@ module ConfigCurator
|
|
22
20
|
TOOLS = {
|
23
21
|
dpkg: 'dpkg',
|
24
22
|
pacman: 'pacman',
|
25
|
-
pkgng: 'pkg'
|
23
|
+
pkgng: 'pkg'
|
26
24
|
}
|
27
25
|
|
28
26
|
attr_accessor :tool, :tools
|
29
27
|
|
30
|
-
def initialize
|
28
|
+
def initialize(tool: nil)
|
31
29
|
self.tool = tool
|
32
30
|
end
|
33
31
|
|
@@ -44,9 +42,8 @@ module ConfigCurator
|
|
44
42
|
return @tool if @tool
|
45
43
|
|
46
44
|
tools.each do |k, v|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
45
|
+
next unless command? v
|
46
|
+
return @tool = k
|
50
47
|
end
|
51
48
|
@tool
|
52
49
|
end
|
@@ -54,7 +51,7 @@ module ConfigCurator
|
|
54
51
|
# Checks if package is installed.
|
55
52
|
# @param package [String] package name to check
|
56
53
|
# @return [Boolean] if package is installed
|
57
|
-
def installed?
|
54
|
+
def installed?(package)
|
58
55
|
fail LookupFailed, 'No supported package tool found.' if tool.nil?
|
59
56
|
|
60
57
|
cmd = tools[tool]
|
@@ -69,26 +66,25 @@ module ConfigCurator
|
|
69
66
|
# Tool specific package lookup methods below.
|
70
67
|
#
|
71
68
|
|
72
|
-
def dpkg
|
69
|
+
def dpkg(package)
|
73
70
|
cmd = command? 'dpkg'
|
74
71
|
Open3.popen3 cmd, '-s', package do |_, _ , _, wait_thr|
|
75
72
|
wait_thr.value.to_i == 0
|
76
73
|
end
|
77
74
|
end
|
78
75
|
|
79
|
-
def pacman
|
76
|
+
def pacman(package)
|
80
77
|
cmd = command? 'pacman'
|
81
78
|
Open3.popen3 cmd, '-qQ', package do |_, _ , _, wait_thr|
|
82
79
|
wait_thr.value.to_i == 0
|
83
80
|
end
|
84
81
|
end
|
85
82
|
|
86
|
-
def pkgng
|
83
|
+
def pkgng(package)
|
87
84
|
cmd = command? 'pkg'
|
88
85
|
Open3.popen3 cmd, 'info', package do |_, _ , _, wait_thr|
|
89
86
|
wait_thr.value.to_i == 0
|
90
87
|
end
|
91
88
|
end
|
92
89
|
end
|
93
|
-
|
94
90
|
end
|
data/lib/config_curator/unit.rb
CHANGED
@@ -2,12 +2,10 @@ require 'logger'
|
|
2
2
|
require 'socket'
|
3
3
|
|
4
4
|
module ConfigCurator
|
5
|
-
|
6
5
|
# A unit is the base class for a type of configuration
|
7
6
|
# that should be installed.
|
8
7
|
# All units must specify a {#source} and a {#destination}.
|
9
8
|
class Unit
|
10
|
-
|
11
9
|
include Utils
|
12
10
|
|
13
11
|
# Error if the unit will fail to install.
|
@@ -21,10 +19,10 @@ module ConfigCurator
|
|
21
19
|
root: Dir.home,
|
22
20
|
|
23
21
|
# Package tool to use. See #package_lookup.
|
24
|
-
package_tool: nil
|
22
|
+
package_tool: nil
|
25
23
|
}
|
26
24
|
|
27
|
-
def initialize
|
25
|
+
def initialize(options: {}, logger: nil)
|
28
26
|
self.options options
|
29
27
|
self.logger = logger unless logger.nil?
|
30
28
|
end
|
@@ -32,7 +30,7 @@ module ConfigCurator
|
|
32
30
|
# Uses {DEFAULT_OPTIONS} as initial value.
|
33
31
|
# @param options [Hash] merged with current options
|
34
32
|
# @return [Hash] current options
|
35
|
-
def options
|
33
|
+
def options(options = {})
|
36
34
|
@options ||= DEFAULT_OPTIONS
|
37
35
|
@options = @options.merge options
|
38
36
|
end
|
@@ -99,7 +97,7 @@ module ConfigCurator
|
|
99
97
|
# Checks if the packages required for this unit are installed.
|
100
98
|
# @return [Boolean] if the packages in {#packages} are installed
|
101
99
|
def packages_installed?
|
102
|
-
packages.map(&method(:pkg_exists?)).delete_if{ |e| e }.empty?
|
100
|
+
packages.map(&method(:pkg_exists?)).delete_if { |e| e }.empty?
|
103
101
|
end
|
104
102
|
|
105
103
|
private
|
@@ -110,9 +108,8 @@ module ConfigCurator
|
|
110
108
|
end
|
111
109
|
|
112
110
|
# @return [Boolean] if the package exists on the system
|
113
|
-
def pkg_exists?
|
111
|
+
def pkg_exists?(pkg)
|
114
112
|
package_lookup.installed? pkg
|
115
113
|
end
|
116
114
|
end
|
117
|
-
|
118
115
|
end
|
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
3
|
module ConfigCurator
|
4
|
-
|
5
4
|
# A component is a folder that should be copied.
|
6
5
|
# The {#destination} will become a mirror of the {#source}.
|
7
6
|
# The contents of the {#destination_path} is
|
8
7
|
# completely replaced by the contents of the {#source_path}.
|
9
8
|
class Component < Unit
|
10
|
-
|
11
9
|
attr_accessor :fmode, :dmode, :owner, :group
|
12
10
|
|
13
11
|
# (see Unit#install)
|
@@ -24,9 +22,9 @@ module ConfigCurator
|
|
24
22
|
def install?
|
25
23
|
s = super
|
26
24
|
return s unless s
|
27
|
-
fail InstallFailed,
|
28
|
-
fail InstallFailed,
|
29
|
-
fail InstallFailed, "Source path does not exist: #{source}" unless Dir.
|
25
|
+
fail InstallFailed, 'No component source path specified.' if source_path.nil?
|
26
|
+
fail InstallFailed, 'No component install path specified.' if destination_path.nil?
|
27
|
+
fail InstallFailed, "Source path does not exist: #{source}" unless Dir.exist? source_path
|
30
28
|
true
|
31
29
|
end
|
32
30
|
|
@@ -40,7 +38,7 @@ module ConfigCurator
|
|
40
38
|
FileUtils.mkdir_p destination_path
|
41
39
|
cmd = [command?('rsync'), '-rt', '--del', "#{source_path}/", destination_path]
|
42
40
|
logger.debug { "Running command: #{cmd.join ' '}" }
|
43
|
-
system
|
41
|
+
system(*cmd)
|
44
42
|
else
|
45
43
|
FileUtils.remove_entry_secure destination_path
|
46
44
|
FileUtils.mkdir_p destination_path
|
@@ -53,14 +51,15 @@ module ConfigCurator
|
|
53
51
|
def set_mode
|
54
52
|
chmod = command? 'chmod'
|
55
53
|
find = command? 'find'
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
54
|
+
|
55
|
+
return unless chmod && find
|
56
|
+
|
57
|
+
{fmode: 'f', dmode: 'd'}.each do |k, v|
|
58
|
+
next if send(k).nil?
|
59
|
+
cmd = [find, destination_path, '-type', v, '-exec']
|
60
|
+
cmd.concat [chmod, send(k).to_s(8), '{}', '+']
|
61
|
+
logger.debug { "Running command: #{cmd.join ' '}" }
|
62
|
+
system(*cmd)
|
64
63
|
end
|
65
64
|
end
|
66
65
|
|
@@ -69,12 +68,12 @@ module ConfigCurator
|
|
69
68
|
def set_owner
|
70
69
|
return unless owner || group
|
71
70
|
chown = command? 'chown'
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
71
|
+
|
72
|
+
return unless chown
|
73
|
+
|
74
|
+
cmd = [chown, '-R', "#{owner}:#{group}", destination_path]
|
75
|
+
logger.debug { "Running command: #{cmd.join ' '}" }
|
76
|
+
system(*cmd)
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
80
79
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module ConfigCurator
|
2
|
-
|
3
2
|
# A config file is a file that should be copied.
|
4
3
|
class ConfigFile < Unit
|
5
|
-
|
6
4
|
attr_accessor :fmode, :owner, :group
|
7
5
|
|
8
6
|
# Will use files of the form `filename.hostname.ext` if found.
|
@@ -10,7 +8,12 @@ module ConfigCurator
|
|
10
8
|
def source
|
11
9
|
path = super
|
12
10
|
host_specific_file = search_for_host_specific_file path if path
|
13
|
-
|
11
|
+
|
12
|
+
if host_specific_file
|
13
|
+
return host_specific_file
|
14
|
+
else
|
15
|
+
return path
|
16
|
+
end
|
14
17
|
end
|
15
18
|
|
16
19
|
# (see Unit#destination)
|
@@ -34,8 +37,8 @@ module ConfigCurator
|
|
34
37
|
def install?
|
35
38
|
s = super
|
36
39
|
return s unless s
|
37
|
-
fail InstallFailed,
|
38
|
-
fail InstallFailed, "Source path does not exist: #{source}" unless File.
|
40
|
+
fail InstallFailed, 'No file source path specified.' if source_path.nil?
|
41
|
+
fail InstallFailed, "Source path does not exist: #{source}" unless File.exist? source_path
|
39
42
|
true
|
40
43
|
end
|
41
44
|
|
@@ -61,11 +64,11 @@ module ConfigCurator
|
|
61
64
|
|
62
65
|
# Will look for files with the naming pattern `filename.hostname.ext`.
|
63
66
|
# @param path [String] path to the non-host-specific file
|
64
|
-
def search_for_host_specific_file
|
67
|
+
def search_for_host_specific_file(path)
|
65
68
|
directory = File.dirname path
|
66
69
|
extension = File.extname path
|
67
70
|
basename = File.basename path.chomp(extension)
|
68
|
-
if Dir.
|
71
|
+
if Dir.exist? directory
|
69
72
|
file = Dir.entries(directory).grep(/^#{basename}.#{hostname.downcase}/).first
|
70
73
|
File.join directory, file unless file.nil?
|
71
74
|
else
|
@@ -73,5 +76,4 @@ module ConfigCurator
|
|
73
76
|
end
|
74
77
|
end
|
75
78
|
end
|
76
|
-
|
77
79
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module ConfigCurator
|
2
|
-
|
3
2
|
# A symlink is a symbolic link that should be created.
|
4
3
|
# The {#destination_path} will be a link
|
5
4
|
# that points to the {#source_path}.
|
6
5
|
class Symlink < Unit
|
7
|
-
|
8
6
|
# (see Unit#install)
|
9
7
|
def install
|
10
8
|
s = super
|
@@ -17,8 +15,8 @@ module ConfigCurator
|
|
17
15
|
def install?
|
18
16
|
s = super
|
19
17
|
return s unless s
|
20
|
-
fail InstallFailed,
|
21
|
-
fail InstallFailed,
|
18
|
+
fail InstallFailed, 'No source file specified.' if source_path.nil?
|
19
|
+
fail InstallFailed, 'No destination specified.' if destination_path.nil?
|
22
20
|
true
|
23
21
|
end
|
24
22
|
|
@@ -30,5 +28,4 @@ module ConfigCurator
|
|
30
28
|
FileUtils.symlink source_path, destination_path, force: true
|
31
29
|
end
|
32
30
|
end
|
33
|
-
|
34
31
|
end
|
data/lib/config_curator/utils.rb
CHANGED
@@ -1,18 +1,15 @@
|
|
1
1
|
module ConfigCurator
|
2
|
-
|
3
2
|
# Utility class.
|
4
3
|
module Utils
|
5
|
-
|
6
4
|
private
|
7
5
|
|
8
6
|
# Checks if command exists.
|
9
7
|
# @param command [String] command name to check
|
10
8
|
# @return [String, nil] full path to command or nil if not found
|
11
|
-
def command?
|
9
|
+
def command?(command)
|
12
10
|
MakeMakefile::Logging.instance_variable_set :@logfile, File::NULL
|
13
11
|
MakeMakefile::Logging.quiet = true
|
14
12
|
MakeMakefile.find_executable command.to_s
|
15
13
|
end
|
16
14
|
end
|
17
|
-
|
18
15
|
end
|
data/spec/.rubocop.yml
ADDED
data/spec/cli_spec.rb
CHANGED
@@ -25,7 +25,7 @@ describe ConfigCurator::CLI do
|
|
25
25
|
describe "#install" do
|
26
26
|
|
27
27
|
it "installs the collection" do
|
28
|
-
allow(File).to receive(:
|
28
|
+
allow(File).to receive(:exist?).with('manifest.yml').and_return(true)
|
29
29
|
expect(cli.collection).to receive(:load_manifest).with('manifest.yml')
|
30
30
|
expect(cli.collection).to receive(:install).and_return(true)
|
31
31
|
expect(cli.install 'manifest.yml').to be true
|
@@ -33,10 +33,10 @@ describe ConfigCurator::CLI do
|
|
33
33
|
|
34
34
|
context "when --dryrun is set" do
|
35
35
|
|
36
|
-
before(:each) { allow(cli).to receive(:options).and_return(
|
36
|
+
before(:each) { allow(cli).to receive(:options).and_return(dryrun: true) }
|
37
37
|
|
38
38
|
it "only checks if install would succeed" do
|
39
|
-
allow(File).to receive(:
|
39
|
+
allow(File).to receive(:exist?).with('manifest.yml').and_return(true)
|
40
40
|
expect(cli.collection).to receive(:load_manifest).with('manifest.yml')
|
41
41
|
expect(cli.collection).to receive(:install?).and_return(true)
|
42
42
|
expect(cli.collection).to_not receive(:install)
|
@@ -47,7 +47,7 @@ describe ConfigCurator::CLI do
|
|
47
47
|
context "manifest not found" do
|
48
48
|
|
49
49
|
it "returns false and doesn't do anything else" do
|
50
|
-
allow(File).to receive(:
|
50
|
+
allow(File).to receive(:exist?).with('manifest.yml').and_return(false)
|
51
51
|
expect(cli.collection).to_not receive(:install)
|
52
52
|
expect(cli.collection).to_not receive(:install?)
|
53
53
|
expect(cli.install 'manifest.yml').to be false
|
@@ -55,10 +55,10 @@ describe ConfigCurator::CLI do
|
|
55
55
|
|
56
56
|
context "when --dryrun is set" do
|
57
57
|
|
58
|
-
before(:each) { allow(cli).to receive(:options).and_return(
|
58
|
+
before(:each) { allow(cli).to receive(:options).and_return(dryrun: true) }
|
59
59
|
|
60
60
|
it "returns false and doesn't do anything else" do
|
61
|
-
allow(File).to receive(:
|
61
|
+
allow(File).to receive(:exist?).with('manifest.yml').and_return(false)
|
62
62
|
expect(cli.collection).to_not receive(:install)
|
63
63
|
expect(cli.collection).to_not receive(:install?)
|
64
64
|
expect(cli.install 'manifest.yml').to be false
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'config_curator'
|
2
|
-
|
3
1
|
require 'coveralls'
|
4
2
|
require 'simplecov'
|
5
3
|
|
@@ -10,9 +8,15 @@ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
|
10
8
|
|
11
9
|
SimpleCov.start
|
12
10
|
|
11
|
+
require 'config_curator'
|
12
|
+
|
13
13
|
RSpec.configure do |c|
|
14
14
|
c.expect_with(:rspec) { |e| e.syntax = :expect }
|
15
15
|
|
16
|
+
c.before(:each) do
|
17
|
+
allow(FileUtils).to receive(:remove_entry_secure).with(anything)
|
18
|
+
end
|
19
|
+
|
16
20
|
stderr = $stderr
|
17
21
|
stdout = $stdout
|
18
22
|
c.before(:all) do
|
@@ -23,6 +27,4 @@ RSpec.configure do |c|
|
|
23
27
|
$stderr = stderr
|
24
28
|
$stdout = stdout
|
25
29
|
end
|
26
|
-
|
27
|
-
c.before(:each) { allow(FileUtils).to receive(:remove_entry_secure).with(anything) }
|
28
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: config_curator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Boyd Sosenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -53,61 +53,61 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.6'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: bump
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 0.5.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.5.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: yard
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: 0.8.7.4
|
76
76
|
type: :development
|
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: 0.
|
82
|
+
version: 0.8.7.4
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name: yard
|
84
|
+
name: yard-redcarpet-ext
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
89
|
+
version: 0.0.3
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
96
|
+
version: 0.0.3
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: redcarpet
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 3.1.
|
103
|
+
version: 3.1.2
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 3.1.
|
110
|
+
version: 3.1.2
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: github-markup
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,89 +123,145 @@ dependencies:
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 1.2.1
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: rubocop
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
131
|
+
version: 0.23.0
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
138
|
+
version: 0.23.0
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
140
|
+
name: rake
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
145
|
+
version: 10.3.2
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
152
|
+
version: 10.3.2
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: guard
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
157
|
- - "~>"
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version:
|
159
|
+
version: 2.6.1
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
164
|
- - "~>"
|
165
165
|
- !ruby/object:Gem::Version
|
166
|
-
version:
|
166
|
+
version: 2.6.1
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
168
|
+
name: guard-yard
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 2.1.0
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 2.1.0
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: guard-rubocop
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
170
184
|
requirements:
|
171
185
|
- - "~>"
|
172
186
|
- !ruby/object:Gem::Version
|
173
|
-
version: 1.
|
187
|
+
version: 1.1.0
|
174
188
|
type: :development
|
175
189
|
prerelease: false
|
176
190
|
version_requirements: !ruby/object:Gem::Requirement
|
177
191
|
requirements:
|
178
192
|
- - "~>"
|
179
193
|
- !ruby/object:Gem::Version
|
180
|
-
version: 1.
|
194
|
+
version: 1.1.0
|
181
195
|
- !ruby/object:Gem::Dependency
|
182
196
|
name: guard-rspec
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
184
198
|
requirements:
|
185
199
|
- - "~>"
|
186
200
|
- !ruby/object:Gem::Version
|
187
|
-
version: 4.2.
|
201
|
+
version: 4.2.9
|
188
202
|
type: :development
|
189
203
|
prerelease: false
|
190
204
|
version_requirements: !ruby/object:Gem::Requirement
|
191
205
|
requirements:
|
192
206
|
- - "~>"
|
193
207
|
- !ruby/object:Gem::Version
|
194
|
-
version: 4.2.
|
208
|
+
version: 4.2.9
|
195
209
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
210
|
+
name: rspec
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: 3.0.0
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: 3.0.0
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: simplecov
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - "~>"
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: 0.8.2
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - "~>"
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: 0.8.2
|
237
|
+
- !ruby/object:Gem::Dependency
|
238
|
+
name: coveralls
|
239
|
+
requirement: !ruby/object:Gem::Requirement
|
240
|
+
requirements:
|
241
|
+
- - "~>"
|
242
|
+
- !ruby/object:Gem::Version
|
243
|
+
version: 0.7.0
|
244
|
+
type: :development
|
245
|
+
prerelease: false
|
246
|
+
version_requirements: !ruby/object:Gem::Requirement
|
247
|
+
requirements:
|
248
|
+
- - "~>"
|
249
|
+
- !ruby/object:Gem::Version
|
250
|
+
version: 0.7.0
|
251
|
+
- !ruby/object:Gem::Dependency
|
252
|
+
name: fuubar
|
197
253
|
requirement: !ruby/object:Gem::Requirement
|
198
254
|
requirements:
|
199
255
|
- - "~>"
|
200
256
|
- !ruby/object:Gem::Version
|
201
|
-
version: 2.
|
257
|
+
version: 2.0.0.rc1
|
202
258
|
type: :development
|
203
259
|
prerelease: false
|
204
260
|
version_requirements: !ruby/object:Gem::Requirement
|
205
261
|
requirements:
|
206
262
|
- - "~>"
|
207
263
|
- !ruby/object:Gem::Version
|
208
|
-
version: 2.
|
264
|
+
version: 2.0.0.rc1
|
209
265
|
description: ''
|
210
266
|
email:
|
211
267
|
- razorx@evansosenko.com
|
@@ -216,6 +272,7 @@ extra_rdoc_files: []
|
|
216
272
|
files:
|
217
273
|
- ".gitignore"
|
218
274
|
- ".rspec"
|
275
|
+
- ".rubocop.yml"
|
219
276
|
- ".travis.yml"
|
220
277
|
- ".yardopts"
|
221
278
|
- CHANGELOG.md
|
@@ -226,6 +283,7 @@ files:
|
|
226
283
|
- Rakefile
|
227
284
|
- bin/curate
|
228
285
|
- config_curator.gemspec
|
286
|
+
- lib/.rubocop.yml
|
229
287
|
- lib/config_curator.rb
|
230
288
|
- lib/config_curator/cli.rb
|
231
289
|
- lib/config_curator/collection.rb
|
@@ -236,6 +294,7 @@ files:
|
|
236
294
|
- lib/config_curator/units/symlink.rb
|
237
295
|
- lib/config_curator/utils.rb
|
238
296
|
- lib/config_curator/version.rb
|
297
|
+
- spec/.rubocop.yml
|
239
298
|
- spec/cli_spec.rb
|
240
299
|
- spec/collection_spec.rb
|
241
300
|
- spec/package_lookup_spec.rb
|
@@ -269,6 +328,7 @@ signing_key:
|
|
269
328
|
specification_version: 4
|
270
329
|
summary: Simple and intelligent configuration file management.
|
271
330
|
test_files:
|
331
|
+
- spec/.rubocop.yml
|
272
332
|
- spec/cli_spec.rb
|
273
333
|
- spec/collection_spec.rb
|
274
334
|
- spec/package_lookup_spec.rb
|