fynd 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|