filelist 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/LICENSE +20 -0
  2. data/README.textile +0 -0
  3. data/Rakefile +53 -0
  4. data/TODO +2 -0
  5. data/filelist.gemspec +23 -0
  6. data/lib/filelist.rb +396 -0
  7. metadata +59 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jakub Stastny aka Botanicus
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
File without changes
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+
4
+ GEM_NAME = "filelist"
5
+ AUTHOR = "Jakub Stastny aka Botanicus"
6
+ EMAIL = "knava.bestvinensis@gmail.com"
7
+ HOMEPAGE = "http://101Ideas.cz/"
8
+ SUMMARY = "FileList from Rake"
9
+ GEM_VERSION = "0.0.1"
10
+
11
+ spec = Gem::Specification.new do |s|
12
+ s.name = GEM_NAME
13
+ s.version = GEM_VERSION
14
+ s.platform = Gem::Platform::RUBY
15
+ s.has_rdoc = true
16
+ s.extra_rdoc_files = ["README.textile", "LICENSE"]
17
+ s.summary = SUMMARY
18
+ s.description = s.summary
19
+ s.author = AUTHOR
20
+ s.email = EMAIL
21
+ s.homepage = HOMEPAGE
22
+ s.require_path = 'lib'
23
+ s.files = %w(LICENSE README.textile Rakefile) + Dir.glob("{lib,spec}/**/*")
24
+ end
25
+
26
+ Rake::GemPackageTask.new(spec) do |pkg|
27
+ pkg.gem_spec = spec
28
+ end
29
+
30
+ desc "Create a gemspec file"
31
+ task :gemspec do
32
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
33
+ file.puts spec.to_ruby
34
+ end
35
+ end
36
+
37
+ def sudo_gem(cmd)
38
+ sh "#{SUDO} #{RUBY} -S gem #{cmd}", :verbose => false
39
+ end
40
+
41
+ desc "Install #{GEM_NAME} #{GEM_VERSION}"
42
+ task :install => [ :package ] do
43
+ sudo_gem "install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
44
+ end
45
+
46
+ desc "Uninstall #{GEM_NAME} #{GEM_VERSION}"
47
+ task :uninstall => [ :clobber ] do
48
+ sudo_gem "uninstall #{GEM_NAME} -v#{GEM_VERSION} -Ix"
49
+ end
50
+
51
+ require 'spec/rake/spectask'
52
+ desc 'Default: run spec examples'
53
+ task :default => 'spec'
data/TODO ADDED
@@ -0,0 +1,2 @@
1
+ - find another useful stuff in rake, not just filelist
2
+ - cp filelist's tests
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env gem build
2
+ # coding: utf-8
3
+
4
+ begin
5
+ require "rubygems/specification"
6
+ rescue SecurityError
7
+ # http://gems.github.com
8
+ end
9
+
10
+ VERSION = "0.0.1"
11
+ SPECIFICATION = ::Gem::Specification.new do |s|
12
+ s.name = "filelist"
13
+ s.version = VERSION
14
+ s.authors = ["Jakub Šťastný aka Botanicus"]
15
+ s.homepage = "http://github.com/botanicus/filelist"
16
+ s.summary = "FileList is taken from Rake"
17
+ s.description = "" # TODO: long description
18
+ s.cert_chain = nil
19
+ s.email = ["knava.bestvinensis", "gmail.com"].join("@")
20
+ s.files = Dir.glob("**/*") - Dir.glob("pkg/*")
21
+ s.require_paths = ["lib"]
22
+ # s.required_ruby_version = ::Gem::Requirement.new(">= 1.9.1")
23
+ end
@@ -0,0 +1,396 @@
1
+ # stolen directly from rake
2
+ module Cloneable
3
+ # Clone an object by making a new object and setting all the instance
4
+ # variables to the same values.
5
+ def dup
6
+ sibling = self.class.new
7
+ instance_variables.each do |ivar|
8
+ value = self.instance_variable_get(ivar)
9
+ new_value = value.clone rescue value
10
+ sibling.instance_variable_set(ivar, new_value)
11
+ end
12
+ sibling.taint if tainted?
13
+ sibling
14
+ end
15
+
16
+ def clone
17
+ sibling = dup
18
+ sibling.freeze if frozen?
19
+ sibling
20
+ end
21
+ end
22
+
23
+ class FileList
24
+
25
+ include Cloneable
26
+
27
+ # == Method Delegation
28
+ #
29
+ # The lazy evaluation magic of FileLists happens by implementing all the
30
+ # array specific methods to call +resolve+ before delegating the heavy
31
+ # lifting to an embedded array object (@items).
32
+ #
33
+ # In addition, there are two kinds of delegation calls. The regular kind
34
+ # delegates to the @items array and returns the result directly. Well,
35
+ # almost directly. It checks if the returned value is the @items object
36
+ # itself, and if so will return the FileList object instead.
37
+ #
38
+ # The second kind of delegation call is used in methods that normally
39
+ # return a new Array object. We want to capture the return value of these
40
+ # methods and wrap them in a new FileList object. We enumerate these
41
+ # methods in the +SPECIAL_RETURN+ list below.
42
+
43
+ # List of array methods (that are not in +Object+) that need to be
44
+ # delegated.
45
+ ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).map { |n| n.to_s }
46
+
47
+ # List of additional methods that must be delegated.
48
+ MUST_DEFINE = %w[to_a inspect]
49
+
50
+ # List of methods that should not be delegated here (we define special
51
+ # versions of them explicitly below).
52
+ MUST_NOT_DEFINE = %w[to_a to_ary partition *]
53
+
54
+ # List of delegated methods that return new array values which need
55
+ # wrapping.
56
+ SPECIAL_RETURN = %w[
57
+ map collect sort sort_by select find_all reject grep
58
+ compact flatten uniq values_at
59
+ + - & |
60
+ ]
61
+
62
+ DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).collect{ |s| s.to_s }.sort.uniq
63
+
64
+ # Now do the delegation.
65
+ DELEGATING_METHODS.each_with_index do |sym, i|
66
+ if SPECIAL_RETURN.include?(sym)
67
+ ln = __LINE__+1
68
+ class_eval %{
69
+ def #{sym}(*args, &block)
70
+ resolve
71
+ result = @items.send(:#{sym}, *args, &block)
72
+ FileList.new.import(result)
73
+ end
74
+ }, __FILE__, ln
75
+ else
76
+ ln = __LINE__+1
77
+ class_eval %{
78
+ def #{sym}(*args, &block)
79
+ resolve
80
+ result = @items.send(:#{sym}, *args, &block)
81
+ result.object_id == @items.object_id ? self : result
82
+ end
83
+ }, __FILE__, ln
84
+ end
85
+ end
86
+
87
+ # Create a file list from the globbable patterns given. If you wish to
88
+ # perform multiple includes or excludes at object build time, use the
89
+ # "yield self" pattern.
90
+ #
91
+ # Example:
92
+ # file_list = FileList.new('lib/**/*.rb', 'test/test*.rb')
93
+ #
94
+ # pkg_files = FileList.new('lib/**/*') do |fl|
95
+ # fl.exclude(/\bCVS\b/)
96
+ # end
97
+ #
98
+ def initialize(*patterns)
99
+ @pending_add = []
100
+ @pending = false
101
+ @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup
102
+ @exclude_procs = DEFAULT_IGNORE_PROCS.dup
103
+ @exclude_re = nil
104
+ @items = []
105
+ patterns.each { |pattern| include(pattern) }
106
+ yield self if block_given?
107
+ end
108
+
109
+ # Add file names defined by glob patterns to the file list. If an array
110
+ # is given, add each element of the array.
111
+ #
112
+ # Example:
113
+ # file_list.include("*.java", "*.cfg")
114
+ # file_list.include %w( math.c lib.h *.o )
115
+ #
116
+ def include(*filenames)
117
+ # TODO: check for pending
118
+ filenames.each do |fn|
119
+ if fn.respond_to? :to_ary
120
+ include(*fn.to_ary)
121
+ else
122
+ @pending_add << fn
123
+ end
124
+ end
125
+ @pending = true
126
+ self
127
+ end
128
+ alias :add :include
129
+
130
+ # Register a list of file name patterns that should be excluded from the
131
+ # list. Patterns may be regular expressions, glob patterns or regular
132
+ # strings. In addition, a block given to exclude will remove entries that
133
+ # return true when given to the block.
134
+ #
135
+ # Note that glob patterns are expanded against the file system. If a file
136
+ # is explicitly added to a file list, but does not exist in the file
137
+ # system, then an glob pattern in the exclude list will not exclude the
138
+ # file.
139
+ #
140
+ # Examples:
141
+ # FileList['a.c', 'b.c'].exclude("a.c") => ['b.c']
142
+ # FileList['a.c', 'b.c'].exclude(/^a/) => ['b.c']
143
+ #
144
+ # If "a.c" is a file, then ...
145
+ # FileList['a.c', 'b.c'].exclude("a.*") => ['b.c']
146
+ #
147
+ # If "a.c" is not a file, then ...
148
+ # FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c']
149
+ #
150
+ def exclude(*patterns, &block)
151
+ patterns.each do |pat|
152
+ @exclude_patterns << pat
153
+ end
154
+ if block_given?
155
+ @exclude_procs << block
156
+ end
157
+ resolve_exclude if ! @pending
158
+ self
159
+ end
160
+
161
+
162
+ # Clear all the exclude patterns so that we exclude nothing.
163
+ def clear_exclude
164
+ @exclude_patterns = []
165
+ @exclude_procs = []
166
+ calculate_exclude_regexp if ! @pending
167
+ self
168
+ end
169
+
170
+ # Define equality.
171
+ def ==(array)
172
+ to_ary == array
173
+ end
174
+
175
+ # Return the internal array object.
176
+ def to_a
177
+ resolve
178
+ @items
179
+ end
180
+
181
+ # Return the internal array object.
182
+ def to_ary
183
+ to_a
184
+ end
185
+
186
+ # Lie about our class.
187
+ def is_a?(klass)
188
+ klass == Array || super(klass)
189
+ end
190
+ alias kind_of? is_a?
191
+
192
+ # Redefine * to return either a string or a new file list.
193
+ def *(other)
194
+ result = @items * other
195
+ case result
196
+ when Array
197
+ FileList.new.import(result)
198
+ else
199
+ result
200
+ end
201
+ end
202
+
203
+ # Resolve all the pending adds now.
204
+ def resolve
205
+ if @pending
206
+ @pending = false
207
+ @pending_add.each do |fn| resolve_add(fn) end
208
+ @pending_add = []
209
+ resolve_exclude
210
+ end
211
+ self
212
+ end
213
+
214
+ def calculate_exclude_regexp
215
+ ignores = []
216
+ @exclude_patterns.each do |pat|
217
+ case pat
218
+ when Regexp
219
+ ignores << pat
220
+ when /[*?]/
221
+ Dir[pat].each do |p| ignores << p end
222
+ else
223
+ ignores << Regexp.quote(pat)
224
+ end
225
+ end
226
+ if ignores.empty?
227
+ @exclude_re = /^$/
228
+ else
229
+ re_str = ignores.collect { |p| "(" + p.to_s + ")" }.join("|")
230
+ @exclude_re = Regexp.new(re_str)
231
+ end
232
+ end
233
+
234
+ def resolve_add(fn)
235
+ case fn
236
+ when %r{[*?\[\{]}
237
+ add_matching(fn)
238
+ else
239
+ self << fn
240
+ end
241
+ end
242
+ private :resolve_add
243
+
244
+ def resolve_exclude
245
+ calculate_exclude_regexp
246
+ reject! { |fn| exclude?(fn) }
247
+ self
248
+ end
249
+ private :resolve_exclude
250
+
251
+ # Return a new FileList with the results of running +sub+ against each
252
+ # element of the oringal list.
253
+ #
254
+ # Example:
255
+ # FileList['a.c', 'b.c'].sub(/\.c$/, '.o') => ['a.o', 'b.o']
256
+ #
257
+ def sub(pat, rep)
258
+ inject(FileList.new) { |res, fn| res << fn.sub(pat,rep) }
259
+ end
260
+
261
+ # Return a new FileList with the results of running +gsub+ against each
262
+ # element of the original list.
263
+ #
264
+ # Example:
265
+ # FileList['lib/test/file', 'x/y'].gsub(/\//, "\\")
266
+ # => ['lib\\test\\file', 'x\\y']
267
+ #
268
+ def gsub(pat, rep)
269
+ inject(FileList.new) { |res, fn| res << fn.gsub(pat,rep) }
270
+ end
271
+
272
+ # Same as +sub+ except that the oringal file list is modified.
273
+ def sub!(pat, rep)
274
+ each_with_index { |fn, i| self[i] = fn.sub(pat,rep) }
275
+ self
276
+ end
277
+
278
+ # Same as +gsub+ except that the original file list is modified.
279
+ def gsub!(pat, rep)
280
+ each_with_index { |fn, i| self[i] = fn.gsub(pat,rep) }
281
+ self
282
+ end
283
+
284
+ # Apply the pathmap spec to each of the included file names, returning a
285
+ # new file list with the modified paths. (See String#pathmap for
286
+ # details.)
287
+ def pathmap(spec=nil)
288
+ collect { |fn| fn.pathmap(spec) }
289
+ end
290
+
291
+ # Return a new array with <tt>String#ext</tt> method applied to each
292
+ # member of the array.
293
+ #
294
+ # This method is a shortcut for:
295
+ #
296
+ # array.collect { |item| item.ext(newext) }
297
+ #
298
+ # +ext+ is a user added method for the Array class.
299
+ def ext(newext='')
300
+ collect { |fn| fn.ext(newext) }
301
+ end
302
+
303
+
304
+ # Grep each of the files in the filelist using the given pattern. If a
305
+ # block is given, call the block on each matching line, passing the file
306
+ # name, line number, and the matching line of text. If no block is given,
307
+ # a standard emac style file:linenumber:line message will be printed to
308
+ # standard out.
309
+ def egrep(pattern)
310
+ each do |fn|
311
+ open(fn) do |inf|
312
+ count = 0
313
+ inf.each do |line|
314
+ count += 1
315
+ if pattern.match(line)
316
+ if block_given?
317
+ yield fn, count, line
318
+ else
319
+ puts "#{fn}:#{count}:#{line}"
320
+ end
321
+ end
322
+ end
323
+ end
324
+ end
325
+ end
326
+
327
+ # Return a new file list that only contains file names from the current
328
+ # file list that exist on the file system.
329
+ def existing
330
+ select { |fn| File.exist?(fn) }
331
+ end
332
+
333
+ # Modify the current file list so that it contains only file name that
334
+ # exist on the file system.
335
+ def existing!
336
+ resolve
337
+ @items = @items.select { |fn| File.exist?(fn) }
338
+ self
339
+ end
340
+
341
+ # FileList version of partition. Needed because the nested arrays should
342
+ # be FileLists in this version.
343
+ def partition(&block) # :nodoc:
344
+ resolve
345
+ result = @items.partition(&block)
346
+ [
347
+ FileList.new.import(result[0]),
348
+ FileList.new.import(result[1]),
349
+ ]
350
+ end
351
+
352
+ # Convert a FileList to a string by joining all elements with a space.
353
+ def to_s
354
+ resolve
355
+ self.join(' ')
356
+ end
357
+
358
+ # Add matching glob patterns.
359
+ def add_matching(pattern)
360
+ Dir[pattern].each do |fn|
361
+ self << fn unless exclude?(fn)
362
+ end
363
+ end
364
+ private :add_matching
365
+
366
+ # Should the given file name be excluded?
367
+ def exclude?(fn)
368
+ calculate_exclude_regexp unless @exclude_re
369
+ fn =~ @exclude_re || @exclude_procs.any? { |p| p.call(fn) }
370
+ end
371
+
372
+ DEFAULT_IGNORE_PATTERNS = [
373
+ /(^|[\/\\])CVS([\/\\]|$)/,
374
+ /(^|[\/\\])\.svn([\/\\]|$)/,
375
+ /\.bak$/,
376
+ /~$/
377
+ ]
378
+ DEFAULT_IGNORE_PROCS = [
379
+ proc { |fn| fn =~ /(^|[\/\\])core$/ && ! File.directory?(fn) }
380
+ ]
381
+ # @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup
382
+
383
+ def import(array)
384
+ @items = array
385
+ self
386
+ end
387
+
388
+ class << self
389
+ # Create a new file list including the files listed. Similar to:
390
+ #
391
+ # FileList.new(*args)
392
+ def [](*args)
393
+ new(*args)
394
+ end
395
+ end
396
+ end # FileList
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: filelist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - "Jakub \xC5\xA0\xC5\xA5astn\xC3\xBD aka Botanicus"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ date: 2009-12-31 00:00:00 +01:00
12
+ default_executable:
13
+ dependencies: []
14
+
15
+ description: ""
16
+ email: knava.bestvinensis@gmail.com
17
+ executables: []
18
+
19
+ extensions: []
20
+
21
+ extra_rdoc_files: []
22
+
23
+ files:
24
+ - filelist.gemspec
25
+ - lib/filelist.rb
26
+ - LICENSE
27
+ - Rakefile
28
+ - README.textile
29
+ - TODO
30
+ has_rdoc: true
31
+ homepage: http://github.com/botanicus/filelist
32
+ licenses: []
33
+
34
+ post_install_message:
35
+ rdoc_options: []
36
+
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project:
54
+ rubygems_version: 1.3.5
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: FileList is taken from Rake
58
+ test_files: []
59
+