Class: Fned::Rename
- Inherits:
-
Object
- Object
- Fned::Rename
- Defined in:
- lib/fned/rename.rb
Instance Method Summary collapse
-
#add(source, destination) ⇒ Object
add source, destination to list of intended renames.
-
#initialize(options = {}) ⇒ Rename
constructor
A new instance of Rename.
-
#normalize(path) ⇒ Object
normalize path.
-
#rename(source, destination) ⇒ Object
rename a single file.
-
#rename_files ⇒ Object
rename the added files, return array of errors.
- #verbose? ⇒ Boolean
Constructor Details
#initialize(options = {}) ⇒ Rename
Returns a new instance of Rename.
19 20 21 22 23 24 25 |
# File 'lib/fned/rename.rb', line 19 def initialize( = {}) @options = { :verbose => false, }.merge() @renames = {} end |
Instance Method Details
#add(source, destination) ⇒ Object
add source, destination to list of intended renames
32 33 34 |
# File 'lib/fned/rename.rb', line 32 def add(source, destination) @renames[source] = destination end |
#normalize(path) ⇒ Object
normalize path
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/fned/rename.rb', line 52 def normalize(path) # NOTE: removing /../ by removing the previous component of a path # is a bad idea as /symlink/../ is the parent directory of the # directory the symlink is pointing to, which is in general not # the same as /. path.to_s. # replace successive slashes gsub(%r{//+}, "/"). # remove trailing slash sub(%r{/\z}, ""). # replace /./ gsub(%r{/\./}, "/"). # remove ./ in the beginning and /. in the end gsub(%r{(?:\A\./|/\.\z)}, "") end |
#rename(source, destination) ⇒ Object
rename a single file
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/fned/rename.rb', line 69 def rename(source, destination) # Normalizing the paths has two reasons: # (1) renaming symlinks fails with trailing slashes but trailing # slashes might be present if the symlink points to a directory # (2) comparison if source and destination are the same src, dst = normalize(source), normalize(destination) return if src == dst # TODO: racy, use link(src, dst); unlink(src)? if File.exist?(dst) warn "not renaming because target exists: %s -> %s" % [source.to_s.inspect, destination.to_s.inspect] return end begin # TODO: add cross filesystem rename puts "%s -> %s" % [source.to_s.inspect, destination.to_s.inspect] if verbose? File.rename(src, dst) rescue SystemCallError => error @errors << error # create a new exception to get the clean error message without # a filename warn "cannot rename %s: %s" % [source.to_s.inspect, SystemCallError.new(error.errno).] end end |
#rename_files ⇒ Object
rename the added files, return array of errors
37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/fned/rename.rb', line 37 def rename_files @errors = [] # Rename in reverse order of source filename such that directories # will be renamed after all files within the directory have been # renamed. # TODO: implement more advanced strategies for renaming # dependencies including cyclic dependencies (i.e. swapping # filenames) @renames.sort_by { |src, dst| src }.reverse.each do |src, dst| rename(src, dst) end @errors end |
#verbose? ⇒ Boolean
27 28 29 |
# File 'lib/fned/rename.rb', line 27 def verbose? @options[:verbose] end |