rakish 0.9.01.beta

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,123 @@
1
+ myDir = File.dirname(__FILE__);
2
+
3
+ require "#{myDir}/BuildConfig.rb";
4
+ require 'rexml/document';
5
+ require 'rexml/streamlistener'
6
+
7
+ module Rakish
8
+
9
+ # Module to include in a 'root' Rakish.Configuration[link:./Rakish.html#method-c-Configuration]
10
+ # to provide settings from an intellij idea invoked rakish build.
11
+ module IntellijConfig
12
+
13
+ class XMLListener # :nodoc:
14
+ include Rakish::Util
15
+ include REXML::StreamListener
16
+
17
+ attr_accessor(:config)
18
+
19
+ @@outPath = [ 'project', 'component', 'output' ];
20
+
21
+ def initialize(config)
22
+ @tagPath=[];
23
+ @config=config;
24
+ @skipping=nil;
25
+ end
26
+
27
+ def tag_start(name, attributes)
28
+ @tagPath.push(name);
29
+ if(@tagPath === @@outPath)
30
+ path = attributes['url'];
31
+ path = File.expand_path(path.sub('file://$PROJECT_DIR$',config.projectRoot));
32
+ config.outputPath = path;
33
+ end
34
+ end
35
+ def tag_end(name)
36
+ @tagPath.pop;
37
+ end
38
+ end
39
+
40
+ class CompilerParser < XMLListener
41
+
42
+ @@flagsPath = [ 'project', 'component', 'option' ];
43
+ @@compPath = [ 'project', 'component' ];
44
+
45
+ def tag_start(name, attributes)
46
+
47
+
48
+ @tagPath.push(name);
49
+ # log.debug(@tagPath.join("::"));
50
+ if(@tagPath == @@compPath)
51
+ @compName = attributes['name'];
52
+ elsif(@tagPath === @@flagsPath)
53
+ optName = attributes['name'];
54
+ if(@compName == 'JavacSettings' && optName == 'ADDITIONAL_OPTIONS_STRING')
55
+ config.javacFlags = attributes['value'];
56
+ end
57
+ end
58
+ end
59
+
60
+ end
61
+
62
+
63
+
64
+
65
+ # If non nil is a PropertyBag containing items parsed from the invoking intllij build.
66
+ # This Works in concert with the call-rake.xml and script if used as an intellij ant script.
67
+ #
68
+ # fields assigned:
69
+ # projectRoot - The path to the .idea folder of the invoking intellij project.
70
+ # outputPath - The "Project compiler Output" path specified in the intellij settings.
71
+ # javacFlags - "Extra Compiler Flags" from Java Compiler settings.
72
+ #
73
+ def intellij
74
+ @@intellij_;
75
+ end
76
+
77
+ class Globals < PropertyBag # :nodoc:
78
+ attr_property :outputPath
79
+ attr_property :javacFlags
80
+ end
81
+
82
+ def self.initGlobals # :nodoc:
83
+ @@intellij_ = nil;
84
+
85
+ if(ENV['IDEA_PROJECT'])
86
+
87
+ @@intellij_ = Globals.new;
88
+ ideaProject = ENV['IDEA_PROJECT'];
89
+ ideaProject = File.expand_path(ideaProject);
90
+ projectRoot = File.dirname(ideaProject);
91
+
92
+ xmlPath = File.expand_path("#{ideaProject}/misc.xml");
93
+
94
+ @@intellij_.enableNewFields do |cfg|
95
+
96
+ javacFlags="";
97
+
98
+ cfg.projectRoot = projectRoot;
99
+
100
+ listener = XMLListener.new(cfg);
101
+ parser = REXML::Parsers::StreamParser.new(File.new(xmlPath), listener)
102
+ parser.parse
103
+
104
+ xmlPath = File.expand_path("#{ideaProject}/compiler.xml");
105
+
106
+ listener = CompilerParser.new(cfg);
107
+ parser = REXML::Parsers::StreamParser.new(File.new(xmlPath), listener)
108
+ parser.parse
109
+
110
+ end
111
+ end
112
+
113
+ end
114
+
115
+ addInitBlock do |pnt,opts|
116
+ # log.debug("initializing intellij config");
117
+ unless(defined? @@intellij_)
118
+ IntellijConfig.initGlobals();
119
+ end
120
+ end
121
+ end
122
+
123
+ end
@@ -0,0 +1,504 @@
1
+ myPath = File.dirname(File.expand_path(__FILE__));
2
+ require "#{myPath}/ZipBuilder.rb"
3
+
4
+ module Rakish
5
+
6
+
7
+ # mixin to add java configuration to a configuration or project
8
+ # adds accessors for javaConfig and java_home
9
+ module JavaProjectConfig
10
+ include BuildConfigModule
11
+
12
+ class JavaConfig < PropertyBag
13
+
14
+ attr_property :javacFlags
15
+
16
+ def initialize(parent,projConfig) # :nodoc:
17
+ super(parent,projConfig);
18
+ # self.class.initializeIncluded(self,parent);
19
+ yield self if block_given?
20
+ end
21
+
22
+
23
+ # Get java class path separator-delimiter
24
+ def classpathSeparator
25
+ @@classpathSeparator_||= ( HostIsWindows_ ? ';' : ':');
26
+ end
27
+
28
+ # Get classpaths - unrersolved until after compile
29
+ def classPaths
30
+ @classPaths_||=(getInherited(:classPaths)||FileSet.new);
31
+ end
32
+
33
+ # Add a path or paths to the compile time class path.
34
+ # jar files added are not resolved until compile time against the
35
+ # jarSearchPath
36
+ def addClassPaths(*paths)
37
+ paths.flatten!
38
+ unless(@_cpWritable_)
39
+ @_cpWritable_ = true;
40
+ cp = classPaths;
41
+ @classPaths_=OrderedFileSet.new;
42
+ cp.each do |v|
43
+ @classPaths_.add?(v);
44
+ end
45
+ end
46
+ paths.each do |v|
47
+ if(v =~ /\.jar$/)
48
+ @_cpResolved_=false unless(File.path_is_absolute?(v));
49
+ else
50
+ v = File.expand_path(v)
51
+ end
52
+ @classPaths_.add?(v);
53
+ end
54
+ end
55
+
56
+ # Retrieve jar file library search path
57
+ # The root config with no parent will have '.' installed as the first item in the path.
58
+ def jarSearchPath
59
+ @jarSearchPaths_||=(getInherited(:jarSearchPath)||SearchPath.new('.'));
60
+ end
61
+
62
+ # Add a jar file library search path for finding jar files
63
+ # reltive paths will be searched relative to the current directory
64
+ # when the search is done.
65
+ # The default root search path contains the entry for '.'
66
+ def addJarSearchPath(*paths)
67
+ unless(@_jspWritable_)
68
+ @jarSearchPaths_=SearchPath.new(jarSearchPath)
69
+ @_jspWritable_=true;
70
+ end
71
+ @jarSearchPaths_.addPath(*paths)
72
+ end
73
+
74
+ # Given a list of jar files any non absolute paths are searched for
75
+ # in the jarSearchPath relative to the current directory, any that are found
76
+ # will have the absolute path is set in the result. the order of the list is
77
+ # preserved. The list is flattened, and wildcards are not allowed.
78
+ # items without the .jar suffix are passed through unaltered
79
+ #
80
+ # named options:
81
+ # :onMissing => ( see Rakish::SearchPath.findFile )
82
+ #
83
+ def resolveJarsWithPath(*jars)
84
+ opts = (jars.last.is_a?(Hash) ? jars.pop : {})
85
+ jars.flatten!
86
+ compact=false;
87
+ jars.map! do |path|
88
+ if(path =~ /\.jar$/)
89
+ path = jarSearchPath.findFile(path,opts);
90
+ compact=true unless path;
91
+ end
92
+ path
93
+ end
94
+ jars.compact! if(compact)
95
+ jars
96
+ end
97
+
98
+ def addJavacFlags(flags)
99
+ self.javacFlags=flags
100
+ end
101
+
102
+ end
103
+
104
+ # Get instance of JavaConfig for this configuration
105
+ def java
106
+ @javaConfig_||=JavaConfig.new(getAnyAbove(:java),parent);
107
+ end
108
+
109
+ end
110
+
111
+
112
+
113
+
114
+ module JarBuilderModule
115
+
116
+ #- Subclass of Rakish::ArchiveBuilder
117
+ class JarBuilder < ArchiveBuilder
118
+
119
+ public
120
+
121
+ # Add task to extract contents from the given jar file, if specified, will apply filters
122
+ # and add the extracted files/folders to the root of the
123
+ # new archive recursively, the extraction is done when the
124
+ # builder task is invoked.
125
+ # filters - if filters are specified, they select files within the source to put in the jar
126
+ # with the wildcard path relative to the source root in the format of a Rake::FileList
127
+ # the default if unspecified is to select all files in the source.
128
+ # The list of files is resolved when the builder task is invoked.
129
+
130
+ def addJarContents(jarPath,*filters)
131
+ addZipContents(jarPath,*filters);
132
+ end
133
+
134
+ def doBuildJarAction(t) # :nodoc:
135
+ cfg = t.config;
136
+
137
+ log.info("creating #{t.name}") if cfg.verbose
138
+
139
+ # delete old jar file and liberate space ? jar when creating clears old file
140
+ # FileUtils.rm_f t.name;
141
+
142
+ # ## use persistent file for debugging
143
+ # dir = "d:/jartemp";
144
+ # rm_rf dir;
145
+ # mkdir_p dir;
146
+ # cd dir do
147
+
148
+ Dir.mktmpdir do |dir|
149
+ FileUtils.cd dir do
150
+ loadTempDir(dir)
151
+
152
+ # ensure we have a place to put the new jar file it.
153
+ FileUtils.mkdir_p(t.name.pathmap('%d'));
154
+
155
+ # need to handle manifest creation etc.
156
+ cmdOpts = 'cvfM';
157
+ unless cfg.verbose?
158
+ cmdOpts = cmdOpts.gsub('v','');
159
+ end
160
+
161
+ cmdline = "\"#{cfg.java_home}/bin/jar\" #{cmdOpts} \"#{getRelativePath(t.name)}\" .";
162
+ execLogged(cmdline, :verbose=>cfg.verbose?);
163
+ end
164
+ # ruby seems to do this ok on windows and screws
165
+ # up if I do due to thread latency in wating for the command to unlock the directory or something.
166
+ # FileUtils.rm_rf dir;
167
+ end
168
+ end
169
+
170
+ @@buildJarAction_ = ->(t) do
171
+ t.config.doBuildJarAction(t);
172
+ end
173
+
174
+ # Create a task for building a jar file to specifications stored in this builder.
175
+ def jarTask(*args)
176
+ tsk = ArchiveTask.define_task(*args).enhance(nil,&@@buildJarAction_);
177
+ tsk.config = self;
178
+ tsk
179
+ end
180
+
181
+ end
182
+
183
+ # Create e new JarBuilder for the including project's context
184
+ def createJarBuilder
185
+ jb = JarBuilder.new(self); # for now we make the parent project the parent config
186
+ end
187
+
188
+ end
189
+
190
+ module JavaProjectModule
191
+ include JavaProjectConfig
192
+
193
+ # Overrides java in JavaProjectConfig
194
+ # Get instance of JavaBuilder < JavaConfig for this project
195
+ def java
196
+ @javaConfig_||=JavaBuilder.new(self);
197
+ end
198
+
199
+ include JarBuilderModule
200
+ include ZipBuilderModule
201
+
202
+ protected
203
+
204
+ addInitBlock do |pnt,opts|
205
+ enableNewFields do |my|
206
+ my.java_home = my.getAnyAbove(:java_home) || File.expand_path(ENV['JAVA_HOME']);
207
+ end
208
+ end
209
+
210
+ # Configuration/Builder API available as JavaProjectModule.java
211
+ # in projects including the JavaProjectModule
212
+ class JavaBuilder < JavaConfig
213
+ include Rakish::Util
214
+
215
+ def initialize(proj) # :nodoc:
216
+ super(proj.getAnyAbove(:java),proj);
217
+
218
+ @myProject = proj; # cache this
219
+ @docOutputDir="#{buildDir}/javadoc/#{moduleName}/api";
220
+ end
221
+
222
+ # the project this is attached to
223
+ attr_reader :myProject
224
+
225
+ # the path javadoc output is written to.
226
+ # this defaults to "#{buildDir}/javadoc/#{moduleName}/api"
227
+ attr_accessor :docOutputDir
228
+
229
+ def export(t,&b) # :nodoc:
230
+ @myProject.export(t,&b)
231
+ end
232
+
233
+ # Add source root directory(s) to the list of source roots for this compile.
234
+ #
235
+ # options:
236
+ #
237
+ # [:generated] if true, part or all of this directory or it's contents will not exist until after a prerequisite target to the :compile task has built it's contents.
238
+ def addSourceRoots(*roots)
239
+ opts = (roots.last.is_a?(Hash) ? roots.pop : {})
240
+ (@javaSourceDirs_||=FileSet.new).include(roots);
241
+ end
242
+
243
+ # retrieve added source roots, default to [projectDir]/src if not set
244
+ def sourceRoots
245
+ @javaSourceDirs_||=[File.join(projectDir,'src')];
246
+ end
247
+
248
+
249
+ # Adds output classpaths from other java project modules to the classpath set for
250
+ # this build configuration
251
+ def addProjectOutputClasspaths(*moduleNames)
252
+ names = moduleNames.flatten;
253
+ names.each do |name|
254
+ proj = nil;
255
+ begin
256
+ proj = Rakish.projectByName(name);
257
+ addClassPaths(proj.java.outputClasspath);
258
+ rescue => e
259
+ log.error { "#{moduleName} - failure loading classpath for #{name}" }
260
+ log.error { e } if(proj);
261
+ end
262
+ end
263
+ end
264
+
265
+ # Resolve all jars in the class path in the jarSearchPath and relative to the owning projects folder
266
+ # returns the resolved classPaths
267
+ def resolveClassPaths()
268
+
269
+ cp = classPaths;
270
+ unless @_cpResolved_
271
+ FileUtils.cd(projectDir) do
272
+ @classPaths_=FileSet.new
273
+ opts={ :onMissing=>'log.warn' };
274
+ cp.each do |path|
275
+ if(path =~ /\.jar$/)
276
+ path = jarSearchPath.findFile(path,opts);
277
+ next unless path
278
+ end
279
+ @classPaths_.add?(path);
280
+ end
281
+ end
282
+ cp=@classPaths_;
283
+ end
284
+ cp;
285
+ end
286
+
287
+ def outputClasspath
288
+ @outputClasspath||="#{buildDir()}/production/#{moduleName()}";
289
+ end
290
+
291
+ def doCompileJava(t) # :nodoc:
292
+
293
+ config = t.config;
294
+
295
+
296
+ FileUtils::mkdir_p(outputClasspath);
297
+
298
+ outClasspath = getRelativePath(outputClasspath);
299
+
300
+ cmdline = "\"#{config.java_home}/bin/javac\"";
301
+ cmdline << " #{config.javacFlags ? config.javacFlags : '-g'} -d \"#{outClasspath}\""
302
+
303
+ separator = config.classpathSeparator;
304
+ paths = config.resolveClassPaths
305
+
306
+ unless(paths.empty?)
307
+ cmdline << " -classpath \"#{outClasspath}";
308
+ paths.each do |path|
309
+ cmdline << "#{separator}#{getRelativePath(path)}"
310
+ end
311
+ cmdline << "\"";
312
+ end
313
+
314
+ paths = sourceRoots
315
+ javaSrc = FileList.new;
316
+
317
+ unless(paths.empty?)
318
+ prepend = " -sourcepath \"";
319
+ paths.each do |path|
320
+ javaSrc.include("#{path}/**/*.java");
321
+ cmdline << "#{prepend}#{getRelativePath(path)}"
322
+ prepend = separator;
323
+ end
324
+ cmdline << "\"";
325
+ end
326
+
327
+
328
+ # sourceRoots.each do |root|
329
+ # srcFiles.addFileTree(javaOutputClasspath, root, files );
330
+ # files = FileList.new
331
+ # files.include("#{root}/**/*");
332
+ # files.exclude("#{root}/**/*.java");
333
+ # copyFiles.addFileTree(javaOutputClasspath, root, files);
334
+ # end
335
+
336
+ # we collect the sources above as geenrated code may not be present when the task is created
337
+ javaSrc.each do |src|
338
+ # t.sources.each do |src|
339
+ cmdline << " \"#{getRelativePath(src)}\"";
340
+ end
341
+
342
+ ret = execLogged(cmdline, :verbose=>verbose?);
343
+ raise "Java compile failure" if(ret.exitstatus != 0);
344
+ end
345
+
346
+ class JavaCTask < Rake::Task # :nodoc:
347
+ def needed?
348
+ !sources.empty?
349
+ end
350
+ end
351
+
352
+ @@CompileJavaAction_ = ->(t) do
353
+ t.config.doCompileJava(t);
354
+ end
355
+
356
+ def javacTask(deps=[])
357
+
358
+ srcFiles = FileCopySet.new;
359
+ copyFiles = FileCopySet.new;
360
+
361
+ sourceRoots.each do |root|
362
+ files = FileList.new
363
+ files.include("#{root}/**/*.java");
364
+ srcFiles.addFileTree(outputClasspath, root, files );
365
+ files = FileList.new
366
+ files.include("#{root}/**/*");
367
+ files.exclude("#{root}/**/*.java");
368
+ copyFiles.addFileTree(outputClasspath, root, files);
369
+ end
370
+
371
+ tsk = JavaCTask.define_unique_task &@@CompileJavaAction_
372
+ task :compile=>[tsk]
373
+
374
+ # add sources we know about
375
+ tasks = srcFiles.generateFileTasks( :config=>tsk, :suffixMap=>{ '.java'=>'.class' }) do |t| # , &DoNothingAction_);
376
+ # add this source prerequisite file to the compile task if it is needed.
377
+ t.config.sources << t.source
378
+ end
379
+
380
+ # if(any_task_earlier?(tasks,File.mtime(File.expand_path(__FILE__))))
381
+ # puts("project is altered");
382
+ # end
383
+
384
+ tsk.enhance(deps);
385
+ tsk.enhance(tasks);
386
+ tsk.config = self;
387
+
388
+
389
+ tasks = copyFiles.generateFileTasks();
390
+ # log.debug("####### copy files [#{tasks.length}] \"#{deps.join("\"\n ")}\"");
391
+ tsk.enhance(tasks);
392
+
393
+ task :clean do
394
+ addCleanFiles(tasks);
395
+ end
396
+
397
+ tsk;
398
+ end
399
+
400
+ def doBuildJavadoc(t) # :nodoc:
401
+
402
+ cfg = t.config;
403
+ java = cfg.java;
404
+
405
+ # log.debug("doc output path is [#{cfg.docOutputDir}]");
406
+
407
+ FileUtils.mkdir_p(cfg.docOutputDir);
408
+ separator = cfg.java.classpathSeparator;
409
+
410
+ cmdline = "\"#{cfg.java_home}/bin/javadoc\" -d \"#{cfg.docOutputDir}\"";
411
+ cmdline += " -quiet";
412
+ unless(java.classPaths.empty?)
413
+ classpath = java.resolveClassPaths.join(separator);
414
+ cmdline += " -classpath \"#{classpath}\"";
415
+ end
416
+
417
+ sourcepath = java.sourceRoots.join(';');
418
+ cmdline += " -sourcepath \"#{sourcepath}\"";
419
+ cmdline += " -subpackages \"com\"";
420
+
421
+ execLogged(cmdline, :verbose=>cfg.verbose?);
422
+
423
+ dtime = Time.new;
424
+ File.open("#{t.name}/_buildDate.txt",'w') do |file|
425
+ file.puts("documentation built on #{dtime}");
426
+ end
427
+ end
428
+
429
+ @@BuildJavadocAction = ->(t) do
430
+ t.config.doBuildJavadoc(t);
431
+ end
432
+
433
+ # Create a new task for building the javadocs for all the source roots specified
434
+ # in the JavaBulder (java) configuration for the owning project.
435
+ # don't call multiple times in a project !!
436
+ def getJavadocTask(opts={})
437
+ tsk = Rake::FileTask.define_task docOutputDir;
438
+ tsk.enhance([:compile], &@@BuildJavadocAction);
439
+ tsk.config = self;
440
+ tsk
441
+ end
442
+
443
+ # Adds and exports simple configured targets for building classes, .jar, -src.zip, and -doc.zip files
444
+ #
445
+ # this creates and exports tasks for:
446
+ # :compile (class files)
447
+ # :libs (.jar file),
448
+ # :javadoc ( -doc.zip file)
449
+ # :dist (jar file, -src.zip, and -doc.zip file
450
+ #
451
+ # this requires that source roots and compile classpaths have been set in this builder.
452
+ #
453
+ def addLibraryTargets(opts={})
454
+
455
+ export task :resources;
456
+
457
+ proj = myProject();
458
+
459
+ javac = java.javacTask
460
+
461
+ export (task :compile => javac);
462
+
463
+ jarBuilder = createJarBuilder();
464
+ jarBuilder.addDirectory(java.outputClasspath());
465
+
466
+ jarPath = opts[:name]||"#{binDir()}/#{moduleName}.jar";
467
+ jarPath = jarPath.pathmap("%X.jar");
468
+
469
+ jarTask = jarBuilder.jarTask(jarPath);
470
+ jarTask.enhance(:compile);
471
+
472
+ zipBuilder = proj.createZipBuilder();
473
+ java.sourceRoots.each do |dir|
474
+ zipBuilder.addDirectory(dir, "**/*.java");
475
+ end
476
+ srcZip = zipBuilder.zipTask(jarTask.name.pathmap('%X-src.zip'));
477
+
478
+ export (task :libs => [jarTask, srcZip ])
479
+
480
+ docTask = getJavadocTask;
481
+ docTask.enhance([:compile]);
482
+
483
+ zipBuilder = proj.createZipBuilder();
484
+ zipBuilder.addDirectory(docOutputDir, "**/*");
485
+
486
+ docZip = zipBuilder.zipTask(jarTask.name.pathmap('%X-doc.zip'));
487
+ docZip.enhance(docTask);
488
+
489
+ export (task :javadoc => [ docZip ])
490
+ export (task :dist => [ :libs, :javadoc ])
491
+
492
+ end
493
+ end
494
+ end
495
+
496
+ # Declare JavaProject
497
+ # Shorthand for:
498
+ # Rakish.Project(:includes=>[Rakish::JavaProjectModule[,...]], ...)
499
+ def self.JavaProject(args={},&b)
500
+ args[:baseIncludes]=JavaProjectModule;
501
+ Rakish.Project(args,&b);
502
+ end
503
+
504
+ end # Rakish