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/openjpa.rb CHANGED
@@ -1,51 +1,63 @@
1
- module Buildr
2
-
3
- module OpenJPA
4
-
5
- VERSION = "0.9.7-incubating-SNAPSHOT"
6
-
7
- REQUIRES = [ "org.apache.openjpa:openjpa-all:jar:#{VERSION}",
8
- "commons-collections:commons-collections:jar:3.1",
9
- "commons-dbcp:commons-dbcp:jar:1.2.1",
10
- "commons-lang:commons-lang:jar:2.1",
11
- "commons-pool:commons-pool:jar:1.2",
12
- "javax.persistence:persistence-api:jar:1.0",
13
- "org.apache.geronimo.specs:geronimo-j2ee-connector_1.5_spec:jar:1.0",
14
- "org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0",
15
- "net.sourceforge.serp:serp:jar:1.11.0" ]
16
-
17
- OPTIONS = [ :verbose, :noop, :cp, :classpath, :properties ]
18
-
19
- def self.enhance(options)
20
- options[:verbose] ||= Rake.application.options.trace || false
21
- fu_check_options options, *OPTIONS + [:output]
22
-
23
- runtool options.merge(:class=>"org.apache.openjpa.enhance.PCEnhancer", :name=>"Enhancer",
24
- :args=>{ "-p"=>options[:properties], "-d"=>options[:output] },
25
- :classpath=>options[:classpath] + [options[:output]])
26
- end
1
+ require "java/java"
27
2
 
28
- def self.mapping_tool(options)
29
- options[:verbose] ||= Rake.application.options.trace || false
30
- fu_check_options options, *OPTIONS + [:action, :sql]
31
-
32
- runtool options.merge(:class=>"org.apache.openjpa.jdbc.meta.MappingTool", :name=>"Mapping Tool",
33
- :args=>{ "-p"=>options[:properties], "-sql"=>options[:sql], "-sa"=>options[:action] })
34
- end
35
-
36
- protected
37
-
38
- def self.runtool(options)
39
- args = [options[:class]] + options[:args].select { |n, v| v }.map { |n, v| [ n, v ] }.flatten
40
- args << { :classpath=>requires + (options[:classpath] || []),
41
- :name=>"OpenJPA #{options[:name]}", :verbose=>options[:verbose] }
42
- java *args
43
- end
3
+ module Buildr
4
+ module Java
5
+ module OpenJPA
6
+
7
+ VERSION = "0.9.7-incubating-SNAPSHOT"
8
+
9
+ REQUIRES = [ "org.apache.openjpa:openjpa-all:jar:#{VERSION}",
10
+ "commons-collections:commons-collections:jar:3.1",
11
+ "commons-dbcp:commons-dbcp:jar:1.2.1",
12
+ "commons-lang:commons-lang:jar:2.1",
13
+ "commons-pool:commons-pool:jar:1.2",
14
+ "javax.persistence:persistence-api:jar:1.0",
15
+ "org.apache.geronimo.specs:geronimo-j2ee-connector_1.5_spec:jar:1.0",
16
+ "org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0",
17
+ "net.sourceforge.serp:serp:jar:1.11.0" ]
18
+
19
+ OPTIONS = [ :verbose, :noop, :classpath, :properties ]
20
+
21
+ class << self
22
+
23
+ def enhance(options)
24
+ fu_check_options options, *OPTIONS + [:output]
25
+ runtool options.merge(:class=>"org.apache.openjpa.enhance.PCEnhancer", :name=>"Enhancer",
26
+ :args=>{ "-p"=>options[:properties], "-d"=>options[:output].to_s },
27
+ :classpath=>options[:classpath])
28
+ end
29
+
30
+ def mapping_tool(options)
31
+ fu_check_options options, *OPTIONS + [:action, :sql]
32
+ runtool options.merge(:class=>"org.apache.openjpa.jdbc.meta.MappingTool", :name=>"Mapping Tool",
33
+ :args=>{ "-p"=>options[:properties], "-sql"=>options[:sql], "-sa"=>options[:action] })
34
+ end
35
+
36
+ private
37
+
38
+ def runtool(options)
39
+ args = [options[:class]] + options[:args].select { |n, v| v }.map { |n, v| [ n, v ] }.flatten
40
+ args << { :classpath=>requires + (options[:classpath] || []),
41
+ :name=>"OpenJPA #{options[:name]}", :verbose=>options[:verbose] }
42
+ Java.java *args
43
+ end
44
+
45
+ def requires()
46
+ @required ||= artifacts(REQUIRES).each { |artifact| artifact.invoke }.map(&:to_s)
47
+ end
48
+
49
+ end
50
+
51
+ def open_jpa_enhance(options = nil)
52
+ jpa_options = { :output=>compile.target, :classpath=>[compile.classpath, compile.target.to_s],
53
+ :properties=>path_to("src/main/resources/META-INF/persistence.xml") }
54
+ Java::OpenJPA.enhance jpa_options.merge(options || {})
55
+ end
44
56
 
45
- def self.requires()
46
- @required ||= artifacts(REQUIRES).each { |artifact| artifact.invoke }.map(&:to_s)
47
57
  end
48
-
49
58
  end
50
59
 
60
+ class Project
61
+ include Java::OpenJPA
62
+ end
51
63
  end
@@ -1,20 +1,52 @@
1
+ require "core/project"
2
+ require "java/artifact"
3
+ require "java/java"
4
+ require "java/compile"
5
+ require "tasks/zip"
6
+
7
+
1
8
  module Buildr
2
9
  module Java
3
10
 
11
+ # This module includes comming packaging classes. Each one is also reflected by
12
+ # a packaging method. Generally, you would want to use the packaging method from
13
+ # the project definition, since it does all the heavy lifting.
4
14
  module Packaging
5
15
 
6
16
  MANIFEST_HEADER = "Manifest-Version: 1.0\nCreated-By: Buildr\n"
7
17
 
18
+ # Extends the ZipTask to create a JAR file.
19
+ #
20
+ # This task supports two additional attributes: manifest and meta-inf.
21
+ #
22
+ # The manifest attribute specifies how to create the MANIFEST.MF file.
23
+ # * A hash of manifest properties (name/value pairs).
24
+ # * An array of hashes, one for each section of the manifest.
25
+ # * A string providing the name of an existing manifest file.
26
+ # * Proc or method called to return the contents of the manifest file.
27
+ # * False to not generate a manifest file.
28
+ #
29
+ # The meta-inf attribute lists one or more files that should be copied into
30
+ # the META-INF directory.
31
+ #
32
+ # For example:
33
+ # package(:jar).using(:manifest=>"src/MANIFEST.MF")
34
+ # package(:jar).meta_inf << file("README")
8
35
  class JarTask < ZipTask
36
+
37
+ # Specifies how to create the manifest file.
9
38
  attr_accessor :manifest
39
+
40
+ # Specifies files to include in the META-INF directory.
10
41
  attr_accessor :meta_inf
11
42
 
12
- def initialize(*args)
43
+ def initialize(*args) #:nodoc:
13
44
  super
14
45
  @manifest = true
46
+ @meta_inf = []
15
47
  end
16
48
 
17
- def []=(key, value)
49
+ def []=(key, value) #:nodoc:
18
50
  if key.to_sym == :manifest
19
51
  self.manifest = value
20
52
  elsif key.to_sym == :meta_inf
@@ -25,11 +57,16 @@ module Buildr
25
57
  value
26
58
  end
27
59
 
60
+ def prerequisites() #:nodoc:
61
+ super + [ String === manifest ? file(manifest) : nil ].compact +
62
+ meta_inf.map { |file| String === file ? file(file) : file }
63
+ end
64
+
28
65
  protected
29
66
 
30
- def create(zip)
67
+ def create(zip) #:nodoc:
31
68
  zip.mkdir "META-INF"
32
- meta_inf.each { |file| zip.add "META-INF/#{File.basename(file)}", file } if meta_inf
69
+ meta_inf.map(&:to_s).uniq.each { |file| zip.add "META-INF/#{File.basename(file)}", file }
33
70
  unless manifest == false
34
71
  zip.file.open("META-INF/MANIFEST.MF", "w") do |output|
35
72
  output.write MANIFEST_HEADER
@@ -56,14 +93,24 @@ module Buildr
56
93
 
57
94
  end
58
95
 
96
+ # Extends the JarTask to create a WAR file.
97
+ #
98
+ # Supports all the same options as JarTask, in additon to these two options:
99
+ # * :libs -- An array of files, tasks, artifact specifications, etc that will be added
100
+ # to the WEB-INF/lib directory.
101
+ # * :classes -- A directory containing class files for inclusion in the WEB-INF/classes
102
+ # directory.
103
+ #
104
+ # For example:
105
+ # package(:war).using(:libs=>"log4j:log4j:jar:1.1")
59
106
  class WarTask < JarTask
60
107
 
61
- def []=(key, value)
108
+ def []=(key, value) #:nodoc:
62
109
  case key.to_sym
63
110
  when :libs
64
111
  self.include artifacts(value), :path=>"WEB-INF/lib"
65
112
  when :classes
66
- self.include value, :path=>"WEB-INF/classes"
113
+ self.include value, :path=>"WEB-INF/classes", :as=>"."
67
114
  else
68
115
  super key, value
69
116
  end
@@ -76,155 +123,240 @@ module Buildr
76
123
  end
77
124
 
78
125
 
79
- # Create a JAR from all the pre-requisites.
80
- #
81
- # For example:
82
- # jar "lib-1.0.jar"=>["target/classes", "MANIFEST,MF"]
83
- def jar(file)
84
- Packaging::JarTask.define_task(file)
85
- end
86
-
87
126
  class Project
88
127
 
89
- # Group used for packaging. Inherited from parent project.
90
- inherited_attr :group
128
+ # Group used for packaging. Inherited from parent project. Defaults to the top-level project name.
129
+ attr_accessor :group
130
+ inherited_attr(:group) { |project| project.name }
91
131
  # Version used for packaging. Inherited from parent project.
132
+ attr_accessor :version
92
133
  inherited_attr :version
93
- # Manifest used for packaging. Inherited from parent project.
134
+ # Manifest used for packaging. Inherited from parent project. The default value
135
+ # is a hash that includes the Build-By, Build-Jdk and Implementation-Version values.
136
+ # The later is taken from the project's version number.
137
+ attr_accessor :manifest
94
138
  inherited_attr :manifest do |project|
95
139
  manifest = { "Build-By"=>ENV['USER'], "Build-Jdk"=>Java.version }
96
140
  manifest["Implementation-Version"] = project.version if project.version
97
141
  manifest
98
142
  end
99
- # Files to always include in the package META-INF directory.
100
- inherited_attr :meta_inf do |project|
101
- meta_inf = ["DISCLAIMER", "LICENSE", "NOTICE"].map { |f| path_to(f) if File.exist?(path_to(f)) }.compact
143
+ # Files to always include in the package META-INF directory. The default value include
144
+ # the LICENSE file if one exists in the project's base directory.
145
+ attr_accessor :meta_inf
146
+ inherited_attr(:meta_inf) do |project|
147
+ license = project.file("LICENSE")
148
+ File.exist?(license.to_s) ? [license] : []
102
149
  end
103
150
 
104
- # The project ID is the project name, and for a sub-project the
105
- # parent project ID followed by the project name, separated with a
106
- # hyphen. For example, "foo" and "foo-bar".
151
+ # The project's identifier. Same as the project name, with colons replaced by dashes.
152
+ # The ID for project foo:bar is foo-bar.
153
+ attr_reader :id
107
154
  def id()
108
155
  name.gsub(":", "-")
109
156
  end
110
- inherited_attr :webapp_src_dir do File.join(src_dir, "main", "webapp") end
111
157
 
112
- def package(*args)
113
- if Hash === args.last
114
- options = args.pop.dup
115
- else
116
- options = {}
117
- end
118
- options[:type] = args.shift.to_s if Symbol === args.first
119
- fail "No packaging type specified" unless options[:type]
158
+ # :call-seq:
159
+ # package(type, options?) => task
160
+ #
161
+ # Defines and returns a package created by this project.
162
+ #
163
+ # The first argument declares the package type. For example, :jar to create a JAR file.
164
+ # The second argument provides additional options used when defining the package.
165
+ #
166
+ # The following options are supported by all package types:
167
+ # * :file_name -- The package file name. By default it uses the artifact identifier,
168
+ # version number and file type to create a file name (id-version.type).
169
+ # * :id -- The artifact identifier. By default, uses the project's #id property.
170
+ # * :group -- The group identifier. By default, uses the project's #group property.
171
+ # * :version -- The version number. By default, uses the project's #version property.
172
+ # * :classifier -- Artifact classifier. By default, the artifact has no classifier.
173
+ #
174
+ # The JAR packager adds the following options:
175
+ # * :manifest -- Specifies how to create the MANIFEST.MF. By default, uses the project's
176
+ # #manifest property.
177
+ # * :meta_inf -- Specifies files to be included in the META-INF directory. By default,
178
+ # uses the project's #meta-inf property.
179
+ # * :include -- List of files and directories to include in the JAR. By default,
180
+ # includes the contents of the target/classes directory.
181
+ #
182
+ # The WAR packager adds the following options:
183
+ # * :manifest -- See JAR.
184
+ # * :meta_inf -- See JAR.
185
+ # * :classes -- Directories of class files to include in WEB-INF/classes. By default,
186
+ # includes the contents of the target/classes directory.
187
+ # * :libs -- Artifacts and files to include in WEB-INF/libs. By default, includes the
188
+ # compile classpath.
189
+ # * :include -- List of files and directories to include in the JAR. By default,
190
+ # includes the contents of the src/main/webapp directory.
191
+ #
192
+ # The ZIP packager adds the following options:
193
+ # * :include -- List of file and directories to include in the ZIP.
194
+ #
195
+ # In addition, you can always enhance the package task directly, e.g. by calling the
196
+ # ZipTask#include and ZipTask#with methods.
197
+ #
198
+ # For example:
199
+ # define "project" do
200
+ # define "beans" do
201
+ # package :jar
202
+ # end
203
+ # define "webapp" do
204
+ # compile.with project("beans")
205
+ # package :war
206
+ # end
207
+ # package :zip, :classifier=>"sources", :include=>"."
208
+ # end
209
+ #
210
+ # The first time you call package, it defines the new task. Afterwards, it only uses some of the
211
+ # options (file_name, id, etc) to find an existing package task and return it.
212
+ #
213
+ # For example:
214
+ # # Create a new package that includes an existing package.
215
+ # package(:war).include project("foo:bar").package(:jar)
216
+ #
217
+ # A package is also an artifact. The following tasks operate on packages created by the project:
218
+ # rake deploy # Deploy packages created by the project
219
+ # rake install # Install packages created by the project
220
+ # rake package # Create packages
221
+ # rake uninstall # Remove previously installed packages
222
+ #
223
+ # If you want to add additional packaging types, implement a method with the name package_as_[type]
224
+ # that accepts two arguments, the file name and a hash of options. The method must yield to the
225
+ # block with the package only when first called to define the package, and must return the package
226
+ # from each call.
227
+ def package(type, options = nil)
228
+ options = options.nil? ? {} : options.dup
229
+ options[:id] ||= self.id
120
230
  options[:group] ||= self.group
121
231
  options[:version] ||= self.version
122
- options[:id] ||= self.id
123
- if String === args.first
124
- file = args.shift
125
- else
126
- file = options.delete(:file) || path_to(:target_dir, Artifact.hash_to_file_name(options))
127
- end
128
- fail "One argument too many; expecting at most type, file name, and hash of options" unless args.empty?
129
-
130
- packager = method("package_as_#{options[:type]}") rescue
131
- fail("Do not know how to create a package of type #{options[:type]}")
132
- package = packager.call(file, options) or fail("Do not know how to create a package of type #{options[:type]}")
133
-
134
- task "package"=>package
135
- package.enhance [ task("build")]
136
-
137
- task "install"=>(file(repositories.locate(package)=>package) { |task|
138
- mkpath File.dirname(task.name), :verbose=>false
139
- cp package.name, task.name
140
- })
141
- task "install"=>package.pom
232
+ options[:type] = type
233
+ file_name = options[:file_name] || path_to("target", Artifact.hash_to_file_name(options))
234
+
235
+ packager = method("package_as_#{type}") rescue
236
+ fail("Do not know how to create a package of type #{:type}")
237
+ packager.call(file_name, options) do |package|
238
+ # Make it an artifact using the specifications, and tell it how to create a POM.
239
+ package.extend ActsAsArtifact
240
+ package.send :apply_spec, options
241
+ package.pom.enhance do |pom|
242
+ mkpath File.dirname(pom.name), :verbose=>false
243
+ File.open(pom.name, "w") do |file|
244
+ xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
245
+ xml.instruct!
246
+ xml.project do
247
+ xml.modelVersion "4.0.0"
248
+ xml.groupId options[:group]
249
+ xml.artifactId options[:id]
250
+ xml.version options[:version]
251
+ xml.classifier options[:classifier] if options[:classifier]
252
+ end
253
+ end
254
+ end
142
255
 
143
- task "uninstall" do |task|
144
- verbose(Rake.application.options.trace) do
145
- [ package, package.pom ].map { |artifact| repositories.locate(artifact) }.
146
- each { |file| rm file if File.exist?(file) }
256
+ # Make sure the package task creates it, and it invokes the build task first.
257
+ task "package"=>package
258
+ package.enhance [task("build")]
259
+
260
+ # Install the artifact along with its POM. Since the artifact (package task) is created
261
+ # in the target directory, we need to copy it into the local repository. However, the
262
+ # POM artifact (created by calling artifact on its spec) is already mapped to its right
263
+ # place in the local repository, so we only need to invoke it.
264
+ installed = file(repositories.locate(package)=>package) { |task|
265
+ verbose(Rake.application.options.trace || false) do
266
+ mkpath File.dirname(task.name), :verbose=>false
267
+ cp package.name, task.name
268
+ end
269
+ puts "Installed #{task.name}" if verbose
270
+ }
271
+ task "install"=>[installed, package.pom]
272
+ task "uninstall" do |task|
273
+ verbose(Rake.application.options.trace || false) do
274
+ [ installed, package.pom ].map(&:to_s).each { |file| rm file if File.exist?(file) }
275
+ end
147
276
  end
277
+ task("deploy") { deploy(installed, package.pom) }
278
+
279
+ # Add the package to the list of packages created by this project, and
280
+ # register it as an artifact. The later is required so if we look up the spec
281
+ # we find the package in the project's target directory, instead of finding it
282
+ # in the local repository and attempting to install it.
283
+ packages << package
284
+ Artifact.register package, package.pom
148
285
  end
149
-
150
- task("deploy") { deploy(package, package.pom) }
151
-
152
- packages << package
153
- Artifact.register package, package.pom
154
- package
155
286
  end
156
287
 
288
+ # :call-seq:
289
+ # packages() => tasks
290
+ #
291
+ # Returns all packages created by this project. A project may create any number of packages.
292
+ #
293
+ # This method is used whenever you pass a project to Buildr#artifact or any other method
294
+ # that accepts artifact specifications and projects. You can use it to list all packages
295
+ # created by the project. If you want to return a specific package, it is often more
296
+ # convenient to call #package with the type.
157
297
  def packages()
158
298
  @packages ||= []
159
299
  end
160
300
 
161
301
  protected
162
302
 
163
- def package_as_jar(file, options)
164
- unless Rake::Task.task_defined?(file)
165
- returning(Java::Packaging::JarTask.define_task(file)) do |task|
166
- package_extend task, options
167
- task.enhance [path_to(:java_target_dir)]
168
- task.include path_to(:java_target_dir, "*")
169
- task.manifest = manifest.merge("Implementation-Title"=>self.comment)
170
- task.meta_inf = meta_inf
171
- end
172
- end
173
- returning(Java::Packaging::JarTask.define_task(file)) do |task|
174
- task.include options[:include] if options[:include]
175
- task.manifest = options[:manifest] if options[:manifest]
176
- end
177
- end
178
-
179
- def package_as_war(file, options)
180
- unless Rake::Task.task_defined?(file)
181
- returning(Java::Packaging::WarTask.define_task(file)) do |task|
182
- package_extend task, options
183
- task.include path_to(:webapp_src_dir, "*")
184
- task.with :classes=>path_to(:java_target_dir, "**")
185
- task.manifest = manifest.merge("Implementation-Title"=>self.comment)
186
- task.meta_inf = meta_inf
303
+ def package_as_jar(file_name, options) #:nodoc:
304
+ unless Rake::Task.task_defined?(file_name)
305
+ Java::Packaging::JarTask.define_task(file_name).tap do |jar|
306
+ jar.manifest = options[:manifest] || manifest.merge("Implementation-Title"=>self.comment)
307
+ jar.meta_inf = options[:meta_inf] || meta_inf
308
+ if options[:include]
309
+ jar.include options[:include]
310
+ else
311
+ # Can only decide on this once we're done configuring the compile task.
312
+ enhance { jar.include compile.target, :as=>"." }
313
+ end
314
+ yield jar
187
315
  end
188
316
  end
189
- # Add anything we find in webapp sources directory.
190
- returning(Java::Packaging::WarTask.define_task(file)) do |task|
191
- task.include options[:include] if options[:include]
192
- # Add libraries in WEB-INF lib, and classes in WEB-INF classes
193
- task.with :libs=>options[:libs].collect if options[:libs]
194
- task.with :classes=>options[:classes] if options[:classes]
195
- task.manifest = options[:manifest] if options[:manifest]
196
- end
317
+ file(file_name)
197
318
  end
198
319
 
199
- def package_as_zip(file, options)
200
- unless Rake::Task.task_defined?(file)
201
- returning(ZipTask.define_task(file)) do |task|
202
- package_extend task, options
203
- task.include path_to(:java_target_dir, "*")
320
+ def package_as_war(file_name, options) #:nodoc:
321
+ unless Rake::Task.task_defined?(file_name)
322
+ Java::Packaging::WarTask.define_task(file_name).tap do |war|
323
+ war.manifest = options[:manifest] || manifest.merge("Implementation-Title"=>self.comment)
324
+ war.meta_inf = options[:meta_inf] || meta_inf
325
+ # Add libraries in WEB-INF lib, and classes in WEB-INF classes
326
+ if options[:classes]
327
+ war.with :classes=>options[:classes]
328
+ else
329
+ # Can only decide on this once we're done configuring the compile task.
330
+ enhance { war.with :classes=>compile.target unless compile.sources.empty? }
331
+ end
332
+ if options[:libs]
333
+ war.with :libs=>options[:libs].collect
334
+ else
335
+ # Can only decide on this once we're done configuring the compile task.
336
+ enhance { war.with :libs=>compile.classpath }
337
+ end
338
+ # Add included files, or the webapp directory.
339
+ if options[:include]
340
+ war.include options[:include]
341
+ elsif File.exist?(path_to("src/main/webapp"))
342
+ war.include path_to("src/main/webapp"), :as=>"."
343
+ end
344
+ yield war
204
345
  end
205
346
  end
206
- returning(ZipTask.define_task(file)) do |task|
207
- task.include options[:include] if options[:include]
208
- end
347
+ file(file_name)
209
348
  end
210
349
 
211
- def package_extend(task, spec)
212
- task.extend ActsAsArtifact
213
- task.apply_spec spec
214
- task.pom.enhance do |task|
215
- mkpath File.dirname(task.name), :verbose=>false
216
- File.open(task.name, "w") do |file|
217
- xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
218
- xml.instruct!
219
- xml.project do
220
- xml.modelVersion "4.0.0."
221
- xml.groupId spec[:group]
222
- xml.artifactId spec[:id]
223
- xml.version spec[:version]
224
- xml.classifier spec[:classifier] if spec[:classifier]
350
+ def package_as_zip(file_name, options) #:nodoc:
351
+ unless Rake::Task.task_defined?(file_name)
352
+ ZipTask.define_task(file_name).tap do |zip|
353
+ if options[:include]
354
+ zip.include options[:include]
225
355
  end
356
+ yield zip
226
357
  end
227
358
  end
359
+ file(file_name)
228
360
  end
229
361
 
230
362
  end