Class: Minitest::VendoredPathExpander
- Inherits:
-
Object
- Object
- Minitest::VendoredPathExpander
- Defined in:
- lib/minitest/path_expander.rb
Overview
PathExpander helps pre-process command-line arguments expanding directories into their constituent files. It further helps by providing additional mechanisms to make specifying subsets easier with path subtraction and allowing for command-line arguments to be saved in a file.
NOTE: this is NOT an options processor. It is a path processor (basically everything else besides options). It does provide a mechanism for pre-filtering cmdline options, but not with the intent of actually processing them in PathExpander. Use OptionParser to deal with options either before or after passing ARGV through PathExpander.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#args ⇒ Object
The args array to process.
-
#glob ⇒ Object
The glob used to expand dirs to files.
-
#path ⇒ Object
The path to scan if no paths are found in the initial scan.
Instance Method Summary collapse
-
#_normalize(f) ⇒ Object
:nodoc:.
-
#expand_dirs_to_files(*dirs) ⇒ Object
Takes an array of paths and returns an array of paths where all directories are expanded to all files found via the glob provided to PathExpander.
-
#filter_files(files, ignore) ⇒ Object
A file filter mechanism similar to, but not as extensive as, .gitignore files:.
-
#initialize(args, glob, path = ".") ⇒ VendoredPathExpander
constructor
Create a new path expander that operates on args and expands via glob as necessary.
- #post_process ⇒ Object
- #pre_process ⇒ Object
-
#process(&b) ⇒ Object
Top-level method processes args.
-
#process_args ⇒ Object
Enumerate over args passed to PathExpander and return a list of files and flags to process.
-
#process_file(path) ⇒ Object
Process a file into more arguments.
-
#process_flags(flags) ⇒ Object
Process over flags and treat any special ones here.
Constructor Details
#initialize(args, glob, path = ".") ⇒ VendoredPathExpander
Create a new path expander that operates on args and expands via glob as necessary. Takes an optional path arg to fall back on if no paths are found on the initial scan (see #process_args).
43 44 45 46 47 |
# File 'lib/minitest/path_expander.rb', line 43 def initialize args, glob, path = "." self.args = args self.glob = glob self.path = path end |
Instance Attribute Details
#args ⇒ Object
The args array to process.
26 27 28 |
# File 'lib/minitest/path_expander.rb', line 26 def args @args end |
#glob ⇒ Object
The glob used to expand dirs to files.
31 32 33 |
# File 'lib/minitest/path_expander.rb', line 31 def glob @glob end |
#path ⇒ Object
The path to scan if no paths are found in the initial scan.
36 37 38 |
# File 'lib/minitest/path_expander.rb', line 36 def path @path end |
Instance Method Details
#_normalize(f) ⇒ Object
:nodoc:
66 |
# File 'lib/minitest/path_expander.rb', line 66 def _normalize(f) = Pathname.new(f).cleanpath.to_s # :nodoc: |
#expand_dirs_to_files(*dirs) ⇒ Object
Takes an array of paths and returns an array of paths where all directories are expanded to all files found via the glob provided to PathExpander.
Paths are normalized to not have a leading “./”.
56 57 58 59 60 61 62 63 64 |
# File 'lib/minitest/path_expander.rb', line 56 def *dirs dirs.flatten.map { |p| if File.directory? p then Dir[File.join(p, glob)].find_all { |f| File.file? f } else p end }.flatten.sort.map { |s| _normalize s } end |
#filter_files(files, ignore) ⇒ Object
A file filter mechanism similar to, but not as extensive as, .gitignore files:
+ If a pattern does not contain a slash, it is treated as a shell glob. + If a pattern ends in a slash, it matches on directories (and contents). + Otherwise, it matches on relative paths.
File.fnmatch is used throughout, so glob patterns work for all 3 types.
Takes a list of files and either an io or path of ignore data and returns a list of files left after filtering.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/minitest/path_expander.rb', line 197 def filter_files files, ignore ignore_paths = if ignore.respond_to? :read then ignore.read elsif File.exist? ignore then File.read ignore end if ignore_paths then nonglobs, globs = ignore_paths.split("\n").partition { |p| p.include? "/" } dirs, ifiles = nonglobs.partition { |p| p.end_with? "/" } dirs = dirs.map { |s| s.chomp "/" } dirs.map! { |i| File. i } globs.map! { |i| File. i } ifiles.map! { |i| File. i } only_paths = File::FNM_PATHNAME files = files.reject { |f| f = File.(f) dirs.any? { |i| File.fnmatch?(i, File.dirname(f), only_paths) } || globs.any? { |i| File.fnmatch?(i, f) } || ifiles.any? { |i| File.fnmatch?(i, f, only_paths) } } end files end |
#post_process ⇒ Object
182 |
# File 'lib/minitest/path_expander.rb', line 182 def post_process = nil |
#pre_process ⇒ Object
181 |
# File 'lib/minitest/path_expander.rb', line 181 def pre_process = nil |
#process(&b) ⇒ Object
Top-level method processes args. If no block is given, immediately returns with an Enumerator for further chaining.
Otherwise, it calls pre_process, process_args and process_flags, enumerates over the files, and then calls post_process, returning self for any further chaining.
Most of the time, you’re going to provide a block to process files and do nothing more with the result. Eg:
PathExpander.new(ARGV).process do |f|
puts "./#{f}"
end
or:
PathExpander.new(ARGV).process # => Enumerator
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/minitest/path_expander.rb', line 165 def process(&b) return enum_for(:process) unless block_given? pre_process files, flags = process_args args.replace process_flags flags files.uniq.each(&b) post_process self end |
#process_args ⇒ Object
Enumerate over args passed to PathExpander and return a list of files and flags to process. Arguments are processed as:
- -file_path
-
Subtract path from file to be processed.
- -dir_path
-
Expand and subtract paths from files to be processed.
- -not_a_path
-
Add to flags to be processed.
- dir_path
-
Expand and add to files to be processed.
- file_path
-
Add to files to be processed.
-
Add “-” (stdin) to files to be processed.
-
See expand_dirs_to_files for details on how expansion occurs.
Subtraction happens last, regardless of argument ordering.
If no files are found (which is not the same as having an empty file list after subtraction), then fall back to expanding on the default #path given to initialize.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/minitest/path_expander.rb', line 96 def process_args pos_files = [] neg_files = [] flags = [] clean = true root_dir = File. "/" # needed for windows paths args.each do |arg| case arg when /^@(.*)/ then # push back on, so they can have dirs/-/@ as well clean = false args.concat process_file $1 when "-" then pos_files << arg when /^-(.*)/ then if File.exist? $1 then clean = false neg_files += ($1) else flags << arg end else root_path = File.(arg) == root_dir # eg: -n /./ if File.exist? arg and not root_path then clean = false pos_files += (arg) else flags << arg end end end files = pos_files - neg_files files += (self.path) if files.empty? && clean [files, flags] end |
#process_file(path) ⇒ Object
Process a file into more arguments. Override this to add additional capabilities.
72 73 74 |
# File 'lib/minitest/path_expander.rb', line 72 def process_file path File.readlines(path).map(&:chomp) end |
#process_flags(flags) ⇒ Object
Process over flags and treat any special ones here. Returns an array of the flags you haven’t processed.
This version does nothing. Subclass and override for customization.
142 143 144 |
# File 'lib/minitest/path_expander.rb', line 142 def process_flags flags flags end |