inspec/lib/verify/specfile.rb

147 lines
3.4 KiB
Ruby
Raw Normal View History

# encoding: utf-8
# copyright: 2015, Dominik Richter
2015-10-06 16:55:44 +00:00
# author: Dominik Richter
# author: Christoph Hartmann
# license: All rights reserved
2015-10-06 16:55:44 +00:00
require 'vulcano/base_rule'
require 'vulcano/log'
require 'verify/dummy'
require 'method_source'
# the user may use dynamic evaluations via pry
begin
require 'pry'
rescue LoadError # rubocop:disable Lint/HandleExceptions
end
module Vulcano
class DummyContext
include Vulcano::DSL
2015-09-03 18:43:58 +00:00
def initialize(path, profile_id)
@path = path
@profile_id = profile_id
@rules = {}
@errors = []
end
2015-09-25 17:46:46 +00:00
def only_if(*_a, &_b)
# always ignore
end
2015-09-03 18:43:58 +00:00
def __get_block_source(&block)
2015-09-05 14:07:54 +00:00
return '' unless block_given?
block.source.to_s
end
# DSL methods
2015-09-03 18:43:58 +00:00
def __register_rule(r, &block)
if block_given?
src = __get_block_source(&block)
else
src = __get_block_source(&r.instance_variable_get(:@__block))
end
r.instance_variable_set(:@__code, src)
full_id = VulcanoBaseRule.full_id @profile_id, r
if @rules[full_id].nil?
@rules[full_id] = r
else
@errors.push "Duplicate definition of rule #{fid}."
end
end
2015-09-03 18:43:58 +00:00
def __unregister_rule(id)
full_id = VulcanoBaseRule.full_id @profile_id, id
if @rules.key?(full_id)
@rules.delete(full_id)
else
@errors.push "Failed to skip rule #{fid}, it isn't defined."
end
end
# redefine require to find files in the context
# of this profile
2015-09-03 18:43:58 +00:00
def require(sth)
# ignore vulcano includes, we already have those
2015-09-05 14:07:54 +00:00
lib = File.expand_path(File.join @path, '..', '..', 'lib', "#{sth}.rb")
require_relative lib if File.file? lib
end
2015-09-03 18:43:58 +00:00
def method_missing(sth, *args)
@errors.push "Don't understand method #{sth} ( #{args} )."
end
end
end
module Vulcano
class SpecFile
2015-09-05 14:07:54 +00:00
Log = ::Vulcano::Log.new
attr_reader :errors, :rules
2015-09-05 14:07:54 +00:00
def initialize(path, metadata)
@filename = File.basename(path)
@rules = []
2015-09-05 14:07:54 +00:00
@raw = File.read(path)
@profile_id = metadata.dict['name']
@invalid_calls = []
ctx = DummyContext.new(path, @profile_id)
ctx.instance_eval(@raw, path, 1)
@errors = ctx.instance_variable_get(:@errors)
@rules = ctx.instance_variable_get(:@rules)
end
def metadata
2015-09-05 14:07:54 +00:00
header = @raw.sub(/^[^#].*\Z/m, '')
{
'title' => header[/^# title: (.*)$/, 1] || @filename,
'copyright' => header[/^# copyright: (.*)$/, 1] || 'All rights reserved',
'rules' => rules2dict(@rules),
}
end
2015-09-03 18:43:58 +00:00
def self.from_file(path, metadata)
2015-09-05 14:07:54 +00:00
if !File.file?(path)
Log.error "Can't find spec file in #{path}"
return nil
end
2015-09-04 07:59:30 +00:00
SpecFile.new(path, metadata)
end
private
def rule2dict(rule)
d = nil
d = rule.desc.gsub(/\s*\n\s*/, ' ').strip unless rule.desc.nil?
{
2015-09-03 21:18:28 +00:00
'impact' => rule.impact,
'title' => rule.title,
'desc' => d,
2015-09-25 17:46:46 +00:00
'code' => rule.instance_variable_get(:@__code),
}
end
def rules2dict(rules)
res = {}
rules.map do |id, rule|
nu = rule2dict(rule)
if res[id].nil?
res[id] = nu
else
Log.error(
2015-09-05 14:07:54 +00:00
"Not redefining rule id #{id}:\n" \
"-- #{res[id]}\n" \
"++ #{nu}\n",
)
end
end
res
end
end
end
2015-09-25 17:46:46 +00:00
def os(*_a, &_b)
{}
end