rant 0.5.0 → 0.5.2
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/NEWS +30 -0
- data/README +4 -1
- data/Rantfile +28 -8
- data/doc/advanced.rdoc +19 -70
- data/doc/filelist.rdoc +963 -0
- data/doc/homepage/index.html +8 -2
- data/doc/rantfile.rdoc +7 -25
- data/doc/rubylib.rdoc +27 -0
- data/doc/sys.rdoc +15 -2
- data/doc/sys_filelist.rdoc +118 -0
- data/lib/rant.rb +1 -1
- data/lib/rant/cs_compiler.rb +4 -4
- data/lib/rant/filelist.rb +8 -0
- data/lib/rant/import/archive.rb +6 -6
- data/lib/rant/import/filelist/core.rb +429 -0
- data/lib/rant/import/filelist/inspect.rb +57 -0
- data/lib/rant/import/filelist/std.rb +64 -0
- data/lib/rant/import/nodes/default.rb +6 -2
- data/lib/rant/import/rubypackage.rb +10 -0
- data/lib/rant/init.rb +200 -0
- data/lib/rant/rantlib.rb +98 -111
- data/lib/rant/rantsys.rb +86 -455
- data/lib/rant/rantvar.rb +1 -7
- data/test/import/directedrule/Rantfile +1 -1
- data/test/lib/test_filelist.rb +481 -0
- data/test/test_filelist.rb +135 -13
- data/test/test_sys.rb +4 -0
- data/test/test_sys_methods.rb +9 -0
- data/test/tutil.rb +37 -15
- metadata +18 -7
- data/lib/rant/rantenv.rb +0 -184
- data/test/deprecated/test_0_5_2.rb +0 -61
data/doc/homepage/index.html
CHANGED
@@ -105,6 +105,12 @@
|
|
105
105
|
before installing a newer version of Rant. It describes
|
106
106
|
non-backwards compatible changes and new features.
|
107
107
|
</p>
|
108
|
+
<h2>Rant libraries</h2>
|
109
|
+
<p>
|
110
|
+
You can reuse code written for the Rant build tool as
|
111
|
+
"normal" Ruby library. Read <a
|
112
|
+
href="files/doc/rubylib_rdoc.html">Rant libraries</a>
|
113
|
+
</p>
|
108
114
|
<h2>Rant vs. Rake</h2>
|
109
115
|
<p>
|
110
116
|
<a href="files/doc/rant_vs_rake_rdoc.html">Read comparison</a>
|
@@ -118,8 +124,8 @@
|
|
118
124
|
<a href="http://developer.berlios.de" title="BerliOS
|
119
125
|
Developer"> <img
|
120
126
|
src="http://developer.berlios.de/bslogo.php?group_id=5046"
|
121
|
-
width="124px" height="32px"
|
122
|
-
Developer Logo"
|
127
|
+
width="124px" height="32px" alt="BerliOS
|
128
|
+
Developer Logo" /></a>
|
123
129
|
</p>
|
124
130
|
|
125
131
|
<!-- BlueRobot was here. -->
|
data/doc/rantfile.rdoc
CHANGED
@@ -209,31 +209,11 @@ explain it a little bit. It can be used in three ways:
|
|
209
209
|
|
210
210
|
file "program" => sys["*.o"]
|
211
211
|
|
212
|
-
The task "program" depends on all files ending in ".o".
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
From now on we'll call <tt>sys[...]</tt> the <em>glob
|
219
|
-
operator</em>.
|
220
|
-
|
221
|
-
You can give more patterns:
|
222
|
-
|
223
|
-
c_files = sys["**/*.h", "**/*.c"]
|
224
|
-
|
225
|
-
gives a list of all files ending in ".h" or ".c" in the current
|
226
|
-
directory and all subdirectories.
|
227
|
-
|
228
|
-
The object returned by the glob operator _behaves_ like an array of
|
229
|
-
strings, so it is possible to pass it to methods expecting an array.
|
230
|
-
If you're getting errors or experience strange behaviour convert
|
231
|
-
the list explicetely to an array:
|
232
|
-
|
233
|
-
# method foo_bar is hardcoded to check for an object of class
|
234
|
-
# Array
|
235
|
-
foo_bar(c_files.to_a)
|
236
|
-
|
212
|
+
The task "program" depends on all files ending in ".o".
|
213
|
+
|
214
|
+
For extensive documentation read
|
215
|
+
doc/sys_filelist.rdoc[link:files/doc/sys_filelist_rdoc.html].
|
216
|
+
|
237
217
|
=== Generators
|
238
218
|
|
239
219
|
The *gen* function takes a generator which usually creates one or more
|
@@ -469,5 +449,7 @@ Packaging::
|
|
469
449
|
doc/package.rdoc[link:files/doc/package_rdoc.html]
|
470
450
|
Ruby project howto::
|
471
451
|
doc/rubyproject.rdoc[link:files/doc/rubyproject_rdoc.html]
|
452
|
+
Using filelists in Rantfiles::
|
453
|
+
doc/sys_filelist.rdoc[link:files/doc/sys_filelist_rdoc.html]
|
472
454
|
Rant Overview::
|
473
455
|
README[link:files/README.html]
|
data/doc/rubylib.rdoc
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
== Rant libraries
|
3
|
+
|
4
|
+
The Rant build tool contains much code that can be reused in other
|
5
|
+
Ruby applications or libraries. This document provides an overview of
|
6
|
+
what is "officially" supported.
|
7
|
+
|
8
|
+
As Rant matures, more classes will be provided to drive Rant
|
9
|
+
programmatically or just to allow reuse of library code.
|
10
|
+
|
11
|
+
=== Rant::FileList class
|
12
|
+
|
13
|
+
This class provides an abstraction over the <tt>Dir.glob</tt> and
|
14
|
+
<tt>File.fnmatch</tt> methods. In many cases it can be used instead of
|
15
|
+
the +Find+ module in Ruby's standard library.
|
16
|
+
|
17
|
+
Read doc/filelist.rdoc[link:files/doc/filelist_rdoc.html] for full
|
18
|
+
documentation of the <tt>Rant::FileList</tt> class.
|
19
|
+
|
20
|
+
== See also
|
21
|
+
|
22
|
+
Rant Homepage::
|
23
|
+
http://make.ruby-co.de
|
24
|
+
Rant Overview::
|
25
|
+
README[link:files/README.html]
|
26
|
+
Rant::FileList documentation::
|
27
|
+
doc/filelist.rdoc[link:files/doc/filelist_rdoc.html]
|
data/doc/sys.rdoc
CHANGED
@@ -536,13 +536,26 @@ standard output:
|
|
536
536
|
# on windows: 'dmd "foo bar.d" util.d -offoo -I"/home/user/program files/d"'
|
537
537
|
# other systems: 'dmd foo\ bar.d util.d -offoo -I/home/user/program\ files/d'
|
538
538
|
|
539
|
+
* <b>regular_filename(path)</b>
|
540
|
+
|
541
|
+
Replaces all platform dependent filename separators with a slash,
|
542
|
+
thus returning a platform independent filename.
|
543
|
+
|
544
|
+
Examples:
|
545
|
+
|
546
|
+
# on windows:
|
547
|
+
sys.regular_filename('foo\bar') # "foo/bar"
|
548
|
+
|
549
|
+
# on all platforms:
|
550
|
+
sys.regular_filename('foo//bar') # "foo/bar"
|
551
|
+
|
539
552
|
* <b>glob(pattern1, pattern2, ...)</b>
|
540
553
|
|
541
554
|
<b>[pattern1, pattern2, ...]</b>
|
542
555
|
|
543
556
|
Returns a filelist including the given patterns. For a discussion of
|
544
|
-
filelists, read
|
545
|
-
doc/
|
557
|
+
filelists, read
|
558
|
+
doc/sys_filelist.rdoc[link:files/doc/sys_filelist_rdoc.html].
|
546
559
|
|
547
560
|
Examples:
|
548
561
|
|
@@ -0,0 +1,118 @@
|
|
1
|
+
|
2
|
+
== Using filelists in Rantfiles
|
3
|
+
|
4
|
+
You can find documentation for Rant's +FileList+ class in the file
|
5
|
+
doc/filelist.rdoc[link:files/doc/filelist_rdoc.html]. This document
|
6
|
+
describes how you can use filelists in your Rant build scripts
|
7
|
+
(Rantfiles).
|
8
|
+
|
9
|
+
First of all, you don't need to <tt>require</tt> or <tt>import</tt>
|
10
|
+
anything to use filelists in Rantfiles. Additionally the
|
11
|
+
<tt>Rant::FileList</tt> class is directly available as +FileList+.
|
12
|
+
Thus, for example, instead of typing:
|
13
|
+
|
14
|
+
c_files = Rant::FileList["*.c"]
|
15
|
+
|
16
|
+
you can type:
|
17
|
+
|
18
|
+
c_files = FileList["*.c"]
|
19
|
+
|
20
|
+
Again, you don't need to <tt>require "rant/filelist"</tt>. But if you
|
21
|
+
want to use one of the methods +no_dir+, +files+ or +dirs+ <tt>import
|
22
|
+
"filelist/std"</tt> is required.
|
23
|
+
|
24
|
+
Often there are files/directories you want to always ignore when using
|
25
|
+
filelists. This could be the "CVS" directories if you are using the
|
26
|
+
CVS version control system or simply all backup files.
|
27
|
+
|
28
|
+
Rant allows you to specify a set of patterns once for your project
|
29
|
+
with the <tt>sys.ignore</tt> method.
|
30
|
+
|
31
|
+
E.g. place the following line of code in your Rantfile:
|
32
|
+
|
33
|
+
sys.ignore "CVS", /~$/
|
34
|
+
|
35
|
+
In the Rant::FileList documentation there are five ways to create a
|
36
|
+
filelist documented. In Rantfiles:
|
37
|
+
|
38
|
+
instead of | use
|
39
|
+
-----------------------------------------------------------------
|
40
|
+
Rant::FileList.new | sys.filelist
|
41
|
+
Rant::FileList[*patterns] | sys[*patterns]
|
42
|
+
Rant::FileList.glob(*patterns) | sys.glob(*patterns)
|
43
|
+
Rant::FileList.glob_all(*patterns) | sys.glob_all(*patterns)
|
44
|
+
Rant::FileList(list) | sys.filelist(list)
|
45
|
+
|
46
|
+
The <tt>sys</tt> variants of filelist creation all honour the project
|
47
|
+
wide ignore patterns set by <tt>sys.ignore</tt>.
|
48
|
+
|
49
|
+
Let's look at an example. First an Rantfile using the "normal"
|
50
|
+
filelist constructors:
|
51
|
+
|
52
|
+
all_files = FileList["**/*"].ignore("CVS", /~$/)
|
53
|
+
lib_files = FileList["lib/**/*.rb"].ignore("CVS")
|
54
|
+
pkg_files = FileList["bin/*", "lib/**/*.rb", "test/**/*"].ignore("CVS", /~$/)
|
55
|
+
backup_files = FileList["**/*~"]
|
56
|
+
|
57
|
+
# define tasks
|
58
|
+
|
59
|
+
I admit that the example is a bit exaggerated, but in essence you
|
60
|
+
always have to care that you don't accidently include a backup file or
|
61
|
+
some file living under a "CVS" directory. Now look at the equivalent
|
62
|
+
Rantfile using <tt>sys</tt> to create filelists.
|
63
|
+
|
64
|
+
sys.ignore "CVS", /~$/
|
65
|
+
all_files = sys["**/*"]
|
66
|
+
lib_files = sys["lib/**/*.rb"]
|
67
|
+
pkg_files = sys["bin/*", "lib/**/*.rb", "test/**/*"]
|
68
|
+
backup_files = FileList["**/*~"]
|
69
|
+
|
70
|
+
# define tasks
|
71
|
+
|
72
|
+
Now, per default CVS directories and backup files won't appear in
|
73
|
+
filelists. We use a "stateless" filelist for +backup_files+, since all
|
74
|
+
backup files would be ignored otherwise.
|
75
|
+
|
76
|
+
== Where to use filelists?
|
77
|
+
|
78
|
+
Basically, you can use a filelist wherever you can use an array. The
|
79
|
+
following is a list of use cases where filelists are handy.
|
80
|
+
|
81
|
+
* As prerequisite list for a task. Example:
|
82
|
+
|
83
|
+
# get a list of all c files
|
84
|
+
c_files = sys["**/*.c"]
|
85
|
+
# get a list of all resulting object files
|
86
|
+
obj_files = c_files.ext("o")
|
87
|
+
|
88
|
+
# static library "foo" depends on all object files
|
89
|
+
file "libfoo.a" => obj_files do |t|
|
90
|
+
# build t.name from t.prerequisites (obj_files)
|
91
|
+
end
|
92
|
+
|
93
|
+
* As argument to file system operations. Example:
|
94
|
+
|
95
|
+
task :clean do
|
96
|
+
# remove all backup files
|
97
|
+
sys.rm_f FileList["**/*~"]
|
98
|
+
end
|
99
|
+
|
100
|
+
* If you want to apply an operation to a list of files, e.g.
|
101
|
+
substituting a variable in text files. Example:
|
102
|
+
|
103
|
+
# Do something with all files in the project
|
104
|
+
import "filelist/std"
|
105
|
+
sys["**/*"].files.each { |filename|
|
106
|
+
# do something with the file "filename"
|
107
|
+
}
|
108
|
+
|
109
|
+
== See also
|
110
|
+
|
111
|
+
Rant Overview::
|
112
|
+
README[link:files/README.html]
|
113
|
+
Rant::FileList documentation::
|
114
|
+
doc/filelist.rdoc[link:files/doc/filelist_rdoc.html]
|
115
|
+
Rantfile basics::
|
116
|
+
doc/rantfile.rdoc[link:files/doc/rantfile_rdoc.html]
|
117
|
+
Advanced Rantfiles::
|
118
|
+
doc/advanced.rdoc[link:files/doc/advanced_rdoc.html]
|
data/lib/rant.rb
CHANGED
@@ -13,7 +13,7 @@ module Rant
|
|
13
13
|
def inspect
|
14
14
|
# what's the right encoding for object_id ?
|
15
15
|
s = "#<#{self.class}:0x#{"%x" % object_id} "
|
16
|
-
s << "#{@actions.size} actions, #{@
|
16
|
+
s << "#{@actions.size} actions, #{@items.size} entries"
|
17
17
|
if @ignore_rx
|
18
18
|
is = @ignore_rx.inspect.gsub(/\n|\t/, ' ')
|
19
19
|
s << ", ignore#{is.squeeze ' '}"
|
data/lib/rant/cs_compiler.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
require 'rant/
|
2
|
+
require 'rant/init'
|
3
3
|
|
4
4
|
module Rant
|
5
5
|
# An object extending this module acts as an
|
@@ -277,7 +277,7 @@ module Rant
|
|
277
277
|
resources.each { |p|
|
278
278
|
cc_args << " -fresources=#{Env.shell_path(p)}"
|
279
279
|
}
|
280
|
-
cc_args << " " << sources
|
280
|
+
cc_args << " " << Rant::Sys.sp(sources) if sources
|
281
281
|
cc_args
|
282
282
|
end
|
283
283
|
|
@@ -302,7 +302,7 @@ module Rant
|
|
302
302
|
resources.each { |p|
|
303
303
|
cc_args << " /res:#{Env.shell_path(p)}"
|
304
304
|
}
|
305
|
-
cc_args << " " << sources
|
305
|
+
cc_args << " " << Rant::Sys.sp(sources) if sources
|
306
306
|
cc_args
|
307
307
|
end
|
308
308
|
|
@@ -328,7 +328,7 @@ module Rant
|
|
328
328
|
resources.each { |p|
|
329
329
|
cc_args << " -resource:#{Env.shell_path(p)}"
|
330
330
|
}
|
331
|
-
cc_args << " " << sources
|
331
|
+
cc_args << " " << Rant::Sys.sp(sources) if sources
|
332
332
|
cc_args
|
333
333
|
end
|
334
334
|
|
data/lib/rant/import/archive.rb
CHANGED
@@ -154,16 +154,16 @@ module Rant::Generators::Archive
|
|
154
154
|
fl = @files ? @files.dup : []
|
155
155
|
if @manifest
|
156
156
|
fl = read_manifest unless @files
|
157
|
-
fl = Rant::
|
158
|
-
fl
|
157
|
+
fl = Rant::FileList(fl)
|
158
|
+
fl.keep(@manifest)
|
159
159
|
elsif @files_only
|
160
|
-
fl = Rant::
|
160
|
+
fl = Rant::FileList(fl)
|
161
161
|
fl.no_dirs
|
162
162
|
else
|
163
|
-
fl = Rant::
|
163
|
+
fl = Rant::FileList(fl)
|
164
164
|
end
|
165
165
|
# remove leading `./' relicts
|
166
|
-
@res_files = fl.
|
166
|
+
@res_files = fl.map! { |fn| fn.sub(/^\.\/(?=.)/,'') }
|
167
167
|
if defined?(@dist_path) && @dist_path
|
168
168
|
# Remove entries from the dist_path directory, which
|
169
169
|
# would create some sort of weird recursion.
|
@@ -172,7 +172,7 @@ module Rant::Generators::Archive
|
|
172
172
|
# but since I tapped into this trap frequently now...
|
173
173
|
@res_files.exclude(/^#{Regexp.escape @dist_path}/)
|
174
174
|
end
|
175
|
-
@res_files.
|
175
|
+
@res_files.uniq!.sort!
|
176
176
|
end
|
177
177
|
|
178
178
|
# Creates an (eventually) temporary manifest file and yields
|
@@ -0,0 +1,429 @@
|
|
1
|
+
|
2
|
+
# core.rb - Core functionality for the Rant::FileList class.
|
3
|
+
#
|
4
|
+
# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
|
5
|
+
|
6
|
+
module Rant
|
7
|
+
def FileList(arg)
|
8
|
+
if arg.respond_to?(:to_rant_filelist)
|
9
|
+
arg.to_rant_filelist
|
10
|
+
elsif arg.respond_to?(:to_ary)
|
11
|
+
FileList.new(arg.to_ary)
|
12
|
+
# or?
|
13
|
+
#FileList.new.concat(arg.to_ary)
|
14
|
+
else
|
15
|
+
raise TypeError,
|
16
|
+
"cannot convert #{arg.class} into Rant::FileList"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
module_function :FileList
|
20
|
+
class FileList
|
21
|
+
include Enumerable
|
22
|
+
|
23
|
+
ESC_SEPARATOR = Regexp.escape(File::SEPARATOR)
|
24
|
+
ESC_ALT_SEPARATOR = File::ALT_SEPARATOR ?
|
25
|
+
Regexp.escape(File::ALT_SEPARATOR) : nil
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def [](*patterns)
|
29
|
+
new.hide_dotfiles.include(*patterns)
|
30
|
+
end
|
31
|
+
def glob(*patterns)
|
32
|
+
fl = new.hide_dotfiles.ignore(".", "..").include(*patterns)
|
33
|
+
if block_given? then yield fl else fl end
|
34
|
+
end
|
35
|
+
def glob_all(*patterns)
|
36
|
+
fl = new.ignore(".", "..").include(*patterns)
|
37
|
+
if block_given? then yield fl else fl end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(store = [])
|
42
|
+
@pending = false
|
43
|
+
@def_glob_dotfiles = true
|
44
|
+
@items = store
|
45
|
+
@ignore_rx = nil
|
46
|
+
@keep = {}
|
47
|
+
@actions = []
|
48
|
+
end
|
49
|
+
alias _object_dup dup
|
50
|
+
private :_object_dup
|
51
|
+
def dup
|
52
|
+
c = _object_dup
|
53
|
+
c.items = @items.dup
|
54
|
+
c.actions = @actions.dup
|
55
|
+
c.ignore_rx = @ignore_rx.dup if @ignore_rx
|
56
|
+
c.instance_variable_set(:@keep, @keep.dup)
|
57
|
+
c
|
58
|
+
end
|
59
|
+
def copy
|
60
|
+
c = _object_dup
|
61
|
+
c.items = @items.map { |entry| entry.dup }
|
62
|
+
c.actions = @actions.dup
|
63
|
+
c.ignore_rx = @ignore_rx.dup if @ignore_rx
|
64
|
+
# alternative approach: copy & freeze "keep" entries on
|
65
|
+
# inclusion in the keep hash
|
66
|
+
h_keep = {}
|
67
|
+
@keep.each_key { |entry| h_keep[entry] = true }
|
68
|
+
c.instance_variable_set(:@keep, h_keep)
|
69
|
+
c
|
70
|
+
end
|
71
|
+
# Currently for Rant internal use only. Might go in future
|
72
|
+
# releases.
|
73
|
+
def glob_dotfiles?
|
74
|
+
@def_glob_dotfiles
|
75
|
+
end
|
76
|
+
# Currently for Rant internal use only. Might go in future
|
77
|
+
# releases.
|
78
|
+
def glob_dotfiles=(flag)
|
79
|
+
@def_glob_dotfiles = flag ? true : false
|
80
|
+
end
|
81
|
+
# Has the same effect as <tt>glob_dotfiles = false</tt>.
|
82
|
+
#
|
83
|
+
# Returns self.
|
84
|
+
#
|
85
|
+
# Currently for Rant internal use only. Might go in future
|
86
|
+
# releases.
|
87
|
+
def hide_dotfiles
|
88
|
+
@def_glob_dotfiles = false
|
89
|
+
self
|
90
|
+
end
|
91
|
+
# Has the same effect as <tt>glob_dotfiles = true</tt>.
|
92
|
+
#
|
93
|
+
# Returns self.
|
94
|
+
#
|
95
|
+
# Currently for Rant internal use only. Might go in future
|
96
|
+
# releases.
|
97
|
+
def glob_dotfiles
|
98
|
+
@def_glob_dotfiles = true
|
99
|
+
self
|
100
|
+
end
|
101
|
+
|
102
|
+
protected
|
103
|
+
attr_accessor :actions, :items
|
104
|
+
attr_accessor :pending
|
105
|
+
attr_accessor :ignore_rx
|
106
|
+
|
107
|
+
public
|
108
|
+
def each(&block)
|
109
|
+
resolve if @pending
|
110
|
+
@items.each(&block)
|
111
|
+
self
|
112
|
+
end
|
113
|
+
def to_ary
|
114
|
+
resolve if @pending
|
115
|
+
@items
|
116
|
+
end
|
117
|
+
alias to_a to_ary
|
118
|
+
alias entries to_ary # entries: defined in Enumerable
|
119
|
+
def to_rant_filelist
|
120
|
+
self
|
121
|
+
end
|
122
|
+
def +(other)
|
123
|
+
if other.respond_to? :to_rant_filelist
|
124
|
+
c = other.to_rant_filelist.dup
|
125
|
+
c.actions.concat(@actions)
|
126
|
+
c.items.concat(@items)
|
127
|
+
c.pending = !c.actions.empty?
|
128
|
+
c
|
129
|
+
elsif other.respond_to? :to_ary
|
130
|
+
c = dup
|
131
|
+
c.actions <<
|
132
|
+
[:apply_ary_method_1, :concat, other.to_ary.dup]
|
133
|
+
c.pending = true
|
134
|
+
c
|
135
|
+
else
|
136
|
+
raise TypeError,
|
137
|
+
"cannot add #{other.class} to Rant::FileList"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
# Use this method to append +file+ to this list. +file+ will
|
141
|
+
# stay in this list even if it matches an exclude or ignore
|
142
|
+
# pattern.
|
143
|
+
#
|
144
|
+
# Returns self.
|
145
|
+
def <<(file)
|
146
|
+
@actions << [:apply_ary_method_1, :push, file]
|
147
|
+
@keep[file] = true
|
148
|
+
@pending = true
|
149
|
+
self
|
150
|
+
end
|
151
|
+
# Add +entry+ to this filelist. Position of +entry+ in this
|
152
|
+
# list is undefined. More efficient than #<<. +entry+ will
|
153
|
+
# stay in this list even if it matches an exclude or ignore
|
154
|
+
# pattern.
|
155
|
+
#
|
156
|
+
# Returns self.
|
157
|
+
def keep(entry)
|
158
|
+
@keep[entry] = true
|
159
|
+
@items << entry
|
160
|
+
self
|
161
|
+
end
|
162
|
+
# Append the entries of +ary+ (an array like object) to
|
163
|
+
# this list.
|
164
|
+
def concat(ary)
|
165
|
+
if @pending
|
166
|
+
ary = ary.to_ary.dup
|
167
|
+
@actions << [:apply_ary_method_1, :concat, ary]
|
168
|
+
else
|
169
|
+
ix = ignore_rx and ary = ary.to_ary.reject { |f| f =~ ix }
|
170
|
+
@items.concat(ary)
|
171
|
+
end
|
172
|
+
self
|
173
|
+
end
|
174
|
+
# Number of entries in this filelist.
|
175
|
+
def size
|
176
|
+
resolve if @pending
|
177
|
+
@items.size
|
178
|
+
end
|
179
|
+
alias length size
|
180
|
+
def empty?
|
181
|
+
resolve if @pending
|
182
|
+
@items.empty?
|
183
|
+
end
|
184
|
+
def join(sep = ' ')
|
185
|
+
resolve if @pending
|
186
|
+
@items.join(sep)
|
187
|
+
end
|
188
|
+
def pop
|
189
|
+
resolve if @pending
|
190
|
+
@items.pop
|
191
|
+
end
|
192
|
+
def push(entry)
|
193
|
+
resolve if @pending
|
194
|
+
@items.push(entry) if entry !~ ignore_rx
|
195
|
+
self
|
196
|
+
end
|
197
|
+
def shift
|
198
|
+
resolve if @pending
|
199
|
+
@items.shift
|
200
|
+
end
|
201
|
+
def unshift(entry)
|
202
|
+
resolve if @pending
|
203
|
+
@items.unshift(entry) if entry !~ ignore_rx
|
204
|
+
self
|
205
|
+
end
|
206
|
+
if Object.method_defined?(:fcall) || Object.method_defined?(:funcall) # in Ruby 1.9 like __send__
|
207
|
+
@@__send_private__ = Object.method_defined?(:fcall) ? :fcall : :funcall
|
208
|
+
def resolve
|
209
|
+
@pending = false
|
210
|
+
@actions.each{ |action| self.__send__(@@__send_private__, *action) }.clear
|
211
|
+
ix = ignore_rx
|
212
|
+
if ix
|
213
|
+
@items.reject! { |f| f =~ ix && !@keep[f] }
|
214
|
+
end
|
215
|
+
self
|
216
|
+
end
|
217
|
+
else
|
218
|
+
# Force evaluation of all patterns.
|
219
|
+
def resolve
|
220
|
+
@pending = false
|
221
|
+
@actions.each{ |action| self.__send__(*action) }.clear
|
222
|
+
ix = ignore_rx
|
223
|
+
if ix
|
224
|
+
@items.reject! { |f| f =~ ix && !@keep[f] }
|
225
|
+
end
|
226
|
+
self
|
227
|
+
end
|
228
|
+
end
|
229
|
+
# Include entries matching one of +patterns+ in this filelist.
|
230
|
+
def include(*pats)
|
231
|
+
@def_glob_dotfiles ? glob_all(*pats) : glob_unix(*pats)
|
232
|
+
end
|
233
|
+
alias glob include
|
234
|
+
# Unix style glob: hide files starting with a dot
|
235
|
+
def glob_unix(*patterns)
|
236
|
+
patterns.flatten.each { |pat|
|
237
|
+
@actions << [:apply_glob_unix, pat]
|
238
|
+
}
|
239
|
+
@pending = true
|
240
|
+
self
|
241
|
+
end
|
242
|
+
def glob_all(*patterns)
|
243
|
+
patterns.flatten.each { |pat|
|
244
|
+
@actions << [:apply_glob_all, pat]
|
245
|
+
}
|
246
|
+
@pending = true
|
247
|
+
self
|
248
|
+
end
|
249
|
+
if RUBY_VERSION < "1.8.2"
|
250
|
+
# Dir.glob of Ruby releases before 1.8.2 returned dotfiles
|
251
|
+
# even if File::FNM_DOTMATCH was not set.
|
252
|
+
FN_DOTFILE_RX_ = ESC_ALT_SEPARATOR ?
|
253
|
+
/(^|(#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+)\..*
|
254
|
+
((#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+|$)/x :
|
255
|
+
/(^|#{ESC_SEPARATOR}+)\..* (#{ESC_SEPARATOR}+|$)/x
|
256
|
+
def apply_glob_unix(pattern)
|
257
|
+
inc_files = Dir.glob(pattern)
|
258
|
+
# it's not 100% correct, but it works for most use
|
259
|
+
# cases
|
260
|
+
unless pattern =~ /(^|\/)\./
|
261
|
+
inc_files.reject! { |fn| fn =~ FN_DOTFILE_RX_ }
|
262
|
+
end
|
263
|
+
@items.concat(inc_files)
|
264
|
+
end
|
265
|
+
else
|
266
|
+
def apply_glob_unix(pattern)
|
267
|
+
@items.concat(Dir.glob(pattern))
|
268
|
+
end
|
269
|
+
end
|
270
|
+
private :apply_glob_unix
|
271
|
+
def apply_glob_all(pattern)
|
272
|
+
@items.concat(Dir.glob(pattern, File::FNM_DOTMATCH))
|
273
|
+
end
|
274
|
+
private :apply_glob_all
|
275
|
+
# Exclude all entries matching one of +patterns+ from this
|
276
|
+
# filelist.
|
277
|
+
#
|
278
|
+
# Note: Only applies to entries previousely included.
|
279
|
+
def exclude(*patterns)
|
280
|
+
patterns.each { |pat|
|
281
|
+
if Regexp === pat
|
282
|
+
@actions << [:apply_exclude_rx, pat]
|
283
|
+
else
|
284
|
+
@actions << [:apply_exclude, pat]
|
285
|
+
end
|
286
|
+
}
|
287
|
+
@pending = true
|
288
|
+
self
|
289
|
+
end
|
290
|
+
def ignore(*patterns)
|
291
|
+
patterns.each { |pat|
|
292
|
+
add_ignore_rx(Regexp === pat ? pat : mk_all_rx(pat))
|
293
|
+
}
|
294
|
+
@pending = true
|
295
|
+
self
|
296
|
+
end
|
297
|
+
def add_ignore_rx(rx)
|
298
|
+
@ignore_rx =
|
299
|
+
if @ignore_rx
|
300
|
+
Regexp.union(@ignore_rx, rx)
|
301
|
+
else
|
302
|
+
rx
|
303
|
+
end
|
304
|
+
end
|
305
|
+
private :add_ignore_rx
|
306
|
+
def apply_exclude(pattern)
|
307
|
+
@items.reject! { |elem|
|
308
|
+
File.fnmatch?(pattern, elem, File::FNM_DOTMATCH) && !@keep[elem]
|
309
|
+
}
|
310
|
+
end
|
311
|
+
private :apply_exclude
|
312
|
+
def apply_exclude_rx(rx)
|
313
|
+
@items.reject! { |elem|
|
314
|
+
elem =~ rx && !@keep[elem]
|
315
|
+
}
|
316
|
+
end
|
317
|
+
private :apply_exclude_rx
|
318
|
+
def exclude_name(*names)
|
319
|
+
names.each { |name|
|
320
|
+
@actions << [:apply_exclude_rx, mk_all_rx(name)]
|
321
|
+
}
|
322
|
+
@pending = true
|
323
|
+
self
|
324
|
+
end
|
325
|
+
alias shun exclude_name
|
326
|
+
if File::ALT_SEPARATOR
|
327
|
+
# TODO: check for FS case sensitivity?
|
328
|
+
def mk_all_rx(file)
|
329
|
+
/(^|(#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+)#{Regexp.escape(file)}
|
330
|
+
((#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+|$)/x
|
331
|
+
end
|
332
|
+
else
|
333
|
+
def mk_all_rx(file)
|
334
|
+
/(^|#{ESC_SEPARATOR}+)#{Regexp.escape(file)}
|
335
|
+
(#{ESC_SEPARATOR}+|$)/x
|
336
|
+
end
|
337
|
+
end
|
338
|
+
private :mk_all_rx
|
339
|
+
def exclude_path(*patterns)
|
340
|
+
patterns.each { |pat|
|
341
|
+
@actions << [:apply_exclude_path, pat]
|
342
|
+
}
|
343
|
+
@pending = true
|
344
|
+
self
|
345
|
+
end
|
346
|
+
def apply_exclude_path(pattern)
|
347
|
+
flags = File::FNM_DOTMATCH|File::FNM_PATHNAME
|
348
|
+
@items.reject! { |elem|
|
349
|
+
File.fnmatch?(pattern, elem, flags) && !@keep[elem]
|
350
|
+
}
|
351
|
+
end
|
352
|
+
private :apply_exclude
|
353
|
+
def select(&block)
|
354
|
+
d = dup
|
355
|
+
d.actions << [:apply_select, block]
|
356
|
+
d.pending = true
|
357
|
+
d
|
358
|
+
end
|
359
|
+
alias find_all select
|
360
|
+
def apply_select blk
|
361
|
+
@items = @items.select(&blk)
|
362
|
+
end
|
363
|
+
private :apply_select
|
364
|
+
def map(&block)
|
365
|
+
d = dup
|
366
|
+
d.actions << [:apply_ary_method, :map!, block]
|
367
|
+
d.pending = true
|
368
|
+
d
|
369
|
+
end
|
370
|
+
alias collect map
|
371
|
+
def sub_ext(ext, new_ext=nil)
|
372
|
+
map { |f| f._rant_sub_ext ext, new_ext }
|
373
|
+
end
|
374
|
+
def ext(ext_str)
|
375
|
+
sub_ext(ext_str)
|
376
|
+
end
|
377
|
+
# Get a string with all entries. This is very usefull
|
378
|
+
# if you invoke a shell:
|
379
|
+
# files # => ["foo/bar", "with space"]
|
380
|
+
# sh "rdoc #{files.arglist}"
|
381
|
+
# will result on windows:
|
382
|
+
# rdoc foo\bar "with space"
|
383
|
+
# on other systems:
|
384
|
+
# rdoc foo/bar with\ space
|
385
|
+
def arglist
|
386
|
+
Rant::Sys.sp to_ary
|
387
|
+
end
|
388
|
+
alias to_s arglist
|
389
|
+
alias object_inspect inspect
|
390
|
+
# Same as #uniq! but evaluation is delayed until the next read
|
391
|
+
# access (e.g. by calling #each). Always returns self.
|
392
|
+
def uniq!
|
393
|
+
@actions << [:apply_ary_method, :uniq!]
|
394
|
+
@pending = true
|
395
|
+
self
|
396
|
+
end
|
397
|
+
# Same as #sort! but evaluation is delayed until the next read
|
398
|
+
# access (e.g. by calling #each). Always returns self.
|
399
|
+
def sort!
|
400
|
+
@actions << [:apply_ary_method, :sort!]
|
401
|
+
@pending = true
|
402
|
+
self
|
403
|
+
end
|
404
|
+
# Same as #map! but evaluation is delayed until the next read
|
405
|
+
# access (e.g. by calling #each). Always returns self.
|
406
|
+
def map!(&block)
|
407
|
+
@actions << [:apply_ary_method, :map!, block]
|
408
|
+
@pending = true
|
409
|
+
self
|
410
|
+
end
|
411
|
+
def reject!(&block)
|
412
|
+
@actions << [:apply_ary_method, :reject!, block]
|
413
|
+
@pending = true
|
414
|
+
self
|
415
|
+
end
|
416
|
+
private
|
417
|
+
def apply_ary_method(meth, block=nil)
|
418
|
+
@items.send meth, &block
|
419
|
+
end
|
420
|
+
def apply_ary_method_1(meth, arg1, block=nil)
|
421
|
+
@items.send meth, arg1, &block
|
422
|
+
end
|
423
|
+
=begin
|
424
|
+
def apply_lazy_operation(meth, args, block)
|
425
|
+
@items.send(meth, *args, &block)
|
426
|
+
end
|
427
|
+
=end
|
428
|
+
end # class FileList
|
429
|
+
end # module Rant
|