185 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
		
		
			
		
	
	
			185 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
|   | require 'rubygems' | ||
|  | require 'rake' # for ext() | ||
|  | require 'constants' | ||
|  | require 'tool_executor'    # for argument replacement pattern | ||
|  | require 'file_path_utils'  # for glob handling class methods | ||
|  | 
 | ||
|  | 
 | ||
|  | class ConfiguratorValidator | ||
|  |    | ||
|  |   constructor :file_wrapper, :stream_wrapper, :system_wrapper | ||
|  | 
 | ||
|  |   # walk into config hash verify existence of data at key depth | ||
|  |   def exists?(config, *keys) | ||
|  |     hash  = retrieve_value(config, keys) | ||
|  |     exist = !hash[:value].nil? | ||
|  | 
 | ||
|  |     if (not exist) | ||
|  |       # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator | ||
|  |       @stream_wrapper.stderr_puts("ERROR: Required config file entry #{format_key_sequence(keys, hash[:depth])} does not exist.")     | ||
|  |     end | ||
|  |      | ||
|  |     return exist | ||
|  |   end | ||
|  | 
 | ||
|  | 
 | ||
|  |   # walk into config hash. verify directory path(s) at given key depth | ||
|  |   def validate_path_list(config, *keys) | ||
|  |     hash = retrieve_value(config, keys) | ||
|  |     list = hash[:value] | ||
|  | 
 | ||
|  |     # return early if we couldn't walk into hash and find a value | ||
|  |     return false if (list.nil?) | ||
|  | 
 | ||
|  |     path_list = [] | ||
|  |     exist = true | ||
|  |      | ||
|  |     case list | ||
|  |       when String then path_list << list | ||
|  |       when Array  then path_list =  list | ||
|  |     end | ||
|  |      | ||
|  |     path_list.each do |path| | ||
|  |       base_path = FilePathUtils::extract_path(path) # lop off add/subtract notation & glob specifiers | ||
|  |        | ||
|  |       if (not @file_wrapper.exist?(base_path)) | ||
|  |         # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator | ||
|  |         @stream_wrapper.stderr_puts("ERROR: Config path #{format_key_sequence(keys, hash[:depth])}['#{base_path}'] does not exist on disk.")  | ||
|  |         exist = false | ||
|  |       end  | ||
|  |     end | ||
|  |      | ||
|  |     return exist | ||
|  |   end | ||
|  | 
 | ||
|  |    | ||
|  |   # simple path verification | ||
|  |   def validate_filepath_simple(path, *keys) | ||
|  |     validate_path = path | ||
|  |      | ||
|  |     if (not @file_wrapper.exist?(validate_path)) | ||
|  |       # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator | ||
|  |       @stream_wrapper.stderr_puts("ERROR: Config path '#{validate_path}' associated with #{format_key_sequence(keys, keys.size)} does not exist on disk.")  | ||
|  |       return false | ||
|  |     end  | ||
|  |      | ||
|  |     return true | ||
|  |   end | ||
|  |   | ||
|  |   # walk into config hash. verify specified file exists. | ||
|  |   def validate_filepath(config, *keys) | ||
|  |     hash          = retrieve_value(config, keys) | ||
|  |     filepath      = hash[:value] | ||
|  | 
 | ||
|  |     # return early if we couldn't walk into hash and find a value | ||
|  |     return false if (filepath.nil?) | ||
|  | 
 | ||
|  |     # skip everything if we've got an argument replacement pattern | ||
|  |     return true if (filepath =~ TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN) | ||
|  |      | ||
|  |     if (not @file_wrapper.exist?(filepath)) | ||
|  |       # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator | ||
|  |       @stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist on disk.")  | ||
|  |       return false | ||
|  |     end       | ||
|  | 
 | ||
|  |     return true | ||
|  |   end | ||
|  | 
 | ||
|  |   # walk into config hash. verify specified file exists. | ||
|  |   def validate_executable_filepath(config, *keys) | ||
|  |     exe_extension = config[:extension][:executable] | ||
|  |     hash          = retrieve_value(config, keys) | ||
|  |     filepath      = hash[:value] | ||
|  | 
 | ||
|  |     # return early if we couldn't walk into hash and find a value | ||
|  |     return false if (filepath.nil?) | ||
|  | 
 | ||
|  |     # skip everything if we've got an argument replacement pattern | ||
|  |     return true if (filepath =~ TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN) | ||
|  |      | ||
|  |     # if there's no path included, verify file exists somewhere in system search paths | ||
|  |     if (not filepath.include?('/')) | ||
|  |       exists = false | ||
|  |        | ||
|  |       @system_wrapper.search_paths.each do |path| | ||
|  |         if (@file_wrapper.exist?( File.join(path, filepath)) ) | ||
|  |           exists = true | ||
|  |           break | ||
|  |         end | ||
|  |          | ||
|  |         if (@file_wrapper.exist?( (File.join(path, filepath)).ext( exe_extension ) )) | ||
|  |           exists = true | ||
|  |           break | ||
|  |         elsif (@system_wrapper.windows? and @file_wrapper.exist?( (File.join(path, filepath)).ext( EXTENSION_WIN_EXE ) )) | ||
|  |           exists = true | ||
|  |           break | ||
|  |         end | ||
|  |       end | ||
|  |        | ||
|  |       if (not exists) | ||
|  |         # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator | ||
|  |         @stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist in system search paths.")  | ||
|  |         return false         | ||
|  |       end | ||
|  |        | ||
|  |     # if there is a path included, check that explicit filepath exists | ||
|  |     else | ||
|  |       if (not @file_wrapper.exist?(filepath)) | ||
|  |         # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator | ||
|  |         @stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist on disk.")  | ||
|  |         return false | ||
|  |       end       | ||
|  |     end | ||
|  | 
 | ||
|  |     return true | ||
|  |   end | ||
|  |    | ||
|  |   def validate_tool_stderr_redirect(config, tools, tool) | ||
|  |     redirect = config[tools][tool][:stderr_redirect] | ||
|  |     if (redirect.class == Symbol) | ||
|  |       # map constants and force to array of strings for runtime universality across ruby versions | ||
|  |       if (not StdErrRedirect.constants.map{|constant| constant.to_s}.include?(redirect.to_s.upcase)) | ||
|  |         error = "ERROR: [:#{tools}][:#{tool}][:stderr_redirect][:#{redirect}] is not a recognized option " + | ||
|  |                 "{#{StdErrRedirect.constants.map{|constant| ':' + constant.to_s.downcase}.join(', ')}}." | ||
|  |         @stream_wrapper.stderr_puts(error)  | ||
|  |         return false         | ||
|  |       end | ||
|  |     end | ||
|  |      | ||
|  |     return true | ||
|  |   end | ||
|  |    | ||
|  |   private ######################################### | ||
|  |    | ||
|  |    | ||
|  |   def retrieve_value(config, keys) | ||
|  |     value = nil | ||
|  |     hash  = config | ||
|  |     depth = 0
 | ||
|  | 
 | ||
|  |     # walk into hash & extract value at requested key sequence | ||
|  |     keys.each do |symbol| | ||
|  |       depth += 1
 | ||
|  |       if (not hash[symbol].nil?) | ||
|  |         hash  = hash[symbol] | ||
|  |         value = hash | ||
|  |       else | ||
|  |         value = nil | ||
|  |         break | ||
|  |       end | ||
|  |     end | ||
|  |      | ||
|  |     return {:value => value, :depth => depth} | ||
|  |   end | ||
|  | 
 | ||
|  | 
 | ||
|  |   def format_key_sequence(keys, depth) | ||
|  |     walked_keys    = keys.slice(0, depth) | ||
|  |     formatted_keys = walked_keys.map{|key| "[:#{key.to_s}]"} | ||
|  |      | ||
|  |     return formatted_keys.join | ||
|  |   end | ||
|  |    | ||
|  | end |