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
 |