/
filewalker.rb
91 lines (75 loc) · 2.59 KB
/
filewalker.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class Filewalker
VERSION = "0.1.0"
def self.proc_files(dir, pattern='*', dotfiles=true, &block)
__traverse(dir, pattern, false, dotfiles, true, false, &block)
end
def self.traverse_files(dir, pattern='*', dotfiles=true, &block)
__traverse(dir, pattern, true, dotfiles, true, false, &block)
end
def self.proc_dirs(dir, pattern='*', dotfiles=true, &block)
__traverse(dir, pattern, false, dotfiles, false, true, &block)
end
def self.traverse_dirs(dir, pattern='*', dotfiles=true, &block)
__traverse(dir, pattern, true, dotfiles, false, true, &block)
end
def self.proc_all(dir, pattern='*', dotfiles=true, &block)
__traverse(dir, pattern, false, dotfiles, true, true, &block)
end
def self.traverse_all(dir, pattern='*', dotfiles=true, &block)
__traverse(dir, pattern, true, dotfiles, true, true, &block)
end
private
def self.__traverse(dir, pattern='*', recursive=true, dotfiles=true, files=true, dirs=false, &block)
dir = File.dirname(dir) if File.file?(dir)
dir = dir.rtrim('/') + '/'
# Sanity
raise Exception.new "filewalker(dir) is not a directory: '#{dir}'." unless File.directory?(dir)
# Files first
if files
Dir[dir+pattern].each do |path|
file = path.rsubstr_from('/')
if (file != '.') && (file != '..')
if (file[0] != '.') || dotfiles
if File.file?(path)
yield(path, nil)
end
end
end
end
end
# Dirs
if recursive || dirs
Dir[dir+'*'].each do |path|
file = path.rsubstr_from('/')
if (file != '.') && (file != '..')
if (file[0] != '.') || dotfiles
if File.directory?(path)
if dirs && File.fnmatch(pattern, file)
yield(nil, path)
end
if recursive
__traverse(path+'/', pattern, recursive, dotfiles, files, dirs, &block)
end
end
end
end
end
end
###
### Same for classes :)
###
def self.classes_do(module_const, recursive=true, &block)
# Yield all classes
module_const.constants.
select{|c| Class === module_const.const_get(c) }.
each{|c| yield(module_const.const_get(c)) }
# Call myself recursively for all modules
if recursive
module_const.constants.
select{|m| m = module_const.const_get(m); m === Module and m.name.start_with?(module_const.name) }.
each{|m| classes_do(module_const.const_get(m), recursive, &block) }
end
nil
end
end
end