inspec-core 5.22.3 → 5.22.36
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/Gemfile +6 -19
- data/inspec-core.gemspec +6 -4
- data/lib/inspec/cli.rb +22 -5
- data/lib/inspec/config.rb +32 -10
- data/lib/inspec/fetcher/git.rb +43 -28
- data/lib/inspec/formatters/base.rb +1 -1
- data/lib/inspec/profile.rb +340 -18
- data/lib/inspec/resources/host.rb +4 -16
- data/lib/inspec/resources/security_policy.rb +7 -2
- data/lib/inspec/rule.rb +5 -0
- data/lib/inspec/utils/profile_ast_helpers.rb +372 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec/waiver_file_reader.rb +5 -3
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +2 -2
- data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +7 -6
- data/lib/plugins/inspec-reporter-html2/templates/default.js +6 -6
- metadata +11 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bbe23835cae58303aa3ac665ecd59e269752bbe4f6448e33db3219df0f04dbc8
|
4
|
+
data.tar.gz: 9a6d1e0e7758054f4d2746355a0c5538ede8af58a4220b3160d999f5e3093f34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c074f69651db5a586e4fee3b1a621ef9cc43d05634136dae9e0008a22c2d74d0515fe2938f83df42aace4ad089bbab3e95cf3d70bf3825b88aaca5e8e0696518
|
7
|
+
data.tar.gz: f01196343c6f7109cb44ced5f3a23a2b3f7b543f88a48d34d0b49c2b2a47dae31c599af4f51febca1afecbc1355f471c543c2ac8484c5c1a669ea4fec41cfe45
|
data/Gemfile
CHANGED
@@ -11,6 +11,10 @@ gem "inspec-bin", path: "./inspec-bin"
|
|
11
11
|
|
12
12
|
gem "ffi", ">= 1.9.14", "!= 1.13.0", "!= 1.14.2"
|
13
13
|
|
14
|
+
# We have a build issue 2023-11-13 with unf_ext 0.0.9 so we are pinning to 0.0.8.2
|
15
|
+
# See https://github.com/knu/ruby-unf_ext/issues/74 https://buildkite.com/chef/inspec-inspec-inspec-5-omnibus-release/builds/22
|
16
|
+
gem "unf_ext", "= 0.0.8.2"
|
17
|
+
|
14
18
|
# inspec tests depend text output that changed in the 3.10 release
|
15
19
|
# but our runtime dep is still 3.9+
|
16
20
|
gem "rspec", ">= 3.10"
|
@@ -25,11 +29,11 @@ end
|
|
25
29
|
group :test do
|
26
30
|
gem "chefstyle", "~> 2.2.2"
|
27
31
|
gem "concurrent-ruby", "~> 1.0"
|
28
|
-
gem "json_schemer", ">= 0.2.1", "< 0.
|
32
|
+
gem "json_schemer", ">= 0.2.1", "< 2.0.1"
|
29
33
|
gem "m"
|
30
34
|
gem "minitest-sprint", "~> 1.0"
|
31
35
|
gem "minitest", "5.15.0"
|
32
|
-
gem "mocha", "~>
|
36
|
+
gem "mocha", "~> 2.1"
|
33
37
|
gem "nokogiri", "~> 1.9"
|
34
38
|
gem "pry-byebug"
|
35
39
|
gem "pry", "~> 0.10"
|
@@ -47,20 +51,3 @@ end
|
|
47
51
|
group :deploy do
|
48
52
|
gem "inquirer"
|
49
53
|
end
|
50
|
-
|
51
|
-
group :kitchen do
|
52
|
-
gem "berkshelf"
|
53
|
-
|
54
|
-
# Chef 18 requires ruby 3
|
55
|
-
if Gem.ruby_version >= Gem::Version.new("3.0.0")
|
56
|
-
gem "chef", ">= 17.0"
|
57
|
-
else
|
58
|
-
# Ruby 2.7 presumably - TODO remove this when 2.7 is sunsetted
|
59
|
-
gem "chef", "~> 16.0"
|
60
|
-
end
|
61
|
-
|
62
|
-
gem "test-kitchen", ">= 2.8"
|
63
|
-
gem "kitchen-inspec", ">= 2.0"
|
64
|
-
gem "kitchen-dokken", ">= 2.11"
|
65
|
-
gem "git"
|
66
|
-
end
|
data/inspec-core.gemspec
CHANGED
@@ -25,13 +25,15 @@ Gem::Specification.new do |spec|
|
|
25
25
|
# Implementation dependencies
|
26
26
|
spec.add_dependency "chef-telemetry", "~> 1.0", ">= 1.0.8" # 1.0.8+ removes the http dep
|
27
27
|
spec.add_dependency "license-acceptance", ">= 0.2.13", "< 3.0"
|
28
|
-
|
28
|
+
# TODO: We should remove the thor pinning in next upcoming releases currently it's breaking our unit test in cli_args_test for aliases due to
|
29
|
+
# recent changes made in thor library REF: https://github.com/rails/thor/releases/tag/v1.3.0 & https://github.com/rails/thor/pull/800
|
30
|
+
spec.add_dependency "thor", ">= 0.20", "< 1.3.0"
|
29
31
|
spec.add_dependency "method_source", ">= 0.8", "< 2.0"
|
30
32
|
spec.add_dependency "rubyzip", ">= 1.2.2", "< 3.0"
|
31
|
-
spec.add_dependency "rspec", ">= 3.9", "<= 3.
|
33
|
+
spec.add_dependency "rspec", ">= 3.9", "<= 3.12"
|
32
34
|
spec.add_dependency "rspec-its", "~> 1.2"
|
33
35
|
spec.add_dependency "pry", "~> 0.13"
|
34
|
-
spec.add_dependency "hashie", ">= 3.4", "<
|
36
|
+
spec.add_dependency "hashie", ">= 3.4", "< 6.0"
|
35
37
|
spec.add_dependency "mixlib-log", "~> 3.0"
|
36
38
|
spec.add_dependency "sslshake", "~> 1.2"
|
37
39
|
spec.add_dependency "parallel", "~> 1.9"
|
@@ -41,7 +43,7 @@ Gem::Specification.new do |spec|
|
|
41
43
|
spec.add_dependency "tty-prompt", "~> 0.17"
|
42
44
|
spec.add_dependency "tomlrb", ">= 1.2", "< 2.1"
|
43
45
|
spec.add_dependency "addressable", "~> 2.4"
|
44
|
-
spec.add_dependency "parslet", ">= 1.5", "<
|
46
|
+
spec.add_dependency "parslet", ">= 1.5", "< 3.0" # Pinned < 2.0, see #5389
|
45
47
|
spec.add_dependency "semverse", "~> 3.0"
|
46
48
|
spec.add_dependency "multipart-post", "~> 2.0"
|
47
49
|
|
data/lib/inspec/cli.rb
CHANGED
@@ -68,8 +68,14 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
68
68
|
desc: "A list of controls to include. Ignore all other tests."
|
69
69
|
option :tags, type: :array,
|
70
70
|
desc: "A list of tags to filter controls and include only those. Ignore all other tests."
|
71
|
+
option :legacy_export, type: :boolean, default: false,
|
72
|
+
desc: "Run with legacy export."
|
71
73
|
profile_options
|
72
74
|
def json(target)
|
75
|
+
# Config initialisation is needed before deprecation warning can be issued
|
76
|
+
# Deprecator calls config get method to fetch the config value
|
77
|
+
# Without config initialisation, the config value is not set and hence calling config get through deprecator will set the value of config as blank, making options of json command inaccessible.
|
78
|
+
config
|
73
79
|
# This deprecation warning is ignored currently.
|
74
80
|
Inspec.deprecate(:renamed_to_inspec_export)
|
75
81
|
export(target, true)
|
@@ -86,6 +92,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
86
92
|
desc: "For --what=profile, a list of controls to include. Ignore all other tests."
|
87
93
|
option :tags, type: :array,
|
88
94
|
desc: "For --what=profile, a list of tags to filter controls and include only those. Ignore all other tests."
|
95
|
+
option :legacy_export, type: :boolean, default: false,
|
96
|
+
desc: "Run with legacy export."
|
89
97
|
profile_options
|
90
98
|
def export(target, as_json = false)
|
91
99
|
o = config
|
@@ -121,16 +129,17 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
121
129
|
|
122
130
|
case what
|
123
131
|
when "profile"
|
132
|
+
profile_info = o[:legacy_export] ? profile.info : profile.info_from_parse
|
124
133
|
if format == "json"
|
125
134
|
require "json" unless defined?(JSON)
|
126
135
|
# Write JSON
|
127
136
|
Inspec::Utils::JsonProfileSummary.produce_json(
|
128
|
-
info:
|
137
|
+
info: profile_info,
|
129
138
|
write_path: dst
|
130
139
|
)
|
131
140
|
elsif format == "yaml"
|
132
141
|
Inspec::Utils::YamlProfileSummary.produce_yaml(
|
133
|
-
info:
|
142
|
+
info: profile_info,
|
134
143
|
write_path: dst
|
135
144
|
)
|
136
145
|
end
|
@@ -152,6 +161,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
152
161
|
desc: "The output format to use. Valid values: `json` and `doc`. Default value: `doc`."
|
153
162
|
option :with_cookstyle, type: :boolean,
|
154
163
|
desc: "Enable or disable cookstyle checks.", default: false
|
164
|
+
option :legacy_check, type: :boolean, default: false,
|
165
|
+
desc: "Run with legacy check."
|
155
166
|
profile_options
|
156
167
|
def check(path) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
157
168
|
o = config
|
@@ -166,7 +177,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
166
177
|
|
167
178
|
# run check
|
168
179
|
profile = Inspec::Profile.for_target(path, o)
|
169
|
-
result = profile.check
|
180
|
+
result = o[:legacy_check] ? profile.legacy_check : profile.check
|
170
181
|
|
171
182
|
if o["format"] == "json"
|
172
183
|
puts JSON.generate(result)
|
@@ -244,6 +255,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
244
255
|
desc: "Fallback to using local archives if fetching fails."
|
245
256
|
option :ignore_errors, type: :boolean, default: false,
|
246
257
|
desc: "Ignore profile warnings."
|
258
|
+
option :check, type: :boolean, default: false,
|
259
|
+
desc: "Run profile check before archiving."
|
260
|
+
option :export, type: :boolean, default: false,
|
261
|
+
desc: "Export the profile to inspec.json and include in archive"
|
262
|
+
option :legacy_export, type: :boolean, default: false,
|
263
|
+
desc: "Export the profile in legacy mode to inspec.json and include in archive"
|
247
264
|
def archive(path, log_level = nil)
|
248
265
|
o = config
|
249
266
|
diagnose(o)
|
@@ -264,7 +281,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
264
281
|
o[:logger].warn "Archiving a profile that contains gem dependencies, but InSpec cannot package gems with the profile! Please archive your ~/.inspec/gems directory separately."
|
265
282
|
end
|
266
283
|
|
267
|
-
result = profile.check
|
284
|
+
result = profile.check if o[:check]
|
268
285
|
|
269
286
|
if result && !o[:ignore_errors] == false
|
270
287
|
o[:logger].info "Profile check failed. Please fix the profile before generating an archive."
|
@@ -514,7 +531,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
514
531
|
end
|
515
532
|
|
516
533
|
def run_command(opts)
|
517
|
-
runner = Inspec::Runner.new(
|
534
|
+
runner = Inspec::Runner.new(opts)
|
518
535
|
res = runner.eval_with_virtual_profile(opts[:command])
|
519
536
|
runner.load
|
520
537
|
|
data/lib/inspec/config.rb
CHANGED
@@ -448,6 +448,22 @@ module Inspec
|
|
448
448
|
# Reporter options may be defined top-level.
|
449
449
|
options.merge!(config_file_reporter_options)
|
450
450
|
|
451
|
+
# when sent reporter from compliance-mode (via chef-client), the reporter is a symbol
|
452
|
+
if @cli_opts.key?(:reporter) && @cli_opts["reporter"].nil?
|
453
|
+
@cli_opts["reporter"] = @cli_opts[:reporter]
|
454
|
+
@cli_opts.delete(:reporter)
|
455
|
+
elsif @cli_opts.key?(:reporter) && @cli_opts.key?("reporter") && @cli_opts["reporter"].is_a?(Array)
|
456
|
+
# combine reporter and "reporter" options into "reporter" option
|
457
|
+
@cli_opts["reporter"] = @cli_opts[:reporter] + @cli_opts["reporter"]
|
458
|
+
end
|
459
|
+
|
460
|
+
if @cli_opts["reporter"]
|
461
|
+
# Add reporter_cli_opts in options to capture reporter cli opts separately
|
462
|
+
options.merge!({ "reporter_cli_opts" => @cli_opts["reporter"] })
|
463
|
+
# Delete reporter from cli_opts to avoid direct merging of reporter info of cli and config
|
464
|
+
@cli_opts.delete("reporter")
|
465
|
+
end
|
466
|
+
|
451
467
|
# Highest precedence: merge in any options defined via the CLI
|
452
468
|
options.merge!(@cli_opts)
|
453
469
|
|
@@ -476,13 +492,13 @@ module Inspec
|
|
476
492
|
end
|
477
493
|
|
478
494
|
def finalize_parse_reporters(options) # rubocop:disable Metrics/AbcSize
|
479
|
-
#
|
480
|
-
options["
|
495
|
+
# Default to cli report for ad-hoc runners
|
496
|
+
options["reporter_cli_opts"] = ["cli"] if (options["reporter"].nil? || options["reporter"].empty?) && options["reporter_cli_opts"].nil?
|
481
497
|
|
482
|
-
#
|
483
|
-
if options["
|
498
|
+
# Parse out reporter_cli_opts to proper report format
|
499
|
+
if options["reporter_cli_opts"].is_a?(Array)
|
484
500
|
reports = {}
|
485
|
-
options["
|
501
|
+
options["reporter_cli_opts"].each do |report|
|
486
502
|
reporter_name, destination = report.split(":", 2)
|
487
503
|
if destination.nil? || destination.strip == "-"
|
488
504
|
reports[reporter_name] = { "stdout" => true }
|
@@ -494,7 +510,12 @@ module Inspec
|
|
494
510
|
reports[reporter_name]["target_id"] = options["target_id"] if options["target_id"]
|
495
511
|
end
|
496
512
|
end
|
497
|
-
|
513
|
+
|
514
|
+
if options["reporter"].nil? || options["reporter"].empty?
|
515
|
+
options["reporter"] = reports
|
516
|
+
else
|
517
|
+
options["reporter"].merge!(reports)
|
518
|
+
end
|
498
519
|
end
|
499
520
|
|
500
521
|
# add in stdout if not specified
|
@@ -507,6 +528,10 @@ module Inspec
|
|
507
528
|
end
|
508
529
|
|
509
530
|
validate_reporters!(options["reporter"])
|
531
|
+
|
532
|
+
# Delete reporter_cli_opts after graceful merging of cli and config reporters
|
533
|
+
options.delete("reporter_cli_opts")
|
534
|
+
|
510
535
|
options
|
511
536
|
end
|
512
537
|
|
@@ -548,15 +573,12 @@ module Inspec
|
|
548
573
|
class Defaults
|
549
574
|
DEFAULTS = {
|
550
575
|
exec: {
|
551
|
-
"reporter" => ["cli"],
|
552
576
|
"show_progress" => false,
|
553
577
|
"color" => true,
|
554
578
|
"create_lockfile" => true,
|
555
579
|
"backend_cache" => true,
|
556
580
|
},
|
557
|
-
shell: {
|
558
|
-
"reporter" => ["cli"],
|
559
|
-
},
|
581
|
+
shell: {},
|
560
582
|
}.freeze
|
561
583
|
|
562
584
|
def self.for_command(command_name)
|
data/lib/inspec/fetcher/git.rb
CHANGED
@@ -41,6 +41,7 @@ module Inspec::Fetcher
|
|
41
41
|
@ref = opts[:ref]
|
42
42
|
@remote_url = expand_local_path(remote_url)
|
43
43
|
@repo_directory = nil
|
44
|
+
@resolved_ref = nil
|
44
45
|
@relative_path = opts[:relative_path] if opts[:relative_path] && !opts[:relative_path].empty?
|
45
46
|
end
|
46
47
|
|
@@ -70,7 +71,7 @@ module Inspec::Fetcher
|
|
70
71
|
if @relative_path
|
71
72
|
perform_relative_path_fetch(destination_path, working_dir)
|
72
73
|
else
|
73
|
-
Inspec::Log.debug("Checkout of #{resolved_ref} successful. " \
|
74
|
+
Inspec::Log.debug("Checkout of #{resolved_ref.nil? ? @remote_url : resolved_ref} successful. " \
|
74
75
|
"Moving checkout to #{destination_path}")
|
75
76
|
FileUtils.cp_r(working_dir + "/.", destination_path)
|
76
77
|
end
|
@@ -80,14 +81,14 @@ module Inspec::Fetcher
|
|
80
81
|
end
|
81
82
|
|
82
83
|
def perform_relative_path_fetch(destination_path, working_dir)
|
83
|
-
Inspec::Log.debug("Checkout of #{resolved_ref} successful. " \
|
84
|
+
Inspec::Log.debug("Checkout of #{resolved_ref.nil? ? @remote_url : resolved_ref} successful. " \
|
84
85
|
"Moving #{@relative_path} to #{destination_path}")
|
85
86
|
unless File.exist?("#{working_dir}/#{@relative_path}")
|
86
87
|
# Cleanup the destination path - otherwise we'll have an empty dir
|
87
88
|
# in the cache, which is enough to confuse the cache reader
|
88
89
|
# This is a courtesy, assuming we're writing to the cache; if we're
|
89
90
|
# vendoring to something more complex, don't bother.
|
90
|
-
FileUtils.
|
91
|
+
FileUtils.rm_r(destination_path) if Dir.exist?(destination_path)
|
91
92
|
|
92
93
|
raise Inspec::FetcherFailure, "Cannot find relative path '#{@relative_path}' " \
|
93
94
|
"within profile in git repo specified by '#{@remote_url}'"
|
@@ -96,9 +97,16 @@ module Inspec::Fetcher
|
|
96
97
|
end
|
97
98
|
|
98
99
|
def cache_key
|
99
|
-
|
100
|
-
|
101
|
-
|
100
|
+
cache_key = if @relative_path && !resolved_ref.nil?
|
101
|
+
OpenSSL::Digest.hexdigest("SHA256", resolved_ref + @relative_path)
|
102
|
+
elsif @relative_path && resolved_ref.nil?
|
103
|
+
OpenSSL::Digest.hexdigest("SHA256", @remote_url + @relative_path)
|
104
|
+
elsif resolved_ref.nil?
|
105
|
+
OpenSSL::Digest.hexdigest("SHA256", @remote_url)
|
106
|
+
else
|
107
|
+
resolved_ref
|
108
|
+
end
|
109
|
+
cache_key
|
102
110
|
end
|
103
111
|
|
104
112
|
def archive_path
|
@@ -106,7 +114,11 @@ module Inspec::Fetcher
|
|
106
114
|
end
|
107
115
|
|
108
116
|
def resolved_source
|
109
|
-
|
117
|
+
if resolved_ref.nil?
|
118
|
+
source = { git: @remote_url }
|
119
|
+
else
|
120
|
+
source = { git: @remote_url, ref: resolved_ref }
|
121
|
+
end
|
110
122
|
source[:relative_path] = @relative_path if @relative_path
|
111
123
|
source
|
112
124
|
end
|
@@ -125,33 +137,27 @@ module Inspec::Fetcher
|
|
125
137
|
elsif @tag
|
126
138
|
resolve_ref(@tag)
|
127
139
|
else
|
128
|
-
resolve_ref
|
140
|
+
resolve_ref
|
129
141
|
end
|
130
142
|
end
|
131
143
|
|
132
|
-
def
|
133
|
-
command_string =
|
144
|
+
def resolve_ref(ref_name = nil)
|
145
|
+
command_string = if ref_name.nil?
|
146
|
+
# Running git ls-remote command helps to raise error if git URL is invalid and avoids cache_key creation
|
147
|
+
"git ls-remote \"#{@remote_url}\""
|
148
|
+
else
|
149
|
+
"git ls-remote \"#{@remote_url}\" \"#{ref_name}*\""
|
150
|
+
end
|
134
151
|
cmd = shellout(command_string)
|
135
|
-
unless cmd.exitstatus == 0
|
136
|
-
|
152
|
+
raise(Inspec::FetcherFailure, "Profile git dependency failed for #{@remote_url} - error running '#{command_string}': #{cmd.stderr}") unless cmd.exitstatus == 0
|
153
|
+
|
154
|
+
if ref_name.nil?
|
155
|
+
ref = nil
|
137
156
|
else
|
138
|
-
ref = cmd.stdout
|
157
|
+
ref = parse_ls_remote(cmd.stdout, ref_name)
|
139
158
|
unless ref
|
140
|
-
raise
|
159
|
+
raise Inspec::FetcherFailure, "Profile git dependency failed - unable to resolve #{ref_name} to a specific git commit for #{@remote_url}"
|
141
160
|
end
|
142
|
-
|
143
|
-
ref
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def resolve_ref(ref_name)
|
148
|
-
command_string = "git ls-remote \"#{@remote_url}\" \"#{ref_name}*\""
|
149
|
-
cmd = shellout(command_string)
|
150
|
-
raise(Inspec::FetcherFailure, "Profile git dependency failed for #{@remote_url} - error running '#{command_string}': #{cmd.stderr}") unless cmd.exitstatus == 0
|
151
|
-
|
152
|
-
ref = parse_ls_remote(cmd.stdout, ref_name)
|
153
|
-
unless ref
|
154
|
-
raise Inspec::FetcherFailure, "Profile git dependency failed - unable to resolve #{ref_name} to a specific git commit for #{@remote_url}"
|
155
161
|
end
|
156
162
|
|
157
163
|
ref
|
@@ -200,7 +206,14 @@ module Inspec::Fetcher
|
|
200
206
|
|
201
207
|
def checkout(dir = @repo_directory)
|
202
208
|
clone(dir)
|
203
|
-
|
209
|
+
# In case of branch, tag or git reference is not provided by User the resolved_ref will always be nil
|
210
|
+
# and will always checkout the default HEAD branch, else it will checkout specific branch, tag or git reference.
|
211
|
+
if resolved_ref.nil?
|
212
|
+
git_cmd("checkout", dir)
|
213
|
+
else
|
214
|
+
git_cmd("checkout #{resolved_ref}", dir)
|
215
|
+
end
|
216
|
+
|
204
217
|
@repo_directory
|
205
218
|
end
|
206
219
|
|
@@ -208,6 +221,8 @@ module Inspec::Fetcher
|
|
208
221
|
cmd = shellout("git #{cmd}", cwd: dir)
|
209
222
|
cmd.error!
|
210
223
|
cmd.status
|
224
|
+
rescue Mixlib::ShellOut::ShellCommandFailed => e
|
225
|
+
raise Inspec::FetcherFailure, "Error while running git command. #{e.message} "
|
211
226
|
rescue Errno::ENOENT
|
212
227
|
raise Inspec::FetcherFailure, "Profile git dependency failed for #{@remote_url} - to use git sources, you must have git installed."
|
213
228
|
end
|
@@ -160,7 +160,7 @@ module Inspec::Formatters
|
|
160
160
|
end
|
161
161
|
|
162
162
|
# added this additionally because stats summary is also used for determining exit code in runner rspec
|
163
|
-
skipped += 1 if control[:results].any? { |r| r[:status] == "skipped" }
|
163
|
+
skipped += 1 if control[:results] && (control[:results].any? { |r| r[:status] == "skipped" })
|
164
164
|
|
165
165
|
end
|
166
166
|
total = error + not_applicable + not_reviewed + failed + passed
|