assaf-buildr 1.3.3

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 (163) hide show
  1. data/CHANGELOG +887 -0
  2. data/DISCLAIMER +7 -0
  3. data/LICENSE +176 -0
  4. data/NOTICE +26 -0
  5. data/README.rdoc +146 -0
  6. data/Rakefile +62 -0
  7. data/_buildr +38 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/cobertura.rb +236 -0
  10. data/addon/buildr/emma.rb +238 -0
  11. data/addon/buildr/hibernate.rb +142 -0
  12. data/addon/buildr/javacc.rb +85 -0
  13. data/addon/buildr/jdepend.rb +60 -0
  14. data/addon/buildr/jetty.rb +248 -0
  15. data/addon/buildr/jibx.rb +86 -0
  16. data/addon/buildr/nailgun.rb +817 -0
  17. data/addon/buildr/openjpa.rb +90 -0
  18. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  19. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  20. data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
  21. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  22. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  23. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  25. data/addon/buildr/xmlbeans.rb +93 -0
  26. data/bin/buildr +28 -0
  27. data/buildr.buildfile +53 -0
  28. data/buildr.gemspec +58 -0
  29. data/doc/css/default.css +228 -0
  30. data/doc/css/print.css +100 -0
  31. data/doc/css/syntax.css +52 -0
  32. data/doc/images/apache-incubator-logo.png +0 -0
  33. data/doc/images/buildr-hires.png +0 -0
  34. data/doc/images/buildr.png +0 -0
  35. data/doc/images/favicon.png +0 -0
  36. data/doc/images/growl-icon.tiff +0 -0
  37. data/doc/images/note.png +0 -0
  38. data/doc/images/project-structure.png +0 -0
  39. data/doc/images/tip.png +0 -0
  40. data/doc/images/zbuildr.tif +0 -0
  41. data/doc/pages/artifacts.textile +207 -0
  42. data/doc/pages/building.textile +240 -0
  43. data/doc/pages/contributing.textile +208 -0
  44. data/doc/pages/download.textile +62 -0
  45. data/doc/pages/extending.textile +175 -0
  46. data/doc/pages/getting_started.textile +273 -0
  47. data/doc/pages/index.textile +42 -0
  48. data/doc/pages/languages.textile +407 -0
  49. data/doc/pages/mailing_lists.textile +17 -0
  50. data/doc/pages/more_stuff.textile +286 -0
  51. data/doc/pages/packaging.textile +427 -0
  52. data/doc/pages/projects.textile +274 -0
  53. data/doc/pages/recipes.textile +103 -0
  54. data/doc/pages/settings_profiles.textile +274 -0
  55. data/doc/pages/testing.textile +212 -0
  56. data/doc/pages/troubleshooting.textile +103 -0
  57. data/doc/pages/whats_new.textile +323 -0
  58. data/doc/print.haml +51 -0
  59. data/doc/print.toc.yaml +29 -0
  60. data/doc/scripts/buildr-git.rb +412 -0
  61. data/doc/scripts/install-jruby.sh +44 -0
  62. data/doc/scripts/install-linux.sh +64 -0
  63. data/doc/scripts/install-osx.sh +52 -0
  64. data/doc/site.haml +56 -0
  65. data/doc/site.toc.yaml +47 -0
  66. data/etc/KEYS +151 -0
  67. data/etc/git-svn-authors +16 -0
  68. data/lib/buildr.rb +35 -0
  69. data/lib/buildr/core.rb +27 -0
  70. data/lib/buildr/core/application.rb +489 -0
  71. data/lib/buildr/core/application_cli.rb +139 -0
  72. data/lib/buildr/core/build.rb +311 -0
  73. data/lib/buildr/core/checks.rb +382 -0
  74. data/lib/buildr/core/common.rb +154 -0
  75. data/lib/buildr/core/compile.rb +596 -0
  76. data/lib/buildr/core/environment.rb +120 -0
  77. data/lib/buildr/core/filter.rb +362 -0
  78. data/lib/buildr/core/generate.rb +195 -0
  79. data/lib/buildr/core/help.rb +118 -0
  80. data/lib/buildr/core/progressbar.rb +156 -0
  81. data/lib/buildr/core/project.rb +892 -0
  82. data/lib/buildr/core/test.rb +715 -0
  83. data/lib/buildr/core/transports.rb +558 -0
  84. data/lib/buildr/core/util.rb +289 -0
  85. data/lib/buildr/groovy.rb +18 -0
  86. data/lib/buildr/groovy/bdd.rb +105 -0
  87. data/lib/buildr/groovy/compiler.rb +138 -0
  88. data/lib/buildr/ide.rb +19 -0
  89. data/lib/buildr/ide/eclipse.rb +212 -0
  90. data/lib/buildr/ide/idea.ipr.template +300 -0
  91. data/lib/buildr/ide/idea.rb +189 -0
  92. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  93. data/lib/buildr/ide/idea7x.rb +210 -0
  94. data/lib/buildr/java.rb +23 -0
  95. data/lib/buildr/java/ant.rb +92 -0
  96. data/lib/buildr/java/bdd.rb +449 -0
  97. data/lib/buildr/java/commands.rb +211 -0
  98. data/lib/buildr/java/compiler.rb +348 -0
  99. data/lib/buildr/java/deprecated.rb +141 -0
  100. data/lib/buildr/java/jruby.rb +117 -0
  101. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  102. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  103. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +119 -0
  104. data/lib/buildr/java/packaging.rb +713 -0
  105. data/lib/buildr/java/pom.rb +178 -0
  106. data/lib/buildr/java/rjb.rb +155 -0
  107. data/lib/buildr/java/test_result.rb +308 -0
  108. data/lib/buildr/java/tests.rb +324 -0
  109. data/lib/buildr/java/version_requirement.rb +172 -0
  110. data/lib/buildr/packaging.rb +21 -0
  111. data/lib/buildr/packaging/artifact.rb +730 -0
  112. data/lib/buildr/packaging/artifact_namespace.rb +972 -0
  113. data/lib/buildr/packaging/artifact_search.rb +140 -0
  114. data/lib/buildr/packaging/gems.rb +102 -0
  115. data/lib/buildr/packaging/package.rb +233 -0
  116. data/lib/buildr/packaging/tar.rb +104 -0
  117. data/lib/buildr/packaging/zip.rb +722 -0
  118. data/lib/buildr/resources/buildr.icns +0 -0
  119. data/lib/buildr/scala.rb +19 -0
  120. data/lib/buildr/scala/compiler.rb +109 -0
  121. data/lib/buildr/scala/tests.rb +203 -0
  122. data/rakelib/apache.rake +191 -0
  123. data/rakelib/changelog.rake +57 -0
  124. data/rakelib/doc.rake +103 -0
  125. data/rakelib/package.rake +73 -0
  126. data/rakelib/release.rake +65 -0
  127. data/rakelib/rspec.rake +83 -0
  128. data/rakelib/rubyforge.rake +53 -0
  129. data/rakelib/scm.rake +49 -0
  130. data/rakelib/setup.rake +86 -0
  131. data/rakelib/stage.rake +48 -0
  132. data/spec/addon/cobertura_spec.rb +77 -0
  133. data/spec/addon/emma_spec.rb +120 -0
  134. data/spec/addon/test_coverage_spec.rb +255 -0
  135. data/spec/core/application_spec.rb +412 -0
  136. data/spec/core/artifact_namespace_spec.rb +646 -0
  137. data/spec/core/build_spec.rb +415 -0
  138. data/spec/core/checks_spec.rb +537 -0
  139. data/spec/core/common_spec.rb +664 -0
  140. data/spec/core/compile_spec.rb +566 -0
  141. data/spec/core/generate_spec.rb +33 -0
  142. data/spec/core/project_spec.rb +754 -0
  143. data/spec/core/test_spec.rb +1091 -0
  144. data/spec/core/transport_spec.rb +500 -0
  145. data/spec/groovy/bdd_spec.rb +80 -0
  146. data/spec/groovy/compiler_spec.rb +239 -0
  147. data/spec/ide/eclipse_spec.rb +243 -0
  148. data/spec/java/ant.rb +28 -0
  149. data/spec/java/bdd_spec.rb +358 -0
  150. data/spec/java/compiler_spec.rb +446 -0
  151. data/spec/java/java_spec.rb +88 -0
  152. data/spec/java/packaging_spec.rb +1103 -0
  153. data/spec/java/tests_spec.rb +466 -0
  154. data/spec/packaging/archive_spec.rb +503 -0
  155. data/spec/packaging/artifact_spec.rb +754 -0
  156. data/spec/packaging/packaging_helper.rb +63 -0
  157. data/spec/packaging/packaging_spec.rb +589 -0
  158. data/spec/sandbox.rb +137 -0
  159. data/spec/scala/compiler_spec.rb +228 -0
  160. data/spec/scala/tests_spec.rb +215 -0
  161. data/spec/spec_helpers.rb +304 -0
  162. data/spec/version_requirement_spec.rb +123 -0
  163. metadata +369 -0
@@ -0,0 +1,154 @@
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 'rake'
18
+ require 'tempfile'
19
+ require 'open-uri'
20
+ $LOADED_FEATURES << 'rubygems/open-uri.rb' # avoid loading rubygems' open-uri
21
+ require 'buildr/core/util'
22
+ require 'buildr/core/transports'
23
+
24
+
25
+ module Buildr
26
+
27
+ # :call-seq:
28
+ # struct(hash) => Struct
29
+ #
30
+ # Convenience method for creating an anonymous Struct.
31
+ #
32
+ # For example:
33
+ # COMMONS = struct(
34
+ # :collections =>'commons-collections:commons-collections:jar:3.1',
35
+ # :lang =>'commons-lang:commons-lang:jar:2.1',
36
+ # :logging =>'commons-logging:commons-logging:jar:1.0.3',
37
+ # )
38
+ #
39
+ # compile.with COMMONS.logging
40
+ def struct(hash)
41
+ Struct.new(nil, *hash.keys).new(*hash.values)
42
+ end
43
+
44
+ # :call-seq:
45
+ # write(name, content)
46
+ # write(name) { ... }
47
+ #
48
+ # Write the contents into a file. The second form calls the block and writes the result.
49
+ #
50
+ # For example:
51
+ # write 'TIMESTAMP', Time.now
52
+ # write('TIMESTAMP') { Time.now }
53
+ #
54
+ # Yields to the block before writing the file, so you can chain read and write together.
55
+ # For example:
56
+ # write('README') { read('README').sub("${build}", Time.now) }
57
+ def write(name, content = nil)
58
+ mkpath File.dirname(name), :verbose=>false
59
+ content = yield if block_given?
60
+ File.open(name.to_s, 'wb') { |file| file.write content.to_s }
61
+ content.to_s
62
+ end
63
+
64
+ # :call-seq:
65
+ # read(name) => string
66
+ # read(name) { |string| ... } => result
67
+ #
68
+ # Reads and returns the contents of a file. The second form yields to the block and returns
69
+ # the result of the block.
70
+ #
71
+ # For example:
72
+ # puts read('README')
73
+ # read('README') { |text| puts text }
74
+ def read(name)
75
+ contents = File.open(name.to_s) { |f| f.read }
76
+ if block_given?
77
+ yield contents
78
+ else
79
+ contents
80
+ end
81
+ end
82
+
83
+ # :call-seq:
84
+ # download(url_or_uri) => task
85
+ # download(path=>url_or_uri) =>task
86
+ #
87
+ # Create a task that will download a file from a URL.
88
+ #
89
+ # Takes a single argument, a hash with one pair. The key is the file being
90
+ # created, the value if the URL to download. The task executes only if the
91
+ # file does not exist; the URL is not checked for updates.
92
+ #
93
+ # The task will show download progress on the console; if there are MD5/SHA1
94
+ # checksums on the server it will verify the download before saving it.
95
+ #
96
+ # For example:
97
+ # download 'image.jpg'=>'http://example.com/theme/image.jpg'
98
+ def download(args)
99
+ args = URI.parse(args) if String === args
100
+ if URI === args
101
+ # Given only a download URL, download into a temporary file.
102
+ # You can infer the file from task name.
103
+ temp = Tempfile.open(File.basename(args.to_s))
104
+ file(temp.path).tap do |task|
105
+ # Since temporary file exists, force a download.
106
+ class << task ; def needed? ; true ; end ; end
107
+ task.sources << args
108
+ task.enhance { args.download temp }
109
+ end
110
+ else
111
+ # Download to a file created by the task.
112
+ fail unless args.keys.size == 1
113
+ uri = URI.parse(args.values.first.to_s)
114
+ file(args.keys.first.to_s).tap do |task|
115
+ task.sources << uri
116
+ task.enhance { uri.download task.name }
117
+ end
118
+ end
119
+
120
+ end
121
+
122
+ # A file task that concatenates all its prerequisites to create a new file.
123
+ #
124
+ # For example:
125
+ # concat("master.sql"=>["users.sql", "orders.sql", reports.sql"]
126
+ #
127
+ # See also Buildr#concat.
128
+ class ConcatTask < Rake::FileTask
129
+ def initialize(*args) #:nodoc:
130
+ super
131
+ enhance do |task|
132
+ content = prerequisites.inject("") do |content, prereq|
133
+ content << File.read(prereq.to_s) if File.exists?(prereq) && !File.directory?(prereq)
134
+ content
135
+ end
136
+ File.open(task.name, "wb") { |file| file.write content }
137
+ end
138
+ end
139
+ end
140
+
141
+ # :call-seq:
142
+ # concat(target=>files) => task
143
+ #
144
+ # Creates and returns a file task that concatenates all its prerequisites to create
145
+ # a new file. See #ConcatTask.
146
+ #
147
+ # For example:
148
+ # concat("master.sql"=>["users.sql", "orders.sql", reports.sql"]
149
+ def concat(args)
150
+ file, arg_names, deps = Buildr.application.resolve_args([args])
151
+ ConcatTask.define_task(File.expand_path(file)=>deps)
152
+ end
153
+
154
+ end
@@ -0,0 +1,596 @@
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 'buildr/core/common'
18
+
19
+
20
+ module Buildr
21
+
22
+ # The underlying compiler used by CompileTask.
23
+ # To add a new compiler, extend Compiler::Base and add your compiler using:
24
+ # Buildr::Compiler.add MyCompiler
25
+ module Compiler
26
+
27
+ class << self
28
+
29
+ # Returns true if the specified compiler exists.
30
+ def has?(name)
31
+ compilers.any? { |compiler| compiler.to_sym == name.to_sym }
32
+ end
33
+
34
+ # Select a compiler by its name.
35
+ def select(name)
36
+ compilers.detect { |compiler| compiler.to_sym == name.to_sym }
37
+ end
38
+
39
+ # Adds a compiler to the list of supported compiler.
40
+ #
41
+ # For example:
42
+ # Buildr::Compiler << Buildr::Javac
43
+ def add(compiler)
44
+ @compilers ||= []
45
+ @compilers |= [compiler]
46
+ end
47
+ alias :<< :add
48
+
49
+ # Returns a list of available compilers.
50
+ def compilers
51
+ @compilers ||= []
52
+ end
53
+
54
+ end
55
+
56
+ # Base class for all compilers, with common functionality. Extend and over-ride as you see fit
57
+ # (see Javac as an example).
58
+ class Base #:nodoc:
59
+
60
+ class << self
61
+
62
+ # The compiler's identifier (e.g. :javac). Inferred from the class name.
63
+ def to_sym
64
+ @symbol ||= name.split('::').last.downcase.to_sym
65
+ end
66
+
67
+ # The compiled language (e.g. :java).
68
+ attr_reader :language
69
+ # Source directories to use if none were specified (e.g. 'java'). Defaults to #language.
70
+ attr_reader :sources
71
+ # Extension for source files (e.g. 'java'). Defaults to language.
72
+ attr_reader :source_ext
73
+ # The target path (e.g. 'classes')
74
+ attr_reader :target
75
+ # Extension for target files (e.g. 'class').
76
+ attr_reader :target_ext
77
+ # The default packaging type (e.g. :jar).
78
+ attr_reader :packaging
79
+
80
+ # Returns true if this compiler applies to any source code found in the listed source
81
+ # directories. For example, Javac returns true if any of the source directories contains
82
+ # a .java file. The default implementation looks to see if there are any files in the
83
+ # specified path with the extension #source_ext.
84
+ def applies_to?(project, task)
85
+ paths = task.sources + [sources].flatten.map { |src| Array(project.path_to(:source, task.usage, src.to_sym)) }
86
+ paths.flatten!
87
+ ext_glob = Array(source_ext).join(',')
88
+ paths.any? { |path| !Dir["#{path}/**/*.{#{ext_glob}}"].empty? }
89
+ end
90
+
91
+ # Implementations can use this method to specify various compiler attributes.
92
+ # For example:
93
+ # specify :language=>:java, :target=>'classes', :target_ext=>'class', :packaging=>:jar
94
+ def specify(attrs)
95
+ attrs[:sources] ||= attrs[:language].to_s
96
+ attrs[:source_ext] ||= attrs[:language].to_s
97
+ attrs.each { |name, value| instance_variable_set("@#{name}", value) }
98
+ end
99
+
100
+ # Returns additional dependencies required by this language. For example, since the
101
+ # test framework picks on these, you can use the JUnit framework with Scala.
102
+ # Defaults to obtaining a list of artifact specifications from the REQUIRES constant.
103
+ def dependencies
104
+ []
105
+ end
106
+
107
+ end
108
+
109
+ # Construct a new compiler with the specified options. Note that options may
110
+ # change before the compiler is run.
111
+ def initialize(project, options)
112
+ @project = project
113
+ @options = options
114
+ end
115
+
116
+ # Options for this compiler.
117
+ attr_reader :options
118
+
119
+ # Determines if the compiler needs to run by checking if the target files exist,
120
+ # and if any source files or dependencies are newer than corresponding target files.
121
+ def needed?(sources, target, dependencies)
122
+ map = compile_map(sources, target)
123
+ return false if map.empty?
124
+ return true unless File.exist?(target.to_s)
125
+ source_files_not_yet_compiled = map.select { |source, target| !File.exist?(target) }
126
+ trace "Compile needed because source file #{source_files_not_yet_compiled[0][0]} has no corresponding #{source_files_not_yet_compiled[0][1]}" unless source_files_not_yet_compiled.empty?
127
+ return true if map.any? { |source, target| !File.exist?(target) || File.stat(source).mtime > File.stat(target).mtime }
128
+ oldest = map.map { |source, target| File.stat(target).mtime }.min
129
+ return dependencies.any? { |path| file(path).timestamp > oldest }
130
+ end
131
+
132
+ # Compile all files lists in sources (files and directories) into target using the
133
+ # specified dependencies.
134
+ def compile(sources, target, dependencies)
135
+ raise 'Not implemented'
136
+ end
137
+
138
+ # Returns additional dependencies required by this language. For example, since the
139
+ # test framework picks on these, you can use the JUnit framework with Scala.
140
+ def dependencies
141
+ self.class.dependencies
142
+ end
143
+
144
+ protected
145
+
146
+ # Use this to complain about CompileTask options not supported by this compiler.
147
+ #
148
+ # For example:
149
+ # def compile(files, task)
150
+ # check_options task, OPTIONS
151
+ # . . .
152
+ # end
153
+ def check_options(options, *supported)
154
+ unsupported = options.to_hash.keys - supported.flatten
155
+ raise ArgumentError, "No such option: #{unsupported.join(' ')}" unless unsupported.empty?
156
+ end
157
+
158
+ # Expands a list of source directories/files into a list of files that have the #source_ext extension.
159
+ def files_from_sources(sources)
160
+ ext_glob = Array(self.class.source_ext).join(',')
161
+ sources.flatten.map { |source| File.directory?(source) ? FileList["#{source}/**/*.{#{ext_glob}}"] : source }.
162
+ flatten.reject { |file| File.directory?(file) }.map { |file| File.expand_path(file) }.uniq
163
+ end
164
+
165
+ # The compile map is a hash that associates source files with target files based
166
+ # on a list of source directories and target directory. The compile task uses this
167
+ # to determine if there are source files to compile, and which source files to compile.
168
+ # The default method maps all files in the source directories with #source_ext into
169
+ # paths in the target directory with #target_ext (e.g. 'source/foo.java'=>'target/foo.class').
170
+ def compile_map(sources, target)
171
+ target_ext = self.class.target_ext
172
+ ext_glob = Array(self.class.source_ext).join(',')
173
+ sources.flatten.map{|f| File.expand_path(f)}.inject({}) do |map, source|
174
+ if File.directory?(source)
175
+ FileList["#{source}/**/*.{#{ext_glob}}"].reject { |file| File.directory?(file) }.
176
+ each { |file| map[file] = File.join(target, Util.relative_path(file, source).ext(target_ext)) }
177
+ else
178
+ map[source] = target # File.join(target, File.basename(source).ext(target_ext))
179
+ end
180
+ map
181
+ end
182
+ end
183
+
184
+ end
185
+
186
+ end
187
+
188
+
189
+ # Compile task.
190
+ #
191
+ # Attempts to determine which compiler to use based on the project layout, for example,
192
+ # uses the Javac compiler if it finds any .java files in src/main/java. You can also
193
+ # select the compiler explicitly:
194
+ # compile.using(:scalac)
195
+ #
196
+ # Accepts multiple source directories that are invoked as prerequisites before compilation.
197
+ # You can pass a task as a source directory:
198
+ # compile.from(apt)
199
+ #
200
+ # Likewise, dependencies are invoked before compiling. All dependencies are evaluated as
201
+ # #artifacts, so you can pass artifact specifications and even projects:
202
+ # compile.with('module1.jar', 'log4j:log4j:jar:1.0', project('foo'))
203
+ #
204
+ # Creates a file task for the target directory, so executing that task as a dependency will
205
+ # execute the compile task first.
206
+ #
207
+ # Compiler options are inherited form a parent task, e.g. the foo:bar:compile task inherits
208
+ # its options from the foo:compile task. Even if foo is an empty project that does not compile
209
+ # any classes itself, you can use it to set compile options for all its sub-projects.
210
+ #
211
+ # Normally, the project will take care of setting the source and target directory, and you
212
+ # only need to set options and dependencies. See Project#compile.
213
+ class CompileTask < Rake::Task
214
+
215
+ def initialize(*args) #:nodoc:
216
+ super
217
+ parent_task = Project.parent_task(name)
218
+ inherit = lambda { |hash, key| parent_task.options[key] } if parent_task.respond_to?(:options)
219
+ @options = OpenObject.new &inherit
220
+ @sources = FileList[]
221
+ @dependencies = FileList[]
222
+
223
+ enhance do |task|
224
+ unless sources.empty?
225
+ raise 'No compiler selected and can\'t determine which compiler to use' unless compiler
226
+ raise 'No target directory specified' unless target
227
+ mkpath target.to_s, :verbose=>false
228
+ info "Compiling #{task.name.gsub(/:[^:]*$/, '')} into #{target.to_s}"
229
+ @compiler.compile(sources.map(&:to_s), target.to_s, dependencies.map(&:to_s))
230
+ # By touching the target we let other tasks know we did something,
231
+ # and also prevent recompiling again for dependencies.
232
+ touch target.to_s, :verbose=>false
233
+ end
234
+ end
235
+ end
236
+
237
+ # Source directories.
238
+ attr_accessor :sources
239
+
240
+ # :call-seq:
241
+ # from(*sources) => self
242
+ #
243
+ # Adds source directories and files to compile, and returns self.
244
+ #
245
+ # For example:
246
+ # compile.from('src/java').into('classes').with('module1.jar')
247
+ def from(*sources)
248
+ @sources |= sources.flatten
249
+ guess_compiler if @compiler.nil? && sources.flatten.any? { |source| File.exist?(source) }
250
+ self
251
+ end
252
+
253
+ # *Deprecated*: Use dependencies instead.
254
+ def classpath
255
+ Buildr.application.deprecated 'Use dependencies instead.'
256
+ dependencies
257
+ end
258
+
259
+ # *Deprecated*: Use dependencies= instead.
260
+ def classpath=(artifacts)
261
+ Buildr.application.deprecated 'Use dependencies= instead.'
262
+ self.dependencies = artifacts
263
+ end
264
+
265
+ # Compilation dependencies.
266
+ attr_accessor :dependencies
267
+
268
+ # :call-seq:
269
+ # with(*artifacts) => self
270
+ #
271
+ # Adds files and artifacts as dependencies, and returns self.
272
+ #
273
+ # Calls #artifacts on the arguments, so you can pass artifact specifications,
274
+ # tasks, projects, etc. Use this rather than setting the dependencies array directly.
275
+ #
276
+ # For example:
277
+ # compile.with('module1.jar', 'log4j:log4j:jar:1.0', project('foo'))
278
+ def with(*specs)
279
+ @dependencies |= Buildr.artifacts(specs.flatten).uniq
280
+ self
281
+ end
282
+
283
+ # The target directory for the compiled code.
284
+ attr_reader :target
285
+
286
+ # :call-seq:
287
+ # into(path) => self
288
+ #
289
+ # Sets the target directory and returns self. This will also set the compile task
290
+ # as a prerequisite to a file task on the target directory.
291
+ #
292
+ # For example:
293
+ # compile(src_dir).into(target_dir).with(artifacts)
294
+ # Both compile.invoke and file(target_dir).invoke will compile the source files.
295
+ def into(path)
296
+ @target = file(path.to_s).enhance([self]) unless @target.to_s == path.to_s
297
+ self
298
+ end
299
+
300
+ # Returns the compiler options.
301
+ attr_reader :options
302
+
303
+ # :call-seq:
304
+ # using(options) => self
305
+ #
306
+ # Sets the compiler options from a hash and returns self. Can also be used to
307
+ # select the compiler.
308
+ #
309
+ # For example:
310
+ # compile.using(:warnings=>true, :source=>'1.5')
311
+ # compile.using(:scala)
312
+ def using(*args)
313
+ args.pop.each { |key, value| options.send "#{key}=", value } if Hash === args.last
314
+ self.compiler = args.pop until args.empty?
315
+ self
316
+ end
317
+
318
+ # Returns the compiler if known. The compiler is either automatically selected
319
+ # based on existing source directories (e.g. src/main/java), or by requesting
320
+ # a specific compiler (see #using).
321
+ def compiler
322
+ guess_compiler unless @compiler
323
+ @compiler && @compiler.class.to_sym
324
+ end
325
+
326
+ # Returns the compiled language, if known. See also #compiler.
327
+ def language
328
+ compiler && @compiler.class.language
329
+ end
330
+
331
+ # Returns the default packaging type for this compiler, if known.
332
+ def packaging
333
+ compiler && @compiler.class.packaging
334
+ end
335
+
336
+ def timestamp #:nodoc:
337
+ # If we compiled successfully, then the target directory reflects that.
338
+ # If we didn't, see needed?
339
+ target ? target.timestamp : Rake::EARLY
340
+ end
341
+
342
+ # The project this task belongs to.
343
+ attr_reader :project
344
+
345
+ # The usage, one of :main or :test.
346
+ attr_reader :usage
347
+
348
+ protected
349
+
350
+ # Selects which compiler to use.
351
+ def compiler=(name) #:nodoc:
352
+ cls = Compiler.select(name) or raise ArgumentError, "No #{name} compiler available. Did you install it?"
353
+ return self if cls === @compiler
354
+ raise "#{compiler} compiler already selected for this project" if @compiler
355
+ @compiler = cls.new(project, options)
356
+ from Array(cls.sources).map { |path| project.path_to(:source, usage, path) }.
357
+ select { |path| File.exist?(path) } if sources.empty?
358
+ into project.path_to(:target, usage, cls.target) unless target
359
+ with Array(@compiler.dependencies)
360
+ self
361
+ end
362
+
363
+ # Associates this task with project and particular usage (:main, :test).
364
+ def associate_with(project, usage) #:nodoc:
365
+ @project, @usage = project, usage
366
+ guess_compiler
367
+ end
368
+
369
+ # Try to guess if we have a compiler to match source files.
370
+ def guess_compiler #:nodoc:
371
+ candidate = Compiler.compilers.detect { |cls| cls.applies_to?(project, self) }
372
+ self.compiler = candidate if candidate
373
+ end
374
+
375
+ private
376
+
377
+ def needed? #:nodoc:
378
+ return false if sources.empty?
379
+ # Fail during invoke.
380
+ return true unless @compiler && target
381
+ return @compiler.needed?(sources.map(&:to_s), target.to_s, dependencies.map(&:to_s))
382
+ end
383
+
384
+ def invoke_prerequisites(args, chain) #:nodoc:
385
+ @sources = Array(@sources).map(&:to_s).uniq
386
+ @dependencies = FileList[@dependencies.uniq]
387
+ @prerequisites |= @dependencies + @sources
388
+ super
389
+ end
390
+
391
+ end
392
+
393
+
394
+ # The resources task is executed by the compile task to copy resource files over
395
+ # to the target directory. You can enhance this task in the normal way, but mostly
396
+ # you will use the task's filter.
397
+ #
398
+ # For example:
399
+ # resources.filter.using 'Copyright'=>'Acme Inc, 2007'
400
+ class ResourcesTask < Rake::Task
401
+
402
+ # Returns the filter used to copy resources over. See Buildr::Filter.
403
+ attr_reader :filter
404
+
405
+ def initialize(*args) #:nodoc:
406
+ super
407
+ @filter = Buildr::Filter.new
408
+ @filter.using Buildr.settings.profile['filter'] if Hash === Buildr.settings.profile['filter']
409
+ enhance do
410
+ filter.run if target
411
+ end
412
+ end
413
+
414
+ # :call-seq:
415
+ # include(*files) => self
416
+ #
417
+ # Includes the specified files in the filter and returns self.
418
+ def include(*files)
419
+ filter.include *files
420
+ self
421
+ end
422
+
423
+ # :call-seq:
424
+ # exclude(*files) => self
425
+ #
426
+ # Excludes the specified files in the filter and returns self.
427
+ def exclude(*files)
428
+ filter.exclude *files
429
+ self
430
+ end
431
+
432
+ # :call-seq:
433
+ # from(*sources) => self
434
+ #
435
+ # Adds additional directories from which to copy resources.
436
+ #
437
+ # For example:
438
+ # resources.from _('src/etc')
439
+ def from(*sources)
440
+ filter.from *sources
441
+ self
442
+ end
443
+
444
+ # Returns the list of source directories (each being a file task).
445
+ def sources
446
+ filter.sources
447
+ end
448
+
449
+ # :call-seq:
450
+ # target => task
451
+ #
452
+ # Returns the filter's target directory as a file task.
453
+ def target
454
+ filter.into @project.path_to(:target, @usage, :resources) unless filter.target || sources.empty?
455
+ filter.target
456
+ end
457
+
458
+ def prerequisites #:nodoc:
459
+ super + filter.sources.flatten
460
+ end
461
+
462
+ protected
463
+
464
+ # Associates this task with project and particular usage (:main, :test).
465
+ def associate_with(project, usage) #:nodoc:
466
+ @project, @usage = project, usage
467
+ end
468
+
469
+ end
470
+
471
+
472
+ # Methods added to Project for compiling, handling of resources and generating source documentation.
473
+ module Compile
474
+
475
+ include Extension
476
+
477
+ first_time do
478
+ desc 'Compile all projects'
479
+ Project.local_task('compile') { |name| "Compiling #{name}" }
480
+ end
481
+
482
+ before_define do |project|
483
+ resources = ResourcesTask.define_task('resources')
484
+ resources.send :associate_with, project, :main
485
+ project.path_to(:source, :main, :resources).tap { |dir| resources.from dir if File.exist?(dir) }
486
+
487
+ compile = CompileTask.define_task('compile'=>resources)
488
+ compile.send :associate_with, project, :main
489
+ project.recursive_task('compile')
490
+ end
491
+
492
+ after_define do |project|
493
+ # TODO: Is this necessary?
494
+ #if project.resources.target
495
+ # file project.resources.target.to_s=>project.resources do |task|
496
+ # mkpath task.name, :verbose=>false
497
+ # end
498
+ #end
499
+ if project.compile.target
500
+ # This comes last because the target path is set inside the project definition.
501
+ project.build project.compile.target
502
+ project.clean do
503
+ rm_rf project.compile.target.to_s, :verbose=>false
504
+ end
505
+ end
506
+ end
507
+
508
+
509
+ # :call-seq:
510
+ # compile(*sources) => CompileTask
511
+ # compile(*sources) { |task| .. } => CompileTask
512
+ #
513
+ # The compile task does what its name suggests. This method returns the project's
514
+ # CompileTask. It also accepts a list of source directories and files to compile
515
+ # (equivalent to calling CompileTask#from on the task), and a block for any
516
+ # post-compilation work.
517
+ #
518
+ # The compile task attempts to guess which compiler to use. For example, if it finds
519
+ # any Java files in the src/main/java directory, it will use the Java compiler and
520
+ # create class files in the target/classes directory.
521
+ #
522
+ # You can also configure it yourself by telling it which compiler to use, pointing
523
+ # it as source directories and chooing a different target directory.
524
+ #
525
+ # For example:
526
+ # # Include Log4J and the api sub-project artifacts.
527
+ # compile.with 'log4j:log4j:jar:1.2', project('api')
528
+ # # Include Apt-generated source files.
529
+ # compile.from apt
530
+ # # For JavaC, force target compatibility.
531
+ # compile.options.source = '1.6'
532
+ # # Run the OpenJPA bytecode enhancer after compilation.
533
+ # compile { open_jpa_enhance }
534
+ # # Pick a given compiler.
535
+ # compile.using(:scalac).from('src/scala')
536
+ #
537
+ # For more information, see CompileTask.
538
+ def compile(*sources, &block)
539
+ task('compile').from(sources).enhance &block
540
+ end
541
+
542
+ # :call-seq:
543
+ # resources(*prereqs) => ResourcesTask
544
+ # resources(*prereqs) { |task| .. } => ResourcesTask
545
+ #
546
+ # The resources task is executed by the compile task to copy resources files
547
+ # from the resource directory into the target directory. By default the resources
548
+ # task copies files from the src/main/resources into the target/resources directory.
549
+ #
550
+ # This method returns the project's resources task. It also accepts a list of
551
+ # prerequisites and a block, used to enhance the resources task.
552
+ #
553
+ # Resources files are copied and filtered (see Buildr::Filter for more information).
554
+ # The default filter uses the profile properties for the current environment.
555
+ #
556
+ # For example:
557
+ # resources.from _('src/etc')
558
+ # resources.filter.using 'Copyright'=>'Acme Inc, 2007'
559
+ #
560
+ # Or in your profiles.yaml file:
561
+ # common:
562
+ # Copyright: Acme Inc, 2007
563
+ def resources(*prereqs, &block)
564
+ task('resources').enhance prereqs, &block
565
+ end
566
+
567
+ end
568
+
569
+
570
+ class Options
571
+
572
+ # Returns the debug option (environment variable DEBUG).
573
+ def debug
574
+ (ENV['DEBUG'] || ENV['debug']) !~ /(no|off|false)/
575
+ end
576
+
577
+ # Sets the debug option (environment variable DEBUG).
578
+ #
579
+ # You can turn this option off directly, or by setting the environment variable
580
+ # DEBUG to +no+. For example:
581
+ # buildr build DEBUG=no
582
+ #
583
+ # The release tasks runs a build with <tt>DEBUG=no</tt>.
584
+ def debug=(flag)
585
+ ENV['debug'] = nil
586
+ ENV['DEBUG'] = flag.to_s
587
+ end
588
+
589
+ end
590
+
591
+ end
592
+
593
+
594
+ class Buildr::Project
595
+ include Buildr::Compile
596
+ end