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
 | 
