buildr 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/java/compile.rb CHANGED
@@ -1,9 +1,32 @@
1
+ require "core/project"
2
+ require "core/build"
3
+ require "java/artifact"
4
+ require "java/java"
5
+ require "tasks/filter"
6
+
1
7
  module Buildr
2
8
  module Java
3
9
 
10
+ # Wraps Javac in a task that does all the heavy lifting.
11
+ #
12
+ # Accepts multiple source directories that are invoked as prerequisites before compilation.
13
+ # You can pass a task as a source directory, e.g. compile.from(apt).
14
+ #
15
+ # Likewise, classpath dependencies are invoked before compiling. All classpath dependencies
16
+ # are evaluated as #artifacts, so you can pass artifact specifications and even projects.
17
+ #
18
+ # Creates a file task for the target directory, so executing that task as a dependency will
19
+ # execute the compile task first.
20
+ #
21
+ # Compiler options are inherited form a parent task, e.g. the foo:bar:compile task inherits
22
+ # its options from the foo:compile task. Even if foo is an empty project that does not compile
23
+ # any classes itself, you can use it to set compile options for all its sub-projects.
24
+ #
25
+ # Normally, the project will take care of setting the source and target directory, and you
26
+ # only need to set options and classpath dependencies. See Project#compile.
4
27
  class CompileTask < Rake::Task
5
28
 
6
- # Compiler options, accessible from Compiler#options.
29
+ # Compiler options, accessible from CompileTask#options.
7
30
  #
8
31
  # Supported options are:
9
32
  # - warnings -- Generate warnings if true (opposite of -nowarn).
@@ -16,37 +39,44 @@ module Buildr
16
39
  # - other -- Array of options to pass to the Java compiler as is.
17
40
  #
18
41
  # For example:
19
- # options.warnings = true
20
- # options.source = options.target = "1.6"
42
+ # compile.options.warnings = true
43
+ # compile.options.source = options.target = "1.6"
21
44
  class Options
22
45
 
23
- include Attributes
46
+ include InheritedAttributes
24
47
 
25
48
  OPTIONS = [:warnings, :deprecation, :source, :target, :lint, :debug, :other]
26
49
 
27
50
  # Generate warnings (opposite of -nowarn).
51
+ attr_accessor :warnings
28
52
  inherited_attr :warnings
29
53
  # Output source locations where deprecated APIs are used.
54
+ attr_accessor :deprecation
30
55
  inherited_attr :deprecation
31
56
  # Provide source compatibility with specified release.
57
+ attr_accessor :source
32
58
  inherited_attr :source
33
59
  # Generate class files for specific VM version.
60
+ attr_accessor :target
34
61
  inherited_attr :target
35
62
  # Values to pass to Xlint: string or array. Use true to enable
36
63
  # Xlint with no values.
64
+ attr_accessor :lint
37
65
  inherited_attr :lint
38
66
  # Generate all debugging info.
67
+ attr_accessor :debug
39
68
  inherited_attr :debug
40
69
  # Array of arguments passed to the Java compiler as is.
70
+ attr_accessor :other
41
71
  inherited_attr :other
42
72
 
43
- def initialize(parent = nil)
73
+ def initialize(parent = nil) #:nodoc:
44
74
  @parent = parent
45
75
  end
46
76
 
47
- # :nodoc:
48
- attr_reader :parent
77
+ attr_reader :parent # :nodoc:
49
78
 
79
+ # Resets all the options.
50
80
  def clear()
51
81
  OPTIONS.each { |name| send "#{name}=", nil }
52
82
  end
@@ -79,7 +109,7 @@ module Buildr
79
109
  end
80
110
 
81
111
 
82
- def initialize(*args)
112
+ def initialize(*args) #:nodoc:
83
113
  super
84
114
  parent = Rake::Task["^compile"] if name[":"] # Only if in namespace
85
115
  if parent && parent.respond_to?(:options)
@@ -91,30 +121,36 @@ module Buildr
91
121
  @classpath = []
92
122
 
93
123
  enhance do |task|
94
- mkpath target, :verbose=>false
124
+ mkpath target.to_s, :verbose=>false
95
125
  Java.javac source_files.keys, :sourcepath=>sources.map(&:to_s).select { |source| File.directory?(source) }.uniq,
96
126
  :classpath=>classpath, :output=>target, :javac_args=>options.javac_args, :name=>task.name
97
127
  # By touching the target we let other tasks know we did something,
98
128
  # and also prevent recompiling again for classpath dependencies.
99
- touch target, :verbose=>false
129
+ touch target.to_s, :verbose=>false
100
130
  end
101
131
  end
102
132
 
103
133
  # Source directories and files to compile.
104
134
  attr_accessor :sources
105
135
 
136
+ # :call-seq:
137
+ # from(*sources) => self
138
+ #
106
139
  # Adds source directories and files to compile, and returns self.
107
140
  #
108
141
  # For example:
109
142
  # compile.from("src/java").into("classes").with("module1.jar")
110
- def from(*files)
111
- @sources |= files.flatten
143
+ def from(*sources)
144
+ @sources |= sources.flatten
112
145
  self
113
146
  end
114
147
 
115
148
  # Classpath dependencies.
116
149
  attr_accessor :classpath
117
150
 
151
+ # :call-seq:
152
+ # with(*artifacts) => self
153
+ #
118
154
  # Adds files and artifacts as classpath dependencies, and returns self.
119
155
  #
120
156
  # Calls #artifacts on the arguments, so you can pass artifact specifications,
@@ -122,31 +158,35 @@ module Buildr
122
158
  #
123
159
  # For example:
124
160
  # compile.with("module1.jar", "log4j:log4j:jar:1.0", project("foo"))
125
- def with(*files)
126
- @classpath |= artifacts(files.flatten).uniq
161
+ def with(*specs)
162
+ @classpath |= artifacts(specs.flatten).uniq
127
163
  self
128
164
  end
129
165
 
130
166
  # The target directory for the generated class files.
131
167
  attr_reader :target
132
168
 
169
+ # :call-seq:
170
+ # into(path) => self
171
+ #
133
172
  # Sets the target directory and returns self. This will also set the compile task
134
173
  # as a prerequisite to a file task on the target directory.
135
174
  #
136
175
  # For example:
137
176
  # compile(src_dir).into(target_dir).with(artifacts)
138
- def into(dir)
139
- dir = File.expand_path(dir)
140
- unless @target == dir
141
- @target = dir
142
- file(dir).enhance [self]
143
- end
177
+ # Both compile.invoke and file(target_dir).invoke will compile the source files.
178
+ def into(path)
179
+ path = File.expand_path(path.to_s)
180
+ @target = file(path).enhance([self]) unless @target && @target.to_s == path
144
181
  self
145
182
  end
146
183
 
147
184
  # Returns the compiler options.
148
185
  attr_reader :options
149
186
 
187
+ # :call-seq:
188
+ # using(options) => self
189
+ #
150
190
  # Sets the compiler options from a hash and returns self.
151
191
  #
152
192
  # For example:
@@ -156,30 +196,28 @@ module Buildr
156
196
  self
157
197
  end
158
198
 
159
- def timestamp()
199
+ def timestamp() #:nodoc:
160
200
  # If we compiled successfully, then the target directory reflects that.
161
201
  # If we didn't, see needed?
162
- @timestamp ||= (File.exist?(target) ? File.stat(target).mtime : Rake::EARLY)
202
+ target ? target.timestamp : Rake::EARLY
163
203
  end
164
204
 
165
- def needed?()
205
+ def needed?() #:nodoc:
166
206
  return false if source_files.empty?
167
- return true unless File.exist?(target)
207
+ return true unless File.exist?(target.to_s)
168
208
  return true if source_files.any? { |j, c| !File.exist?(c) || File.stat(j).mtime > File.stat(c).mtime }
169
209
  oldest = source_files.map { |j, c| File.stat(c).mtime }.min
170
210
  return classpath.any? { |path| application[path].timestamp > oldest }
171
211
  end
172
212
 
173
- def prerequisites()
213
+ def prerequisites() #:nodoc:
174
214
  super + classpath + sources
175
215
  end
176
216
 
177
- def invoke_prerequisites()
217
+ def invoke_prerequisites() #:nodoc:
178
218
  prerequisites.each { |n| application[n, @scope].invoke }
179
219
  end
180
220
 
181
- protected
182
-
183
221
  # Returns the files to compile. This list is derived from the list of sources,
184
222
  # expanding directories into files, and includes only source files that are
185
223
  # newer than the corresponding class file. Includes all files if one or more
@@ -187,12 +225,13 @@ module Buildr
187
225
  def source_files()
188
226
  @source_files ||= @sources.map(&:to_s).inject({}) do |map, source|
189
227
  raise "Compile task #{name} has source files, but no target directory" unless target
228
+ target_dir = target.to_s
190
229
  if File.directory?(source)
191
230
  base = Pathname.new(source)
192
- FileList[File.join(source, "**", "*.java")].
193
- each { |file| map[file] = File.join(target, Pathname.new(file).relative_path_from(base).to_s.ext(".class")) }
231
+ FileList["#{source}/**/*.java"].
232
+ each { |file| map[file] = File.join(target_dir, Pathname.new(file).relative_path_from(base).to_s.ext(".class")) }
194
233
  else
195
- map[source] = File.join(target, File.basename(source).ext(".class"))
234
+ map[source] = File.join(target_dir, File.basename(source).ext(".class"))
196
235
  end
197
236
  map
198
237
  end
@@ -200,73 +239,121 @@ module Buildr
200
239
 
201
240
  end
202
241
 
242
+
243
+ # The resources task is executed by the compile task to copy resource files over
244
+ # to the target directory. You can enhance this task in the normal way, but mostly
245
+ # you will use the task's filter.
246
+ #
247
+ # For example:
248
+ # resources.filter.using "Copyright"=>"Acme Inc, 2007"
249
+ class ResourcesTask < Rake::Task
250
+
251
+ # Returns the filter used to copy resources over. See Buildr::Filter.
252
+ attr_reader :filter
253
+
254
+ def initialize(*args) #:nodoc:
255
+ super
256
+ @filter = Buildr::filter
257
+ enhance { filter.run }
258
+ end
259
+
260
+ # :call-seq:
261
+ # include(*files) => self
262
+ #
263
+ # Includes the specified files in the filter and returns self.
264
+ def include(*files)
265
+ filter.include *files
266
+ self
267
+ end
268
+
269
+ # :call-seq:
270
+ # exclude(*files) => self
271
+ #
272
+ # Excludes the specified files in the filter and returns self.
273
+ def exclude(*files)
274
+ filter.exclude *files
275
+ self
276
+ end
277
+
278
+ def prerequisites() #:nodoc:
279
+ super + filter.sources
280
+ end
281
+
282
+ end
283
+
203
284
  end
204
285
 
205
286
 
206
287
  # Local task to execute the compile task of the current project.
207
288
  # This task is not itself a compile task.
208
289
  desc "Compile all projects"
209
- Project.local_task(task("compile"))
290
+ Project.local_task("compile") { |name| "Compiling #{name}" }
210
291
 
211
292
  class Project
212
293
 
213
- # The source directory. The default is "src".
214
- inherited_attr :src_dir, "src"
215
- # The Java source code directory. The default is <src_dir>/main/java.
216
- inherited_attr :java_src_dir do File.join(src_dir, "main", "java") end
217
- # The resources source directory. The default is <src_dir>/main/resources.
218
- inherited_attr :resources_dir do File.join(src_dir, "main", "resources") end
219
- # The target directory. The default is "target".
220
- inherited_attr :target_dir, "target"
221
- # The Java target directory. The default is <target_dir>/classes.
222
- inherited_attr :java_target_dir do File.join(target_dir, "classes") end
223
-
294
+ # :call-seq:
295
+ # prepare(*prereqs) => task
296
+ # prepare(*prereqs) { |task| .. } => task
297
+ #
224
298
  # The prepare task executes before the #compile task. Use it for pre-compilation
225
299
  # tasks, e.g. generating source code.
226
300
  #
227
301
  # This method returns the project's prepare task. It also accepts a list of
228
302
  # prerequisites and a block, used to enhance the prepare task.
229
303
  #
230
- # By default the prepare task will only generate the #target_dir directory.
231
- #
232
304
  # For example:
233
- # prepare "src/generated"
234
- # prepare { javacc.run }
235
- def prepare(*tasks, &block)
236
- task("prepare").enhance tasks, &block
305
+ # prepare { schema_to_java }
306
+ def prepare(*prereqs, &block)
307
+ task("prepare").enhance prereqs, &block
237
308
  end
238
309
 
310
+ # :call-seq:
311
+ # compile(*sources) => CompileTask
312
+ # compile(*sources) { |task| .. } => CompileTask
313
+ #
239
314
  # The compile task does what its name suggests. This method returns the project's
240
- # compile task. It also accepts a list of source directories and files to compile
241
- # (equivalent to calling Java::CompileTask#from on the task), and a block for any
315
+ # CompileTask. It also accepts a list of source directories and files to compile
316
+ # (equivalent to calling CompileTask#from on the task), and a block for any
242
317
  # post-compilation work.
243
318
  #
244
- # For more information, see Java::CompileTask.
245
- #
246
- # The compile task will pick all the source files in the #java_src_dir directory,
247
- # and unless specified, compile into the #java_target_dir directory. It will pick
319
+ # The compile task will pick all the source files in the src/main/java directory,
320
+ # and unless specified, compile them into the target/classes directory. It will pick
248
321
  # the default values for compiler options from the parent project's compile task.
249
322
  #
250
323
  # For example:
251
- # compile.options.source = "1.5"
252
- # compile("src").with("log4j:log4j:jar:1.2")
253
- # compile { backport(compile.target) }
324
+ # # Force target compatibility.
325
+ # compile.options.source = "1.6"
326
+ # # Include Apt-generated source files.
327
+ # compile.from apt
328
+ # # Include Log4J and the api sub-project artifacts.
329
+ # compile.with "log4j:log4j:jar:1.2", project("api")
330
+ # # Run the OpenJPA bytecode enhancer after compilation.
331
+ # compile { open_jpa_enhance }
332
+ #
333
+ # For more information, see Java::CompileTask.
254
334
  def compile(*sources, &block)
255
335
  task("compile").from(sources).enhance &block
256
336
  end
257
337
 
258
- # The resources task executes after compilation, and will copy resources files
338
+ # :call-seq:
339
+ # resources(*prereqs) => ResourcesTask
340
+ # resources(*prereqs) { |task| .. } => ResourcesTask
341
+ #
342
+ # The resources task is executed by the compile task to copy resources files
259
343
  # from the resource directory into the target directory.
260
344
  #
261
345
  # This method returns the project's resources task. It also accepts a list of
262
346
  # prerequisites and a block, used to enhance the resources task.
263
347
  #
264
- # By default the resources task copies files from the #resources_dir into the
265
- # same target directory as the #compile task.
348
+ # By default the resources task copies files from the src/main/resources into the
349
+ # same target directory as the #compile task. It does so using a filter that you
350
+ # can access by calling resources.filter (see Buildr::Filter).
266
351
  #
267
- # For more information, see Filter.
268
- def resources(*tasks, &block)
269
- task("resources").enhance tasks, &block
352
+ # For example:
353
+ # resources.filter.include "config.xml"
354
+ # resources.filter.using "Copyright"=>"Acme Inc, 2007"
355
+ def resources(*prereqs, &block)
356
+ task("resources").enhance prereqs, &block
270
357
  end
271
358
 
272
359
  end
@@ -274,26 +361,19 @@ module Buildr
274
361
  Project.on_define do |project|
275
362
  prepare = task("prepare")
276
363
  # Resources task is a filter.
277
- resources = FilterTask.define_task("resources")
364
+ resources = Java::ResourcesTask.define_task("resources")
365
+ project.path_to("src/main/resources").tap { |dir| resources.filter.include project.path_to(dir, "*") if File.exist?(dir) }
278
366
  # Compile task requires prepare and performs resources, if anything compiled.
279
- compile = Java::CompileTask.define_task("compile"=>prepare) { |task| resources.invoke }
367
+ compile = Java::CompileTask.define_task("compile"=>[prepare, resources]) { |task| project.resources.invoke }
368
+ project.path_to("src/main/java").tap { |dir| compile.from dir if File.exist?(dir) }
369
+ compile.into project.path_to("target/classes")
370
+ resources.filter.into project.compile.target
280
371
  project.recursive_task("compile")
372
+ project.clean { verbose(false) { rm_rf project.path_to("target") } }
281
373
 
282
374
  project.enhance do |project|
283
- # For convenience, have the prepare task generate the target directory.
284
- #directory project.path_to(:target_dir)
285
- #project.prepare.prerequisites.unshift project.path_to(:target_dir)
286
- # Use the source directory if exists, and set the target directory is not already set.
287
- project.compile.from project.path_to(:java_src_dir) if File.exist?(project.path_to(:java_src_dir))
288
- project.compile.into project.path_to(:java_target_dir) unless project.compile.target
289
- # Do the same for resources.
290
- project.resources.include project.path_to(:resources_dir, "*") if File.exists?(project.path_to(:resources_dir))
291
- project.resources.into project.compile.target unless project.resources.target
292
- # Now we know what to build/clean.
293
375
  project.build project.compile.target
294
- project.clean { verbose(false) { rm_rf project.path_to(:target_dir) } }
295
376
  end
296
-
297
377
  end
298
378
 
299
379
  end
data/lib/java/eclipse.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  require "pathname"
2
+ require "core/project"
3
+ require "java/artifact"
2
4
 
3
5
  module Buildr
4
6
 
5
7
  # Global task "eclipse" generates artifacts for all projects.
6
8
  desc "Generate Eclipse artifacts for all projects"
7
- Project.local_task task("eclipse"=>"artifacts")
9
+ Project.local_task "eclipse"=>"artifacts"
8
10
 
9
11
  Project.on_define do |project|
10
12
  eclipse = project.recursive_task("eclipse")
@@ -13,9 +15,12 @@ module Buildr
13
15
 
14
16
  # We need paths relative to the top project's base directory.
15
17
  root_path = lambda { |p| f = lambda { |p| p.parent ? f[p.parent] : p.base_dir } ; f[p] }[project]
16
- # We're guessing the Rakefile is there, but keep in mind it might not exist
17
- # (most test cases don't create it).
18
- sources = []
18
+ # We want the Eclipse files changed every time the Rakefile changes, but also anything loaded by
19
+ # the Rakefile (buildr.rb, separate file listing dependencies, etc), so we add anything required
20
+ # after the Rakefile. So which don't know where Buildr shows up exactly, ignore files that show
21
+ # in $LOADED_FEATURES that we cannot resolve.
22
+ sources = ($LOADED_FEATURES - Buildr.instance_eval("@loaded_features_to_ignore")).
23
+ map { |file| File.expand_path(file) }.select { |file| File.exist?(file) }
19
24
  sources << File.expand_path(Rake.application.rakefile, root_path) if Rake.application.rakefile
20
25
 
21
26
  # Only for projects that are Eclipse packagable.
@@ -25,9 +30,14 @@ module Buildr
25
30
  # The only thing we need to look for is a change in the Rakefile.
26
31
  file(project.path_to(".classpath")=>sources) do |task|
27
32
  puts "Writing #{task.name}" if verbose
28
-
33
+
29
34
  # Find a path relative to the project's root directory.
30
- relative = lambda { |path| Pathname.new(path).relative_path_from(Pathname.new(project.path_to)).to_s }
35
+ relative = lambda do |path|
36
+ msg = [:to_path, :to_str, :to_s].find { |msg| path.respond_to? msg }
37
+ path = path.__send__(msg)
38
+ Pathname.new(path).relative_path_from(Pathname.new(project.path_to)).to_s
39
+ end
40
+ m2repo = Buildr::Repositories.instance.local
31
41
 
32
42
  File.open(task.name, "w") do |file|
33
43
  xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
@@ -37,16 +47,21 @@ module Buildr
37
47
  internal, external = project.compile.classpath.map(&:to_s).
38
48
  map { |path| projects.detect { |prj| prj.packages.detect { |pkg| pkg.to_s == path } } || path }.
39
49
  partition { |path| path.is_a?(Project) }
50
+ vars, libs = external.partition { |path| path.to_s.index(m2repo) == 0 }
51
+ generated, libs = libs.partition { |path| path.to_s.index(project.path_to.to_s) == 0 }
52
+ xml.classpathentry :kind=>'con', :path=>'org.eclipse.jdt.launching.JRE_CONTAINER'
40
53
  # Collect all the classpaths, key is the kind, value is
41
54
  # string or array (or anything responding to to_a).
42
- { :src => project.compile.sources.map { |src| relative[src] },
43
- :output => relative[project.path_to(:java_target_dir)],
44
- :con => "org.eclipse.jdt.launching.JRE_CONTAINER",
45
- :lib => external.map(&:to_s)
55
+ { :src => project.compile.sources.map { |src| relative[src] } + generated.map { |src| relative[src] },
56
+ :output => relative[project.compile.target],
57
+ :lib => libs.map(&:to_s),
58
+ :var => vars.map { |path| path.to_s.sub(m2repo, 'M2_REPO') }
46
59
  }.each do |kind, paths|
47
- paths.to_a.each { |path| xml.classpathentry :kind=>kind, :path=>path }
60
+ paths.sort.uniq.each do |path|
61
+ xml.classpathentry :kind=>kind, :path=>path
62
+ end
48
63
  end
49
- internal.map(&:name).uniq.each do |prj_name|
64
+ internal.map(&:name).sort.uniq.each do |prj_name|
50
65
  xml.classpathentry :kind=>"src", :combineaccessrules=>"false", :path=>"/#{prj_name}"
51
66
  end
52
67
  end