buildr 0.18.0 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
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