diff --git a/lib/inspec/control_eval_context.rb b/lib/inspec/control_eval_context.rb index 0b87bcccc..df8ec4f73 100644 --- a/lib/inspec/control_eval_context.rb +++ b/lib/inspec/control_eval_context.rb @@ -52,6 +52,7 @@ module Inspec @conf = conf @dependencies = dependencies @require_loader = require_loader + @skip_file_message = nil @skip_file = false @skip_only_if_eval = skip_only_if_eval end @@ -118,18 +119,18 @@ module Inspec define_method :register_control do |control, &block| if @skip_file - ::Inspec::Rule.set_skip_rule(control, true) + ::Inspec::Rule.set_skip_rule(control, true, @skip_file_message) end unless profile_context_owner.profile_supports_platform? platform = inspec.platform msg = "Profile #{profile_context_owner.profile_id} is not supported on platform #{platform.name}/#{platform.release}." - ::Inspec::Rule.set_skip_rule(control, msg) + ::Inspec::Rule.set_skip_rule(control, true, msg) end unless profile_context_owner.profile_supports_inspec_version? msg = "Profile #{profile_context_owner.profile_id} is not supported on InSpec version (#{Inspec::VERSION})." - ::Inspec::Rule.set_skip_rule(control, msg) + ::Inspec::Rule.set_skip_rule(control, true, msg) end profile_context_owner.register_rule(control, &block) unless control.nil? @@ -144,19 +145,19 @@ module Inspec profile_context_owner.unregister_rule(id) end - define_method :only_if do |&block| + define_method :only_if do |message = nil, &block| return unless block return if @skip_file == true return if @skip_only_if_eval == true return if block.yield == true - # Apply `set_skip_rule` for other rules in the same file profile_context_owner.rules.values.each do |r| sources_match = r.source_file == block.source_location[0] - Inspec::Rule.set_skip_rule(r, true) if sources_match + Inspec::Rule.set_skip_rule(r, true, message) if sources_match end + @skip_file_message = message @skip_file = true end diff --git a/lib/inspec/rule.rb b/lib/inspec/rule.rb index ed6aa6798..5ed349266 100644 --- a/lib/inspec/rule.rb +++ b/lib/inspec/rule.rb @@ -174,8 +174,9 @@ module Inspec rule.instance_variable_get(:@__skip_rule) end - def self.set_skip_rule(rule, value) - rule.instance_variable_set(:@__skip_rule, { result: value }) + def self.set_skip_rule(rule, value, message = nil) + rule.instance_variable_set(:@__skip_rule, + { result: value, message: message }) end def self.merge_count(rule) diff --git a/test/unit/profiles/profile_context_test.rb b/test/unit/profiles/profile_context_test.rb index 0859b0ec2..320e691a5 100644 --- a/test/unit/profiles/profile_context_test.rb +++ b/test/unit/profiles/profile_context_test.rb @@ -117,6 +117,7 @@ describe Inspec::ProfileContext do describe 'global only_if' do let(:if_true) { "only_if { true }\n" } let(:if_false) { "only_if { false }\n" } + let(:if_false_message) { "only_if('if_false_message skipped') { false }\n" } let(:describe) { "describe nil do its(:to_i) { should eq rand } end\n" } let(:control) { "control 1 do\n#{describe}\nend\n" } let(:control_2) { "control 2 do\n#{describe}\nend\n" } @@ -180,6 +181,14 @@ describe Inspec::ProfileContext do get_checks[0][1][0].resource_failed?.must_equal false end + it 'allows specifying a message with true only_if' do + profile.load(if_false_message + control) + get_checks.length.must_equal 1 + get_checks[0][1][0].resource_skipped?.must_equal true + get_checks[0][1][0].resource_exception_message.must_equal 'Skipped control due to only_if condition: if_false_message skipped' + get_checks[0][1][0].resource_failed?.must_equal false + end + it 'doesnt extend into other control files' do fake_control_file = if_false + control profile.load_control_file(fake_control_file, '(eval)', nil)