rfs 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +7 -0
- data/Rakefile.rb +193 -0
- data/bin/RenameFileSet.rbw +14 -0
- data/bin/rfs.rb +214 -0
- data/bin/rfsd.rb +8 -0
- data/description.txt +24 -0
- data/lib/RenameFileSet.bak.rb +372 -0
- data/lib/errors.rb +15 -0
- data/lib/filters.rb +68 -0
- data/lib/gui.rb +216 -0
- data/lib/innate/array.rb +104 -0
- data/lib/innate/coverage.rb +315 -0
- data/lib/innate/debug.rb +12 -0
- data/lib/innate/debugger.rb +944 -0
- data/lib/innate/file.rb +5 -0
- data/lib/innate/filelines.rb +148 -0
- data/lib/innate/kernel.rb +41 -0
- data/lib/innate/metaid.rb +30 -0
- data/lib/innate/mkdirs.rb +12 -0
- data/lib/innate/regexp.rb +80 -0
- data/lib/innate/reload.rb +11 -0
- data/lib/innate/roman.rb +72 -0
- data/lib/innate/scriptlines.rb +60 -0
- data/lib/innate/string.rb +56 -0
- data/lib/innate/test/all_tests.rb +11 -0
- data/lib/innate/test/files/mkdirs_dummy.file +1 -0
- data/lib/innate/test/files/reloadtarget.rb +5 -0
- data/lib/innate/test/files/reloadtarget1.rb +5 -0
- data/lib/innate/test/files/reloadtarget2.rb +5 -0
- data/lib/innate/test/test_coverage.rb +13 -0
- data/lib/innate/test/testarray.rb +98 -0
- data/lib/innate/test/testfile.rb +15 -0
- data/lib/innate/test/testfilelines.rb +106 -0
- data/lib/innate/test/testkernel.rb +30 -0
- data/lib/innate/test/testmkdirs.rb +19 -0
- data/lib/innate/test/testregexp.rb +86 -0
- data/lib/innate/test/testreload.rb +61 -0
- data/lib/innate/test/testroman.rb +54 -0
- data/lib/innate/test/testscriptlines.rb +39 -0
- data/lib/innate/test/teststring.rb +52 -0
- data/lib/innate/test/testtitlecase.rb +20 -0
- data/lib/innate/titlecase.rb +64 -0
- data/lib/innate/tracerequire.rb +22 -0
- data/lib/namesource.rb +53 -0
- data/lib/options.rb +64 -0
- data/lib/providers.rb +93 -0
- data/lib/regexp.rb +56 -0
- data/lib/rename_functions.rb +142 -0
- data/lib/renamer.rb +210 -0
- data/lib/results.rb +83 -0
- data/lib/test/test_helper.rb +147 -0
- data/tests/dir/file1 +0 -0
- data/tests/dir/file2 +0 -0
- data/tests/dir/file3 +0 -0
- data/tests/test_helper.rb +147 -0
- data/tests/test_rename_functions.rb +605 -0
- metadata +105 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
def copy(a, b)
|
2
|
+
File.open(b, 'w') do |f|
|
3
|
+
f.write File.read(a)
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'test/unit'
|
8
|
+
require 'innate/reload'
|
9
|
+
require 'innate/scriptlines'
|
10
|
+
|
11
|
+
class TestReload < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def t
|
14
|
+
begin
|
15
|
+
copy 'files/reloadtarget1.rb', 'files/reloadtarget.rb'
|
16
|
+
require 'files/reloadtarget'
|
17
|
+
yield :original
|
18
|
+
copy 'files/reloadtarget2.rb', 'files/reloadtarget.rb'
|
19
|
+
reload 'files/reloadtarget'
|
20
|
+
yield :reloaded
|
21
|
+
ensure
|
22
|
+
# I don't delete anymore because it messes up the tests
|
23
|
+
# for scriptlines
|
24
|
+
#File.delete 'files/reloadtarget.rb' rescue nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
#targetfn sleeps for 2 seconds.. more than enough time to have an overlap
|
30
|
+
def test_reload
|
31
|
+
thread = nil
|
32
|
+
t do |step|
|
33
|
+
if step == :original
|
34
|
+
thread = Thread.new do
|
35
|
+
assert_equal 'function1', targetfn {|v| assert_equal 'start 1', v }
|
36
|
+
end
|
37
|
+
elsif step == :reloaded
|
38
|
+
assert_equal 'function2', targetfn {|v| assert_equal 'start 2', v }
|
39
|
+
thread.join
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_reload_scriptlines
|
45
|
+
orig = nil
|
46
|
+
fn = nil
|
47
|
+
t do |step|
|
48
|
+
if step == :original
|
49
|
+
fn = find_in_path 'files/reloadtarget'
|
50
|
+
orig = SCRIPT_LINES__[fn].collect
|
51
|
+
elsif step == :reloaded
|
52
|
+
r = SCRIPT_LINES__[fn]
|
53
|
+
assert_not_nil orig.first
|
54
|
+
assert_equal orig.first, r.first
|
55
|
+
assert_equal orig.last, r.last
|
56
|
+
assert_equal orig[1..-2].collect {|l| l.tr('12', '21') }, r[1..-2]
|
57
|
+
assert_equal orig.collect {|l| l.tr('12', '21') }, r.collect
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'innate/roman'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestRoman < Test::Unit::TestCase
|
5
|
+
# Since it works already I don't really need more
|
6
|
+
# detailed tests. If it breaks, break this down.
|
7
|
+
def test_full_range
|
8
|
+
r = (1..4999).inject(['']) { |lon, v|
|
9
|
+
lon.unshift v.roman if v.roman.length > lon.first.length
|
10
|
+
lon
|
11
|
+
}.delete_if {|v| v == ''}.reverse.collect {|v| [v, v.roman_to_i] }
|
12
|
+
assert_equal([["I", 1],
|
13
|
+
["II", 2],
|
14
|
+
["III", 3],
|
15
|
+
["VIII", 8],
|
16
|
+
["XVIII", 18],
|
17
|
+
["XXVIII", 28],
|
18
|
+
["XXXVIII", 38],
|
19
|
+
["LXXXVIII", 88],
|
20
|
+
["CLXXXVIII", 188],
|
21
|
+
["CCLXXXVIII", 288],
|
22
|
+
["CCCLXXXVIII", 388],
|
23
|
+
["DCCCLXXXVIII", 888],
|
24
|
+
["MDCCCLXXXVIII", 1888],
|
25
|
+
["MMDCCCLXXXVIII", 2888],
|
26
|
+
["MMMDCCCLXXXVIII", 3888],
|
27
|
+
["MMMMDCCCLXXXVIII", 4888]],
|
28
|
+
r)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_lower_case
|
32
|
+
assert_equal 1914, 'mcmxiv'.roman_to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_toggle1
|
36
|
+
assert_equal '1914', '1914'.toggle_roman.toggle_roman
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_toggle2
|
40
|
+
assert_equal 'MCMXLIV', 'mcmxliv'.toggle_roman.toggle_roman
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_interpolate_regexp
|
44
|
+
assert_equal('(?-mix:valiant(' + Regexp.ROMAN_PATTERN + ')soldier)',
|
45
|
+
(/valiant(roman)soldier/).interpolate_roman.to_s)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_interpolate_regexp2
|
49
|
+
assert_equal('(?i-mx:valiant(' + Regexp.ROMAN_PATTERN + ')soldier)',
|
50
|
+
(/valiant(roman)soldier/i).interpolate_roman.to_s)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'innate/scriptlines'
|
3
|
+
require 'cursor/indexed'
|
4
|
+
require 'timeout'
|
5
|
+
|
6
|
+
class TestScriptLines < Test::Unit::TestCase
|
7
|
+
def test_defined
|
8
|
+
assert defined?(SCRIPT_LINES__)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_types
|
12
|
+
assert SCRIPT_LINES__.length > 0
|
13
|
+
SCRIPT_LINES__.each do |name, file|
|
14
|
+
assert File.exists?(name)
|
15
|
+
assert_kind_of FileLines, file
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_contents
|
20
|
+
locked = 0
|
21
|
+
begin
|
22
|
+
Timeout::timeout(30) do
|
23
|
+
SCRIPT_LINES__.each do |name, file|
|
24
|
+
begin
|
25
|
+
lines = File.open(name) {|f| f.readlines }.to_cursor
|
26
|
+
file.each do |line|
|
27
|
+
assert_equal lines.read1next, line
|
28
|
+
end
|
29
|
+
rescue Errno::EACCES
|
30
|
+
locked += 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
assert locked <= 3, 'too many locked files...??'
|
34
|
+
end
|
35
|
+
rescue Timeout::Error
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'innate/string'
|
3
|
+
require 'cursor/indexed'
|
4
|
+
|
5
|
+
class TestString < Test::Unit::TestCase
|
6
|
+
def test_starts_with?
|
7
|
+
assert_nil 'o\'hare'.starts_with?('Mc', 'Mac', 'O\'')
|
8
|
+
assert_equal 'O\'', 'O\'hare'.starts_with?('Mc', 'Mac', 'O\'')
|
9
|
+
assert_nil 'mcdonald'.starts_with?('Mc', 'Mac', 'O\'')
|
10
|
+
assert_equal 'Mc', 'Mcdonald'.starts_with?('Mc', 'Mac', 'O\'')
|
11
|
+
assert_nil 'normal'.starts_with?('Mc', 'Mac', 'O\'')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_starts_with_i?
|
15
|
+
assert_equal 'O\'', 'o\'hare'.starts_with_i?('Mc', 'Mac', 'O\'')
|
16
|
+
assert_equal 'O\'', 'O\'hare'.starts_with_i?('Mc', 'Mac', 'O\'')
|
17
|
+
assert_equal 'Mc', 'mcdonald'.starts_with_i?('Mc', 'Mac', 'O\'')
|
18
|
+
assert_nil 'normal'.starts_with_i?('Mc', 'Mac', 'O\'')
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_prefix_to?
|
22
|
+
assert_equal 'spud', 's'.prefix_to?('blog', 'roil', 'spud', 'star')
|
23
|
+
assert_equal 'star', 'st'.prefix_to?('blog', 'roil', 'spud', 'star')
|
24
|
+
assert_nil 'S'.prefix_to?('blog', 'roil', 'spud', 'star')
|
25
|
+
assert_nil 'xz'.prefix_to?('blog', 'roil', 'spud', 'star')
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_prefix_to?
|
29
|
+
assert_equal 'Spud', 's'.prefix_to_i?('Blog', 'Roil', 'Spud', 'star')
|
30
|
+
assert_equal 'star', 'St'.prefix_to_i?('blog', 'roil', 'spud', 'star')
|
31
|
+
assert_nil 'xz'.prefix_to_i?('blog', 'roil', 'spud', 'star')
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_split_with_separator
|
35
|
+
assert_equal([[nil, 'hello'], [', ', 'is darrick there'], ['? ', 'no'], ['.', '']],
|
36
|
+
'hello, is darrick there? no.'.split_with_separator(/[.,?]\s*/))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_split_with_separator2
|
40
|
+
count = 0
|
41
|
+
c = [[nil, 'hello'], [', ', 'is darrick there'], ['? ', 'no'], ['.', '']].to_cursor
|
42
|
+
'hello, is darrick there? no.'.split_with_separator(/[.,?]\s*/) do |s, text|
|
43
|
+
cs, ctext = c.read1next
|
44
|
+
assert_equal cs, s
|
45
|
+
assert_equal ctext, text
|
46
|
+
count += 1
|
47
|
+
end
|
48
|
+
assert_equal 4, count
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'innate/titlecase'
|
3
|
+
require 'cursor/indexed'
|
4
|
+
|
5
|
+
class TestTitleCase < Test::Unit::TestCase
|
6
|
+
def test_s
|
7
|
+
s = ['this sentence should be capitalized',
|
8
|
+
'here is another one. the best is to see what will happen! is it good?',
|
9
|
+
'how many more do i need here? a few.',
|
10
|
+
"i'll have to get this done soon, it may get boring..."]
|
11
|
+
t = ['This Sentence Should Be Capitalized',
|
12
|
+
'Here is Another One. The Best is to See What Will Happen! Is it Good?',
|
13
|
+
'How Many More Do I Need Here? A Few.',
|
14
|
+
"I'll Have to Get This Done Soon, it May Get Boring..."].to_cursor
|
15
|
+
s.each do |string|
|
16
|
+
assert_equal t.read1next, string.title_case
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'innate/roman'
|
2
|
+
require 'innate/string'
|
3
|
+
require 'innate/array'
|
4
|
+
|
5
|
+
class String
|
6
|
+
# lower even if it occurs after punctuation.
|
7
|
+
def self.ALWAYS_LOWER
|
8
|
+
[]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.LOWER
|
12
|
+
%w{ as of in the and at or a to it is on by for with an from }
|
13
|
+
end
|
14
|
+
|
15
|
+
# good for names with a second capital.
|
16
|
+
# this is prefixes rather than words, so it
|
17
|
+
# doesn't use +Array#match?+
|
18
|
+
def self.DOUBLE_CAP
|
19
|
+
%w{ mac mc o' d' }
|
20
|
+
end
|
21
|
+
|
22
|
+
# which punctuation causes :lower words to be capitalized after all
|
23
|
+
def self.CAP_AFTER
|
24
|
+
%w{ . ! ? ( � : ; } << ' - '
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.SPLIT_PATTERN
|
28
|
+
/('?[ .!?:;""()\-\n\r\t�_]'?)+/
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.UPPER
|
32
|
+
[Regexp.ROMAN]
|
33
|
+
end
|
34
|
+
|
35
|
+
def title_case(opts = {})
|
36
|
+
opts[:always_lower] ||= String.ALWAYS_LOWER
|
37
|
+
opts[:lower] ||= String.LOWER
|
38
|
+
opts[:double_cap] ||= String.DOUBLE_CAP
|
39
|
+
opts[:cap_after] ||= String.CAP_AFTER
|
40
|
+
opts[:split_pattern] ||= String.SPLIT_PATTERN
|
41
|
+
opts[:upper] ||= String.UPPER
|
42
|
+
|
43
|
+
res = split_with_separator(opts[:split_pattern]) do |s, w|
|
44
|
+
w.downcase!
|
45
|
+
s.to_s + if opts[:always_lower].match? w
|
46
|
+
w
|
47
|
+
elsif opts[:lower].match? w
|
48
|
+
if !s or opts[:cap_after].match?(s.rstrip[-1, 1]) or opts[:cap_after].match?(s)
|
49
|
+
w.capitalize
|
50
|
+
else
|
51
|
+
w
|
52
|
+
end
|
53
|
+
elsif opts[:upper].match? w
|
54
|
+
w.upcase
|
55
|
+
elsif (t = w.starts_with?(opts[:double_cap]))
|
56
|
+
t.capitalize + w[t.length...w.length].capitalize
|
57
|
+
else
|
58
|
+
w.capitalize
|
59
|
+
end
|
60
|
+
end
|
61
|
+
res.join
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Object
|
2
|
+
alias :require_before_tracerequire :require unless respond_to? :require_before_tracerequire
|
3
|
+
@@__require_depth = 0
|
4
|
+
@@__require_count = 0
|
5
|
+
|
6
|
+
def require(s)
|
7
|
+
@@__require_count += 1
|
8
|
+
rc = @@__require_count
|
9
|
+
print "\n#{' ' * @@__require_depth}require '#{s}'"
|
10
|
+
@@__require_depth += 1
|
11
|
+
r = require_before_tracerequire(s)
|
12
|
+
@@__require_depth -= 1
|
13
|
+
s = "=> #{r.to_s}"
|
14
|
+
if rc == @@__require_count
|
15
|
+
print " " + s
|
16
|
+
else
|
17
|
+
print "\n#{' ' * @@__require_depth}" + s
|
18
|
+
end
|
19
|
+
puts if @@__require_depth == 0
|
20
|
+
return r
|
21
|
+
end
|
22
|
+
end
|
data/lib/namesource.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
class NameSource
|
2
|
+
def name(file, md, path)
|
3
|
+
file
|
4
|
+
end
|
5
|
+
|
6
|
+
def close
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
class NameStreamSource < NameSource
|
12
|
+
def initialize(stream)
|
13
|
+
@stream = stream
|
14
|
+
end
|
15
|
+
|
16
|
+
def name(file, md, path)
|
17
|
+
@stream.readline.chomp
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
class NameFileSource < NameSource
|
23
|
+
def initialize(file_name)
|
24
|
+
@file_name = file_name
|
25
|
+
end
|
26
|
+
|
27
|
+
def name(file, md, path)
|
28
|
+
unless @file and @path == path
|
29
|
+
@file.close if @file
|
30
|
+
@path = path
|
31
|
+
fn = File.join(path, @file_name)
|
32
|
+
if File.exists? fn
|
33
|
+
@file = File.open(fn)
|
34
|
+
else
|
35
|
+
@file = File.open(@file_name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
@file.readline.chomp
|
39
|
+
end
|
40
|
+
|
41
|
+
def close
|
42
|
+
@file.close if @file
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
class NamePromptSource < NameSource
|
48
|
+
def name(file, md, path)
|
49
|
+
print "Rename #{File.join(path, file)}\n#[captures: #{md.display} ] to:\n>>> "
|
50
|
+
STDIN.gets.chomp
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
data/lib/options.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
class OptionError < RenamerError
|
2
|
+
end
|
3
|
+
|
4
|
+
class MissingOptionError < OptionError
|
5
|
+
attr_reader :missing_opt
|
6
|
+
def initialize missing_opt
|
7
|
+
@missing_opt = missing_opt
|
8
|
+
super "The required option #{missing_opt} was not present."
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class BadOptionValueError < OptionError
|
13
|
+
attr_reader :opt, :klass, :klass_expected
|
14
|
+
def initialize opt, klass, klass_expected
|
15
|
+
@opt = opt
|
16
|
+
@klass = klass
|
17
|
+
@klass_expected = klass_expected
|
18
|
+
super "#{opt} was expected to be one of #{klass_expected.to_a.flatten.join ', '} but was #{klass}."
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
module Options
|
24
|
+
|
25
|
+
|
26
|
+
attr_accessor :options
|
27
|
+
|
28
|
+
def opt(sym, *types)
|
29
|
+
v = @options[sym]
|
30
|
+
if v
|
31
|
+
unless types.empty?
|
32
|
+
if types.find {|t| v.is_a? t}
|
33
|
+
if block_given?
|
34
|
+
yield v
|
35
|
+
else
|
36
|
+
v
|
37
|
+
end
|
38
|
+
else
|
39
|
+
raise BadOptionValueError.new(sym, v.class, types)
|
40
|
+
end
|
41
|
+
else
|
42
|
+
if block_given?
|
43
|
+
yield v
|
44
|
+
else
|
45
|
+
v
|
46
|
+
end
|
47
|
+
end
|
48
|
+
elsif !types.include? NilClass
|
49
|
+
raise MissingOptionError.new(sym)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def opt_if(sym, *types)
|
54
|
+
begin
|
55
|
+
v = opt sym, *types
|
56
|
+
rescue OptionError
|
57
|
+
end
|
58
|
+
if block_given?
|
59
|
+
yield v if v
|
60
|
+
else
|
61
|
+
v
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/providers.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
module Provider
|
3
|
+
module Folder
|
4
|
+
class Tree
|
5
|
+
def initialize(tree)
|
6
|
+
@tree = tree
|
7
|
+
end
|
8
|
+
|
9
|
+
def each(&block)
|
10
|
+
traverse_list @tree, nil, &block
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
def traverse_list branch, path, &block
|
15
|
+
branch.each do |i|
|
16
|
+
if i.selected?
|
17
|
+
yield @tree.itemPathname(i)
|
18
|
+
end
|
19
|
+
traverse_list(i, p, &block) if i.expanded?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
module File
|
27
|
+
class Base
|
28
|
+
def initialize(folder_provider)
|
29
|
+
@folders = folder_provider
|
30
|
+
@iterator = :each
|
31
|
+
end
|
32
|
+
|
33
|
+
def reverse
|
34
|
+
@iterator = :reverse_each
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
class NonRecursive < Base
|
40
|
+
def each
|
41
|
+
@folders.each do |folder|
|
42
|
+
dir = Dir.new(folder)
|
43
|
+
dir.collect.send(@iterator) do |file|
|
44
|
+
unless file =~ /^\.+$/
|
45
|
+
yield folder, file
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
class Recursive < Base
|
54
|
+
def each(&block)
|
55
|
+
@folders.each do |folder|
|
56
|
+
recursive_each(folder, &block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def recursive_each(folder, &block)
|
62
|
+
dir = Dir.new(folder) rescue return
|
63
|
+
dir.collect.send(@iterator) do |file|
|
64
|
+
j = ::File.join(folder, file)
|
65
|
+
unless file =~ /^\.+$/
|
66
|
+
if ::File.directory? j
|
67
|
+
recursive_each j, &block
|
68
|
+
end
|
69
|
+
yield folder, file
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class Array < Base
|
76
|
+
attr_accessor :files
|
77
|
+
|
78
|
+
def initialize(files)
|
79
|
+
super nil
|
80
|
+
@files = files
|
81
|
+
end
|
82
|
+
|
83
|
+
def each
|
84
|
+
@files.send(@iterator) do |file|
|
85
|
+
p, f = ::File.split file
|
86
|
+
yield p, f
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|