Class: FunWith::Files::FilePath
- Defined in:
- lib/files/file_path.rb
Direct Known Subclasses
Constant Summary collapse
- SUCC_DIGIT_COUNT =
Gives a sequence of files. Examples: file.dat –> file.000000.dat file_without_ext –> file_without_ext.000000 If it sees a six-digit number at or near the end of the filename, it increments it.
You can change the length of the sequence string by passing in an argument, but it should always be the same value for a given set of files.
6
Class Method Summary collapse
-
.cwd(*args) ⇒ Object
args implicitly joined to cwd.
- .home(*args) ⇒ Object
- .pwd(*args) ⇒ Object
- .tmpdir(&block) ⇒ Object
Instance Method Summary collapse
- #append(content = nil, &block) ⇒ Object
-
#basename_and_ext ⇒ Object
base, ext = @path.basename_and_ext.
-
#basename_no_ext ⇒ Object
Does not return a filepath.
-
#empty? ⇒ Boolean
Not the same as zero?.
- #expand ⇒ Object
-
#ext ⇒ Object
Does not return a filepath.
- #fwf_filepath ⇒ Object
-
#glob(*args) ⇒ Object
opts: :flags => File::FNM_CASEFOLD File::FNM_DOTMATCH File::FNM_NOESCAPE File::FNM_PATHNAME File::FNM_SYSCASE See Dir documentation for details.
- #grep(regex) ⇒ Object
-
#gsub(*args) ⇒ Object
gsub acts on the filepath, not the file contents.
- #gsub!(*args) ⇒ Object
-
#initialize(*args) ⇒ FilePath
constructor
A new instance of FilePath.
- #join(*args, &block) ⇒ Object (also: #down)
-
#relative_path_from(dir) ⇒ Object
Basically Pathname.relative_path_from, but you can pass in strings.
-
#rename(filename) ⇒ Object
File manipulation.
- #rename_all(pattern, gsubbed) ⇒ Object
- #succ(opts = { digit_count: SUCC_DIGIT_COUNT, timestamp: false }) ⇒ Object
-
#succession(opts = { digit_count: SUCC_DIGIT_COUNT, timestamp: false }) ⇒ Object
TODO: succession : enumerates a sequence of files that get passed to a block in order.
-
#touch(*args) ⇒ Object
Raises error if self is a file and args present.
- #touch_dir(*args) {|touched| ... } ⇒ Object
- #up ⇒ Object
- #without_ext ⇒ Object
- #write(content = nil, &block) ⇒ Object
Constructor Details
#initialize(*args) ⇒ FilePath
Returns a new instance of FilePath.
4 5 6 |
# File 'lib/files/file_path.rb', line 4 def initialize( *args ) super( File.join( *args ) ) end |
Class Method Details
.cwd(*args) ⇒ Object
args implicitly joined to cwd
9 10 11 |
# File 'lib/files/file_path.rb', line 9 def self.cwd( *args ) Dir.pwd.fwf_filepath.join( *args ) end |
.home(*args) ⇒ Object
27 28 29 |
# File 'lib/files/file_path.rb', line 27 def self.home( *args ) Dir.home.fwf_filepath.join( *args ) end |
.pwd(*args) ⇒ Object
13 14 15 |
# File 'lib/files/file_path.rb', line 13 def self.pwd( *args ) self.cwd( *args ) end |
.tmpdir(&block) ⇒ Object
17 18 19 20 21 22 23 24 25 |
# File 'lib/files/file_path.rb', line 17 def self.tmpdir( &block ) if block_given? Dir.mktmpdir do |d| yield d.fwf_filepath end else Dir.mktmpdir.fwf_filepath end end |
Instance Method Details
#append(content = nil, &block) ⇒ Object
162 163 164 165 166 167 168 169 |
# File 'lib/files/file_path.rb', line 162 def append( content = nil, &block ) File.open( self, "a" ) do |f| f << content if content if block_given? yield f end end end |
#basename_and_ext ⇒ Object
base, ext = @path.basename_and_ext
208 209 210 |
# File 'lib/files/file_path.rb', line 208 def basename_and_ext [basename_no_ext, ext] end |
#basename_no_ext ⇒ Object
Does not return a filepath
192 193 194 |
# File 'lib/files/file_path.rb', line 192 def basename_no_ext self.basename.to_s.split(".")[0..-2].join(".") end |
#empty? ⇒ Boolean
Not the same as zero?
181 182 183 184 185 186 187 188 189 |
# File 'lib/files/file_path.rb', line 181 def empty? raise Exceptions::FileDoesNotExist unless self.exist? if self.file? File.size( self ) == 0 elsif self.directory? self.glob( "**", "*" ).length == 0 end end |
#expand ⇒ Object
117 118 119 |
# File 'lib/files/file_path.rb', line 117 def self.class.new( File.( self ) ) end |
#ext ⇒ Object
Does not return a filepath. Does not include leading period
202 203 204 205 |
# File 'lib/files/file_path.rb', line 202 def ext split_basename = self.basename.to_s.split(".") split_basename.length > 1 ? split_basename.last : "" end |
#fwf_filepath ⇒ Object
228 229 230 |
# File 'lib/files/file_path.rb', line 228 def fwf_filepath self end |
#glob(*args) ⇒ Object
opts:
:flags => File::FNM_CASEFOLD
File::FNM_DOTMATCH
File::FNM_NOESCAPE
File::FNM_PATHNAME
File::FNM_SYSCASE
See Dir documentation for details.
Can be given as an integer: (File::FNM_DOTMATCH | File::FNM_NOESCAPE)
or as an array: [File::FNM_CASEFOLD, File::FNM_DOTMATCH]
:class => [self.class] The class of objects you want returned (String, FilePath, ClassLoader, etc.)
Should probably be a subclass of FilePath or String. Class.initialize() must accept a string
[representing a file path] as the sole argument.
:recurse => [false]
:ext => [] A single symbol, or a list containing strings/symbols representing file name extensions.
No leading periods kthxbai.
:sensitive => true : do a case sensitive search. I guess the default is an insensitive search, so
the default behaves similarly on Windows and Unix. Not gonna fight it.
:dots => true : include dotfiles. Does not include . and ..s unless you also
specify the option :parent_and_current => true.
If opts[:recurse] / opts[:ext] not given, the user can get the same
results explicitly with arguments like .glob("**", "*.rb")
:all : if :all is the only argument, this is the same as .glob(“**”, “*”)
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/files/file_path.rb', line 75 def glob( *args ) opts = args.last.is_a?(Hash) ? args.pop : {} flags = case opts[:flags] when NilClass 0 when Array # should be an array of integers opts[:flags].inject(0) do |memo, obj| memo | obj end when Integer opts[:flags] end flags |= File::FNM_DOTMATCH if opts[:dots] flags |= File::FNM_CASEFOLD if opts[:sensitive] if args.first == :all args = ["**", "*"] else recurser = opts[:recurse] ? "**" : nil extensions = case opts[:ext] when Symbol, String "*.#{opts[:ext]}" when Array extensions = opts[:ext].map(&:to_s).join(',') "*.{#{extensions}}" when NilClass nil end args += [recurser, extensions] args.compact! end opts[:class] ||= self.class files = Dir.glob( self.join(*args), flags ).map{ |f| opts[:class].new(f) } files.reject!{ |f| f.basename.to_s.match(/^\.{1,2}$/) } unless opts[:parent_and_current] files end |
#grep(regex) ⇒ Object
171 172 173 174 175 176 177 178 |
# File 'lib/files/file_path.rb', line 171 def grep( regex ) return [] unless self.file? matching = [] self.each_line do |line| matching.push( line ) if line.match( regex ) end matching end |
#gsub(*args) ⇒ Object
gsub acts on the filepath, not the file contents
219 220 221 |
# File 'lib/files/file_path.rb', line 219 def gsub( *args ) self.to_s.gsub(*args).fwf_filepath end |
#gsub!(*args) ⇒ Object
223 224 225 226 |
# File 'lib/files/file_path.rb', line 223 def gsub!( *args ) new_path = self.to_s.gsub(*args) self.instance_variable_set(:@path, new_path) end |
#join(*args, &block) ⇒ Object Also known as: down
31 32 33 34 35 36 37 |
# File 'lib/files/file_path.rb', line 31 def join( *args, &block ) if block_given? yield self.class.new( super(*args) ) else self.class.new( super(*args) ) end end |
#relative_path_from(dir) ⇒ Object
Basically Pathname.relative_path_from, but you can pass in strings
213 214 215 216 |
# File 'lib/files/file_path.rb', line 213 def relative_path_from( dir ) dir = super( Pathname.new( dir ) ) self.class.new( dir ) end |
#rename(filename) ⇒ Object
File manipulation
326 327 328 |
# File 'lib/files/file_path.rb', line 326 def rename( filename ) end |
#rename_all(pattern, gsubbed) ⇒ Object
330 331 332 |
# File 'lib/files/file_path.rb', line 330 def rename_all( pattern, gsubbed ) end |
#succ(opts = { digit_count: SUCC_DIGIT_COUNT, timestamp: false }) ⇒ Object
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/files/file_path.rb', line 242 def succ( opts = { digit_count: SUCC_DIGIT_COUNT, timestamp: false } ) if opts[:timestamp] = Time.now.strftime("%Y%m%d%H%M%S%L") digit_count = .length else = false digit_count = opts[:digit_count] end chunks = self.basename.to_s.split(".") # not yet sequence stamped, no file extension. if chunks.length == 1 if chunks.push( ) else chunks.push( "0" * digit_count ) end # sequence stamp before file extension elsif match_data = chunks[-2].match( /^(\d{#{digit_count}})$/ ) if chunks[-2] = else i = match_data[1].to_i + 1 chunks[-2] = sprintf("%0#{digit_count}i", i) end # try to match sequence stamp to end of filename elsif match_data = chunks[-1].match( /^(\d{#{digit_count}})$/ ) if chunks[-1] = else i = match_data[1].to_i + 1 chunks[-1] = sprintf("%0#{digit_count}i", i) end # not yet sequence_stamped, has file extension else chunks = [chunks[0..-2], ( ? : "0" * digit_count), chunks[-1]].flatten end self.up.join( chunks.join(".") ) end |
#succession(opts = { digit_count: SUCC_DIGIT_COUNT, timestamp: false }) ⇒ Object
TODO: succession : enumerates a sequence of files that get passed to a block in order.
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/files/file_path.rb', line 286 def succession( opts = { digit_count: SUCC_DIGIT_COUNT, timestamp: false } ) if opts[:timestamp] = Time.now.strftime("%Y%m%d%H%M%S%L") digit_count = .length else = false digit_count = opts[:digit_count] end chunks = self.basename.to_s.split(".") glob_stamp_matcher = '[0-9]' * digit_count # unstamped filename, no extension if chunks.length == 1 original = chunks.first stamped = [original, glob_stamp_matcher].join(".") # stamped filename, no extension elsif chunks[-1].match( /^\d{#{digit_count}}$/ ) original = chunks[0..-2].join(".") stamped = [original, glob_stamp_matcher].join(".") # stamped filename, has extension elsif chunks[-2].match( /^\d{#{digit_count}}$/ ) original = [chunks[0..-3], chunks.last].flatten.join(".") stamped = [chunks[0..-3], glob_stamp_matcher, chunks.last].join(".") # unstamped filename, has extension else original = chunks.join(".") stamped = [ chunks[0..-2], glob_stamp_matcher, chunks[-1] ].flatten.join(".") end [self.dirname.glob(original), self.dirname.glob(stamped)].flatten end |
#touch(*args) ⇒ Object
Raises error if self is a file and args present. Raises error if the file is not accessible for writing, or cannot be created. attempts to create a directory
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/files/file_path.rb', line 124 def touch( *args ) raise "Cannot create subdirectory to a file" if self.file? && args.length > 0 touched = self.join(*args) dir_for_touched_file = case args.length when 0 self.up when 1 self when 2..Infinity self.join( *(args[0..-2] ) ) end self.touch_dir( dir_for_touched_file ) unless dir_for_touched_file.directory? FileUtils.touch( touched ) return touched end |
#touch_dir(*args) {|touched| ... } ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/files/file_path.rb', line 141 def touch_dir( *args, &block ) touched = self.join(*args) if touched.directory? FileUtils.touch( touched ) # update access time else FileUtils.mkdir_p( touched ) # create directory (and any needed parents) end yield touched if block_given? return touched end |
#up ⇒ Object
41 42 43 |
# File 'lib/files/file_path.rb', line 41 def up self.class.new( self.join("..") ). end |
#without_ext ⇒ Object
196 197 198 |
# File 'lib/files/file_path.rb', line 196 def without_ext self.gsub(/\.#{self.ext}$/, '') end |
#write(content = nil, &block) ⇒ Object
153 154 155 156 157 158 159 160 |
# File 'lib/files/file_path.rb', line 153 def write( content = nil, &block ) File.open( self, "w" ) do |f| f << content if content if block_given? yield f end end end |