source: Dev/trunk/src/client/util/buildscripts/build.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 14.4 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:
262        //              copies modules and supporting files from the prefix path to the release
263        //              directory. Also adds code guards to module resources.
264        var prefixSlashName = prefixName.replace(/\./g, "/");
265        var releasePath = kwArgs.releaseDir + "/"  + prefixSlashName;
266        var copyRegExps = {
267                include: /./
268        };
269       
270        //Use the copyRegExps to filter out tests if requested.
271        if(!kwArgs.copyTests){
272                copyRegExps.exclude = /\/tests\//;
273        }
274       
275        if(kwArgs.mini){
276                copyRegExps.exclude = /\/tests\/|\/demos\/|tests\.js|dijit\/bench|dijit\/themes\/themeTest|(\.php$)/;
277        }
278
279        logger.info("Copying: " + prefixPath + " to: " + releasePath);
280        var copiedFiles = fileUtil.copyDir(prefixPath, releasePath, copyRegExps, true);
281
282        //If want a different selector engine, adjust that now.
283        //Copy the new selector js over the dojo._base.query file
284        if(prefixName == "dojo" && kwArgs.query == "sizzle"){
285                fileUtil.copyFile(releasePath + "/_base/query-sizzle.js", releasePath + "/_base/query.js");
286        }
287       
288        if(!copiedFiles){
289                logger.info(" ********** Not Copied: " + prefixPath );
290        }
291       
292        //Make sure to copy over any "source" files for the layers be targeted by
293        //buildLayers. Otherwise dependencies will not be calculated correctly.
294        if(buildLayers){
295                for(i = 0; i < buildLayers.length; i++){
296                        var relativeLayerPath = buildLayers[i].replace(/\.\.\//g, "");
297                       
298                        //See if relativeLayerPath has teh prefix slash name in it.
299                        //This means the layer is probably in this prefix dir (but no guarantee)
300                        //This is a bit hacky.
301                        if(relativeLayerPath.indexOf(prefixSlashName) == 0){
302                               
303                                //Remove the prefix part from the dir and add the prefix path to get a
304                                //full path.
305                                var layerPathSuffix = relativeLayerPath.replace(prefixSlashName, "");
306                                relativeLayerPath = prefixPath + layerPathSuffix;
307                               
308                                //If that source path exists, it means we need to copy over the source
309                                //layer file.
310                                if((new java.io.File(relativeLayerPath)).exists()){
311                                        //Need to copy over from the source area.
312                                        var destPath = releasePath + layerPathSuffix;
313                                        fileUtil.copyFile(relativeLayerPath, destPath);
314                                }
315                        }
316                }
317        }
318
319        //Put in code guards for each resource, to protect against redefinition of
320        //code in the layered build cases. Also inject base require calls if there is
321        //a layer with the customBase attribute. Do this here before the layers are built.
322        if(copiedFiles){
323                var needBaseRequires = false;
324                var layers = kwArgs.profileProperties.dependencies.layers;
325                if(layers){
326                        for(var i = 0; i < layers.length; i++){
327                                if((needBaseRequires = layers[i].customBase)){
328                                        break;
329                                }
330                        }
331                }
332
333                if(kwArgs.addGuards){
334                        buildUtil.addGuardsAndBaseRequires(copiedFiles, needBaseRequires);
335                }
336        }
337}
338//********* End _copyToRelease *********
339
340//********* Start _optimizeReleaseDirs *********
341function _optimizeReleaseDirs(
342        /*String*/prefixName,
343        /*String*/prefixPath,
344        /*String*/copyrightText,
345        /*Object*/kwArgs,
346        /*RegExp*/layerIgnoreRegExp,
347        /*RegExp*/nlsIgnoreRegExp){
348        // summary:
349        //              runs intern strings, i18n bundle flattening and xdomain file generation
350        //              on the files in a release directory, if those options are enabled.
351        var releasePath = kwArgs.releaseDir + "/"  + prefixName.replace(/\./g, "/");
352        var prefixes = kwArgs.profileProperties.dependencies.prefixes;
353
354        //Intern strings if desired.
355        if(kwArgs.internStrings){
356                logger.info("Interning strings for: " + releasePath);
357                buildUtil.internTemplateStrings(kwArgs.profileProperties.dependencies, releasePath, layerIgnoreRegExp);
358        }
359
360        //Process build conditionals in non-layer module files.
361        buildUtil.processConditionalsForDir(releasePath, layerIgnoreRegExp, kwArgs);
362
363        //Flatten bundles inside the directory
364        i18nUtil.flattenDirBundles(prefixName, prefixPath, kwArgs, nlsIgnoreRegExp);
365       
366        if(kwArgs.loader == "xdomain"){
367                buildUtilXd.xdgen(prefixName, prefixPath, prefixes, layerIgnoreRegExp, kwArgs);
368        }
369
370        buildUtil.optimizeJsDir(releasePath, layerIgnoreRegExp, copyrightText, kwArgs.optimize, kwArgs.stripConsole);
371
372        if(kwArgs.cssOptimize){
373                buildUtil.optimizeCss(releasePath, kwArgs.cssOptimize, kwArgs.cssImportIgnore);
374        }
375}
376//********* End _optimizeReleaseDirs *********
Note: See TracBrowser for help on using the repository browser.