fynd 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +30 -0
- data/Guardfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/Rakefile +1 -0
- data/fynd.gemspec +21 -0
- data/lib/fynd/actions.rb +336 -0
- data/lib/fynd/criteria.rb +75 -0
- data/lib/fynd/helpers.rb +3 -0
- data/lib/fynd/operators.rb +10 -0
- data/lib/fynd/sieve.rb +34 -0
- data/lib/fynd/tests.rb +357 -0
- data/lib/fynd/version.rb +3 -0
- data/lib/fynd.rb +22 -0
- data/spec/spec_helper.rb +35 -0
- metadata +85 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in fynd.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'rake'
|
8
|
+
end
|
9
|
+
|
10
|
+
group :doc do
|
11
|
+
gem 'yard', '~> 0.8.2.1'
|
12
|
+
gem 'redcarpet', '~> 2.1.1'
|
13
|
+
end
|
14
|
+
|
15
|
+
group :test do
|
16
|
+
gem 'guard', '~> 1.3.2'
|
17
|
+
gem 'guard-rspec', '~> 1.2.1'
|
18
|
+
gem 'guard-spork', '~> 1.1.0'
|
19
|
+
gem 'rb-fsevent', '~> 0.9.1'
|
20
|
+
gem 'growl', '~> 1.0.3'
|
21
|
+
gem 'simplecov', '~> 0.6.4'
|
22
|
+
gem 'timecop', '~> 0.4.6'
|
23
|
+
end
|
24
|
+
|
25
|
+
# JSON
|
26
|
+
# gem 'json', :platform => :jruby
|
27
|
+
gem 'yajl-ruby', :platform => [ :ruby_18, :ruby_19 ]
|
28
|
+
|
29
|
+
# OpenSSL
|
30
|
+
gem 'jruby-openssl', :platform => :jruby
|
data/Guardfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
ignore %r{^spec/fixtures/}
|
2
|
+
|
3
|
+
guard 'rspec', :version => 2, :cli => "--color --format doc" do
|
4
|
+
watch(%r{^spec/.+_spec\.rb$})
|
5
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
6
|
+
watch('spec/spec_helper.rb') { "spec" }
|
7
|
+
watch(%r{^spec/support/.+.rb$}) { "spec" }
|
8
|
+
end
|
9
|
+
|
10
|
+
guard 'spork' do
|
11
|
+
watch('spec/spec_helper.rb')
|
12
|
+
watch(%r{^spec/support/.+.rb$}) { "spec" }
|
13
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Dan Ryan
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Fynd
|
2
|
+
|
3
|
+
I found GNU find to be slow, so I made it slower.
|
4
|
+
|
5
|
+
## Is it any good?
|
6
|
+
|
7
|
+
[No.](http://news.ycombinator.com/item?id=3067434)
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
gem install fynd
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require 'fynd'
|
17
|
+
include Fynd
|
18
|
+
|
19
|
+
# `find /var/log -iname '*system*' -type f`
|
20
|
+
|
21
|
+
find("/var/log").iname("system").type(:file).files
|
22
|
+
|
23
|
+
=> ["/var/log/system.log", "/var/log/system.log.0.bz2", "/var/log/system.log.1.bz2", "/var/log/system.log.2.bz2", "/var/log/system.log.3.bz2", "/var/log/system.log.4.bz2", "/var/log/system.log.5.bz2", "/var/log/system.log.6.bz2", "/var/log/system.log.7.bz2"]
|
24
|
+
```
|
25
|
+
|
26
|
+
You can keep pass the files to a block [if you're a bad enough dude](http://i.imgur.com/x37pI.jpg).
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'fynd'
|
30
|
+
include Fynd
|
31
|
+
|
32
|
+
# `find /var/log -iname '*system` -type f -print
|
33
|
+
|
34
|
+
find("/var/log").iname("system").type(:file).files do |file|
|
35
|
+
puts file
|
36
|
+
end
|
37
|
+
|
38
|
+
# Prints out:
|
39
|
+
# /var/log/system.log
|
40
|
+
# /var/log/system.log.0.bz2
|
41
|
+
# /var/log/system.log.1.bz2
|
42
|
+
# /var/log/system.log.2.bz2
|
43
|
+
# /var/log/system.log.3.bz2
|
44
|
+
# /var/log/system.log.4.bz2
|
45
|
+
# /var/log/system.log.5.bz2
|
46
|
+
# /var/log/system.log.6.bz2
|
47
|
+
# /var/log/system.log.7.bz2
|
48
|
+
```
|
49
|
+
## Contributing
|
50
|
+
|
51
|
+
1. Fork it
|
52
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
53
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
54
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
55
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/fynd.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fynd/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "fynd"
|
8
|
+
gem.version = Fynd::VERSION
|
9
|
+
gem.authors = ["Dan Ryan"]
|
10
|
+
gem.email = ["scriptfu@gmail.com"]
|
11
|
+
gem.description = %q{I found GNU find to be slow, so I made it slower.}
|
12
|
+
gem.summary = %q{A pure Ruby re-implementation of GNU find.}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "activesupport", '~> 3.2.8'
|
21
|
+
end
|
data/lib/fynd/actions.rb
ADDED
@@ -0,0 +1,336 @@
|
|
1
|
+
module Fynd::Actions
|
2
|
+
# Delete files; true if removal succeeded. If the removal failed,
|
3
|
+
# an error message is issued. Use of this action automatically
|
4
|
+
# turns on the '-depth' option.
|
5
|
+
def delete
|
6
|
+
end
|
7
|
+
|
8
|
+
# Execute command; true if 0 status is returned. All following
|
9
|
+
# arguments to find are taken to be arguments to the command until
|
10
|
+
# an argument consisting of ';' is encountered. The string '{}'
|
11
|
+
# is replaced by the current file name being processed everywhere
|
12
|
+
# it occurs in the arguments to the command, not just in arguments
|
13
|
+
# where it is alone, as in some versions of find. Both of these
|
14
|
+
# constructions might need to be escaped (with a '\') or quoted to
|
15
|
+
# protect them from expansion by the shell. See the EXAMPLES sec-
|
16
|
+
# tion for examples of the use of the '-exec' option. The speci-
|
17
|
+
# fied command is run once for each matched file. The command is
|
18
|
+
# executed in the starting directory. There are unavoidable
|
19
|
+
# security problems surrounding use of the -exec option; you
|
20
|
+
# should use the -execdir option instead.
|
21
|
+
#
|
22
|
+
# -exec command {} +
|
23
|
+
#
|
24
|
+
# This variant of the -exec option runs the specified command on
|
25
|
+
# the selected files, but the command line is built by appending
|
26
|
+
# each selected file name at the end; the total number of invoca-
|
27
|
+
# tions of the command will be much less than the number of
|
28
|
+
# matched files. The command line is built in much the same way
|
29
|
+
# that xargs builds its command lines. Only one instance of '{}'
|
30
|
+
# is allowed within the command. The command is executed in the
|
31
|
+
# starting directory.
|
32
|
+
def exec(command)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Like -exec, but the specified command is run from the subdirec-
|
36
|
+
# tory containing the matched file, which is not normally the
|
37
|
+
# directory in which you started find. This a much more secure
|
38
|
+
# method for invoking commands, as it avoids race conditions dur-
|
39
|
+
# ing resolution of the paths to the matched files. As with the
|
40
|
+
# -exec option, the '+' form of -execdir will build a command line
|
41
|
+
# to process more than one matched file, but any given invocation
|
42
|
+
# of command will only list files that exist in the same subdirec-
|
43
|
+
# tory. If you use this option, you must ensure that your $PATH
|
44
|
+
# environment variable does not reference the current directory;
|
45
|
+
# otherwise, an attacker can run any commands they like by leaving
|
46
|
+
# an appropriately-named file in a directory in which you will run
|
47
|
+
# -execdir.
|
48
|
+
def execdir(command)
|
49
|
+
end
|
50
|
+
|
51
|
+
# True; like -ls but write to file like -fprint. The output file
|
52
|
+
# is always created, even if the predicate is never matched. See
|
53
|
+
# the UNUSUAL FILENAMES section for information about how unusual
|
54
|
+
# characters in filenames are handled.
|
55
|
+
def fls(file)
|
56
|
+
end
|
57
|
+
|
58
|
+
# True; print the full file name into file file. If file does not
|
59
|
+
# exist when find is run, it is created; if it does exist, it is
|
60
|
+
# truncated. The file names ''/dev/stdout'' and ''/dev/stderr''
|
61
|
+
# are handled specially; they refer to the standard output and
|
62
|
+
# standard error output, respectively. The output file is always
|
63
|
+
# created, even if the predicate is never matched. See the
|
64
|
+
# UNUSUAL FILENAMES section for information about how unusual
|
65
|
+
# characters in filenames are handled.
|
66
|
+
def fprint(file)
|
67
|
+
end
|
68
|
+
|
69
|
+
# True; like -print0 but write to file like -fprint. The output
|
70
|
+
# file is always created, even if the predicate is never matched.
|
71
|
+
# See the UNUSUAL FILENAMES section for information about how
|
72
|
+
# unusual characters in filenames are handled.
|
73
|
+
def fprint0(file)
|
74
|
+
end
|
75
|
+
|
76
|
+
# True; like -printf but write to file like -fprint. The output
|
77
|
+
# file is always created, even if the predicate is never matched.
|
78
|
+
# See the UNUSUAL FILENAMES section for information about how
|
79
|
+
# unusual characters in filenames are handled.
|
80
|
+
def fprintf(file, format)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Like -exec but ask the user first (on the standard input); if
|
84
|
+
# the response does not start with 'y' or 'Y', do not run the com-
|
85
|
+
# mand, and return false. If the command is run, its standard
|
86
|
+
# input is redirected from /dev/null.
|
87
|
+
def ok(command)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Like -execdir but ask the user first (on the standard input); if
|
91
|
+
# the response does not start with 'y' or 'Y', do not run the com-
|
92
|
+
# mand, and return false. If the command is run, its standard
|
93
|
+
# input is redirected from /dev/null.
|
94
|
+
def okdir(command)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Print the full file name on the standard output, followed
|
98
|
+
# by a newline. If you are piping the output of find into
|
99
|
+
# another program and there is the faintest possibility that the
|
100
|
+
# files which you are searching for might contain a newline, then
|
101
|
+
# you should seriously consider using the '-print0' option instead
|
102
|
+
# of '-print'. See the UNUSUAL FILENAMES section for information
|
103
|
+
# about how unusual characters in filenames are handled.
|
104
|
+
def print
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
# Print the full file name on the standard output, followed
|
109
|
+
# by a null character (instead of the newline character that
|
110
|
+
# '-print' uses). This allows file names that contain newlines or
|
111
|
+
# other types of white space to be correctly interpreted by pro-
|
112
|
+
# grams that process the find output. This option corresponds to
|
113
|
+
# the '-0' option of xargs.
|
114
|
+
def print0
|
115
|
+
end
|
116
|
+
|
117
|
+
# Print format on the standard output, interpreting '\'
|
118
|
+
# escapes and '%' directives. Field widths and precisions can be
|
119
|
+
# specified as with the 'printf' C function. Please note that
|
120
|
+
# many of the fields are printed as %s rather than %d, and this
|
121
|
+
# may mean that flags don't work as you might expect. This also
|
122
|
+
# means that the '-' flag does work (it forces fields to be left-
|
123
|
+
# aligned). Unlike -print, -printf does not add a newline at the
|
124
|
+
# end of the string. The escapes and directives are:
|
125
|
+
#
|
126
|
+
# \a Alarm bell.
|
127
|
+
#
|
128
|
+
# \b Backspace.
|
129
|
+
#
|
130
|
+
# \c Stop printing from this format immediately and flush the
|
131
|
+
# output.
|
132
|
+
#
|
133
|
+
# \f Form feed.
|
134
|
+
#
|
135
|
+
# \n Newline.
|
136
|
+
#
|
137
|
+
# \r Carriage return.
|
138
|
+
#
|
139
|
+
# \t Horizontal tab.
|
140
|
+
#
|
141
|
+
# \v Vertical tab.
|
142
|
+
#
|
143
|
+
# \ ASCII NUL.
|
144
|
+
#
|
145
|
+
# \\ A literal backslash ('\').
|
146
|
+
#
|
147
|
+
# \NNN The character whose ASCII code is NNN (octal).
|
148
|
+
#
|
149
|
+
# A '\' character followed by any other character is treated as an
|
150
|
+
# ordinary character, so they both are printed.
|
151
|
+
#
|
152
|
+
# %% A literal percent sign.
|
153
|
+
#
|
154
|
+
# %a File's last access time in the format returned by the C
|
155
|
+
# 'ctime' function.
|
156
|
+
#
|
157
|
+
# %Ak File's last access time in the format specified by k,
|
158
|
+
# which is either '@' or a directive for the C 'strftime'
|
159
|
+
# function. The possible values for k are listed below;
|
160
|
+
# some of them might not be available on all systems, due
|
161
|
+
# to differences in 'strftime' between systems.
|
162
|
+
#
|
163
|
+
# @ seconds since Jan. 1, 1970, 00:00 GMT.
|
164
|
+
#
|
165
|
+
# Time fields:
|
166
|
+
#
|
167
|
+
# H hour (00..23)
|
168
|
+
#
|
169
|
+
# I hour (01..12)
|
170
|
+
#
|
171
|
+
# k hour ( 0..23)
|
172
|
+
#
|
173
|
+
# l hour ( 1..12)
|
174
|
+
#
|
175
|
+
# M minute (00..59)
|
176
|
+
#
|
177
|
+
# p locale's AM or PM
|
178
|
+
#
|
179
|
+
# r time, 12-hour (hh:mm:ss [AP]M)
|
180
|
+
#
|
181
|
+
# S second (00..61)
|
182
|
+
#
|
183
|
+
# T time, 24-hour (hh:mm:ss)
|
184
|
+
#
|
185
|
+
# + Date and time, separated by '+', for example
|
186
|
+
# '2004-04-28+22:22:05'. The time is given in the
|
187
|
+
# current timezone (which may be affected by set-
|
188
|
+
# ting the TZ environment variable). This is a GNU
|
189
|
+
# extension.
|
190
|
+
#
|
191
|
+
# X locale's time representation (H:M:S)
|
192
|
+
#
|
193
|
+
# Z time zone (e.g., EDT), or nothing if no time zone
|
194
|
+
# is determinable
|
195
|
+
#
|
196
|
+
# Date fields:
|
197
|
+
#
|
198
|
+
# a locale's abbreviated weekday name (Sun..Sat)
|
199
|
+
#
|
200
|
+
# A locale's full weekday name, variable length (Sun-
|
201
|
+
# day..Saturday)
|
202
|
+
#
|
203
|
+
# b locale's abbreviated month name (Jan..Dec)
|
204
|
+
#
|
205
|
+
# B locale's full month name, variable length (Jan-
|
206
|
+
# uary..December)
|
207
|
+
#
|
208
|
+
# c locale's date and time (Sat Nov 04 12:02:33 EST
|
209
|
+
# 1989)
|
210
|
+
#
|
211
|
+
# d day of month (01..31)
|
212
|
+
#
|
213
|
+
# D date (mm/dd/yy)
|
214
|
+
#
|
215
|
+
# h same as b
|
216
|
+
#
|
217
|
+
# j day of year (001..366)
|
218
|
+
#
|
219
|
+
# m month (01..12)
|
220
|
+
#
|
221
|
+
# U week number of year with Sunday as first day of
|
222
|
+
# week (00..53)
|
223
|
+
#
|
224
|
+
# w day of week (0..6)
|
225
|
+
#
|
226
|
+
# W week number of year with Monday as first day of
|
227
|
+
# week (00..53)
|
228
|
+
#
|
229
|
+
# x locale's date representation (mm/dd/yy)
|
230
|
+
#
|
231
|
+
# y last two digits of year (00..99)
|
232
|
+
#
|
233
|
+
# Y year (1970...)
|
234
|
+
#
|
235
|
+
# %b The amount of disk space used for this file in 512-byte
|
236
|
+
# blocks. Since disk space is allocated in multiples of the
|
237
|
+
# filesystem block size this is usually greater than
|
238
|
+
# %s/1024, but it can also be smaller if the file is a
|
239
|
+
# sparse file.
|
240
|
+
#
|
241
|
+
# %c File's last status change time in the format returned by
|
242
|
+
# the C 'ctime' function.
|
243
|
+
#
|
244
|
+
# %Ck File's last status change time in the format specified by
|
245
|
+
# k, which is the same as for %A.
|
246
|
+
#
|
247
|
+
# %d File's depth in the directory tree; 0 means the file is a
|
248
|
+
# command line argument.
|
249
|
+
#
|
250
|
+
# %D The device number on which the file exists (the st_dev
|
251
|
+
# field of struct stat), in decimal.
|
252
|
+
#
|
253
|
+
# %f File's name with any leading directories removed (only
|
254
|
+
# the last element).
|
255
|
+
#
|
256
|
+
# %F Type of the filesystem the file is on; this value can be
|
257
|
+
# used for -fstype.
|
258
|
+
#
|
259
|
+
# %g File's group name, or numeric group ID if the group has
|
260
|
+
# no name.
|
261
|
+
#
|
262
|
+
# %G File's numeric group ID.
|
263
|
+
#
|
264
|
+
# %h Leading directories of file's name (all but the last ele-
|
265
|
+
# ment). If the file name contains no slashes (since it is
|
266
|
+
# in the current directory) the %h specifier expands to
|
267
|
+
# ".".
|
268
|
+
#
|
269
|
+
# %H Command line argument under which file was found.
|
270
|
+
#
|
271
|
+
# %i File's inode number (in decimal).
|
272
|
+
#
|
273
|
+
# %k The amount of disk space used for this file in 1K blocks.
|
274
|
+
# Since disk space is allocated in multiples of the
|
275
|
+
# filesystem block size this is usually greater than
|
276
|
+
# %s/1024, but it can also be smaller if the file is a
|
277
|
+
# sparse file.
|
278
|
+
#
|
279
|
+
# %l Object of symbolic link (empty string if file is not a
|
280
|
+
# symbolic link).
|
281
|
+
#
|
282
|
+
# %m File's permission bits (in octal). This option uses the
|
283
|
+
# 'traditional' numbers which most Unix implementations
|
284
|
+
# use, but if your particular implementation uses an
|
285
|
+
# unusual ordering of octal permissions bits, you will see
|
286
|
+
# a difference between the actual value of the file's mode
|
287
|
+
# and the output of %m. Normally you will want to have a
|
288
|
+
# leading zero on this number, and to do this, you should
|
289
|
+
# use the # flag (as in, for example, '%#m').
|
290
|
+
#
|
291
|
+
# %M File's permissions (in symbolic form, as for ls). This
|
292
|
+
# directive is supported in findutils 4.2.5 and later.
|
293
|
+
#
|
294
|
+
# %n Number of hard links to file.
|
295
|
+
#
|
296
|
+
# %p File's name.
|
297
|
+
#
|
298
|
+
# %P File's name with the name of the command line argument
|
299
|
+
# under which it was found removed.
|
300
|
+
#
|
301
|
+
# %s File's size in bytes.
|
302
|
+
#
|
303
|
+
# %t File's last modification time in the format returned by
|
304
|
+
# the C 'ctime' function.
|
305
|
+
#
|
306
|
+
# %Tk File's last modification time in the format specified by
|
307
|
+
# k, which is the same as for %A.
|
308
|
+
#
|
309
|
+
# %u File's user name, or numeric user ID if the user has no
|
310
|
+
# name.
|
311
|
+
#
|
312
|
+
# %U File's numeric user ID.
|
313
|
+
#
|
314
|
+
# %y File's type (like in ls -l), U=unknown type (shouldn't
|
315
|
+
# happen)
|
316
|
+
#
|
317
|
+
# %Y File's type (like %y), plus follow symlinks: L=loop,
|
318
|
+
# N=nonexistent
|
319
|
+
#
|
320
|
+
# %Z (SELinux only) file's security context.
|
321
|
+
#
|
322
|
+
# A '%' character followed by any other character is discarded
|
323
|
+
# (but the other character is printed).
|
324
|
+
#
|
325
|
+
# The %m and %d directives support the # , 0 and + flags, but the
|
326
|
+
# other directives do not, even if they print numbers. Numeric
|
327
|
+
# directives that do not support these flags include G, U, b, D, k
|
328
|
+
# and n. The '-' format flag is supported and changes the align-
|
329
|
+
# ment of a field from right-justified (which is the default) to
|
330
|
+
# left-justified.
|
331
|
+
#
|
332
|
+
# See the UNUSUAL FILENAMES section for information about how
|
333
|
+
# unusual characters in filenames are handled.
|
334
|
+
def printf(format)
|
335
|
+
end
|
336
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'find' # <- lol
|
3
|
+
|
4
|
+
require 'fynd/sieve'
|
5
|
+
|
6
|
+
module Fynd
|
7
|
+
class Criteria
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
attr_accessor :sieve
|
11
|
+
|
12
|
+
def_delegators :@sieve, :collection, :conditions
|
13
|
+
|
14
|
+
def initialize(*paths)
|
15
|
+
@sieve = Sieve.new
|
16
|
+
@sieve.collection = []
|
17
|
+
@sieve.conditions = {}
|
18
|
+
@sieve.conditions['actions'] = {}
|
19
|
+
@sieve.conditions['operators'] = {}
|
20
|
+
@sieve.conditions['tests'] = {}
|
21
|
+
|
22
|
+
# For every path...
|
23
|
+
paths.each do |path|
|
24
|
+
# Pull out all directories
|
25
|
+
# dirs = Dir.glob(File.expand_path(path)).select { |f| File.stat(f).directory? }
|
26
|
+
# Shove all found files into the collection
|
27
|
+
# @sieve.collection << Dir.glob(File.expand_path(path))
|
28
|
+
@sieve.collection << Find.find(path).to_a
|
29
|
+
end
|
30
|
+
|
31
|
+
# Flatten it and strip out non-unique files
|
32
|
+
@sieve.collection.flatten!.uniq!
|
33
|
+
end
|
34
|
+
|
35
|
+
# def find(*paths)
|
36
|
+
# where(:paths => paths)
|
37
|
+
# self
|
38
|
+
# end
|
39
|
+
|
40
|
+
def run
|
41
|
+
sieve.run
|
42
|
+
return sieve.files
|
43
|
+
end
|
44
|
+
|
45
|
+
def files
|
46
|
+
files = sieve.run
|
47
|
+
|
48
|
+
if block_given?
|
49
|
+
yield files
|
50
|
+
else
|
51
|
+
return files
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def method_missing(symbol, *args, &block)
|
56
|
+
if sieve.respond_to?(symbol)
|
57
|
+
if ACTIONS.include?(symbol)
|
58
|
+
# Only one action per expression
|
59
|
+
sieve.conditions['action'] = { symbol.to_s => args[0] }
|
60
|
+
elsif OPERATORS.include?(symbol)
|
61
|
+
sieve.conditions['operations'].deep_merge!({ symbol.to_s => args[0] })
|
62
|
+
elsif TESTS.include?(symbol)
|
63
|
+
sieve.conditions['tests'].deep_merge!({ symbol.to_s => args[0] })
|
64
|
+
else
|
65
|
+
super(symbol, *args, &blocks)
|
66
|
+
end
|
67
|
+
self
|
68
|
+
else
|
69
|
+
super(symbol, *args, &blocks)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# TODO: implement enumerables; all, first, each, etc.
|
74
|
+
end
|
75
|
+
end
|
data/lib/fynd/helpers.rb
ADDED
data/lib/fynd/sieve.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
require 'fynd/actions'
|
4
|
+
require 'fynd/operators'
|
5
|
+
require 'fynd/tests'
|
6
|
+
require 'fynd/helpers'
|
7
|
+
|
8
|
+
module Fynd
|
9
|
+
class Sieve
|
10
|
+
include Helpers
|
11
|
+
include Actions
|
12
|
+
include Operators
|
13
|
+
include Tests
|
14
|
+
|
15
|
+
attr_accessor :collection, :conditions, :files
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@collection = []
|
19
|
+
@conditions = {}
|
20
|
+
@files = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def run
|
24
|
+
@files = collection.dup
|
25
|
+
# first we match files with our tests
|
26
|
+
conditions['tests'].each do |symbol, value|
|
27
|
+
value.nil? ? self.__send__(symbol) : self.__send__(symbol, value)
|
28
|
+
end
|
29
|
+
|
30
|
+
@files
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/lib/fynd/tests.rb
ADDED
@@ -0,0 +1,357 @@
|
|
1
|
+
require 'etc'
|
2
|
+
|
3
|
+
module Fynd::Tests
|
4
|
+
# Numeric arguments can be specified as
|
5
|
+
#
|
6
|
+
# +n for greater than n,
|
7
|
+
#
|
8
|
+
# -n for less than n,
|
9
|
+
#
|
10
|
+
# n for exactly n.
|
11
|
+
|
12
|
+
# File was last accessed n minutes ago.
|
13
|
+
def amin(n)
|
14
|
+
end
|
15
|
+
|
16
|
+
# File was last accessed more recently than file was modified. If
|
17
|
+
# file is a symbolic link and the -H option or the -L option is in
|
18
|
+
# effect, the access time of the file it points to is always used.
|
19
|
+
def anewer(other)
|
20
|
+
files.select! do |file|
|
21
|
+
File.stat(file).atime > File.stat(other).atime
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# File was last accessed n*24 hours ago. When find figures out
|
26
|
+
# how many 24-hour periods ago the file was last accessed, any
|
27
|
+
# fractional part is ignored, so to match -atime +1, a file has to
|
28
|
+
# have been accessed at least two days ago.
|
29
|
+
def atime(n)
|
30
|
+
match = n.match(/([-+]?)(\d+)/)
|
31
|
+
comparer, interval = match[1], match[2].to_i
|
32
|
+
time = Time.now
|
33
|
+
|
34
|
+
files.select! do |file|
|
35
|
+
atime = File.stat(file).atime
|
36
|
+
|
37
|
+
case comparer
|
38
|
+
when '+'
|
39
|
+
# more than n days ago
|
40
|
+
atime < time - interval.days
|
41
|
+
when '-'
|
42
|
+
# less than n days ago
|
43
|
+
atime > time - interval.days
|
44
|
+
when ''
|
45
|
+
# exactly n days ago
|
46
|
+
atime <= time - (interval - 1).days && atime >= time - interval.days
|
47
|
+
else
|
48
|
+
raise ArgumentError, "argument must be n, +n, or -n"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# File's status was last changed n minutes ago.
|
54
|
+
def cmin(n)
|
55
|
+
end
|
56
|
+
|
57
|
+
# File's status was last changed more recently than file was modi-
|
58
|
+
# fied. If file is a symbolic link and the -H option or the -L
|
59
|
+
# option is in effect, the status-change time of the file it
|
60
|
+
# points to is always used.
|
61
|
+
def cnewer(other)
|
62
|
+
files.select! do |file|
|
63
|
+
File.stat(file).ctime > File.stat(other).ctime
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# File's status was last changed n*24 hours ago. See the comments
|
68
|
+
# for -atime to understand how rounding affects the interpretation
|
69
|
+
# of file status change times.
|
70
|
+
def ctime(n)
|
71
|
+
end
|
72
|
+
|
73
|
+
# File is empty and is either a regular file or a directory.
|
74
|
+
def empty
|
75
|
+
files.select! do |file|
|
76
|
+
File.stat(file).zero?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
alias :empty? :empty
|
81
|
+
|
82
|
+
# Always false.
|
83
|
+
def false
|
84
|
+
# false
|
85
|
+
end
|
86
|
+
|
87
|
+
alias :false? :false
|
88
|
+
|
89
|
+
# File's numeric group ID is n.
|
90
|
+
def gid(n)
|
91
|
+
files.select! do |file|
|
92
|
+
File.stat(file).gid == n.to_i
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# File belongs to group gname (numeric group ID allowed).
|
97
|
+
def group(name)
|
98
|
+
files.select! do |file|
|
99
|
+
gid = File.stat(file).gid
|
100
|
+
Etc.getgrgid(gid).name == name
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Like -lname, but the match is case insensitive. If the -L
|
105
|
+
# option or the -follow option is in effect, this test returns
|
106
|
+
# false unless the symbolic link is broken.
|
107
|
+
def ilname(pattern)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Like -name, but the match is case insensitive. For example, the
|
111
|
+
# patterns 'fo*' and 'F??' match the file names 'Foo', 'FOO',
|
112
|
+
# 'foo', 'fOo', etc. In these patterns, unlike filename expan-
|
113
|
+
# sion by the shell, an initial '.' can be matched by '*'. That
|
114
|
+
# is, find -name *bar will match the file '.foobar'. Please note
|
115
|
+
# that you should quote patterns as a matter of course, otherwise
|
116
|
+
# the shell will expand any wildcard characters in them.
|
117
|
+
def iname(pattern)
|
118
|
+
files.select! do |file|
|
119
|
+
file =~ /#{pattern}/i
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# File has inode number n. It is normally easier to use the
|
124
|
+
# -samefile test instead.
|
125
|
+
def inum(n)
|
126
|
+
files.select! do |file|
|
127
|
+
File.stat(file).ino == n.to_i
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Like -regex, but the match is case insensitive.
|
132
|
+
def iregex(pattern)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Like -wholename, but the match is case insensitive.
|
136
|
+
def iwholename(pattern)
|
137
|
+
end
|
138
|
+
|
139
|
+
# File has n links.
|
140
|
+
def links(n)
|
141
|
+
end
|
142
|
+
|
143
|
+
# File is a symbolic link whose contents match shell pattern pat-
|
144
|
+
# tern. The metacharacters do not treat '/' or '.' specially. If
|
145
|
+
# the -L option or the -follow option is in effect, this test
|
146
|
+
# returns false unless the symbolic link is broken.
|
147
|
+
def lname(pattern)
|
148
|
+
end
|
149
|
+
|
150
|
+
# File's data was last modified n minutes ago.
|
151
|
+
def mmin(n)
|
152
|
+
end
|
153
|
+
|
154
|
+
# File's data was last modified n*24 hours ago. See the comments
|
155
|
+
# for -atime to understand how rounding affects the interpretation
|
156
|
+
# of file modification times.
|
157
|
+
def mtime(n)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Base of file name (the path with the leading directories
|
161
|
+
# removed) matches shell pattern pattern. The metacharacters
|
162
|
+
# ('*', '?', and '[]') match a '.' at the start of the base name
|
163
|
+
# (this is a change in findutils-4.2.2; see section STANDARDS CON-
|
164
|
+
# FORMANCE below). To ignore a directory and the files under it,
|
165
|
+
# use -prune; see an example in the description of -wholename.
|
166
|
+
# Braces are not recognised as being special, despite the fact
|
167
|
+
# that some shells including Bash imbue braces with a special
|
168
|
+
# meaning in shell patterns. The filename matching is performed
|
169
|
+
# with the use of the fnmatch(3) library function. Don't forget
|
170
|
+
# to enclose the pattern in quotes in order to protect it from
|
171
|
+
# expansion by the shell.
|
172
|
+
def name(pattern)
|
173
|
+
files.select! do |file|
|
174
|
+
file =~ /#{pattern}/
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# File was modified more recently than file. If file is a sym-
|
179
|
+
# bolic link and the -H option or the -L option is in effect, the
|
180
|
+
# modification time of the file it points to is always used.
|
181
|
+
def newer(other)
|
182
|
+
end
|
183
|
+
|
184
|
+
# No user corresponds to file's numeric user ID.
|
185
|
+
def nouser
|
186
|
+
files.select! do |file|
|
187
|
+
uid = File.stat(file).uid
|
188
|
+
begin
|
189
|
+
Etc.getpwuid(uid)
|
190
|
+
false
|
191
|
+
rescue ArgumentError => e
|
192
|
+
true
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# No group corresponds to file's numeric group ID.
|
198
|
+
def nogroup
|
199
|
+
files.select! do |file|
|
200
|
+
gid = File.stat(file).gid
|
201
|
+
begin
|
202
|
+
Etc.getgrgid(gid)
|
203
|
+
false
|
204
|
+
rescue ArgumentError => e
|
205
|
+
true
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# See -wholename. The predicate -path is also supported by HP-UX find.
|
211
|
+
def path(pattern)
|
212
|
+
end
|
213
|
+
|
214
|
+
# -perm mode
|
215
|
+
#
|
216
|
+
# File's permission bits are exactly mode (octal or symbolic).
|
217
|
+
# Since an exact match is required, if you want to use this form
|
218
|
+
# for symbolic modes, you may have to specify a rather complex
|
219
|
+
# mode string. For example '-perm g=w' will only match files
|
220
|
+
# which have mode 0020 (that is, ones for which group write per-
|
221
|
+
# mission is the only permission set). It is more likely that you
|
222
|
+
# will want to use the '/' or '-' forms, for example '-perm -g=w',
|
223
|
+
# which matches any file with group write permission. See the
|
224
|
+
# EXAMPLES section for some illustrative examples.
|
225
|
+
#
|
226
|
+
# -perm -mode
|
227
|
+
#
|
228
|
+
# All of the permission bits mode are set for the file. Symbolic
|
229
|
+
# modes are accepted in this form, and this is usually the way in
|
230
|
+
# which would want to use them. You must specify 'u', 'g' or 'o'
|
231
|
+
# if you use a symbolic mode. See the EXAMPLES section for some
|
232
|
+
# illustrative examples.
|
233
|
+
#
|
234
|
+
# -perm /mode
|
235
|
+
#
|
236
|
+
# Any of the permission bits mode are set for the file. Symbolic
|
237
|
+
# modes are accepted in this form. You must specify 'u', 'g' or
|
238
|
+
# 'o' if you use a symbolic mode. See the EXAMPLES section for
|
239
|
+
# some illustrative examples. If no permission bits in mode are
|
240
|
+
# set, this test currently matches no files. However, it will
|
241
|
+
# soon be changed to match any file (the idea is to be more con-
|
242
|
+
# sistent with the behaviour of perm -000).
|
243
|
+
def perm(mode)
|
244
|
+
end
|
245
|
+
|
246
|
+
# File name matches regular expression pattern. This is a match
|
247
|
+
# on the whole path, not a search. For example, to match a file
|
248
|
+
# named './fubar3', you can use the regular expression '.*bar.' or
|
249
|
+
# '.*b.*3', but not 'f.*r3'. The regular expressions understood
|
250
|
+
# by find are by default Emacs Regular Expressions, but this can
|
251
|
+
# be changed with the -regextype option.
|
252
|
+
def regex(pattern)
|
253
|
+
end
|
254
|
+
|
255
|
+
# File refers to the same inode as name. When -L is in effect,
|
256
|
+
# this can include symbolic links.
|
257
|
+
def samefile(other)
|
258
|
+
end
|
259
|
+
|
260
|
+
# File uses n units of space. The following suffixes can be used:
|
261
|
+
#
|
262
|
+
# 'b' for 512-byte blocks (this is the default if no suffix is
|
263
|
+
# used)
|
264
|
+
#
|
265
|
+
# 'c' for bytes
|
266
|
+
#
|
267
|
+
# 'w' for two-byte words
|
268
|
+
#
|
269
|
+
# 'k' for Kilobytes (units of 1024 bytes)
|
270
|
+
#
|
271
|
+
# 'M' for Megabytes (units of 1048576 bytes)
|
272
|
+
#
|
273
|
+
# 'G' for Gigabytes (units of 1073741824 bytes)
|
274
|
+
#
|
275
|
+
# The size does not count indirect blocks, but it does count
|
276
|
+
# blocks in sparse files that are not actually allocated. Bear in
|
277
|
+
# mind that the '%k' and '%b' format specifiers of -printf handle
|
278
|
+
# sparse files differently. The 'b' suffix always denotes
|
279
|
+
# 512-byte blocks and never 1 Kilobyte blocks, which is different
|
280
|
+
# to the behaviour of -ls.
|
281
|
+
def size(n)
|
282
|
+
end
|
283
|
+
|
284
|
+
# Always true.
|
285
|
+
def true
|
286
|
+
end
|
287
|
+
|
288
|
+
# File is of type c:
|
289
|
+
#
|
290
|
+
# b block (buffered) special
|
291
|
+
# c character (unbuffered) special
|
292
|
+
# d directory
|
293
|
+
# p named pipe (FIFO)
|
294
|
+
# f regular file
|
295
|
+
# l symbolic link; this is never true if the -L option or the
|
296
|
+
# -follow option is in effect, unless the symbolic link is
|
297
|
+
# broken. If you want to search for symbolic links when -L
|
298
|
+
# is in effect, use -xtype.
|
299
|
+
# s socket
|
300
|
+
# D door (Solaris)
|
301
|
+
def type(c)
|
302
|
+
files.select! do |file|
|
303
|
+
case c.to_s
|
304
|
+
when 'f', 'file'
|
305
|
+
File.stat(file).file?
|
306
|
+
when 'd', 'dir', 'directory'
|
307
|
+
File.stat(file).directory?
|
308
|
+
else
|
309
|
+
false
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
# File's numeric user ID is n.
|
315
|
+
def uid(n)
|
316
|
+
files.select! do |file|
|
317
|
+
File.stat(file).uid == n.to_i
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
# File was last accessed n days after its status was last changed.
|
322
|
+
def used(n)
|
323
|
+
end
|
324
|
+
|
325
|
+
# File is owned by user uname (numeric user ID allowed).
|
326
|
+
def user(name)
|
327
|
+
files.select! do |file|
|
328
|
+
uid = File.stat(file).uid.to_i
|
329
|
+
Etc.getpwuid(uid).name == name
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
# File name matches shell pattern pattern. The metacharacters do
|
334
|
+
# not treat '/' or '.' specially; so, for example,
|
335
|
+
#
|
336
|
+
# find . -wholename './sr*sc'
|
337
|
+
#
|
338
|
+
# will print an entry for a directory called './src/misc' (if one
|
339
|
+
# exists). To ignore a whole directory tree, use -prune rather
|
340
|
+
# than checking every file in the tree. For example, to skip the
|
341
|
+
# directory 'src/emacs' and all files and directories under it,
|
342
|
+
# and print the names of the other files found, do something like
|
343
|
+
# this:
|
344
|
+
#
|
345
|
+
# find . -wholename './src/emacs' -prune -o -print
|
346
|
+
#
|
347
|
+
def wholename(pattern)
|
348
|
+
end
|
349
|
+
|
350
|
+
# The same as -type unless the file is a symbolic link. For sym-
|
351
|
+
# bolic links: if the -H or -P option was specified, true if the
|
352
|
+
# file is a link to a file of type c; if the -L option has been
|
353
|
+
# given, true if c is 'l'. In other words, for symbolic links,
|
354
|
+
# -xtype checks the type of the file that -type does not check.
|
355
|
+
def xtype(c)
|
356
|
+
end
|
357
|
+
end
|
data/lib/fynd/version.rb
ADDED
data/lib/fynd.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
|
3
|
+
require 'fynd/version'
|
4
|
+
|
5
|
+
require 'fynd/actions'
|
6
|
+
require 'fynd/operators'
|
7
|
+
require 'fynd/tests'
|
8
|
+
|
9
|
+
require 'fynd/criteria'
|
10
|
+
|
11
|
+
module Fynd
|
12
|
+
ACTIONS = Fynd::Actions.instance_methods
|
13
|
+
OPERATORS = Fynd::Operators.instance_methods
|
14
|
+
TESTS = Fynd::Tests.instance_methods
|
15
|
+
|
16
|
+
extend self
|
17
|
+
|
18
|
+
def find(*paths)
|
19
|
+
Criteria.new(*paths)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spork'
|
3
|
+
|
4
|
+
Spork.prefork do
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
require 'bundler'
|
8
|
+
Bundler.require
|
9
|
+
|
10
|
+
require 'rspec'
|
11
|
+
require 'timecop'
|
12
|
+
# require 'fakefs'
|
13
|
+
require 'fileutils'
|
14
|
+
|
15
|
+
require 'fynd'
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.before do
|
19
|
+
Timecop.freeze
|
20
|
+
# FakeFS.activate!
|
21
|
+
end
|
22
|
+
config.after do
|
23
|
+
Timecop.return
|
24
|
+
# FakeFS.deactivate!
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Spork.each_run do
|
30
|
+
# This code will be run each time you run your specs.
|
31
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
32
|
+
end
|
33
|
+
|
34
|
+
# Crash loud in tests!
|
35
|
+
Thread.abort_on_exception = true
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fynd
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dan Ryan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.8
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.8
|
30
|
+
description: I found GNU find to be slow, so I made it slower.
|
31
|
+
email:
|
32
|
+
- scriptfu@gmail.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- Gemfile
|
39
|
+
- Guardfile
|
40
|
+
- LICENSE.txt
|
41
|
+
- README.md
|
42
|
+
- Rakefile
|
43
|
+
- fynd.gemspec
|
44
|
+
- lib/fynd.rb
|
45
|
+
- lib/fynd/actions.rb
|
46
|
+
- lib/fynd/criteria.rb
|
47
|
+
- lib/fynd/helpers.rb
|
48
|
+
- lib/fynd/operators.rb
|
49
|
+
- lib/fynd/sieve.rb
|
50
|
+
- lib/fynd/tests.rb
|
51
|
+
- lib/fynd/version.rb
|
52
|
+
- spec/spec_helper.rb
|
53
|
+
homepage: ''
|
54
|
+
licenses: []
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
hash: -1732080129686787563
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
hash: -1732080129686787563
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.8.24
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: A pure Ruby re-implementation of GNU find.
|
83
|
+
test_files:
|
84
|
+
- spec/spec_helper.rb
|
85
|
+
has_rdoc:
|