rfs 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +51 -0
- data/Rakefile.rb +4 -4
- data/bin/rfs.rb +35 -4
- data/lib/innate/array.rb +1 -0
- data/lib/innate/test/all_tests.rb +2 -0
- data/lib/providers.rb +45 -55
- data/lib/rename_functions.rb +12 -0
- data/lib/renamer.rb +9 -9
- data/lib/results.rb +29 -24
- data/lib/test/test_helper.rb +6 -1
- data/tests/all_tests.rb +3 -0
- data/tests/test_add.rb +45 -0
- data/tests/test_basics.rb +67 -0
- data/tests/test_capitalize.rb +24 -0
- data/tests/test_confirm.rb +145 -0
- data/tests/test_count.rb +20 -0
- data/tests/test_delete.rb +106 -0
- data/tests/test_downcase.rb +35 -0
- data/tests/test_files_txt.rb +90 -0
- data/tests/test_fill.rb +37 -0
- data/tests/test_filter.rb +36 -0
- data/tests/test_full_name.rb +20 -0
- data/tests/test_glob.rb +11 -0
- data/tests/test_mark_change.rb +55 -0
- data/tests/test_move_up.rb +18 -0
- data/tests/test_replace.rb +45 -0
- data/tests/test_roman.rb +28 -0
- data/tests/test_tape_numbers.rb +20 -0
- data/tests/test_upcase.rb +24 -0
- metadata +23 -4
- data/tests/test_rename_functions.rb +0 -613
data/CHANGELOG
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
Sept. 3, 2005
|
2
|
+
|
3
|
+
Rename File Set v0.2 has been released with a few
|
4
|
+
more features. All bugs found so far have been
|
5
|
+
fixed, too.
|
6
|
+
|
7
|
+
What's new?
|
8
|
+
|
9
|
+
GUI version:
|
10
|
+
* when using the 'Toggle Roman Numerals' option
|
11
|
+
the search pattern " (roman) " will be replaced with
|
12
|
+
a robust regexp to capture roman numerals.
|
13
|
+
* the output pane will display results in multiple
|
14
|
+
columns if possible
|
15
|
+
* gui should now work from a gem installation
|
16
|
+
(requires fxruby 1.2.x. 1.4.x is yet untested)
|
17
|
+
|
18
|
+
Command-line version:
|
19
|
+
* same change for --roman as above.
|
20
|
+
* added --rm option to remove files matching
|
21
|
+
the search
|
22
|
+
* added --eval EXPR to allow you to do pretty
|
23
|
+
much whatever you like. Captures can be used
|
24
|
+
with %1..%n, but should be enclosed in quotes,
|
25
|
+
and local variables file, path, and md (match data)
|
26
|
+
are available, amoung other things. The idea
|
27
|
+
is to be able to do things like:
|
28
|
+
--eval "6 * '%2'.to_f"
|
29
|
+
* enhanced --count to allow anything as the starting
|
30
|
+
point, and increment using String#succ.
|
31
|
+
* changed the way --raw_output is displayed
|
32
|
+
* fixed up the --help output a lot
|
33
|
+
|
34
|
+
Cheers!
|
35
|
+
Darrick => innatesoftware.com
|
36
|
+
|
37
|
+
Sept. 6, 2005
|
38
|
+
|
39
|
+
* All of the remaining tests have now been implemented
|
40
|
+
and are passing.
|
41
|
+
|
42
|
+
* Fixed a bug in row or column output which occurred if
|
43
|
+
no items were wider than the 80 chars but only one-column
|
44
|
+
layout was possible. The bug would crash both interfaces.
|
45
|
+
|
46
|
+
Command-line version:
|
47
|
+
* Added --pattern to use Dir.glob type patterns
|
48
|
+
instead of path names
|
49
|
+
* Added --stdin to allow the program to capture
|
50
|
+
file names from a pipe. This does not work with
|
51
|
+
confirmations (STDIN is already in use).
|
data/Rakefile.rb
CHANGED
@@ -4,17 +4,17 @@ require 'rake/gempackagetask'
|
|
4
4
|
require 'rake/contrib/rubyforgepublisher'
|
5
5
|
|
6
6
|
PKG_NAME = 'rfs'
|
7
|
-
PKG_VERSION = '0.
|
7
|
+
PKG_VERSION = '0.3'
|
8
8
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
9
9
|
|
10
|
-
RELEASE_NAME = "
|
10
|
+
RELEASE_NAME = "rfs #{PKG_VERSION}"
|
11
11
|
|
12
12
|
RUBY_FORGE_PROJECT = "rfs"
|
13
13
|
RUBY_FORGE_USER = "pangloss"
|
14
14
|
|
15
15
|
task :default => :test
|
16
16
|
Rake::TestTask.new { |t|
|
17
|
-
t.pattern = 'tests/
|
17
|
+
t.pattern = 'tests/all_tests.rb'
|
18
18
|
}
|
19
19
|
|
20
20
|
# Create compressed packages
|
@@ -50,7 +50,7 @@ spec = Gem::Specification.new do |s|
|
|
50
50
|
).delete_if { |item| item.include?( "\.svn" ) || item.include?("\pkg") }
|
51
51
|
s.require_path = 'lib'
|
52
52
|
s.has_rdoc = false
|
53
|
-
s.test_files = ['./tests/
|
53
|
+
s.test_files = ['./tests/all_tests.rb', './lib/innate/test/all_tests.rb']
|
54
54
|
|
55
55
|
s.bindir = 'bin'
|
56
56
|
s.executables << 'rfs.rb'
|
data/bin/rfs.rb
CHANGED
@@ -44,6 +44,7 @@ class CommandLineInterface
|
|
44
44
|
quiet = false
|
45
45
|
silent = false
|
46
46
|
reverse = false
|
47
|
+
use_stdin = false
|
47
48
|
|
48
49
|
# more defaults... make configurable in the future
|
49
50
|
CommandLineInterface.confirm # confirm changes
|
@@ -152,6 +153,12 @@ class CommandLineInterface
|
|
152
153
|
op.on('-T', '--title', 'Convert capture to title case.') {
|
153
154
|
function = :rename_capitalize
|
154
155
|
}
|
156
|
+
op.on('--upcase', 'Convert capture to upper case.') {
|
157
|
+
function = :rename_upcase
|
158
|
+
}
|
159
|
+
op.on('--downcase', 'Convert capture to lower case.') {
|
160
|
+
function = :rename_downcase
|
161
|
+
}
|
155
162
|
op.on('-u', '--up', 'Move matching files up to parent directory.') {
|
156
163
|
function = :rename_move_up
|
157
164
|
}
|
@@ -171,6 +178,11 @@ class CommandLineInterface
|
|
171
178
|
op.on('-I', '--ignorecase', 'Make all REGEXP options case-insensitive.') {
|
172
179
|
insensitive = true
|
173
180
|
}
|
181
|
+
op.on('-P', '--pattern', 'Treat trailing [path] arguments as',
|
182
|
+
'file search patterns rather than as',
|
183
|
+
'folder names. ie. **/xy?/*.mp3') {
|
184
|
+
file_provider = Provider::File::Glob
|
185
|
+
}
|
174
186
|
op.on('-R', '--recursive',
|
175
187
|
'Recursively descend the directory',
|
176
188
|
'tree.') {
|
@@ -179,7 +191,9 @@ class CommandLineInterface
|
|
179
191
|
op.on('--reverse', 'Operate on files in reverse order.') {
|
180
192
|
reverse = true
|
181
193
|
}
|
182
|
-
|
194
|
+
op.on('--stdin', 'Read filenames from stdin.') {
|
195
|
+
use_stdin = true
|
196
|
+
}
|
183
197
|
|
184
198
|
op.separator "Output Options:"
|
185
199
|
op.on('--sort', 'Sort output') { @@results.sorted = true }
|
@@ -197,9 +211,9 @@ class CommandLineInterface
|
|
197
211
|
op.on('-x', '--sideways', 'Display in rows instead of in columns.') {
|
198
212
|
@@results.sideways = true
|
199
213
|
}
|
200
|
-
op.on('-X', '--raw_output', '
|
201
|
-
'
|
202
|
-
@@results
|
214
|
+
op.on('-X', '--raw_output', 'Alternate output mode. Output immediately',
|
215
|
+
'without sorting, line by line.') {
|
216
|
+
@@results = RawResults.new $<
|
203
217
|
}
|
204
218
|
|
205
219
|
paths = op.parse ARGV
|
@@ -224,6 +238,8 @@ class CommandLineInterface
|
|
224
238
|
puts "DON'T confirm changes."
|
225
239
|
end
|
226
240
|
end
|
241
|
+
|
242
|
+
puts "function: #{function}" if options[:verbose]
|
227
243
|
|
228
244
|
PrepareRegexp.each(options) do |k, v|
|
229
245
|
t = v.create(insensitive, print_matches, true) do |mode, output|
|
@@ -232,6 +248,21 @@ class CommandLineInterface
|
|
232
248
|
t.k = k if print_matches
|
233
249
|
t
|
234
250
|
end
|
251
|
+
|
252
|
+
if use_stdin
|
253
|
+
if options[:confirm] and options[:action] == :commit
|
254
|
+
puts 'You may not use confirmations when using stdin to read file data. ' +
|
255
|
+
'Please specify --noconfirm'
|
256
|
+
exit
|
257
|
+
file_provider = Provider::File::BufferedStdIn
|
258
|
+
else
|
259
|
+
file_provider = Provider::File::StdIn
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# todo: ask: is it possible to read data from a pipe and then
|
264
|
+
# close that pipe and open stdin on a tty? I want to be able
|
265
|
+
# to ask the user for confirmations.
|
235
266
|
|
236
267
|
options[:file_provider] = file_provider.new(paths)
|
237
268
|
options[:file_provider].reverse if reverse
|
data/lib/innate/array.rb
CHANGED
data/lib/providers.rb
CHANGED
@@ -50,6 +50,18 @@ module Provider
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
53
|
+
|
54
|
+
|
55
|
+
class Glob < Base
|
56
|
+
def each
|
57
|
+
@folders.each do |pattern|
|
58
|
+
Dir.glob(pattern).send(@iterator) do |fn|
|
59
|
+
path, file = ::File.split fn
|
60
|
+
yield path, file unless file =~ /^\.+$/
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
53
65
|
|
54
66
|
|
55
67
|
class Recursive < Base
|
@@ -65,7 +77,7 @@ module Provider
|
|
65
77
|
dir.collect.send(@iterator) do |file|
|
66
78
|
j = ::File.join(folder, file)
|
67
79
|
unless file =~ /^\.+$/
|
68
|
-
if ::File.directory? j
|
80
|
+
if ::File.directory? j
|
69
81
|
recursive_each j, &block
|
70
82
|
end
|
71
83
|
yield folder, file
|
@@ -92,61 +104,39 @@ module Provider
|
|
92
104
|
end
|
93
105
|
|
94
106
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
#def each
|
114
|
-
#@cache.each do |a|
|
115
|
-
#yield a.first, a.last
|
116
|
-
#end
|
117
|
-
#unless @cache_complete
|
118
|
-
#while @fg.next?
|
119
|
-
#begin
|
120
|
-
#Thread.critical = true
|
121
|
-
#path, file = @fg.next
|
122
|
-
#@cache << [path, file]
|
123
|
-
#@cache_complete = true unless @fg.next?
|
124
|
-
#ensure
|
125
|
-
#Thread.critical = false
|
126
|
-
#end
|
127
|
-
#yield path, file
|
128
|
-
#end
|
129
|
-
#end
|
130
|
-
#end
|
131
|
-
#end
|
132
|
-
|
107
|
+
class BufferedStdIn < Base
|
108
|
+
def initialize(*ignored)
|
109
|
+
super nil
|
110
|
+
end
|
111
|
+
|
112
|
+
def each
|
113
|
+
file = []
|
114
|
+
until STDIN.eof?
|
115
|
+
file << STDIN.readline.rstrip
|
116
|
+
end
|
117
|
+
file.each do |line|
|
118
|
+
next if line.empty?
|
119
|
+
path, file = ::File.split(line)
|
120
|
+
yield path, file
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
133
125
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
#end
|
126
|
+
class StdIn < Base
|
127
|
+
def initialize(*ignored)
|
128
|
+
super nil
|
129
|
+
end
|
130
|
+
|
131
|
+
def each
|
132
|
+
until STDIN.eof?
|
133
|
+
line = STDIN.readline.rstrip
|
134
|
+
next if line.empty?
|
135
|
+
path, file = ::File.split(line)
|
136
|
+
yield path, file
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
149
140
|
end
|
150
141
|
end
|
151
142
|
|
152
|
-
|
data/lib/rename_functions.rb
CHANGED
@@ -150,6 +150,18 @@ protected
|
|
150
150
|
subst(file, md, eval(s).to_s)
|
151
151
|
end
|
152
152
|
end
|
153
|
+
|
154
|
+
def rename_upcase
|
155
|
+
rename_each_match do |file, md|
|
156
|
+
subst(file, md, active_capture(md).upcase)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def rename_downcase
|
161
|
+
rename_each_match do |file, md|
|
162
|
+
subst(file, md, active_capture(md).downcase)
|
163
|
+
end
|
164
|
+
end
|
153
165
|
end
|
154
166
|
|
155
167
|
|
data/lib/renamer.rb
CHANGED
@@ -42,14 +42,8 @@ protected
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def actual_rename(o, n)
|
45
|
-
len = File.expand_path(n).length
|
46
|
-
raise NameLengthError.new(len) if len >= 255
|
47
45
|
File.mkdirs File.split(n).first
|
48
|
-
|
49
|
-
raise DirectoryExistsError.new("Can't overwrite an existing directory.")
|
50
|
-
else
|
51
|
-
File.rename(o, n)
|
52
|
-
end
|
46
|
+
File.rename(o, n)
|
53
47
|
end
|
54
48
|
|
55
49
|
def actual_delete(fn)
|
@@ -103,12 +97,18 @@ protected
|
|
103
97
|
unless oldfn == newfn or (full_path and old_full == newfn)
|
104
98
|
t = newfn
|
105
99
|
fn = dest_file path, newfn, full_path
|
106
|
-
if !@options[:force] and already_exists?(path, oldfn, newfn, full_path)
|
100
|
+
if (!@options[:force]) and already_exists?(path, oldfn, newfn, full_path)
|
107
101
|
result :fileerror, 'File already exists', path, oldfn
|
108
102
|
elsif @options[:action] == :commit
|
109
103
|
if confirm path, oldfn, newfn, full_path
|
110
104
|
begin
|
111
|
-
|
105
|
+
len = File.expand_path(fn).length
|
106
|
+
raise NameLengthError.new(len) if len >= 255
|
107
|
+
if File.directory? fn and old_full.downcase != fn.downcase
|
108
|
+
raise DirectoryExistsError.new("Can't overwrite an existing directory.")
|
109
|
+
else
|
110
|
+
actual_rename old_full, fn
|
111
|
+
end
|
112
112
|
rescue => e
|
113
113
|
result :fileerror, "#{e.class}: #{e.message}", path, oldfn
|
114
114
|
else
|
data/lib/results.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
-
class
|
2
|
-
attr_accessor :verbose, :quiet, :silent, :sideways, :
|
1
|
+
class BaseResults
|
2
|
+
attr_accessor :verbose, :quiet, :silent, :sideways, :sorted, :list
|
3
3
|
attr_accessor :out
|
4
4
|
attr_reader :results
|
5
|
+
end
|
6
|
+
|
7
|
+
class CollectResults < BaseResults
|
5
8
|
|
6
9
|
def initialize(out_io, width)
|
7
10
|
@verbose = false
|
8
11
|
@quiet = false
|
9
12
|
@silent = false
|
10
13
|
@sideways = false
|
11
|
-
@lineways = false
|
12
14
|
@sorted = false
|
13
15
|
@list = false
|
14
16
|
|
@@ -53,31 +55,15 @@ class CollectResults
|
|
53
55
|
when :fileerror: errors += v.length
|
54
56
|
end
|
55
57
|
s = ''
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
@out.puts s
|
60
|
-
end
|
58
|
+
s += "\n#{File.expand_path(k)}"
|
59
|
+
s += ": #{mode.to_s.upcase} - #{v.length} files" unless @quiet or @list
|
60
|
+
@out.puts s
|
61
61
|
v = v.sort if @sorted
|
62
|
-
|
63
|
-
v.each do |file|
|
64
|
-
if @list
|
65
|
-
out.puts File.join(k, file)
|
66
|
-
else
|
67
|
-
@out.puts format('%s: %s', mode.to_s.upcase, File.join(k, file))
|
68
|
-
end
|
69
|
-
end
|
70
|
-
else
|
71
|
-
@out.puts v.send(m, @width)
|
72
|
-
end
|
62
|
+
@out.puts v.send(m, @width)
|
73
63
|
end
|
74
64
|
else
|
75
65
|
@out.puts "\n#{mode.to_s.upcase}"
|
76
|
-
|
77
|
-
@out.puts value.join("\n")
|
78
|
-
else
|
79
|
-
@out.puts value.send(m, @width)
|
80
|
-
end
|
66
|
+
@out.puts value.send(m, @width)
|
81
67
|
end
|
82
68
|
end
|
83
69
|
unless @quiet
|
@@ -90,4 +76,23 @@ class CollectResults
|
|
90
76
|
end
|
91
77
|
end
|
92
78
|
|
79
|
+
class RawResults < BaseResults
|
80
|
+
def initialize(out_io)
|
81
|
+
@out = out_io
|
82
|
+
end
|
83
|
+
|
84
|
+
def output(mode, text, path = nil, file = nil)
|
85
|
+
return if @silent
|
86
|
+
if @quiet or @list
|
87
|
+
puts text
|
88
|
+
else
|
89
|
+
puts "#{mode}: #{File.join(path, file)} => #{text}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def display
|
94
|
+
puts '-- done' unless @quiet or @silent
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
93
98
|
|
data/lib/test/test_helper.rb
CHANGED
@@ -8,7 +8,6 @@ $:.unshift '../lib'
|
|
8
8
|
require 'renamer'
|
9
9
|
require 'cursor/indexed'
|
10
10
|
|
11
|
-
|
12
11
|
class RenamerMock < Renamer
|
13
12
|
attr_reader :renames
|
14
13
|
|
@@ -106,6 +105,12 @@ class BaseTest < Test::Unit::TestCase
|
|
106
105
|
def setup
|
107
106
|
new_files( %w{ dir/. dir/.. dir/file1 dir/file2 dir/file3 } )
|
108
107
|
@r = RenamerMock.new
|
108
|
+
@orig_dir = Dir.getwd
|
109
|
+
Dir.chdir File.join(File.split(__FILE__).first, '/../../tests')
|
110
|
+
end
|
111
|
+
|
112
|
+
def teardown
|
113
|
+
Dir.chdir @orig_dir
|
109
114
|
end
|
110
115
|
|
111
116
|
def new_files(files)
|