source: Dev/branches/rest-dojo-ui/client/util/buildscripts/build.js @ 263

Last change on this file since 263 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 14.3 KB
Line 
1//Main build script for Dojo
2var buildTimerStart = (new Date()).getTime();
3buildScriptsPath = typeof buildScriptsPath == "undefined" ? "./" : buildScriptsPath;
4load(buildScriptsPath + "jslib/logger.js");
5load(buildScriptsPath + "jslib/fileUtil.js");
6load(buildScriptsPath + "jslib/buildUtil.js");
7load(buildScriptsPath + "jslib/buildUtilXd.js");
8load(buildScriptsPath + "jslib/i18nUtil.js");
9
10//NOTE: See buildUtil.DojoBuildOptions for the list of build options.
11
12//*****************************************************************************
13//Convert arguments to keyword arguments.
14var kwArgs = buildUtil.makeBuildOptions(arguments);
15
16//Remove the default namespaces that are created by Rhino, but only
17//if asked to -- it has bad consequences if the build system is used
18//with other rhino-based server-side code.
19if(kwArgs.removeDefaultNameSpaces){
20        delete com;
21        delete net;
22        delete org;
23}
24
25//Set logging level.
26logger.level = kwArgs["log"];
27
28//Execute the requested build actions
29var action = kwArgs.action;
30for(var i = 0; i < action.length; i ++){
31        logger.logPrefix = action[i] + ": ";
32        this[action[i]]();
33        logger.logPrefix = "";
34}
35
36var buildTime = ((new Date().getTime() - buildTimerStart) / 1000);
37logger.info("Build time: " + buildTime + " seconds");
38//*****************************************************************************
39
40//********* Start help ************
41function help(){
42        var buildOptionText = "";
43        for(var param in buildUtil.DojoBuildOptions){
44                buildOptionText += param + "=" + buildUtil.DojoBuildOptions[param].defaultValue + "\n"
45                        + buildUtil.DojoBuildOptions[param].helpText + "\n\n";
46        }
47
48        var helpText = "To run the build, you must have Java 1.4.2 or later installed.\n"
49                + "To run a build run the following command from this directory:\n\n"
50                + "> java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar "
51                + "org.mozilla.javascript.tools.shell.Main build.js [name=value...]\n\n"
52                + "Here is an example of a typical release build:\n\n"
53                + "> java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar "
54                + "org.mozilla.javascript.tools.shell.Main  build.js profile=base action=release\n\n"
55                + "If you get a 'java.lang.OutOfMemoryError: Java heap space' error, try increasing the "
56                + "memory Java can use for the command:\n\n"
57                + "> java -Xms256m -Xmx256m -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar "
58                + "org.mozilla.javascript.tools.shell.Main build.js profile=base action=release\n\n"
59                + "Change the 256 number to the number of megabytes you want to give Java.\n\n"
60                + "The possible name=value build options are shown below with the defaults as their values:\n\n"
61                + buildOptionText;
62       
63        print(helpText);
64}
65//********* End help *********
66
67//********* Start clean ************
68function clean(){
69        logger.info("Deleting: " + kwArgs.releaseDir);
70        fileUtil.deleteFile(kwArgs.releaseDir);
71}
72//********* End clean *********
73
74//********* Start release *********
75function release(){
76        logger.info("Using profile: " + kwArgs.profileFile);
77        logger.info("Using version number: " + kwArgs.version + " for the release.");
78
79        if(!kwArgs.buildLayers){
80                clean();
81        }
82
83        var dependencies = kwArgs.profileProperties.dependencies;
84        var prefixes = dependencies.prefixes;
85        var lineSeparator = fileUtil.getLineSeparator();
86        var copyrightText = fileUtil.readFile(buildScriptsPath + "copyright.txt");
87        var buildNoticeText = fileUtil.readFile(buildScriptsPath + "build_notice.txt");
88       
89        //Find the dojo prefix path. Need it to process other module prefixes.
90        var dojoPrefixPath = buildUtil.getDojoPrefixPath(prefixes);
91
92        //Convert targeted build layers to an array.
93        var buildLayers = null;
94        if(kwArgs.buildLayers){
95                //Make sure to copy over any "source" files for the layers be targeted by
96                //buildLayers. Otherwise dependencies will not be calculated correctly.
97                buildLayers = kwArgs.buildLayers.split(",");
98        }
99
100        //Get the list of module directories we need to process.
101        //They will be in the dependencies.prefixes array.
102        //Copy each prefix dir to the releases and
103        //operate on that copy instead of modifying the source.
104        for(var i = 0; i < prefixes.length; i++){
105                var prefixName = prefixes[i][0];
106                var prefixPath = prefixes[i][1];
107
108                var finalPrefixPath = prefixPath;
109                if(finalPrefixPath.indexOf(".") == 0 && prefixName != "dojo"){
110                        finalPrefixPath = dojoPrefixPath + "/" + prefixPath;
111                }
112                _copyToRelease(prefixName, finalPrefixPath, kwArgs, buildLayers);
113
114                if(kwArgs.symbol){
115                        var releasePath = kwArgs.releaseDir + "/"  + prefixName.replace(/\./g, "/");
116                        buildUtil.insertSymbols(releasePath, kwArgs);
117                }
118        }
119
120        //Fix all the prefix paths to be in the release directory.
121        //Do this after the copy step above. If it is done as part
122        //of that loop, then dojo path gets set first usually, and any prefixes
123        //after it are wrong.
124        for(i = 0; i < prefixes.length; i++){
125                prefixes[i][1] = kwArgs.releaseDir + "/"  + prefixes[i][0].replace(/\./g, "/");
126        }
127
128        //Make sure dojo is clear before trying to map dependencies.
129        if(typeof dojo != "undefined"){
130                dojo = undefined;
131        }
132
133        logger.trace("Building dojo.js and layer files");
134        var result = buildUtil.makeDojoJs(buildUtil.loadDependencyList(kwArgs.profileProperties, kwArgs, buildScriptsPath), kwArgs.version, kwArgs);
135
136        //Save the build layers. The first layer is dojo.js.
137        var defaultLegalText = copyrightText + buildNoticeText;
138        var dojoReleaseDir = kwArgs.releaseDir + "/dojo/";
139        var layerIgnoreString = "";
140        var nlsIgnoreString = "";
141       
142        //Add an ending comma to the list to make matches easier.
143        //Also make sure we normalize to unix path separators.
144        if(kwArgs.buildLayers){
145                kwArgs.buildLayers += ",";
146                kwArgs.buildLayers = kwArgs.buildLayers.replace(/\\/g, "/");
147        }
148        for(i = 0; i < result.length; i++){
149                var currentLayer = result[i];
150                var layerName = currentLayer.layerName;
151                var layerLegalText = (currentLayer.copyrightFile ? fileUtil.readFile(currentLayer.copyrightFile) : defaultLegalText);
152                var fileName = dojoReleaseDir + currentLayer.layerName;
153                var fileContents = currentLayer.contents;
154
155                //Build up string of files to ignore for the directory optimization step
156                var ignoreName = layerName.replace(/\.\.\//g, "");
157                var nameSegment = ignoreName.replace(/\.js$/, "");
158                layerIgnoreString += (layerIgnoreString ? "|" : "") + buildUtil.regExpEscape(ignoreName) + "$";
159                layerIgnoreString += "|" + buildUtil.regExpEscape(ignoreName + ".uncompressed.js") + "$";
160
161                if(nameSegment.indexOf("/") != -1){
162                        nameSegment = nameSegment.substring(nameSegment.lastIndexOf("/") + 1, nameSegment.length);
163                }
164                nlsIgnoreString += (nlsIgnoreString ? "|" : "") + buildUtil.regExpEscape(nameSegment);
165
166                //If only want to build certain layers, skip ones that do not match.
167                if(kwArgs.buildLayers && kwArgs.buildLayers.indexOf(layerName + ",") == -1){
168                        continue;
169                }
170
171                //Burn in djConfig for dojo.js/xd.js if requested.
172                if(kwArgs.scopeDjConfig && (layerName.match(/dojo\.xd\.js$/) || layerName.match(/dojo\.js$/))){
173                        fileContents = buildUtil.setScopeDjConfig(fileContents, kwArgs.scopeDjConfig);
174                }
175
176                //Burn in scope names for dojo.js/xd.js if requested.
177                if(kwArgs.scopeMap && (layerName.match(/dojo\.xd\.js$/) || layerName.match(/dojo\.js$/))){
178                        fileContents = buildUtil.setScopeNames(fileContents, kwArgs.scopeMap);
179                }
180
181                //Burn in xd path for dojo if requested, and only do this in dojo.xd.js.
182                if(layerName == "dojo.xd.js" && kwArgs.xdDojoPath){
183                        fileContents = buildUtilXd.setXdDojoConfig(fileContents, kwArgs.xdDojoPath);
184                }
185
186                //Flatten resources
187                fileContents = i18nUtil.flattenLayerFileBundles(fileName, fileContents, kwArgs);
188
189                //Save uncompressed file.
190                var uncompressedFileName = fileName + ".uncompressed.js";
191                var uncompressedContents = layerLegalText + fileContents;
192                if(layerName.match(/\.xd\.js$/) && !layerName.match(/dojo(\.xd)?\.js/)){
193                        uncompressedContents = buildUtilXd.makeXdContents(uncompressedContents, prefixes, kwArgs);
194                }
195                fileUtil.saveUtf8File(uncompressedFileName, uncompressedContents);
196
197                //Intern strings if desired. Do this before compression, since, in the xd case,
198                //"dojo" gets converted to a shortened name.
199                if(kwArgs.internStrings){
200                        logger.info("Interning strings for file: " + fileName);
201                        prefixes = dependencies["prefixes"] || [];
202                        var skiplist = dependencies["internSkipList"] || [];
203                        buildUtil.internTemplateStringsInFile(uncompressedFileName, dojoReleaseDir, prefixes, skiplist);
204
205                        //Load the file contents after string interning, to pick up interned strings.
206                        fileContents = fileUtil.readFile(uncompressedFileName);
207                }else{
208                        fileContents = uncompressedContents;
209                }
210
211                //Save compressed file.
212                logger.trace("Optimizing (" + kwArgs.layerOptimize + ") file: " + fileName);
213                var compressedContents = buildUtil.optimizeJs(fileName, fileContents, layerLegalText, kwArgs.layerOptimize, kwArgs.stripConsole);
214                fileUtil.saveUtf8File(fileName, compressedContents);
215        }
216
217        //Save the dependency lists to build.txt
218        var buildText = "Files baked into this build:" + lineSeparator;
219        for(i = 0; i < result.length; i++){
220                buildText += lineSeparator + result[i].layerName + ":" + lineSeparator;
221                buildText += result[i].depList.join(lineSeparator) + lineSeparator;
222        }
223        fileUtil.saveFile(kwArgs.releaseDir + "/dojo/build.txt", buildText);
224        logger.info(buildText);
225
226        //Run string interning, xd file building, etc.. on the prefix dirs in the
227        //release area.
228        var layerIgnoreRegExp = new RegExp("(" + layerIgnoreString + ")");
229        var nlsIgnoreRegExp = new RegExp("\\/nls\\/(" + nlsIgnoreString + ")_");
230
231        for(i = 0; i < prefixes.length; i++){
232                copyrightText = null;
233                if(prefixes[i][2]){
234                        copyrightText = fileUtil.readFile(prefixes[i][2]);
235                }
236
237                //Optimize the release dirs, but only if we are not building just a layer.
238                if(!kwArgs.buildLayers){
239                        _optimizeReleaseDirs(prefixes[i][0], prefixes[i][1], copyrightText, kwArgs, layerIgnoreRegExp, nlsIgnoreRegExp);
240                }
241        }
242
243        //Copy over DOH if tests where copied.
244        if(kwArgs.copyTests && !kwArgs.mini){
245                fileUtil.copyDir("../doh", kwArgs.releaseDir + "/util/doh", /./);
246        }
247       
248        //Remove any files no longer needed.
249        if(kwArgs.mini && kwArgs.internStrings){
250                fileUtil.deleteFile(kwArgs.releaseDir + "/dijit/templates");
251                fileUtil.deleteFile(kwArgs.releaseDir + "/dijit/form/templates");
252                fileUtil.deleteFile(kwArgs.releaseDir + "/dijit/layout/templates");
253        }
254
255        logger.info("Build is in directory: " + kwArgs.releaseDir);
256}
257//********* End release *********
258
259//********* Start _copyToRelease *********
260function _copyToRelease(/*String*/prefixName, /*String*/prefixPath, /*Object*/kwArgs, /*Array?*/buildLayers){
261        //summary: copies modules and supporting files from the prefix path to the release
262        //directory. Also adds code guards to module resources.
263        var prefixSlashName = prefixName.replace(/\./g, "/");
264        var releasePath = kwArgs.releaseDir + "/"  + prefixSlashName;
265        var copyRegExps = {
266                include: /./
267        };
268       
269        //Use the copyRegExps to filter out tests if requested.
270        if(!kwArgs.copyTests){
271                copyRegExps.exclude = /\/tests\//;
272        }
273       
274        if(kwArgs.mini){
275                copyRegExps.exclude = /\/tests\/|\/demos\/|tests\.js|dijit\/bench|dijit\/themes\/themeTest|(\.php$)/;
276        }
277
278        logger.info("Copying: " + prefixPath + " to: " + releasePath);
279        var copiedFiles = fileUtil.copyDir(prefixPath, releasePath, copyRegExps, true);
280
281        //If want a different selector engine, adjust that now.
282        //Copy the new selector js over the dojo._base.query file
283        if(prefixName == "dojo" && kwArgs.query == "sizzle"){
284                fileUtil.copyFile(releasePath + "/_base/query-sizzle.js", releasePath + "/_base/query.js");
285        }
286       
287        if(!copiedFiles){
288                logger.info(" ********** Not Copied: " + prefixPath );
289        }
290       
291        //Make sure to copy over any "source" files for the layers be targeted by
292        //buildLayers. Otherwise dependencies will not be calculated correctly.
293        if(buildLayers){
294                for(i = 0; i < buildLayers.length; i++){
295                        var relativeLayerPath = buildLayers[i].replace(/\.\.\//g, "");
296                       
297                        //See if relativeLayerPath has teh prefix slash name in it.
298                        //This means the layer is probably in this prefix dir (but no guarantee)
299                        //This is a bit hacky.
300                        if(relativeLayerPath.indexOf(prefixSlashName) == 0){
301                               
302                                //Remove the prefix part from the dir and add the prefix path to get a
303                                //full path.
304                                var layerPathSuffix = relativeLayerPath.replace(prefixSlashName, "");
305                                relativeLayerPath = prefixPath + layerPathSuffix;
306                               
307                                //If that source path exists, it means we need to copy over the source
308                                //layer file.
309                                if((new java.io.File(relativeLayerPath)).exists()){
310                                        //Need to copy over from the source area.
311                                        var destPath = releasePath + layerPathSuffix;
312                                        fileUtil.copyFile(relativeLayerPath, destPath);
313                                }
314                        }
315                }
316        }
317
318        //Put in code guards for each resource, to protect against redefinition of
319        //code in the layered build cases. Also inject base require calls if there is
320        //a layer with the customBase attribute. Do this here before the layers are built.
321        if(copiedFiles){
322                var needBaseRequires = false;
323                var layers = kwArgs.profileProperties.dependencies.layers;
324                if(layers){
325                        for(var i = 0; i < layers.length; i++){
326                                if((needBaseRequires = layers[i].customBase)){
327                                        break;
328                                }
329                        }
330                }
331
332                if(kwArgs.addGuards){
333                        buildUtil.addGuardsAndBaseRequires(copiedFiles, needBaseRequires);
334                }
335        }
336}
337//********* End _copyToRelease *********
338
339//********* Start _optimizeReleaseDirs *********
340function _optimizeReleaseDirs(
341        /*String*/prefixName,
342        /*String*/prefixPath,
343        /*String*/copyrightText,
344        /*Object*/kwArgs,
345        /*RegExp*/layerIgnoreRegExp,
346        /*RegExp*/nlsIgnoreRegExp){
347        //summary: runs intern strings, i18n bundle flattening and xdomain file generation
348        //on the files in a release directory, if those options are enabled.
349        var releasePath = kwArgs.releaseDir + "/"  + prefixName.replace(/\./g, "/");
350        var prefixes = kwArgs.profileProperties.dependencies.prefixes;
351
352        //Intern strings if desired.
353        if(kwArgs.internStrings){
354                logger.info("Interning strings for: " + releasePath);
355                buildUtil.internTemplateStrings(kwArgs.profileProperties.dependencies, releasePath, layerIgnoreRegExp);
356        }
357
358        //Process build conditionals in non-layer module files.
359        buildUtil.processConditionalsForDir(releasePath, layerIgnoreRegExp, kwArgs);
360
361        //Flatten bundles inside the directory
362        i18nUtil.flattenDirBundles(prefixName, prefixPath, kwArgs, nlsIgnoreRegExp);
363       
364        if(kwArgs.loader == "xdomain"){
365                buildUtilXd.xdgen(prefixName, prefixPath, prefixes, layerIgnoreRegExp, kwArgs);
366        }
367
368        buildUtil.optimizeJsDir(releasePath, layerIgnoreRegExp, copyrightText, kwArgs.optimize, kwArgs.stripConsole);
369
370        if(kwArgs.cssOptimize){
371                buildUtil.optimizeCss(releasePath, kwArgs.cssOptimize, kwArgs.cssImportIgnore);
372        }
373}
374//********* End _optimizeReleaseDirs *********
Note: See TracBrowser for help on using the repository browser.