bee_java 0.0.1

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.
@@ -0,0 +1,486 @@
1
+ # Copyright 2008-2009 Michel Casabianca <michel.casabianca@gmail.com>
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'bee_task'
16
+ require 'fileutils'
17
+ require 'rexml/document'
18
+ require 'rexml/xpath'
19
+ require 'dependency_resolver'
20
+
21
+ module Bee
22
+
23
+ module Task
24
+
25
+ # Package for Java tasks.
26
+ class Java < Package
27
+
28
+ # Classpath scopes.
29
+ SCOPES = ['compile', 'runtime', 'test']
30
+
31
+ # Compile Java source files.
32
+ #
33
+ # - src: directory or list of directories containing Java source files to
34
+ # compile.
35
+ # - dest: destination directory for generated class files.
36
+ # - classpath: the classpath as defined on javac command line (optional,
37
+ # if dependencies not set).
38
+ # - dependencies: the list of files to include into classpath (optional,
39
+ # if classpath not set).
40
+ # - deprecation: tells if we should show deprecation description, should
41
+ # be true or false (defaults to false).
42
+ # - encoding: specify encoding for source files (defaults to platform
43
+ # encoding).
44
+ # - debug: tells if we should generate debug information, must be true
45
+ # or false (defaults to false).
46
+ # - nowarn: tells if we should ignore warnings, must be true or false
47
+ # (defaults to false).
48
+ # - verbose: tells if we should generate verbose output, must be true
49
+ # or false (defaults to false).
50
+ # - options: custom options to use on command line (optional).
51
+ #
52
+ # Example
53
+ #
54
+ # - java.javac:
55
+ # src: "test"
56
+ # dest: "#{build_dir}/test_classes"
57
+ # classpath: ["#{build_dir}/classes", "lib/*.jar"]
58
+ def javac(params)
59
+ # check parameters
60
+ params_desc = {
61
+ :src => { :mandatory => true, :type => :string_or_array },
62
+ :dest => { :mandatory => true, :type => :string },
63
+ :classpath => { :mandatory => false, :type => :string },
64
+ :dependencies => { :mandatory => false, :type => :string_or_array },
65
+ :deprecation => { :mandatory => false, :type => :boolean,
66
+ :default => false },
67
+ :encoding => { :mandatory => false, :type => :string },
68
+ :debug => { :mandatory => false, :type => :boolean,
69
+ :default => false },
70
+ :nowarn => { :mandatory => false, :type => :boolean,
71
+ :default => false },
72
+ :verbose => { :mandatory => false, :type => :boolean,
73
+ :default => false },
74
+ :options => { :mandatory => false, :type => :string }
75
+ }
76
+ check_parameters(params, params_desc)
77
+ src = params[:src]
78
+ dest = params[:dest]
79
+ classpath = params[:classpath]
80
+ dependencies = params[:dependencies]
81
+ deprecation = params[:deprecation]
82
+ encoding = params[:encoding]
83
+ debug = params[:debug]
84
+ nowarn = params[:nowarn]
85
+ verbose = params[:verbose]
86
+ options = params[:options]
87
+ # build the list of java source files
88
+ src = Array(src)
89
+ files = []
90
+ for dir in src
91
+ files += Dir.glob("#{dir}/**/*.java")
92
+ end
93
+ files.map! { |file| "\"#{file}\"" }
94
+ files.uniq!
95
+ # build classpath
96
+ error "Only one of classpath or dependencies may be set" if
97
+ classpath and dependencies
98
+ path = classpath if classpath
99
+ path = build_classpath(dependencies) if dependencies
100
+ # make destination directory if it doesn't exist
101
+ FileUtils.makedirs(dest) if not File.exists?(dest)
102
+ error "javac 'dest' parameter must be a writable directory" unless
103
+ File.directory?(dest) and File.writable?(dest)
104
+ # run javac command
105
+ puts "Compiling #{files.length} Java source file(s)"
106
+ command = "javac "
107
+ command += "-classpath #{path} " if path
108
+ command += "-d \"#{dest}\" "
109
+ command += "-deprecation " if deprecation
110
+ command += "-encoding #{encoding} " if encoding
111
+ command += "-g " if debug
112
+ command += "-nowarn " if nowarn
113
+ command += "-verbose " if verbose
114
+ command += "#{options} " if options
115
+ command += "#{files.join(' ')}"
116
+ puts "Running command '#{command}'" if @build.listener.verbose
117
+ ok = system(command)
118
+ error "Error compiling Java source files" unless ok
119
+ end
120
+
121
+ # Generate Jar file.
122
+ #
123
+ # - src: directory or list of directories to include to the archive.
124
+ # - includes: glob or list of globs for files to include in the Jar file.
125
+ # - excludes: glob or list of globs for files to exclude from the Jar
126
+ # file.
127
+ # - manifest: manifest file to include in generated Jar file (optional).
128
+ # - dest: the Jar file to generate.
129
+ # - options: custom options to use on command line (optional).
130
+ #
131
+ # Example
132
+ #
133
+ # - java.jar:
134
+ # src: "#{build_dir}/classes"
135
+ # dest: "#{build_dir}/myjar.jar"
136
+ def jar(params)
137
+ # check parameters
138
+ params_desc = {
139
+ :src => { :mandatory => false, :type => :string_or_array },
140
+ :includes => { :mandatory => false, :type => :string_or_array },
141
+ :excludes => { :mandatory => false, :type => :string_or_array },
142
+ :manifest => { :mandatory => false, :type => :string },
143
+ :dest => { :mandatory => true, :type => :string },
144
+ :options => { :mandatory => false, :type => :string }
145
+ }
146
+ check_parameters(params, params_desc)
147
+ src = params[:src]
148
+ includes = params[:includes]
149
+ excludes = params[:excludes]
150
+ manifest = params[:manifest]
151
+ dest = params[:dest]
152
+ options = params[:options]
153
+ error "jar 'src' or 'includes' parameter must be specified" unless
154
+ src or includes
155
+ error "jar 'manifest' parameter must be an existing file" unless
156
+ not manifest or File.exists?(manifest)
157
+ # select directories to include in the Jar file
158
+ directories = []
159
+ if src
160
+ dirs = Array(src)
161
+ for dir in dirs
162
+ directories += Dir.glob(dir)
163
+ end
164
+ end
165
+ # select files to include in the Jar file
166
+ files = []
167
+ if includes
168
+ files = filter_files(includes, excludes)
169
+ files.map! { |file| "\"#{file}\"" }
170
+ end
171
+ # run command line
172
+ puts "Processing Jar archive '#{dest}'"
173
+ command = "jar c"
174
+ command += "v" if @build.listener.verbose
175
+ command += "m" if manifest
176
+ command +="f "
177
+ command += "\"#{manifest}\" " if manifest
178
+ command += "\"#{dest}\" "
179
+ command += "#{options} " if options
180
+ if directories.length > 0
181
+ for dir in directories
182
+ command += "-C \"#{dir}\" ."
183
+ end
184
+ end
185
+ if files.length > 0
186
+ command += "#{files.join(' ')}"
187
+ end
188
+ puts "Running command '#{command}'" if @build.listener.verbose
189
+ ok = system(command)
190
+ error "Error generating Jar archive" unless ok
191
+ end
192
+
193
+ # Run a Java class.
194
+ #
195
+ # - main: main Java class to run.
196
+ # - classpath: the classpath as defined on javac command line (optional,
197
+ # if dependencies not set).
198
+ # - dependencies: the list of files to include into classpath (optional,
199
+ # if classpath not set).
200
+ # - jar: Jar file to launch.
201
+ # - server: run server version of the VM, must be true or false
202
+ # (defaults to false).
203
+ # - properties: system properties to pass to virtual machine, must be
204
+ # a hash, such as { foo: bar } (optional).
205
+ # - assertions: enables assertions, must be true or false (defaults to
206
+ # true).
207
+ # - verbose: tells if we should generate verbose output, must be true
208
+ # or false (defaults to false).
209
+ # - options: custom options to use on command line (optional).
210
+ # - arguments: arguments to pass on Java program command line.
211
+ #
212
+ # Example
213
+ #
214
+ # - java.java:
215
+ # main: test/Test
216
+ # classpath: build/classes
217
+ def java(params)
218
+ # check parameters
219
+ params_desc = {
220
+ :main => { :mandatory => false, :type => :string },
221
+ :classpath => { :mandatory => false, :type => :string },
222
+ :dependencies => { :mandatory => false, :type => :string_or_array },
223
+ :jar => { :mandatory => false, :type => :string },
224
+ :server => { :mandatory => false, :type => :boolean,
225
+ :default => false },
226
+ :properties => { :mandatory => false, :type => :hash },
227
+ :assertions => { :mandatory => false, :type => :boolean,
228
+ :default => true },
229
+ :verbose => { :mandatory => false, :type => :boolean,
230
+ :default => false },
231
+ :options => { :mandatory => false, :type => :string },
232
+ :arguments => { :mandatory => false, :type => :string }
233
+ }
234
+ check_parameters(params, params_desc)
235
+ main = params[:main]
236
+ classpath = params[:classpath]
237
+ dependencies = params[:dependencies]
238
+ jar = params[:jar]
239
+ server = params[:server]
240
+ properties = params[:properties]
241
+ assertions = params[:assertions]
242
+ verbose = params[:verbose]
243
+ options = params[:options]
244
+ arguments = params[:arguments]
245
+ error "jar 'classpath', 'dependencies' or 'jar' parameters must be set" if
246
+ not classpath and not dependencies and not jar
247
+ # build classpath
248
+ error "Only one of classpath or dependencies may be set" if
249
+ classpath and dependencies
250
+ path = classpath if classpath
251
+ path = build_classpath(dependencies) if dependencies
252
+ # run command line
253
+ if main
254
+ puts "Running java class '#{main}'"
255
+ else
256
+ puts "Running jar file '#{jar}'"
257
+ end
258
+ command = "java "
259
+ command += "-server " if server
260
+ if properties
261
+ for key in properties.keys
262
+ command += "-D#{key}=#{properties[key]} "
263
+ end
264
+ end
265
+ command += "-enableassertions " if assertions
266
+ command += "-verbose " if verbose
267
+ command += "#{options} " if options
268
+ command += "-jar #{jar} " if jar
269
+ command += "-classpath #{path} " if path
270
+ command += "\"#{main}\"" if main
271
+ command += " #{arguments}" if arguments
272
+ puts "Running command '#{command}'" if @build.listener.verbose
273
+ ok = system(command)
274
+ error "Error running java" unless ok
275
+ end
276
+
277
+ # Generate Java documentation. Parameters is a hash with following
278
+ # entries:
279
+ #
280
+ # - src: directory or list of directories for Java source files to
281
+ # document.
282
+ # - includes: glob or list of globs for files to document.
283
+ # - excludes: glob or list of globs for files to exclude from
284
+ # documentation.
285
+ # - dest: destination directory for generated documentation.
286
+ # - verbose: tells if we should generate verbose output, must be true
287
+ # or false (defaults to false).
288
+ # - options: custom options to use on command line (optional).
289
+ #
290
+ # Example
291
+ #
292
+ # - java.javadoc:
293
+ # src: :src
294
+ # dest: "#{build_dir}/api"
295
+ def javadoc(params)
296
+ # check parameters
297
+ params_desc = {
298
+ :src => { :mandatory => false, :type => :string_or_array },
299
+ :includes => { :mandatory => false, :type => :string_or_array },
300
+ :excludes => { :mandatory => false, :type => :string_or_array },
301
+ :dest => { :mandatory => true, :type => :string },
302
+ :verbose => { :mandatory => false, :type => :boolean,
303
+ :default => false },
304
+ :options => { :mandatory => false, :type => :string }
305
+ }
306
+ check_parameters(params, params_desc)
307
+ src = params[:src]
308
+ includes = params[:includes]
309
+ excludes = params[:excludes]
310
+ dest = params[:dest]
311
+ verbose = params[:verbose]
312
+ options = params[:options]
313
+ error "javadoc 'src' or 'includes' parameter must be specified" unless
314
+ src or includes
315
+ # select files to document
316
+ files = []
317
+ if src
318
+ dirs = Array(src)
319
+ for dir in dirs
320
+ files += Dir.glob("#{dir}/**/*.java")
321
+ end
322
+ end
323
+ if includes
324
+ files = filter_files(includes, excludes)
325
+ end
326
+ files.map! { |file| "\"#{file}\"" }
327
+ # run command line
328
+ puts "Running javadoc on #{files.length} Java source file(s)"
329
+ command = "javadoc -d \"#{dest}\" "
330
+ command += "-quiet " if not verbose
331
+ command += "#{options} " if options
332
+ command += "#{files.join(' ')}"
333
+ puts "Running command '#{command}'" if @build.listener.verbose
334
+ ok = system(command)
335
+ error "Error running javadoc" unless ok
336
+ end
337
+
338
+ # Run Junit tests.
339
+ #
340
+ # - src: directory or list of directories of Java source files for
341
+ # tests to run.
342
+ # - includes: glob or list of globs for tests to run within source
343
+ # directory(ies) (defaults to '**/*Test.java').
344
+ # - excludes: glob or list of globs for tests to exclude within
345
+ # source directory(ies) (optional).
346
+ # - classpath: the list of directories and files to include into
347
+ # classpath. Note that this should include Jar file for JUnit,
348
+ # class files for classes under test and unit tests themselves.
349
+ # - skip: tells if we should skip test. Optional, defaults to false.
350
+ # - options: custom options to use on command line (optional).
351
+ #
352
+ # Example
353
+ #
354
+ # - java.junit:
355
+ # src: :test_src
356
+ # classpath: [:junit_jar, :classes, :test-classes]
357
+ def junit(params)
358
+ # check parameters
359
+ params_desc = {
360
+ :src => { :mandatory => true, :type => :string_or_array },
361
+ :includes => { :mandatory => false, :type => :string_or_array,
362
+ :default => '**/*Test.java' },
363
+ :excludes => { :mandatory => false, :type => :string_or_array },
364
+ :classpath => { :mandatory => false, :type => :string },
365
+ :dependencies => { :mandatory => false, :type => :string_or_array },
366
+ :skip => { :mandatory => false, :type => :boolean,
367
+ :default => false },
368
+ :options => { :mandatory => false, :type => :string }
369
+ }
370
+ check_parameters(params, params_desc)
371
+ src = params[:src]
372
+ includes = params[:includes]
373
+ excludes = params[:excludes]
374
+ classpath = params[:classpath]
375
+ dependencies = params[:dependencies]
376
+ skip = params[:skip]
377
+ options = params[:options]
378
+ for dir in src
379
+ error "junit 'src' directory was not found" unless
380
+ File.exists?(dir) and File.directory?(dir)
381
+ end
382
+ if not skip
383
+ # build classpath
384
+ error "Only one of classpath or dependencies may be set" if
385
+ classpath and dependencies
386
+ path = classpath if classpath
387
+ path = build_classpath(dependencies) if dependencies
388
+ # select test files to run
389
+ files = []
390
+ for dir in src
391
+ files += filter_files(includes, excludes, dir)
392
+ end
393
+ files.uniq!
394
+ classes = files.map do |file|
395
+ file = file[0, file.rindex('.')] if File.extname(file).length > 0
396
+ file.gsub!(/\//, '.')
397
+ "\"#{file}\""
398
+ end
399
+ # run command line
400
+ puts "Running JUnit on #{files.length} test file(s)"
401
+ command = "java "
402
+ command += "#{options} " if options
403
+ command += "-classpath #{path} " if path
404
+ command += "org.junit.runner.JUnitCore #{classes.join(' ')}"
405
+ puts "Running command '#{command}'" if @build.listener.verbose
406
+ ok = system(command)
407
+ error "Error running JUnit" unless ok
408
+ else
409
+ puts "Skipping unit tests!!!"
410
+ end
411
+ end
412
+
413
+ # Resolve dependencies and genrate a classpath for a given Maven file.
414
+ # - file: Dependencies file to parse (dependencies.yml, project.xml or
415
+ # pom.xml depending on type). Defaults to dependencies.yml.
416
+ # - type: the dependencies type: maven1, maven2 or bee. Defaults to bee.
417
+ # - classpath: the property name to set with classpath.
418
+ # - dependencies: the property name to set with the list of dependencies
419
+ # files.
420
+ def classpath(params)
421
+ params_desc = {
422
+ :file => { :mandatory => false, :type => :string,
423
+ :default => 'dependencies.yml'},
424
+ :type => { :mandatory => false, :type => :string,
425
+ :default => 'bee' },
426
+ :scope => { :mandatory => false, :type => :string,
427
+ :default => 'compile' },
428
+ :directories => { :mandatory => false, :type => :string_or_array },
429
+ :classpath => { :mandatory => false, :type => :string },
430
+ :dependencies => { :mandatory => false, :type => :string }
431
+ }
432
+ check_parameters(params, params_desc)
433
+ file = params[:file]
434
+ type = params[:type]
435
+ scope = params[:scope]
436
+ directories = params[:directories]
437
+ classpath = params[:classpath]
438
+ dependencies = params[:dependencies]
439
+ if not SCOPES.include?(scope)
440
+ scopes = SCOPES.map{ |s| "'#{s}'"}.join(', ')
441
+ error "Unknown scope '#{scope}', must be one of #{scopes}"
442
+ end
443
+ puts "Building CLASSPATH for dependencies '#{file}' and scope '#{scope}'..."
444
+ verbose = @build.listener.verbose
445
+ if type == 'bee'
446
+ resolver = Bee::Task::BeeDependencyResolver.new(file, scope, verbose)
447
+ elsif type == 'maven1'
448
+ resolver = Bee::Task::MavenDependencyResolver.new(file, scope, verbose)
449
+ elsif type == 'maven2'
450
+ resolver = Bee::Task::Maven2DependencyResolver.new(file, scope, verbose)
451
+ else
452
+ error "Unknown type, must be 'bee', 'maven1' or 'maven2'"
453
+ end
454
+ if classpath
455
+ path = resolver.classpath
456
+ if directories
457
+ for directory in directories
458
+ path += File::PATH_SEPARATOR+directory
459
+ end
460
+ end
461
+ @build.context.set_property(classpath, path)
462
+ end
463
+ @build.context.set_property(dependencies, resolver.dependencies) if
464
+ dependencies
465
+ end
466
+
467
+ private
468
+
469
+ # Build a classpath from a set of globs.
470
+ # - globs: glob or list of globs that make this classpath.
471
+ def build_classpath(globs)
472
+ return nil if not globs
473
+ globs = Array(globs)
474
+ files = []
475
+ for glob in globs
476
+ files += Dir.glob(glob)
477
+ end
478
+ files.map! { |entry| "\"#{entry}\"" }
479
+ return files.join(File::PATH_SEPARATOR)
480
+ end
481
+
482
+ end
483
+
484
+ end
485
+
486
+ end