buildr 1.2.5 → 1.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,23 @@
1
+ 1.2.6 (9/26/2007)
2
+ * Added: Option for setting environment name (-e) and attribute accessor (Buildr.environment). Default taken from BUILDR_ENV environment variable.
3
+ * Added: AAR packaging for Axis2 service archives (Alex Boisvert)
4
+ * Added: Environment variable for JUnit tests (test.using :environment=>).
5
+ * Added: tar method similar to zip method.
6
+ * Added: Experimental transitive method. Looks like artifacts, quacks like artifacts, but returns artifacts by the boat load. (Credit, Daniel Roop)
7
+ * Changed: Now accepting JAVA_OPTS in addition to JAVA_OPTIONS.
8
+ * Changed: TarTask is now based on ArchiveTask, same API as ZipTask.
9
+ * Changed: Javadoc array arguments now passed as multiple command line options (e.g. :link=>['foo', 'bar'] becomes --link foo --link bar). (Daniel Roop)
10
+ * Changed: Jetty task now uses SLF4J instead of commons-logging + log4j for better hot-swap capability and plugability (Alex Boisvert)
11
+ * Removed: Turns out --verbose command line option is useless. Removed.
12
+ * Fixed: Jetty task now uses WebAppContextClassLoader to support hot-swapping webapps (Alex Boisvert)
13
+ * Fixed: "release" task now works with SVN URLs ending with /branches/*/ (Alex Boisvert)
14
+ * Fixed: Resources not included in JAR/WAR unless there's a src/main/java directory (Olexandr Zakordonskyy).
15
+ * Fixed: Files starting with dot (e.g. .config) not copied over as resource files, and not included in ZIP (Olexandr Zakordonskyy).
16
+ * Fixed: Empty directories not copied over as resources (Olexandr Zakordonskyy).
17
+ * Fixed: JAVA_OPTS and test.options[:java_args] not passed to JUnit task (Staube).
18
+ * Fixed: archive.exclude doesn't work when including a directory using :from/:as option.
19
+ * Fixed: JUnit/TestNG no longer run inner classes as test classes (Mark Feeney).
20
+
1
21
  1.2.5 (8/13/2007)
2
22
  * Fixed: Buildr not finding buildfile in parent directory, or switching to parent directory.
3
23
  * Fixed: checks.rb:103: warning: multiple values for a block parameter (2 for 1)
data/Rakefile CHANGED
@@ -6,7 +6,6 @@ require "spec/rake/spectask"
6
6
 
7
7
  # Gem specification comes first, other tasks rely on it.
8
8
  spec = Gem::Specification.new do |spec|
9
-
10
9
  spec.name = "buildr"
11
10
  spec.version = File.read(__FILE__.pathmap("%d/lib/buildr.rb")).scan(/VERSION\s*=\s*(['"])(.*)\1/)[0][1]
12
11
  spec.author = "Assaf Arkin"
@@ -32,10 +31,10 @@ spec = Gem::Specification.new do |spec|
32
31
  spec.add_dependency "net-ssh", "= 1.1.2"
33
32
  spec.add_dependency "net-sftp", "= 1.1.0"
34
33
  spec.add_dependency "rubyzip", "= 0.9.1"
35
- spec.add_dependency "highline", "= 1.2.9"
34
+ spec.add_dependency "highline", "= 1.4.0"
36
35
  spec.add_dependency "rjb", "= 1.0.6"
37
36
  spec.add_dependency "Antwrap", "= 0.6.0"
38
- spec.add_dependency "rspec", "= 1.0.5"
37
+ spec.add_dependency "rspec", "= 1.0.8"
39
38
  spec.add_dependency "xml-simple", "= 1.0.11"
40
39
  spec.add_dependency "archive-tar-minitar", "= 0.5.1"
41
40
  end
@@ -171,8 +170,37 @@ namespace :upload do
171
170
  end
172
171
  end
173
172
 
173
+ namespace :release do
174
+ task :ready? do
175
+ require 'highline'
176
+ require 'highline/import'
177
+
178
+ puts "This version: #{spec.version}"
179
+ puts
180
+ puts "Top 4 lines form CHANGELOG:"
181
+ puts File.readlines("CHANGELOG")[0..3].map { |l| " #{l}" }
182
+ puts
183
+ ask("Top-entry in CHANGELOG file includes today's date?") =~ /yes/i or
184
+ fail "Please update CHANGELOG to include the right date"
185
+ end
186
+
187
+ task :post do
188
+ # Practical example of functional read but not comprehend code:
189
+ next_version = spec.version.to_ints.zip([0, 0, 1]).map { |a| a.inject(0) { |t,i| t + i } }.join(".")
190
+ puts "Updating lib/buildr.rb to next version number: #{next_version}"
191
+ buildr_rb = File.read(__FILE__.pathmap("%d/lib/buildr.rb")).
192
+ sub(/(VERSION\s*=\s*)(['"])(.*)\2/) { |line| "#{$1}#{$2}#{next_version}#{$2}" }
193
+ File.open(__FILE__.pathmap("%d/lib/buildr.rb"), "w") { |file| file.write buildr_rb }
194
+ puts "Adding entry to CHANGELOG"
195
+ changelog = File.read(__FILE__.pathmap("%d/CHANGELOG"))
196
+ File.open(__FILE__.pathmap("%d/CHANGELOG"), "w") { |file| file.write "#{next_version} (Pending)\n\n#{changelog}" }
197
+ end
198
+
199
+ task :meat=>["clobber", "svn:clean?", "test", "upload:packages", "upload:docs", "svn:tag"]
200
+ end
201
+
174
202
  desc "Upload release to RubyForge including docs, tag SVN"
175
- task :release=>[ "clobber", "svn:clean?", "test", "upload:packages", "upload:docs", "svn:tag" ]
203
+ task :release=>[ "release:ready?", "release:meat", "release:post" ]
176
204
 
177
205
 
178
206
 
@@ -24,7 +24,7 @@ require "builder"
24
24
 
25
25
 
26
26
  module Buildr
27
- VERSION = "1.2.5".freeze # unless const_defined?(:VERSION)
27
+ VERSION = "1.2.6".freeze # unless const_defined?(:VERSION)
28
28
  end
29
29
 
30
30
 
@@ -29,12 +29,15 @@ module Buildr
29
29
 
30
30
  # Which version of Jetty we're using by default (change with options.jetty.version).
31
31
  VERSION = "6.1.3"
32
-
32
+ SLF4J_VERSION = "1.4.3"
33
+
33
34
  # Libraries used by Jetty.
34
35
  REQUIRES = [ "org.mortbay.jetty:jetty:jar:#{VERSION}", "org.mortbay.jetty:jetty-util:jar:#{VERSION}",
35
- "org.mortbay.jetty:servlet-api-2.5:jar:#{VERSION}", "log4j:log4j:jar:1.2.13", "commons-logging:commons-logging:jar:1.1" ]
36
+ "org.mortbay.jetty:servlet-api-2.5:jar:#{VERSION}", "org.slf4j:slf4j-api:jar:#{SLF4J_VERSION}",
37
+ "org.slf4j:slf4j-simple:jar:#{SLF4J_VERSION}", "org.slf4j:jcl104-over-slf4j:jar:#{SLF4J_VERSION}" ]
38
+
36
39
  Java.rjb.onload { |rjb| rjb.classpath << REQUIRES << File.join(__DIR__, "jetty") }
37
-
40
+
38
41
  # Default URL for Jetty (change with options.jetty.url).
39
42
  URL = "http://localhost:8080"
40
43
 
@@ -72,6 +75,9 @@ module Buildr
72
75
  def start(sync = nil)
73
76
  begin
74
77
  Java.rjb do
78
+ puts "RJB classpath #{Java.rjb.classpath.inspect}"
79
+ props = Rjb::import('java.lang.System').getProperties
80
+ props.setProperty("log4j.configuration", "file:./log4j.properties")
75
81
  port = URI.parse(url).port
76
82
  puts "Starting Jetty at http://localhost:#{port}" if verbose
77
83
  jetty = Rjb::import("JettyWrapper").new(port)
@@ -5,6 +5,7 @@ import org.mortbay.jetty.handler.AbstractHandler;
5
5
  import org.mortbay.jetty.handler.ContextHandler;
6
6
  import org.mortbay.jetty.handler.ContextHandlerCollection;
7
7
  import org.mortbay.jetty.webapp.WebAppContext;
8
+ import org.mortbay.jetty.webapp.WebAppClassLoader;
8
9
 
9
10
  import javax.servlet.http.HttpServletRequest;
10
11
  import javax.servlet.http.HttpServletResponse;
@@ -74,6 +75,8 @@ public class JettyWrapper {
74
75
  context.setConfigurationClasses(new String[] {
75
76
  "org.mortbay.jetty.webapp.WebInfConfiguration",
76
77
  "org.mortbay.jetty.webapp.WebXmlConfiguration"});
78
+ context.setClassLoader(new WebAppClassLoader(context));
79
+
77
80
  _handlerColl.addHandler(context);
78
81
  context.start();
79
82
  _apps.put(path, context);
@@ -0,0 +1,368 @@
1
+ require "java/java"
2
+
3
+ # TODO List
4
+ # -Eclipse support
5
+ # -SUnit
6
+ # -Cleanup compiler options
7
+
8
+ module Buildr
9
+
10
+ module Scala
11
+ class << self
12
+ def scala_base
13
+ ENV["SCALA_HOME"] + "/share/scala"
14
+ end
15
+
16
+ def scala_lib
17
+ scala_lib = scala_base + "/lib/scala-library.jar"
18
+ end
19
+
20
+ def scalac(*args)
21
+ options = Hash === args.last ? args.pop : {}
22
+ rake_check_options options, :classpath, :sourcepath, :output, :scalac_args, :name
23
+
24
+ files = args.flatten.each { |f| f.invoke if f.respond_to?(:invoke) }.map(&:to_s).
25
+ collect { |arg| File.directory?(arg) ? FileList["#{arg}/**/*.scala"] : arg }.flatten
26
+ name = options[:name] || Dir.pwd
27
+ return if files.empty?
28
+
29
+ fail "Missing SCALA_HOME environment variable" unless ENV["SCALA_HOME"]
30
+ fail "Invalid SCALA_HOME environment variable" unless File.directory? ENV["SCALA_HOME"]
31
+
32
+ cmd_args = []
33
+ use_fsc = !(ENV["USE_FSC"] =~ /^(no|off|false)$/i)
34
+ classpath = classpath_from(options)
35
+ scala_cp = [ classpath, FileList["#{scala_base}/lib/*"] ].flatten.join(File::PATH_SEPARATOR)
36
+ cmd_args << "-cp" << scala_cp unless scala_cp.empty?
37
+ cmd_args << "-sourcepath" << options[:sourcepath].join(File::PATH_SEPARATOR) if options[:sourcepath]
38
+ cmd_args << "-d" << options[:output].to_s if options[:output]
39
+ cmd_args += options[:scalac_args].flatten if options[:scalac_args]
40
+ cmd_args += files
41
+ unless Rake.application.options.dryrun
42
+ puts "Compiling #{files.size} source files in #{name}" if verbose
43
+ puts (["scalac"] + cmd_args).join(" ") if Rake.application.options.trace
44
+ if use_fsc
45
+ system ([ENV["SCALA_HOME"]+"/bin/fsc"] + cmd_args).join(" ")
46
+ else
47
+ Java.rjb do |rjb|
48
+ rjb.import("scala.tools.nsc.Main").main(cmd_args) == 0 or
49
+ fail "Failed to compile, see errors above"
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ protected
56
+
57
+ # :call-seq:
58
+ # classpath_from(options) => files
59
+ #
60
+ # Extracts the classpath from the options, expands it by calling artifacts, invokes
61
+ # each of the artifacts and returns an array of paths.
62
+ def classpath_from(options)
63
+ classpath = (options[:classpath] || []).collect
64
+ Buildr.artifacts(classpath).each { |t| t.invoke if t.respond_to?(:invoke) }.map(&:to_s)
65
+ end
66
+ end # Scala << self
67
+
68
+
69
+ # !! This is mostly a copy-paste Buildr:Java:CompileTask !!
70
+ #
71
+ # Wraps Scalac in a task that does all the heavy lifting.
72
+ #
73
+ # Accepts multiple source directories that are invoked as prerequisites before compilation.
74
+ # You can pass a task as a source directory, e.g. compile.from(apt).
75
+ #
76
+ # Likewise, classpath dependencies are invoked before compiling. All classpath dependencies
77
+ # are evaluated as #artifacts, so you can pass artifact specifications and even projects.
78
+ #
79
+ # Creates a file task for the target directory, so executing that task as a dependency will
80
+ # execute the compile task first.
81
+ #
82
+ # Compiler options are inherited form a parent task, e.g. the foo:bar:compile task inherits
83
+ # its options from the foo:compile task. Even if foo is an empty project that does not compile
84
+ # any classes itself, you can use it to set compile options for all its sub-projects.
85
+ #
86
+ # Normally, the project will take care of setting the source and target directory, and you
87
+ # only need to set options and classpath dependencies. See Project#compile.
88
+ class ScalaCompilerTask < Rake::Task
89
+
90
+ # Compiler options, accessible from CompileTask#options.
91
+ #
92
+ # Supported options are:
93
+ # - warnings -- Generate warnings if true (opposite of -nowarn).
94
+ # - deprecation -- Output source locations where deprecated APIs are used.
95
+ # - source -- Source compatibility with specified release.
96
+ # - target -- Class file compatibility with specified release.
97
+ # - lint -- Value to pass to xlint argument. Use true to enable default lint
98
+ # options, or pass a specific setting as string or array of strings.
99
+ # - debug -- Generate debugging info.
100
+ # - other -- Array of options to pass to the Scalac compiler as is.
101
+ #
102
+ # For example:
103
+ # compile.options.warnings = true
104
+ # compile.options.source = options.target = "1.6"
105
+ class Options
106
+
107
+ include InheritedAttributes
108
+
109
+ OPTIONS = [:warnings, :deprecation, :source, :target, :lint, :debug, :other]
110
+
111
+ # Generate warnings (opposite of -nowarn).
112
+ attr_accessor :warnings
113
+ inherited_attr(:warnings) { verbose }
114
+ # Output source locations where deprecated APIs are used.
115
+ attr_accessor :deprecation
116
+ inherited_attr :deprecation, false
117
+ # Provide source compatibility with specified release.
118
+ attr_accessor :source
119
+ inherited_attr :source
120
+ # Generate class files for specific VM version.
121
+ attr_accessor :target
122
+ inherited_attr :target
123
+ # Values to pass to Xlint: string or array. Use true to enable
124
+ # Xlint with no values.
125
+ attr_accessor :lint
126
+ inherited_attr :lint, false
127
+ # Generate all debugging info.
128
+ attr_accessor :debug
129
+ inherited_attr(:debug) { Buildr.options.debug }
130
+ # Array of arguments passed to the Scalac compiler as is.
131
+ attr_accessor :other
132
+ inherited_attr :other
133
+
134
+ def initialize(parent = nil) #:nodoc:
135
+ @parent = parent
136
+ end
137
+
138
+ attr_reader :parent # :nodoc:
139
+
140
+ # Resets all the options.
141
+ def clear()
142
+ OPTIONS.each { |name| send "#{name}=", nil }
143
+ end
144
+
145
+ def to_s() #:nodoc:
146
+ OPTIONS.inject({}){ |hash, name| hash[name] = send(name) ; hash }.reject{ |name,value| value.nil? }.inspect
147
+ end
148
+
149
+ # Returns Scalac command line arguments from the set of options.
150
+ def scalac_args()
151
+ args = []
152
+ args << "-nowarn" unless warnings
153
+ args << "-verbose" if Rake.application.options.trace
154
+ args << "-g" if debug
155
+ args << "-deprecation" if deprecation
156
+ args << "-source" << source.to_s if source
157
+ args << "-target" << target.to_s if target
158
+ case lint
159
+ when Array
160
+ args << "-Xlint:#{lint.join(',')}"
161
+ when String
162
+ args << "-Xlint:#{lint}"
163
+ when true
164
+ args << "-Xlint"
165
+ end
166
+ args.concat(other.to_a) if other
167
+ args
168
+ end
169
+
170
+ end
171
+
172
+
173
+ def initialize(*args) #:nodoc:
174
+ super
175
+ parent = Rake::Task["^scalac"] if name[":"] # Only if in namespace
176
+ if parent && parent.respond_to?(:options)
177
+ @options = Options.new(parent.options)
178
+ else
179
+ @options = Options.new
180
+ end
181
+ @sources = []
182
+ @classpath = []
183
+
184
+ enhance do |task|
185
+ mkpath target.to_s, :verbose=>false
186
+ Scala.scalac source_files.keys, :sourcepath=>sources.map(&:to_s).select { |source| File.directory?(source) }.uniq,
187
+ :classpath=>classpath, :output=>target, :scalac_args=>options.scalac_args, :name=>task.name
188
+ # By touching the target we let other tasks know we did something,
189
+ # and also prevent recompiling again for classpath dependencies.
190
+ touch target.to_s, :verbose=>false
191
+ end
192
+ end
193
+
194
+ # Source directories and files to compile.
195
+ attr_accessor :sources
196
+
197
+ # :call-seq:
198
+ # from(*sources) => self
199
+ #
200
+ # Adds source directories and files to compile, and returns self.
201
+ #
202
+ # For example:
203
+ # compile.from("src/scala").into("classes").with("module1.jar")
204
+ def from(*sources)
205
+ @sources |= sources.flatten
206
+ self
207
+ end
208
+
209
+ # Classpath dependencies.
210
+ attr_accessor :classpath
211
+
212
+ # :call-seq:
213
+ # with(*artifacts) => self
214
+ #
215
+ # Adds files and artifacts as classpath dependencies, and returns self.
216
+ #
217
+ # Calls #artifacts on the arguments, so you can pass artifact specifications,
218
+ # tasks, projects, etc. Use this rather than setting the classpath directly.
219
+ #
220
+ # For example:
221
+ # compile.with("module1.jar", "log4j:log4j:jar:1.0", project("foo"))
222
+ def with(*specs)
223
+ @classpath |= Buildr.artifacts(specs.flatten).uniq
224
+ self
225
+ end
226
+
227
+ # The target directory for the generated class files.
228
+ attr_reader :target
229
+
230
+ # :call-seq:
231
+ # into(path) => self
232
+ #
233
+ # Sets the target directory and returns self. This will also set the compile task
234
+ # as a prerequisite to a file task on the target directory.
235
+ #
236
+ # For example:
237
+ # compile(src_dir).into(target_dir).with(artifacts)
238
+ # Both compile.invoke and file(target_dir).invoke will compile the source files.
239
+ def into(path)
240
+ path = File.expand_path(path.to_s)
241
+ @target = file(path).enhance([self]) unless @target && @target.to_s == path
242
+ self
243
+ end
244
+
245
+ # Returns the compiler options.
246
+ attr_reader :options
247
+
248
+ # :call-seq:
249
+ # using(options) => self
250
+ #
251
+ # Sets the compiler options from a hash and returns self.
252
+ #
253
+ # For example:
254
+ # compile.using(:warnings=>true, :source=>"1.5")
255
+ def using(*args)
256
+ args.pop.each { |key, value| options.send "#{key}=", value } if Hash === args.last
257
+ args.each { |key| options.send "#{key}=", value = true }
258
+ self
259
+ end
260
+
261
+ def timestamp() #:nodoc:
262
+ # If we compiled successfully, then the target directory reflects that.
263
+ # If we didn't, see needed?
264
+ target ? target.timestamp : Rake::EARLY
265
+ end
266
+
267
+ def needed?() #:nodoc:
268
+ return false if source_files.empty?
269
+ return true unless File.exist?(target.to_s)
270
+ return true if source_files.any? { |j, c| !File.exist?(c) || File.stat(j).mtime > File.stat(c).mtime }
271
+ oldest = source_files.map { |j, c| File.stat(c).mtime }.min
272
+ return classpath.any? { |path| application[path].timestamp > oldest }
273
+ end
274
+
275
+ def prerequisites() #:nodoc:
276
+ super + classpath + sources
277
+ end
278
+
279
+ def invoke_prerequisites() #:nodoc:
280
+ prerequisites.each { |n| application[n, @scope].invoke }
281
+ end
282
+
283
+ # Returns the files to compile. This list is derived from the list of sources,
284
+ # expanding directories into files, and includes only source files that are
285
+ # newer than the corresponding class file. Includes all files if one or more
286
+ # classpath dependency has been updated.
287
+ def source_files()
288
+ @source_files ||= @sources.map(&:to_s).inject({}) do |map, source|
289
+ raise "Compile task #{name} has source files, but no target directory" unless target
290
+ target_dir = target.to_s
291
+ if File.directory?(source)
292
+ base = Pathname.new(source)
293
+ FileList["#{source}/**/*.scala"].
294
+ each { |file| map[file] = File.join(target_dir, Pathname.new(file).relative_path_from(base).to_s.ext(".class")) }
295
+ else
296
+ map[source] = File.join(target_dir, File.basename(source).ext(".class"))
297
+ end
298
+ map
299
+ end
300
+ end
301
+
302
+ def scala_lib
303
+ Scala.scala_lib
304
+ end
305
+ end # ScalaCompilerTask
306
+
307
+ end # Scala
308
+
309
+ # Local task to execute the Scalac compile task of the current project.
310
+ # This task is not itself a compile task.
311
+ desc "Compile all scalac projects"
312
+ Project.local_task("scalac") { |name| "Compiling scala sources for #{name}" }
313
+
314
+ class Project
315
+
316
+ # :call-seq:
317
+ # compile(*sources) => CompileTask
318
+ # compile(*sources) { |task| .. } => CompileTask
319
+ #
320
+ # The compile task does what its name suggests. This method returns the project's
321
+ # CompileTask. It also accepts a list of source directories and files to compile
322
+ # (equivalent to calling CompileTask#from on the task), and a block for any
323
+ # post-compilation work.
324
+ #
325
+ # The compile task will pick all the source files in the src/main/scala directory,
326
+ # and unless specified, compile them into the target/classes directory. It will pick
327
+ # the default values for compiler options from the parent project's compile task.
328
+ #
329
+ # For example:
330
+ # # Force target compatibility.
331
+ # compile.options.source = "1.6"
332
+ # # Include Apt-generated source files.
333
+ # compile.from apt
334
+ # # Include Log4J and the api sub-project artifacts.
335
+ # compile.with "log4j:log4j:jar:1.2", project("api")
336
+ # # Run the OpenJPA bytecode enhancer after compilation.
337
+ # compile { open_jpa_enhance }
338
+ #
339
+ # For more information, see Scala::ScalaCompilerTask.
340
+ def scalac(*sources, &block)
341
+ task("scalac").from(sources).enhance &block
342
+ end
343
+
344
+ end # Project
345
+
346
+ Project.on_define do |project|
347
+ # Scalac runs after compile task (and therefore, after "prepare" and "resources")
348
+ scalac = Scala::ScalaCompilerTask.define_task("scalac"=>[task("compile")])
349
+ project.path_to("src/main/scala").tap { |dir| scalac.from dir if File.exist?(dir) }
350
+ scalac.into project.path_to(:target, "classes")
351
+ project.recursive_task("scalac")
352
+
353
+ project.enhance do |project|
354
+ # This comes last because the target path may change.
355
+ project.packages.each do |p|
356
+ p.with scalac.target if p.type == :jar
357
+ p.classes = scalac.target if p.type == :war
358
+ end
359
+ # Work-in-progress
360
+ #project.task("eclipse").classpathContainers 'ch.epfl.lamp.sdt.launching.SCALA_CONTAINER'
361
+
362
+ project.build project.scalac.target
363
+ project.clean { verbose(false) { rm_rf project.scalac.target.to_s } }
364
+ end
365
+ end
366
+
367
+ end # Buildr
368
+