class RuboCop::TargetFinder
and picking ruby files.
This class finds target files to inspect by scanning the directory tree
def all_cops_include
def all_cops_include @config_store.for('.').for_all_cops['Include'].map(&:to_s) end
def configured_include?(file)
def configured_include?(file) @config_store.for('.').file_to_include?(file) end
def debug?
def debug? @options[:debug] end
def excluded_dirs(base_dir)
def excluded_dirs(base_dir) all_cops_config = @config_store.for(base_dir).for_all_cops dir_tree_excludes = all_cops_config['Exclude'].select do |pattern| pattern.is_a?(String) && pattern.end_with?('/**/*') end dir_tree_excludes.map { |pattern| pattern.sub(%r{/\*\*/\*$}, '') } end
def fail_fast?
def fail_fast? @options[:fail_fast] end
def find(args)
-
(Array)
- array of file paths
def find(args) return target_files_in_dir if args.empty? files = [] args.uniq.each do |arg| files += if File.directory?(arg) target_files_in_dir(arg.chomp(File::SEPARATOR)) else process_explicit_path(arg) end end files.map { |f| File.expand_path(f) }.uniq end
def find_files(base_dir, flags)
the top level directories that are excluded in configuration in the
be removed later by the caller, but as an optimization find_files removes
the given flags that determine how the match is made. Excluded files will
Search for files recursively starting at the given base directory using
def find_files(base_dir, flags) wanted_toplevel_dirs = toplevel_dirs(base_dir, flags) - excluded_dirs(base_dir) wanted_toplevel_dirs.map! { |dir| dir << '/**/*' } pattern = if wanted_toplevel_dirs.empty? # We need this special case to avoid creating the pattern # /**/* which searches the entire file system. ["#{base_dir}/**/*"] else # Search the non-excluded top directories, but also add files # on the top level, which would otherwise not be found. wanted_toplevel_dirs.unshift("#{base_dir}/*") end Dir.glob(pattern, flags).select { |path| FileTest.file?(path) } end
def force_exclusion?
def force_exclusion? @options[:force_exclusion] end
def included_file?(file)
def included_file?(file) ruby_file?(file) || configured_include?(file) end
def initialize(config_store, options = {})
def initialize(config_store, options = {}) @config_store = config_store @options = options end
def process_explicit_path(path)
def process_explicit_path(path) files = path.include?('*') ? Dir[path] : [path] files.select! { |file| included_file?(file) } return files unless force_exclusion? files.reject do |file| config = @config_store.for(file) config.file_to_exclude?(file) end end
def ruby_executable?(file)
def ruby_executable?(file) return false unless File.extname(file).empty? && File.exist?(file) first_line = File.open(file, &:readline) !(first_line =~ /#!.*(#{ruby_interpreters(file).join('|')})/).nil? rescue EOFError, ArgumentError => e warn "Unprocessable file #{file}: #{e.class}, #{e.message}" if debug? false end
def ruby_extension?(file)
def ruby_extension?(file) ruby_extensions.include?(File.extname(file)) end
def ruby_extensions
def ruby_extensions ext_patterns = all_cops_include.select do |pattern| pattern.start_with?('**/*.') end ext_patterns.map { |pattern| pattern.sub('**/*', '') } end
def ruby_file?(file)
def ruby_file?(file) stdin? || ruby_extension?(file) || ruby_filename?(file) || ruby_executable?(file) end
def ruby_filename?(file)
def ruby_filename?(file) ruby_filenames.include?(File.basename(file)) end
def ruby_filenames
def ruby_filenames file_patterns = all_cops_include.reject do |pattern| pattern.start_with?('**/*.') end file_patterns.map { |pattern| pattern.sub('**/', '') } end
def ruby_interpreters(file)
def ruby_interpreters(file) @config_store.for(file).for_all_cops['RubyInterpreters'] end
def stdin?
def stdin? @options.key?(:stdin) end
def target_files_in_dir(base_dir = Dir.pwd)
-
(Array)
- Array of filenames
Parameters:
-
base_dir
() -- Root directory under which to search for
def target_files_in_dir(base_dir = Dir.pwd) # Support Windows: Backslashes from command-line -> forward slashes if File::ALT_SEPARATOR base_dir = base_dir.gsub(File::ALT_SEPARATOR, File::SEPARATOR) end all_files = find_files(base_dir, File::FNM_DOTMATCH) hidden_files = Set.new(all_files - find_files(base_dir, 0)) base_dir_config = @config_store.for(base_dir) target_files = all_files.select do |file| to_inspect?(file, hidden_files, base_dir_config) end # Most recently modified file first. target_files.sort_by! { |path| -Integer(File.mtime(path)) } if fail_fast? target_files end
def to_inspect?(file, hidden_files, base_dir_config)
def to_inspect?(file, hidden_files, base_dir_config) return false if base_dir_config.file_to_exclude?(file) return true if !hidden_files.include?(file) && ruby_file?(file) base_dir_config.file_to_include?(file) end
def toplevel_dirs(base_dir, flags)
def toplevel_dirs(base_dir, flags) Dir.glob(File.join(base_dir, '*'), flags).select do |dir| File.directory?(dir) && !dir.end_with?('/.', '/..') end end