2015-06-07 19:41:54 +00:00
|
|
|
# encoding: utf-8
|
|
|
|
# copyright: 2015, Dominik Richter
|
2015-10-06 16:55:44 +00:00
|
|
|
# author: Dominik Richter
|
|
|
|
# author: Christoph Hartmann
|
2015-06-07 19:41:54 +00:00
|
|
|
# license: All rights reserved
|
2015-10-06 16:55:44 +00:00
|
|
|
|
2015-06-19 14:45:36 +00:00
|
|
|
require 'verify/specfile'
|
2015-06-19 13:06:44 +00:00
|
|
|
require 'vulcano/log'
|
2015-06-07 19:41:54 +00:00
|
|
|
|
|
|
|
module Vulcano
|
|
|
|
# Handle Vulcano Profiles
|
|
|
|
class Profiles
|
|
|
|
attr_reader :profiles
|
2015-09-03 18:43:58 +00:00
|
|
|
def initialize(opts = {})
|
2015-06-07 19:41:54 +00:00
|
|
|
@profiles = {}
|
2015-06-25 15:45:46 +00:00
|
|
|
@profile_id = opts[:id]
|
2015-06-07 19:41:54 +00:00
|
|
|
@log = Log.new(opts)
|
|
|
|
end
|
|
|
|
|
2015-09-03 18:43:58 +00:00
|
|
|
def add_folder(f)
|
2015-09-05 14:07:54 +00:00
|
|
|
path = File.expand_path(f)
|
2015-06-07 19:41:54 +00:00
|
|
|
if File.directory? path
|
|
|
|
add_specs_in_folder path
|
|
|
|
else
|
|
|
|
@log.error "Path is not a folder: #{path}"
|
|
|
|
end
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2015-09-03 18:43:58 +00:00
|
|
|
def valid_folder?(f)
|
2015-09-05 14:07:54 +00:00
|
|
|
path = File.expand_path(f)
|
2015-06-07 19:41:54 +00:00
|
|
|
if !File.directory? path
|
|
|
|
return @log.error "This is not a folder: #{path}"
|
|
|
|
else
|
2015-09-03 21:18:28 +00:00
|
|
|
@log.ok 'Valid directory'
|
2015-06-07 19:41:54 +00:00
|
|
|
end
|
|
|
|
|
2015-06-25 15:45:46 +00:00
|
|
|
metadata = Metadata.for_path(path, @profile_id)
|
2015-09-03 21:18:28 +00:00
|
|
|
@log.ok 'vmetadata.rb' unless metadata.nil? or !metadata.valid?
|
2015-06-07 19:41:54 +00:00
|
|
|
|
|
|
|
specs = Dir["#{path}/spec/*_spec.rb"]
|
|
|
|
if specs.empty?
|
|
|
|
@log.warn "No tests found in #{path}"
|
|
|
|
end
|
2015-09-05 14:07:54 +00:00
|
|
|
specs.each { |s| valid_spec? s, metadata }
|
2015-06-07 19:41:54 +00:00
|
|
|
end
|
|
|
|
|
2015-09-03 18:43:58 +00:00
|
|
|
def valid_spec?(f, metadata)
|
2015-09-05 14:07:54 +00:00
|
|
|
return @log.error "Can't find spec file #{f}" unless File.file? f
|
2015-09-30 00:20:47 +00:00
|
|
|
|
|
|
|
# Load the spec file
|
|
|
|
specs = SpecFile.from_file(f, metadata)
|
|
|
|
valid = validate_spec_file(specs)
|
|
|
|
|
|
|
|
return unless valid && specs.instance_variable_get(:@invalid_calls).empty?
|
|
|
|
@log.ok "Valid spec file in #{f} with #{meta['rules'].length} rules"
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def validate_spec_file(specs, invalid) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
2015-06-07 19:41:54 +00:00
|
|
|
valid = true
|
2015-09-30 00:20:47 +00:00
|
|
|
# helper for printing violations
|
2015-07-27 15:31:08 +00:00
|
|
|
invalid = lambda {|type, msg|
|
2015-09-05 14:07:54 +00:00
|
|
|
@log.send type, "#{msg} (#{File.basename f})"
|
2015-07-27 15:31:08 +00:00
|
|
|
valid = false if type == :error
|
2015-06-19 23:36:27 +00:00
|
|
|
}
|
2015-09-30 00:20:47 +00:00
|
|
|
|
2015-06-19 23:36:27 +00:00
|
|
|
# find all errors during parsing
|
|
|
|
specs.errors.each do |err|
|
2015-09-25 17:46:46 +00:00
|
|
|
invalid.call(:error, err)
|
2015-06-19 23:36:27 +00:00
|
|
|
end
|
|
|
|
# detect missing metadata
|
|
|
|
meta = specs.metadata
|
|
|
|
if meta['title'].nil?
|
2015-09-25 17:46:46 +00:00
|
|
|
invalid.call(:warn, 'Missing title in spec file')
|
2015-06-07 19:41:54 +00:00
|
|
|
end
|
|
|
|
if meta['copyright'].nil?
|
2015-09-25 17:46:46 +00:00
|
|
|
invalid.call(:warn, 'Missing copyright in spec file')
|
2015-06-07 19:41:54 +00:00
|
|
|
end
|
2015-06-19 23:36:27 +00:00
|
|
|
# detect empty rules
|
2015-06-16 21:20:24 +00:00
|
|
|
unless meta['rules'][''].nil?
|
2015-09-25 17:46:46 +00:00
|
|
|
invalid.call(:error, 'Please configure IDs for all rules.')
|
2015-06-07 19:41:54 +00:00
|
|
|
end
|
|
|
|
|
2015-09-25 17:46:46 +00:00
|
|
|
meta['rules'].each do |k, v|
|
2015-06-10 15:36:30 +00:00
|
|
|
if v['impact'].nil?
|
2015-09-25 17:46:46 +00:00
|
|
|
invalid.call(:error, "Missing impact for rule #{k}")
|
2015-06-10 15:36:30 +00:00
|
|
|
else
|
2015-09-25 17:46:46 +00:00
|
|
|
invalid.call(:error, "Impact cannot be larger than 1.0 for rule #{k}") if v['impact'] > 1.0
|
|
|
|
invalid.call(:error, "Impact cannot be less than 0.0 for rule #{k}") if v['impact'] < 0.0
|
2015-06-10 15:36:30 +00:00
|
|
|
end
|
2015-09-25 17:46:46 +00:00
|
|
|
invalid.call(:warn, "Missing title for rule #{k}") if v['title'].nil?
|
|
|
|
invalid.call(:warn, "Missing description for rule #{k}") if v['desc'].nil?
|
2015-06-07 19:41:54 +00:00
|
|
|
end
|
|
|
|
|
2015-09-30 00:20:47 +00:00
|
|
|
valid
|
2015-06-07 19:41:54 +00:00
|
|
|
end
|
|
|
|
|
2015-09-03 18:43:58 +00:00
|
|
|
def add_specs_in_folder(path)
|
2015-06-16 21:20:24 +00:00
|
|
|
allrules = {}
|
2015-06-25 15:45:46 +00:00
|
|
|
meta = Metadata.for_path(path, @profile_id, @log)
|
2015-06-07 19:41:54 +00:00
|
|
|
|
|
|
|
Dir["#{path}/spec/*_spec.rb"].each do |specfile|
|
2015-09-05 14:07:54 +00:00
|
|
|
rel_path = specfile.sub(File.join(path, ''), '')
|
2015-06-19 23:41:48 +00:00
|
|
|
specs = SpecFile.from_file(specfile, meta)
|
|
|
|
allrules[rel_path] = sanitize_specfile_json(specs.metadata)
|
2015-06-07 19:41:54 +00:00
|
|
|
end
|
|
|
|
|
2015-06-19 23:41:48 +00:00
|
|
|
meta.dict['rules'] = allrules
|
|
|
|
@profiles = meta.dict
|
2015-06-07 19:41:54 +00:00
|
|
|
end
|
|
|
|
|
2015-09-03 18:43:58 +00:00
|
|
|
def sanitize_specfile_json(j)
|
2015-09-05 14:07:54 +00:00
|
|
|
j['rules'].each do |k, v|
|
2015-06-10 15:21:03 +00:00
|
|
|
v['title'] = k if v['title'].nil?
|
2015-09-05 14:07:54 +00:00
|
|
|
v['desc'] = '' if v['desc'].nil?
|
2015-08-13 06:05:26 +00:00
|
|
|
v['impact'] = 0.5 if v['impact'].nil?
|
2015-06-10 15:21:03 +00:00
|
|
|
end
|
2015-06-12 10:32:10 +00:00
|
|
|
j
|
2015-06-10 15:21:03 +00:00
|
|
|
end
|
2015-06-07 19:41:54 +00:00
|
|
|
end
|
|
|
|
end
|