buildr 1.3.5-x86-mswin32

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.
Files changed (186) hide show
  1. data/CHANGELOG +998 -0
  2. data/LICENSE +176 -0
  3. data/NOTICE +26 -0
  4. data/README.rdoc +134 -0
  5. data/Rakefile +45 -0
  6. data/_buildr +29 -0
  7. data/_jbuildr +29 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/cobertura.rb +22 -0
  10. data/addon/buildr/drb.rb +281 -0
  11. data/addon/buildr/emma.rb +22 -0
  12. data/addon/buildr/hibernate.rb +142 -0
  13. data/addon/buildr/javacc.rb +85 -0
  14. data/addon/buildr/jdepend.rb +60 -0
  15. data/addon/buildr/jetty.rb +248 -0
  16. data/addon/buildr/jibx.rb +86 -0
  17. data/addon/buildr/nailgun.rb +221 -0
  18. data/addon/buildr/openjpa.rb +90 -0
  19. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  20. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  21. data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
  22. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  23. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  25. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  26. data/addon/buildr/xmlbeans.rb +93 -0
  27. data/bin/buildr +19 -0
  28. data/buildr.buildfile +58 -0
  29. data/buildr.gemspec +65 -0
  30. data/doc/_config.yml +1 -0
  31. data/doc/_layouts/default.html +88 -0
  32. data/doc/_layouts/preface.html +22 -0
  33. data/doc/artifacts.textile +211 -0
  34. data/doc/building.textile +244 -0
  35. data/doc/contributing.textile +252 -0
  36. data/doc/css/default.css +236 -0
  37. data/doc/css/print.css +101 -0
  38. data/doc/css/syntax.css +23 -0
  39. data/doc/download.textile +79 -0
  40. data/doc/extending.textile +186 -0
  41. data/doc/images/1442160941-frontcover.jpg +0 -0
  42. data/doc/images/asf-logo.gif +0 -0
  43. data/doc/images/asf-logo.png +0 -0
  44. data/doc/images/buildr-hires.png +0 -0
  45. data/doc/images/buildr.png +0 -0
  46. data/doc/images/favicon.png +0 -0
  47. data/doc/images/growl-icon.tiff +0 -0
  48. data/doc/images/note.png +0 -0
  49. data/doc/images/project-structure.png +0 -0
  50. data/doc/images/tip.png +0 -0
  51. data/doc/images/zbuildr.png +0 -0
  52. data/doc/images/zbuildr.tif +0 -0
  53. data/doc/index.textile +69 -0
  54. data/doc/installing.textile +266 -0
  55. data/doc/languages.textile +459 -0
  56. data/doc/mailing_lists.textile +25 -0
  57. data/doc/more_stuff.textile +457 -0
  58. data/doc/packaging.textile +430 -0
  59. data/doc/preface.textile +54 -0
  60. data/doc/projects.textile +271 -0
  61. data/doc/quick_start.textile +210 -0
  62. data/doc/scripts/buildr-git.rb +512 -0
  63. data/doc/scripts/gitflow.rb +296 -0
  64. data/doc/scripts/install-jruby.sh +44 -0
  65. data/doc/scripts/install-linux.sh +72 -0
  66. data/doc/scripts/install-osx.sh +52 -0
  67. data/doc/settings_profiles.textile +280 -0
  68. data/doc/testing.textile +222 -0
  69. data/etc/KEYS +151 -0
  70. data/lib/buildr.rb +36 -0
  71. data/lib/buildr/core.rb +35 -0
  72. data/lib/buildr/core/application.rb +656 -0
  73. data/lib/buildr/core/build.rb +452 -0
  74. data/lib/buildr/core/checks.rb +254 -0
  75. data/lib/buildr/core/common.rb +150 -0
  76. data/lib/buildr/core/compile.rb +608 -0
  77. data/lib/buildr/core/environment.rb +129 -0
  78. data/lib/buildr/core/filter.rb +362 -0
  79. data/lib/buildr/core/generate.rb +195 -0
  80. data/lib/buildr/core/help.rb +119 -0
  81. data/lib/buildr/core/osx.rb +46 -0
  82. data/lib/buildr/core/progressbar.rb +156 -0
  83. data/lib/buildr/core/project.rb +866 -0
  84. data/lib/buildr/core/shell.rb +198 -0
  85. data/lib/buildr/core/test.rb +723 -0
  86. data/lib/buildr/core/transports.rb +559 -0
  87. data/lib/buildr/core/util.rb +449 -0
  88. data/lib/buildr/groovy.rb +19 -0
  89. data/lib/buildr/groovy/bdd.rb +106 -0
  90. data/lib/buildr/groovy/compiler.rb +138 -0
  91. data/lib/buildr/groovy/shell.rb +48 -0
  92. data/lib/buildr/ide.rb +19 -0
  93. data/lib/buildr/ide/eclipse.rb +334 -0
  94. data/lib/buildr/ide/eclipse/java.rb +53 -0
  95. data/lib/buildr/ide/eclipse/plugin.rb +68 -0
  96. data/lib/buildr/ide/eclipse/scala.rb +66 -0
  97. data/lib/buildr/ide/idea.ipr.template +300 -0
  98. data/lib/buildr/ide/idea.rb +190 -0
  99. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  100. data/lib/buildr/ide/idea7x.rb +212 -0
  101. data/lib/buildr/java.rb +23 -0
  102. data/lib/buildr/java/ant.rb +94 -0
  103. data/lib/buildr/java/bdd.rb +459 -0
  104. data/lib/buildr/java/cobertura.rb +274 -0
  105. data/lib/buildr/java/commands.rb +213 -0
  106. data/lib/buildr/java/compiler.rb +349 -0
  107. data/lib/buildr/java/deprecated.rb +141 -0
  108. data/lib/buildr/java/emma.rb +244 -0
  109. data/lib/buildr/java/jruby.rb +117 -0
  110. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  111. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  112. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +137 -0
  113. data/lib/buildr/java/packaging.rb +716 -0
  114. data/lib/buildr/java/pom.rb +174 -0
  115. data/lib/buildr/java/rjb.rb +155 -0
  116. data/lib/buildr/java/test_result.rb +353 -0
  117. data/lib/buildr/java/tests.rb +333 -0
  118. data/lib/buildr/java/version_requirement.rb +172 -0
  119. data/lib/buildr/packaging.rb +24 -0
  120. data/lib/buildr/packaging/archive.rb +488 -0
  121. data/lib/buildr/packaging/artifact.rb +749 -0
  122. data/lib/buildr/packaging/artifact_namespace.rb +972 -0
  123. data/lib/buildr/packaging/artifact_search.rb +140 -0
  124. data/lib/buildr/packaging/gems.rb +102 -0
  125. data/lib/buildr/packaging/package.rb +238 -0
  126. data/lib/buildr/packaging/tar.rb +186 -0
  127. data/lib/buildr/packaging/version_requirement.rb +172 -0
  128. data/lib/buildr/packaging/zip.rb +73 -0
  129. data/lib/buildr/packaging/ziptask.rb +316 -0
  130. data/lib/buildr/resources/buildr.icns +0 -0
  131. data/lib/buildr/scala.rb +25 -0
  132. data/lib/buildr/scala/bdd.rb +109 -0
  133. data/lib/buildr/scala/compiler.rb +195 -0
  134. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner$.class +0 -0
  135. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.class +0 -0
  136. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.scala +35 -0
  137. data/lib/buildr/scala/shell.rb +55 -0
  138. data/lib/buildr/scala/tests.rb +157 -0
  139. data/lib/buildr/shell.rb +180 -0
  140. data/rakelib/checks.rake +57 -0
  141. data/rakelib/doc.rake +92 -0
  142. data/rakelib/jekylltask.rb +120 -0
  143. data/rakelib/package.rake +73 -0
  144. data/rakelib/release.rake +149 -0
  145. data/rakelib/rspec.rake +73 -0
  146. data/rakelib/setup.rake +54 -0
  147. data/rakelib/stage.rake +213 -0
  148. data/rakelib/stage.rake~ +213 -0
  149. data/spec/addon/drb_spec.rb +328 -0
  150. data/spec/core/application_spec.rb +502 -0
  151. data/spec/core/build_spec.rb +677 -0
  152. data/spec/core/checks_spec.rb +519 -0
  153. data/spec/core/common_spec.rb +670 -0
  154. data/spec/core/compile_spec.rb +583 -0
  155. data/spec/core/extension_spec.rb +93 -0
  156. data/spec/core/generate_spec.rb +33 -0
  157. data/spec/core/project_spec.rb +762 -0
  158. data/spec/core/test_spec.rb +1098 -0
  159. data/spec/core/transport_spec.rb +537 -0
  160. data/spec/core/util_spec.rb +67 -0
  161. data/spec/groovy/bdd_spec.rb +80 -0
  162. data/spec/groovy/compiler_spec.rb +240 -0
  163. data/spec/ide/eclipse_spec.rb +501 -0
  164. data/spec/ide/idea7x_spec.rb +84 -0
  165. data/spec/java/ant_spec.rb +33 -0
  166. data/spec/java/bdd_spec.rb +382 -0
  167. data/spec/java/cobertura_spec.rb +85 -0
  168. data/spec/java/compiler_spec.rb +446 -0
  169. data/spec/java/emma_spec.rb +119 -0
  170. data/spec/java/java_spec.rb +124 -0
  171. data/spec/java/packaging_spec.rb +1134 -0
  172. data/spec/java/test_coverage_helper.rb +257 -0
  173. data/spec/java/tests_spec.rb +493 -0
  174. data/spec/packaging/archive_spec.rb +527 -0
  175. data/spec/packaging/artifact_namespace_spec.rb +654 -0
  176. data/spec/packaging/artifact_spec.rb +795 -0
  177. data/spec/packaging/packaging_helper.rb +63 -0
  178. data/spec/packaging/packaging_spec.rb +684 -0
  179. data/spec/sandbox.rb +142 -0
  180. data/spec/scala/bdd_spec.rb +119 -0
  181. data/spec/scala/compiler_spec.rb +284 -0
  182. data/spec/scala/scala.rb +38 -0
  183. data/spec/scala/tests_spec.rb +261 -0
  184. data/spec/spec_helpers.rb +340 -0
  185. data/spec/version_requirement_spec.rb +129 -0
  186. metadata +383 -0
@@ -0,0 +1,129 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+
17
+ module Buildr
18
+
19
+ # Collection of options for controlling Buildr.
20
+ class Options
21
+
22
+ # We use this to present environment variable as arrays.
23
+ class EnvArray < Array #:nodoc:
24
+
25
+ def initialize(name)
26
+ @name = name.upcase
27
+ replace((ENV[@name] || ENV[@name.downcase] || '').split(/\s*,\s*/).reject(&:empty?))
28
+ end
29
+
30
+ (Array.instance_methods - Object.instance_methods - Enumerable.instance_methods).sort.each do |method|
31
+ class_eval %{def #{method}(*args, &block) ; result = super ; write ; result ; end}
32
+ end
33
+
34
+ private
35
+
36
+ def write
37
+ ENV[@name.downcase] = nil
38
+ ENV[@name] = map(&:to_s).join(',')
39
+ end
40
+
41
+ end
42
+
43
+
44
+ # Wraps around the proxy environment variables:
45
+ # * :http -- HTTP_PROXY
46
+ # * :https -- HTTPS_PROXY
47
+ # * :exclude -- NO_PROXY
48
+ class Proxies
49
+
50
+ # Returns the HTTP_PROXY URL.
51
+ def http
52
+ ENV['HTTP_PROXY'] || ENV['http_proxy']
53
+ end
54
+
55
+ # Sets the HTTP_PROXY URL.
56
+ def http=(url)
57
+ ENV['http_proxy'] = nil
58
+ ENV['HTTP_PROXY'] = url
59
+ end
60
+
61
+ # Returns the HTTPS_PROXY URL.
62
+ def https
63
+ ENV['HTTPS_PROXY'] || ENV['https_proxy']
64
+ end
65
+
66
+ # Sets the HTTPS_PROXY URL.
67
+ def https=(url)
68
+ ENV['https_proxy'] = nil
69
+ ENV['HTTPS_PROXY'] = url
70
+ end
71
+
72
+ # Returns list of hosts to exclude from proxying (NO_PROXY).
73
+ def exclude
74
+ @exclude ||= EnvArray.new('NO_PROXY')
75
+ end
76
+
77
+ # Sets list of hosts to exclude from proxy (NO_PROXY). Accepts host name, array of names,
78
+ # or nil to clear the list.
79
+ def exclude=(url)
80
+ exclude.clear
81
+ exclude.concat [url].flatten if url
82
+ exclude
83
+ end
84
+
85
+ end
86
+
87
+ # :call-seq:
88
+ # proxy => options
89
+ #
90
+ # Returns the proxy options. Currently supported options are:
91
+ # * :http -- HTTP proxy for use when downloading.
92
+ # * :exclude -- Do not use proxy for these hosts/domains.
93
+ #
94
+ # For example:
95
+ # options.proxy.http = 'http://proxy.acme.com:8080'
96
+ # You can also set it using the environment variable HTTP_PROXY.
97
+ #
98
+ # You can exclude individual hosts from being proxied, or entire domains, for example:
99
+ # options.proxy.exclude = 'optimus'
100
+ # options.proxy.exclude = ['optimus', 'prime']
101
+ # options.proxy.exclude << '*.internal'
102
+ def proxy
103
+ @proxy ||= Proxies.new
104
+ end
105
+
106
+ end
107
+
108
+
109
+ class << self
110
+
111
+ # :call-seq:
112
+ # options => Options
113
+ #
114
+ # Returns the Buildr options. See Options.
115
+ def options
116
+ @options ||= Options.new
117
+ end
118
+
119
+ end
120
+
121
+ # :call-seq:
122
+ # options => Options
123
+ #
124
+ # Returns the Buildr options. See Options.
125
+ def options
126
+ Buildr.options
127
+ end
128
+
129
+ end
@@ -0,0 +1,362 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+
17
+ require 'erb'
18
+
19
+
20
+ module Buildr
21
+
22
+ # A filter knows how to copy files from one directory to another, applying mappings to the
23
+ # contents of these files.
24
+ #
25
+ # You can specify the mapping using a Hash, and it will map ${key} fields found in each source
26
+ # file into the appropriate value in the target file. For example:
27
+ #
28
+ # filter.using 'version'=>'1.2', 'build'=>Time.now
29
+ #
30
+ # will replace all occurrences of <tt>${version}</tt> with <tt>1.2</tt>, and <tt>${build}</tt>
31
+ # with the current date/time.
32
+ #
33
+ # You can also specify the mapping by passing a proc or a method, that will be called for
34
+ # each source file, with the file name and content, returning the modified content.
35
+ #
36
+ # Without any mapping, the filter simply copies files from the source directory into the target
37
+ # directory.
38
+ #
39
+ # A filter has one target directory, but you can specify any number of source directories,
40
+ # either when creating the filter or calling #from. Include/exclude patterns are specified
41
+ # relative to the source directories, so:
42
+ # filter.include '*.png'
43
+ # will only include PNG files from any of the source directories.
44
+ #
45
+ # See Buildr#filter.
46
+ class Filter
47
+
48
+ def initialize #:nodoc:
49
+ clear
50
+ end
51
+
52
+ # Returns the list of source directories (each being a file task).
53
+ attr_reader :sources
54
+
55
+ # :call-seq:
56
+ # clear => self
57
+ #
58
+ # Clear filter sources and include/exclude patterns
59
+ def clear
60
+ @include = []
61
+ @exclude = []
62
+ @sources = FileList[]
63
+ @mapper = Mapper.new
64
+ self
65
+ end
66
+
67
+ # :call-seq:
68
+ # from(*sources) => self
69
+ #
70
+ # Adds additional directories from which to copy resources.
71
+ #
72
+ # For example:
73
+ # filter.from('src').into('target').using('build'=>Time.now)
74
+ def from(*sources)
75
+ @sources |= sources.flatten.map { |dir| file(File.expand_path(dir.to_s)) }
76
+ self
77
+ end
78
+
79
+ # The target directory as a file task.
80
+ attr_reader :target
81
+
82
+ # :call-seq:
83
+ # into(dir) => self
84
+ #
85
+ # Sets the target directory into which files are copied and returns self.
86
+ #
87
+ # For example:
88
+ # filter.from('src').into('target').using('build'=>Time.now)
89
+ def into(dir)
90
+ @target = file(File.expand_path(dir.to_s)) { |task| run if target == task }
91
+ self
92
+ end
93
+
94
+ # :call-seq:
95
+ # include(*files) => self
96
+ #
97
+ # Specifies files to include and returns self. See FileList#include.
98
+ #
99
+ # By default all files are included. You can use this method to only include specific
100
+ # files from the source directory.
101
+ def include(*files)
102
+ @include += files
103
+ self
104
+ end
105
+ alias :add :include
106
+
107
+ # :call-seq:
108
+ # exclude(*files) => self
109
+ #
110
+ # Specifies files to exclude and returns self. See FileList#exclude.
111
+ def exclude(*files)
112
+ @exclude += files
113
+ self
114
+ end
115
+
116
+ # The mapping. See #using.
117
+ def mapping #:nodoc:
118
+ @mapper.config
119
+ end
120
+
121
+ # The mapper to use. See #using.
122
+ def mapper #:nodoc:
123
+ @mapper.mapper_type
124
+ end
125
+
126
+ # :call-seq:
127
+ # using(mapping) => self
128
+ # using { |file_name, contents| ... } => self
129
+ #
130
+ # Specifies the mapping to use and returns self.
131
+ #
132
+ # The most typical mapping uses a Hash, and the default mapping uses the Maven style, so
133
+ # <code>${key}</code> are mapped to the values. You can change that by passing a different
134
+ # format as the first argument. Currently supports:
135
+ # * :ant -- Map <code>@key@</code>.
136
+ # * :maven -- Map <code>${key}</code> (default).
137
+ # * :ruby -- Map <code>#{key}</code>.
138
+ # * :erb -- Map <code><%= key %></code>.
139
+ # * Regexp -- Maps the matched data (e.g. <code>/=(.*?)=/</code>
140
+ #
141
+ # For example:
142
+ # filter.using 'version'=>'1.2'
143
+ # Is the same as:
144
+ # filter.using :maven, 'version'=>'1.2'
145
+ #
146
+ # You can also pass a proc or method. It will be called with the file name and content,
147
+ # to return the mapped content.
148
+ #
149
+ # Without any mapping, all files are copied as is.
150
+ #
151
+ # To register new mapping type see the Mapper class.
152
+ def using(*args, &block)
153
+ @mapper.using(*args, &block)
154
+ self
155
+ end
156
+
157
+ # :call-seq:
158
+ # run => boolean
159
+ #
160
+ # Runs the filter.
161
+ def run
162
+ sources.each { |source| raise "Source directory #{source} doesn't exist" unless File.exist?(source.to_s) }
163
+ raise 'No target directory specified, where am I going to copy the files to?' if target.nil?
164
+
165
+ copy_map = sources.flatten.map(&:to_s).inject({}) do |map, source|
166
+ files = Util.recursive_with_dot_files(source).
167
+ map { |file| Util.relative_path(file, source) }.
168
+ select { |file| @include.empty? || @include.any? { |pattern| File.fnmatch(pattern, file) } }.
169
+ reject { |file| @exclude.any? { |pattern| File.fnmatch(pattern, file) } }
170
+ files.each do |file|
171
+ src, dest = File.expand_path(file, source), File.expand_path(file, target.to_s)
172
+ map[file] = src if !File.exist?(dest) || File.stat(src).mtime >= File.stat(dest).mtime
173
+ end
174
+ map
175
+ end
176
+
177
+ mkpath target.to_s
178
+ return false if copy_map.empty?
179
+
180
+ copy_map.each do |path, source|
181
+ dest = File.expand_path(path, target.to_s)
182
+ if File.directory?(source)
183
+ mkpath dest
184
+ else
185
+ mkpath File.dirname(dest)
186
+ if @mapper.mapper_type
187
+ mapped = @mapper.transform(File.open(source, 'rb') { |file| file.read }, path)
188
+ File.open(dest, 'wb') { |file| file.write mapped }
189
+ else # no mapping
190
+ cp source, dest
191
+ File.chmod(0664, dest)
192
+ end
193
+ end
194
+ end
195
+ touch target.to_s
196
+ true
197
+ end
198
+
199
+ # Returns the target directory.
200
+ def to_s
201
+ @target.to_s
202
+ end
203
+
204
+ # This class implements content replacement logic for Filter.
205
+ #
206
+ # To register a new template engine @:foo@, extend this class with a method like:
207
+ #
208
+ # def foo_transform(content, path = nil)
209
+ # # if this method yields a key, the value comes from the mapping hash
210
+ # content.gsub(/world/) { |str| yield :bar }
211
+ # end
212
+ #
213
+ # Then you can use :foo mapping type on a Filter
214
+ #
215
+ # filter.using :foo, :bar => :baz
216
+ #
217
+ # Or all by your own, simply
218
+ #
219
+ # Mapper.new(:foo, :bar => :baz).transform("Hello world") # => "Hello baz"
220
+ #
221
+ # You can handle configuration arguments by providing a @*_config@ method like:
222
+ #
223
+ # # The return value of this method is available with the :config accessor.
224
+ # def moo_config(*args, &block)
225
+ # raise ArgumentError, "Expected moo block" unless block_given?
226
+ # { :moos => args, :callback => block }
227
+ # end
228
+ #
229
+ # def moo_transform(content, path = nil)
230
+ # content.gsub(/moo+/i) do |str|
231
+ # moos = yield :moos # same than config[:moos]
232
+ # moo = moos[str.size - 3] || str
233
+ # config[:callback].call(moo)
234
+ # end
235
+ # end
236
+ #
237
+ # Usage for the @:moo@ mapper would be something like:
238
+ #
239
+ # mapper = Mapper.new(:moo, 'ooone', 'twoo') do |str|
240
+ # i = nil; str.capitalize.gsub(/\w/) { |s| s.send( (i = !i) ? 'upcase' : 'downcase' ) }
241
+ # end
242
+ # mapper.transform('Moo cow, mooo cows singing mooooo') # => 'OoOnE cow, TwOo cows singing MoOoOo'
243
+ class Mapper
244
+
245
+ attr_reader :mapper_type, :config
246
+
247
+ def initialize(*args, &block) #:nodoc:
248
+ using(*args, &block)
249
+ end
250
+
251
+ def using(*args, &block)
252
+ case args.first
253
+ when Hash # Maven hash mapping
254
+ using :maven, *args
255
+ when Binding # Erb binding
256
+ using :erb, *args
257
+ when Symbol # Mapping from a method
258
+ raise ArgumentError, "Unknown mapping type: #{args.first}" unless respond_to?("#{args.first}_transform", true)
259
+ configure(*args, &block)
260
+ when Regexp # Mapping using a regular expression
261
+ raise ArgumentError, 'Expected regular expression followed by mapping hash' unless args.size == 2 && Hash === args[1]
262
+ @mapper_type, @config = *args
263
+ else
264
+ unless args.empty? && block.nil?
265
+ raise ArgumentError, 'Expected proc, method or a block' if args.size > 1 || (args.first && block)
266
+ @mapper_type = :callback
267
+ config = args.first || block
268
+ raise ArgumentError, 'Expected proc, method or callable' unless config.respond_to?(:call)
269
+ @config = config
270
+ end
271
+ end
272
+ self
273
+ end
274
+
275
+ def transform(content, path = nil)
276
+ type = Regexp === mapper_type ? :regexp : mapper_type
277
+ raise ArgumentError, "Invalid mapper type: #{type.inspect}" unless respond_to?("#{type}_transform", true)
278
+ self.__send__("#{type}_transform", content, path) { |key| config[key] || config[key.to_s.to_sym] }
279
+ end
280
+
281
+ private
282
+ def configure(mapper_type, *args, &block)
283
+ configurer = method("#{mapper_type}_config") rescue nil
284
+ if configurer
285
+ @config = configurer.call(*args, &block)
286
+ else
287
+ raise ArgumentError, "Missing hash argument after :#{mapper_type}" unless args.size == 1 && Hash === args[0]
288
+ @config = args.first
289
+ end
290
+ @mapper_type = mapper_type
291
+ end
292
+
293
+ def maven_transform(content, path = nil)
294
+ content.gsub(/\$\{.*?\}/) { |str| yield(str[2..-2]) || str }
295
+ end
296
+
297
+ def ant_transform(content, path = nil)
298
+ content.gsub(/@.*?@/) { |str| yield(str[1..-2]) || str }
299
+ end
300
+
301
+ def ruby_transform(content, path = nil)
302
+ content.gsub(/#\{.*?\}/) { |str| yield(str[2..-2]) || str }
303
+ end
304
+
305
+ def regexp_transform(content, path = nil)
306
+ content.gsub(mapper_type) { |str| yield(str.scan(mapper_type).join) || str }
307
+ end
308
+
309
+ def callback_transform(content, path = nil)
310
+ config.call(path, content)
311
+ end
312
+
313
+ def erb_transform(content, path = nil)
314
+ case config
315
+ when Binding
316
+ bnd = config
317
+ when Hash
318
+ bnd = OpenStruct.new
319
+ table = config.inject({}) { |h, e| h[e.first.to_sym] = e.last; h }
320
+ bnd.instance_variable_set(:@table, table)
321
+ bnd = bnd.instance_eval { binding }
322
+ else
323
+ bnd = config.instance_eval { binding }
324
+ end
325
+ require 'erb'
326
+ ERB.new(content).result(bnd)
327
+ end
328
+
329
+ def erb_config(*args, &block)
330
+ if block_given?
331
+ raise ArgumentError, "Expected block or single argument, but both given." unless args.empty?
332
+ block
333
+ elsif args.size > 1
334
+ raise ArgumentError, "Expected block or single argument."
335
+ else
336
+ args.first
337
+ end
338
+ end
339
+
340
+ end # class Mapper
341
+
342
+ end
343
+
344
+ # :call-seq:
345
+ # filter(*source) => Filter
346
+ #
347
+ # Creates a filter that will copy files from the source directory(ies) into the target directory.
348
+ # You can extend the filter to modify files by mapping <tt>${key}</tt> into values in each
349
+ # of the copied files, and by including or excluding specific files.
350
+ #
351
+ # A filter is not a task, you must call the Filter#run method to execute it.
352
+ #
353
+ # For example, to copy all files from one directory to another:
354
+ # filter('src/files').into('target/classes').run
355
+ # To include only the text files, and replace each instance of <tt>${build}</tt> with the current
356
+ # date/time:
357
+ # filter('src/files').into('target/classes').include('*.txt').using('build'=>Time.now).run
358
+ def filter(*sources)
359
+ Filter.new.from(*sources)
360
+ end
361
+
362
+ end