rfs 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/MIT-LICENSE +7 -0
  2. data/Rakefile.rb +193 -0
  3. data/bin/RenameFileSet.rbw +14 -0
  4. data/bin/rfs.rb +214 -0
  5. data/bin/rfsd.rb +8 -0
  6. data/description.txt +24 -0
  7. data/lib/RenameFileSet.bak.rb +372 -0
  8. data/lib/errors.rb +15 -0
  9. data/lib/filters.rb +68 -0
  10. data/lib/gui.rb +216 -0
  11. data/lib/innate/array.rb +104 -0
  12. data/lib/innate/coverage.rb +315 -0
  13. data/lib/innate/debug.rb +12 -0
  14. data/lib/innate/debugger.rb +944 -0
  15. data/lib/innate/file.rb +5 -0
  16. data/lib/innate/filelines.rb +148 -0
  17. data/lib/innate/kernel.rb +41 -0
  18. data/lib/innate/metaid.rb +30 -0
  19. data/lib/innate/mkdirs.rb +12 -0
  20. data/lib/innate/regexp.rb +80 -0
  21. data/lib/innate/reload.rb +11 -0
  22. data/lib/innate/roman.rb +72 -0
  23. data/lib/innate/scriptlines.rb +60 -0
  24. data/lib/innate/string.rb +56 -0
  25. data/lib/innate/test/all_tests.rb +11 -0
  26. data/lib/innate/test/files/mkdirs_dummy.file +1 -0
  27. data/lib/innate/test/files/reloadtarget.rb +5 -0
  28. data/lib/innate/test/files/reloadtarget1.rb +5 -0
  29. data/lib/innate/test/files/reloadtarget2.rb +5 -0
  30. data/lib/innate/test/test_coverage.rb +13 -0
  31. data/lib/innate/test/testarray.rb +98 -0
  32. data/lib/innate/test/testfile.rb +15 -0
  33. data/lib/innate/test/testfilelines.rb +106 -0
  34. data/lib/innate/test/testkernel.rb +30 -0
  35. data/lib/innate/test/testmkdirs.rb +19 -0
  36. data/lib/innate/test/testregexp.rb +86 -0
  37. data/lib/innate/test/testreload.rb +61 -0
  38. data/lib/innate/test/testroman.rb +54 -0
  39. data/lib/innate/test/testscriptlines.rb +39 -0
  40. data/lib/innate/test/teststring.rb +52 -0
  41. data/lib/innate/test/testtitlecase.rb +20 -0
  42. data/lib/innate/titlecase.rb +64 -0
  43. data/lib/innate/tracerequire.rb +22 -0
  44. data/lib/namesource.rb +53 -0
  45. data/lib/options.rb +64 -0
  46. data/lib/providers.rb +93 -0
  47. data/lib/regexp.rb +56 -0
  48. data/lib/rename_functions.rb +142 -0
  49. data/lib/renamer.rb +210 -0
  50. data/lib/results.rb +83 -0
  51. data/lib/test/test_helper.rb +147 -0
  52. data/tests/dir/file1 +0 -0
  53. data/tests/dir/file2 +0 -0
  54. data/tests/dir/file3 +0 -0
  55. data/tests/test_helper.rb +147 -0
  56. data/tests/test_rename_functions.rb +605 -0
  57. 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
+