inspec 3.0.0 → 3.0.9
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/CHANGELOG.md +27 -10
- data/etc/plugin_filters.json +9 -1
- data/inspec.gemspec +1 -1
- data/lib/inspec/plugin/v2/installer.rb +4 -1
- data/lib/inspec/plugin/v2/plugin_types/cli.rb +17 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +1 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb +8 -0
- data/lib/plugins/shared/core_plugin_test_helper.rb +1 -0
- data/lib/resources/docker.rb +17 -17
- data/lib/resources/groups.rb +2 -12
- data/lib/utils/filter.rb +22 -2
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6f49689c3694c4ec3a2c9128df201e1ac81ffdf4981948d343d5396ed6599f1b
|
|
4
|
+
data.tar.gz: cc3f864f342fba8a7f404f69727e807cb12a397683ae2e2a217d4efd89a25586
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1dc4515fa59a0412e2c97d2a3b2ccc80fda17b93d823e9865eb14428da5c58d3dedadc59e999c97fc09d9c5290840176403fb8d5b5d03bc9508a34f1e9fc5f79
|
|
7
|
+
data.tar.gz: 779e7a23b102ebe6cb28d4d6ba03e95c0975691d6835ee830f40e52ad326deeb450e1a3e90f8503d013eef10251706aab2d85fb4fb8b10ffab86d229cc505a41
|
data/CHANGELOG.md
CHANGED
|
@@ -1,29 +1,46 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
<!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ -->
|
|
3
|
-
<!-- latest_release
|
|
4
|
-
##
|
|
3
|
+
<!-- latest_release 3.0.9 -->
|
|
4
|
+
## [v3.0.9](https://github.com/inspec/inspec/tree/v3.0.9) (2018-10-18)
|
|
5
5
|
|
|
6
|
-
####
|
|
7
|
-
-
|
|
6
|
+
#### Merged Pull Requests
|
|
7
|
+
- Add missing tests for groups resource, document members property, and assorted fixes. [#3467](https://github.com/inspec/inspec/pull/3467) ([miah](https://github.com/miah))
|
|
8
8
|
<!-- latest_release -->
|
|
9
9
|
|
|
10
|
-
<!-- release_rollup since=
|
|
11
|
-
### Changes since
|
|
10
|
+
<!-- release_rollup since=3.0.0 -->
|
|
11
|
+
### Changes since 3.0.0 release
|
|
12
12
|
|
|
13
13
|
#### Enhancements
|
|
14
|
-
-
|
|
14
|
+
- Minor cleanups of plugin documentation. 'Plugin' instead of 'PluginDefinition' [#3527](https://github.com/inspec/inspec/pull/3527) ([mattray](https://github.com/mattray)) <!-- 3.0.5 -->
|
|
15
|
+
|
|
16
|
+
#### Bug Fixes
|
|
17
|
+
- Fixes corrupt plugins.json when testing a plugin outside of core [#3526](https://github.com/inspec/inspec/pull/3526) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 3.0.7 -->
|
|
18
|
+
- FilterTable: allow Strings or Symbols as fields [#3481](https://github.com/inspec/inspec/pull/3481) ([clintoncwolfe](https://github.com/clintoncwolfe)) <!-- 3.0.2 -->
|
|
15
19
|
|
|
16
20
|
#### Merged Pull Requests
|
|
17
|
-
-
|
|
18
|
-
-
|
|
21
|
+
- Add missing tests for groups resource, document members property, and assorted fixes. [#3467](https://github.com/inspec/inspec/pull/3467) ([miah](https://github.com/miah)) <!-- 3.0.9 -->
|
|
22
|
+
- Pin inspec to the new train [#3531](https://github.com/inspec/inspec/pull/3531) ([jquick](https://github.com/jquick)) <!-- 3.0.8 -->
|
|
23
|
+
- Add debug and sort options for plugins [#3530](https://github.com/inspec/inspec/pull/3530) ([jquick](https://github.com/jquick)) <!-- 3.0.6 -->
|
|
24
|
+
- docs: Fix small issues with the `file` resource [#3515](https://github.com/inspec/inspec/pull/3515) ([jerryaldrichiii](https://github.com/jerryaldrichiii)) <!-- 3.0.4 -->
|
|
25
|
+
- Filter out inspec-k8s and inspec-release [#3525](https://github.com/inspec/inspec/pull/3525) ([miah](https://github.com/miah)) <!-- 3.0.3 -->
|
|
26
|
+
- style: Fix quotes/style on the `docker` resource [#3516](https://github.com/inspec/inspec/pull/3516) ([jerryaldrichiii](https://github.com/jerryaldrichiii)) <!-- 3.0.1 -->
|
|
19
27
|
<!-- release_rollup -->
|
|
20
28
|
|
|
21
29
|
<!-- latest_stable_release -->
|
|
30
|
+
## [v3.0.0](https://github.com/inspec/inspec/tree/v3.0.0) (2018-10-15)
|
|
31
|
+
|
|
32
|
+
#### Enhancements
|
|
33
|
+
- Inspec 3.0 [#3512](https://github.com/inspec/inspec/pull/3512) ([jquick](https://github.com/jquick))
|
|
34
|
+
|
|
35
|
+
#### Merged Pull Requests
|
|
36
|
+
- Change `Inspec ` to `InSpec ` where appropriate [#3494](https://github.com/inspec/inspec/pull/3494) ([jerryaldrichiii](https://github.com/jerryaldrichiii))
|
|
37
|
+
- Update the text on the generic default attribute [#3508](https://github.com/inspec/inspec/pull/3508) ([jquick](https://github.com/jquick))
|
|
38
|
+
<!-- latest_stable_release -->
|
|
39
|
+
|
|
22
40
|
## [v2.3.24](https://github.com/inspec/inspec/tree/v2.3.24) (2018-10-12)
|
|
23
41
|
|
|
24
42
|
#### Bug Fixes
|
|
25
43
|
- Fix plugin install issues in different ruby envs [#3505](https://github.com/inspec/inspec/pull/3505) ([jquick](https://github.com/jquick))
|
|
26
|
-
<!-- latest_stable_release -->
|
|
27
44
|
|
|
28
45
|
## [v2.3.23](https://github.com/inspec/inspec/tree/v2.3.23) (2018-10-12)
|
|
29
46
|
|
data/etc/plugin_filters.json
CHANGED
|
@@ -5,10 +5,18 @@
|
|
|
5
5
|
"plugin_name": "inspec-core",
|
|
6
6
|
"rationale": "This gem is a stripped-down alternate packaging of InSpec. It is not a plugin."
|
|
7
7
|
},
|
|
8
|
+
{
|
|
9
|
+
"plugin_name": "inspec-k8s",
|
|
10
|
+
"rationale": "This gem is currently only a placeholder, waiting to be built."
|
|
11
|
+
},
|
|
8
12
|
{
|
|
9
13
|
"plugin_name": "inspec-multi-server",
|
|
10
14
|
"rationale": "This gem is a script that attempts to drive a parallel execution of InSpec by wrapping and forking. It is not a plugin."
|
|
11
15
|
},
|
|
16
|
+
{
|
|
17
|
+
"plugin_name": "inspec-release",
|
|
18
|
+
"rationale": "It is not plugin."
|
|
19
|
+
},
|
|
12
20
|
{
|
|
13
21
|
"plugin_name": "train-tax-calculator",
|
|
14
22
|
"rationale": "This gem is a tax calculation tool for the Philippines. It has nothing to do the Chef Train remote execution framework, or the InSpec project."
|
|
@@ -22,4 +30,4 @@
|
|
|
22
30
|
"rationale": "This gem is a stripped-down alternate packaging of Train. It is not a plugin."
|
|
23
31
|
}
|
|
24
32
|
]
|
|
25
|
-
}
|
|
33
|
+
}
|
data/inspec.gemspec
CHANGED
|
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
|
|
|
26
26
|
|
|
27
27
|
spec.required_ruby_version = '>= 2.3'
|
|
28
28
|
|
|
29
|
-
spec.add_dependency 'train', '~> 1.5'
|
|
29
|
+
spec.add_dependency 'train', '~> 1.5', '>= 1.5.4'
|
|
30
30
|
spec.add_dependency 'thor', '~> 0.20'
|
|
31
31
|
spec.add_dependency 'json', '>= 1.8', '< 3.0'
|
|
32
32
|
spec.add_dependency 'method_source', '~> 0.8'
|
|
@@ -119,7 +119,7 @@ module Inspec::Plugin::V2
|
|
|
119
119
|
# @option opts [TrueClass, FalseClass] :exact If true, use plugin_search_term exactly. If false (default), append a wildcard.
|
|
120
120
|
# @option opts [Symbol] :scope Which versions to search for. :released (default) - all released versions. :prerelease - Also include versioned marked prerelease. :latest - only return one version, the latest one.
|
|
121
121
|
# @return [Hash of Arrays] - Keys are String names of gems, arrays contain String versions.
|
|
122
|
-
def search(plugin_query, opts = {})
|
|
122
|
+
def search(plugin_query, opts = {}) # rubocop: disable Metrics/AbcSize
|
|
123
123
|
validate_search_opts(plugin_query, opts)
|
|
124
124
|
|
|
125
125
|
fetcher = Gem::SpecFetcher.fetcher
|
|
@@ -133,6 +133,9 @@ module Inspec::Plugin::V2
|
|
|
133
133
|
end
|
|
134
134
|
end
|
|
135
135
|
|
|
136
|
+
# sort tuples
|
|
137
|
+
matched_tuples.sort! { |a, b| b.first.version <=> a.first.version }
|
|
138
|
+
|
|
136
139
|
gem_info = {}
|
|
137
140
|
matched_tuples.each do |tuple|
|
|
138
141
|
gem_info[tuple.first.name] ||= []
|
|
@@ -2,6 +2,16 @@ require 'inspec/base_cli'
|
|
|
2
2
|
|
|
3
3
|
module Inspec::Plugin::V2::PluginType
|
|
4
4
|
class CliCommand < Inspec::BaseCLI
|
|
5
|
+
# initalize log options for plugins
|
|
6
|
+
def initialize(args, options, config)
|
|
7
|
+
super(args, options, config)
|
|
8
|
+
class_options = config.fetch(:class_options, nil)
|
|
9
|
+
if class_options
|
|
10
|
+
Inspec::Log.init(class_options['log_location']) if class_options.key?('log_location')
|
|
11
|
+
Inspec::Log.level = get_log_level(class_options['log_level']) if class_options.key?('log_level')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
5
15
|
# This class MUST inherit from Thor, which makes it a bit awkward to register the plugin subtype
|
|
6
16
|
# Since we can't inherit from PluginBase, we use the two-arg form of register_plugin_type
|
|
7
17
|
Inspec::Plugin::V2::PluginBase.register_plugin_type(:cli_command, self)
|
|
@@ -23,5 +33,12 @@ module Inspec::Plugin::V2::PluginType
|
|
|
23
33
|
# Register with Thor
|
|
24
34
|
Inspec::InspecCLI.register(self, subcommand_name, @usage_msg, @desc_msg, {})
|
|
25
35
|
end
|
|
36
|
+
|
|
37
|
+
# Allow plugins to use inspec log settings
|
|
38
|
+
class_option :log_level, type: :string,
|
|
39
|
+
desc: 'Set the log level: info (default), debug, warn, error'
|
|
40
|
+
|
|
41
|
+
class_option :log_location, type: :string,
|
|
42
|
+
desc: 'Location to send diagnostic log messages to. (default: STDOUT or Inspec::Log.error)'
|
|
26
43
|
end
|
|
27
44
|
end
|
data/lib/inspec/version.rb
CHANGED
|
@@ -367,6 +367,7 @@ module InspecPlugins
|
|
|
367
367
|
puts 'If you disagree with this determination, please accept our apologies for the misunderstanding, and open an issue at https://github.com/inspec/inspec/issues/new'
|
|
368
368
|
exit 2
|
|
369
369
|
rescue Inspec::Plugin::V2::InstallError
|
|
370
|
+
raise if Inspec::Log.level == :debug
|
|
370
371
|
results = installer.search(plugin_name, exact: true)
|
|
371
372
|
if results.empty?
|
|
372
373
|
puts(red { 'No such plugin gem ' } + plugin_name + ' could be found on rubygems.org - installation failed.')
|
|
@@ -567,6 +567,14 @@ class PluginManagerCliInstall < MiniTest::Test
|
|
|
567
567
|
assert_includes refusal_message, 'github.com/inspec/inspec/issues/new'
|
|
568
568
|
end
|
|
569
569
|
end
|
|
570
|
+
|
|
571
|
+
def test_error_install_with_debug_enabled
|
|
572
|
+
install_result = run_inspec_process_with_this_plugin('plugin install inspec-test-fixture -v 0.1.1 --log-level debug')
|
|
573
|
+
|
|
574
|
+
assert_equal 1, install_result.exit_status, 'Exit status should be 1'
|
|
575
|
+
assert_includes install_result.stdout, 'DEBUG'
|
|
576
|
+
assert_includes install_result.stderr, "can't activate rake"
|
|
577
|
+
end
|
|
570
578
|
end
|
|
571
579
|
|
|
572
580
|
|
data/lib/resources/docker.rb
CHANGED
|
@@ -37,13 +37,13 @@ module Inspec::Resources
|
|
|
37
37
|
class DockerImageFilter
|
|
38
38
|
filter = FilterTable.create
|
|
39
39
|
filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
|
|
40
|
-
filter.register_column(:ids,
|
|
41
|
-
.register_column(:repositories,
|
|
42
|
-
.register_column(:tags,
|
|
43
|
-
.register_column(:sizes,
|
|
44
|
-
.register_column(:digests,
|
|
45
|
-
.register_column(:created,
|
|
46
|
-
.register_column(:created_since,
|
|
40
|
+
filter.register_column(:ids, field: 'id')
|
|
41
|
+
.register_column(:repositories, field: 'repository')
|
|
42
|
+
.register_column(:tags, field: 'tag')
|
|
43
|
+
.register_column(:sizes, field: 'size')
|
|
44
|
+
.register_column(:digests, field: 'digest')
|
|
45
|
+
.register_column(:created, field: 'createdat')
|
|
46
|
+
.register_column(:created_since, field: 'createdsize')
|
|
47
47
|
filter.install_filter_methods_on_resource(self, :images)
|
|
48
48
|
|
|
49
49
|
attr_reader :images
|
|
@@ -54,10 +54,10 @@ module Inspec::Resources
|
|
|
54
54
|
|
|
55
55
|
class DockerPluginFilter
|
|
56
56
|
filter = FilterTable.create
|
|
57
|
-
filter.add(:ids,
|
|
58
|
-
.add(:names,
|
|
59
|
-
.add(:versions,
|
|
60
|
-
.add(:enabled,
|
|
57
|
+
filter.add(:ids, field: 'id')
|
|
58
|
+
.add(:names, field: 'name')
|
|
59
|
+
.add(:versions, field: 'version')
|
|
60
|
+
.add(:enabled, field: 'enabled')
|
|
61
61
|
filter.connect(self, :plugins)
|
|
62
62
|
|
|
63
63
|
attr_reader :plugins
|
|
@@ -69,12 +69,12 @@ module Inspec::Resources
|
|
|
69
69
|
class DockerServiceFilter
|
|
70
70
|
filter = FilterTable.create
|
|
71
71
|
filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
|
|
72
|
-
filter.register_column(:ids,
|
|
73
|
-
.register_column(:names,
|
|
74
|
-
.register_column(:modes,
|
|
75
|
-
.register_column(:replicas,
|
|
76
|
-
.register_column(:images,
|
|
77
|
-
.register_column(:ports,
|
|
72
|
+
filter.register_column(:ids, field: 'id')
|
|
73
|
+
.register_column(:names, field: 'name')
|
|
74
|
+
.register_column(:modes, field: 'mode')
|
|
75
|
+
.register_column(:replicas, field: 'replicas')
|
|
76
|
+
.register_column(:images, field: 'image')
|
|
77
|
+
.register_column(:ports, field: 'ports')
|
|
78
78
|
filter.install_filter_methods_on_resource(self, :services)
|
|
79
79
|
|
|
80
80
|
attr_reader :services
|
data/lib/resources/groups.rb
CHANGED
|
@@ -51,7 +51,7 @@ module Inspec::Resources
|
|
|
51
51
|
filter.register_column(:names, field: 'name')
|
|
52
52
|
.register_column(:gids, field: 'gid')
|
|
53
53
|
.register_column(:domains, field: 'domain')
|
|
54
|
-
.register_column(:members, field: 'members')
|
|
54
|
+
.register_column(:members, field: 'members', style: :simple)
|
|
55
55
|
filter.install_filter_methods_on_resource(self, :collect_group_details)
|
|
56
56
|
|
|
57
57
|
def to_s
|
|
@@ -73,10 +73,6 @@ module Inspec::Resources
|
|
|
73
73
|
# its('gid') { should eq 0 }
|
|
74
74
|
# end
|
|
75
75
|
#
|
|
76
|
-
# deprecated has matcher
|
|
77
|
-
# describe group('root') do
|
|
78
|
-
# it { should have_gid 0 }
|
|
79
|
-
# end
|
|
80
76
|
class Group < Inspec.resource(1)
|
|
81
77
|
include GroupManagementSelector
|
|
82
78
|
|
|
@@ -112,13 +108,7 @@ module Inspec::Resources
|
|
|
112
108
|
flatten_entry(group_info, 'gid')
|
|
113
109
|
end
|
|
114
110
|
|
|
115
|
-
# implements rspec has matcher, to be compatible with serverspec
|
|
116
|
-
def has_gid?(compare_gid)
|
|
117
|
-
gid == compare_gid
|
|
118
|
-
end
|
|
119
|
-
|
|
120
111
|
def members
|
|
121
|
-
return unless inspec.os.windows?
|
|
122
112
|
flatten_entry(group_info, 'members')
|
|
123
113
|
end
|
|
124
114
|
|
|
@@ -223,7 +213,7 @@ module Inspec::Resources
|
|
|
223
213
|
end
|
|
224
214
|
|
|
225
215
|
# ensure we have an array of groups
|
|
226
|
-
groups = [groups]
|
|
216
|
+
groups = [groups] unless groups.is_a?(Array)
|
|
227
217
|
groups
|
|
228
218
|
end
|
|
229
219
|
end
|
data/lib/utils/filter.rb
CHANGED
|
@@ -106,7 +106,7 @@ module FilterTable
|
|
|
106
106
|
# If we were provided params, interpret them as criteria to be evaluated
|
|
107
107
|
# against the raw data. Criteria are assumed to be hash keys.
|
|
108
108
|
conditions.each do |raw_field_name, desired_value|
|
|
109
|
-
raise(ArgumentError, "'#{raw_field_name}' is not a recognized criterion - expected one of #{list_fields.join(', ')}'") unless field?(raw_field_name)
|
|
109
|
+
raise(ArgumentError, "'#{decorate_symbols(raw_field_name)}' is not a recognized criterion - expected one of #{decorate_symbols(list_fields).join(', ')}'") unless field?(raw_field_name)
|
|
110
110
|
populate_lazy_field(raw_field_name, desired_value) if is_field_lazy?(raw_field_name)
|
|
111
111
|
new_criteria_string += " #{raw_field_name} == #{desired_value.inspect}"
|
|
112
112
|
filtered_raw_data = filter_raw_data(filtered_raw_data, raw_field_name, desired_value)
|
|
@@ -175,7 +175,15 @@ module FilterTable
|
|
|
175
175
|
# Currently we only know about a field if it is present in a at least one row of the raw data.
|
|
176
176
|
# If we have no rows in the raw data, assume all fields are acceptable (and rely on failing to match on value, nil)
|
|
177
177
|
return true if raw_data.empty?
|
|
178
|
-
|
|
178
|
+
|
|
179
|
+
# Most resources have Symbol keys in their raw data. Some have Strings (looking at you, `shadow`).
|
|
180
|
+
is_field = false
|
|
181
|
+
is_field ||= list_fields.include?(proposed_field.to_s)
|
|
182
|
+
is_field ||= list_fields.include?(proposed_field.to_sym)
|
|
183
|
+
is_field ||= is_field_lazy?(proposed_field.to_s)
|
|
184
|
+
is_field ||= is_field_lazy?(proposed_field.to_sym)
|
|
185
|
+
|
|
186
|
+
is_field
|
|
179
187
|
end
|
|
180
188
|
|
|
181
189
|
def to_s
|
|
@@ -240,6 +248,8 @@ module FilterTable
|
|
|
240
248
|
end
|
|
241
249
|
|
|
242
250
|
def filter_raw_data(current_raw_data, field, desired_value)
|
|
251
|
+
return [] if current_raw_data.empty?
|
|
252
|
+
|
|
243
253
|
method_ref = case desired_value
|
|
244
254
|
when Float then method(:matches_float)
|
|
245
255
|
when Integer then method(:matches_int)
|
|
@@ -247,11 +257,21 @@ module FilterTable
|
|
|
247
257
|
else method(:matches)
|
|
248
258
|
end
|
|
249
259
|
|
|
260
|
+
assume_symbolic_keyed_data = current_raw_data.first.keys.first.is_a? Symbol
|
|
261
|
+
field = assume_symbolic_keyed_data ? field.to_sym : field.to_s
|
|
262
|
+
|
|
250
263
|
current_raw_data.find_all do |row|
|
|
251
264
|
next unless row.key?(field)
|
|
252
265
|
method_ref.call(row[field], desired_value)
|
|
253
266
|
end
|
|
254
267
|
end
|
|
268
|
+
|
|
269
|
+
def decorate_symbols(thing)
|
|
270
|
+
return thing.map { |t| decorate_symbols(t) } if thing.is_a?(Array)
|
|
271
|
+
return ':' + thing.to_s if thing.is_a? Symbol
|
|
272
|
+
return thing + ' (String)' if thing.is_a? String
|
|
273
|
+
thing
|
|
274
|
+
end
|
|
255
275
|
end
|
|
256
276
|
|
|
257
277
|
class Factory
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: inspec
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dominik Richter
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-10-
|
|
11
|
+
date: 2018-10-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: train
|
|
@@ -17,6 +17,9 @@ dependencies:
|
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '1.5'
|
|
20
|
+
- - ">="
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: 1.5.4
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -24,6 +27,9 @@ dependencies:
|
|
|
24
27
|
- - "~>"
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
29
|
version: '1.5'
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 1.5.4
|
|
27
33
|
- !ruby/object:Gem::Dependency
|
|
28
34
|
name: thor
|
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|