source: Dev/trunk/src/client/util/build/buildControl.js @ 532

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

Added Dojo 1.9.3 release.

File size: 23.4 KB
Line 
1define([
2        "require",
3        "dojo/_base/lang",
4        "./argv",
5        "./fs",
6        "./fileUtils",
7        "./buildControlDefault",
8        "./v1xProfiles",
9        "./stringify",
10        "./process",
11        "./messages",
12        "dojo/text!./help.txt"
13], function(require, lang, argv, fs, fileUtils, bc, v1xProfiles, stringify, process, messages, helpText){
14        //
15        // Process the arguments given on the command line to build up a profile object that is used to instruct and control
16        // the build process.
17        //
18        // This modules is a bit tedious. Is methodically goes through each option set, cleaning and conditioning user input making it
19        // easy to use for the remainder of the program. Readers are advised to tackle it top-to-bottom. There is no magic...just
20        // a whole bunch of imperative programming.
21        //
22
23        if(!isNaN(argv)){
24                // if argv is a number, then it's an exit code
25                bc.exitCode = argv;
26                return bc;
27        }
28
29        eval(require.scopeify("./fs, ./fileUtils, ./v1xProfiles"));
30        var
31                isString = function(it){
32                        return typeof it === "string";
33                },
34
35                isNonemptyString = function(it){
36                        return isString(it) && it.length;
37                },
38
39                isDefined = function(it){
40                        return typeof it !="undefined";
41                },
42
43                cleanupFilenamePair = function(item, srcBasePath, destBasePath, hint){
44                        var result;
45                        if(isString(item)){
46                                result = [computePath(item, srcBasePath), computePath(item, destBasePath)];
47                        }else{
48                                result = [computePath(item[0], srcBasePath), computePath(item[1], destBasePath)].concat(item.slice(2));
49                        }
50                        if(!isAbsolutePath(result[0]) || !isAbsolutePath(result[1])){
51                                bc.log("inputInvalidPath", ["path", item, "hint", hint]);
52                        }
53                        return result;
54                },
55
56                slashTerminate = function(path){
57                        return path + /\/$/.test(path) ? "" : "/";
58                },
59
60                isEmpty = function(it){
61                        for(var p in it) return false;
62                        return true;
63                },
64
65                cleanDeprecated = function(o, inputFile){
66                        var deprecated = [];
67                        for(p in o){
68                                if(/^(log|loader|xdDojoPath|scopeDjConfig|xdScopeArgs|xdDojoScopeName|expandProvide|buildLayers|query|removeDefaultNameSpaces|addGuards)$/.test(p)){
69                                        deprecated.push(p);
70                                        bc.log("inputDeprecated", ["switch", p, inputFile]);
71                                }
72                        }
73                        deprecated.forEach(function(p){
74                                delete o[p];
75                        });
76                },
77
78                mix = function(dest, src){
79                        dest = dest || {};
80                        src = src || {};
81                        for(var p in src) dest[p] = src[p];
82                        return dest;
83                },
84
85                mixPackage = function(packageInfo){
86                        var name = packageInfo.name;
87                        bc.packageMap[name] = mix(bc.packageMap[name], packageInfo);
88                },
89
90                // mix a profile object into the global profile object
91                mixProfileObject = function(src){
92                        cleanDeprecated(src, src.selfFilename);
93
94                        // the profile properties...
95                        //       paths, plugins, transforms, staticHasFeatures
96                        // ...are mixed one level deep; messageCategories, messages, packages, and packagePaths require special handling; all others are over-written
97                        // FIXME: the only way to modify the transformJobs vector is to create a whole new vector?
98                        for(var p in src){
99                                if(!/paths|plugins|messages|transforms|staticHasFeatures|packages|packagePaths|defaultConfig/.test(p)){
100                                        bc[p] = src[p];
101                                }
102                        }
103
104                        // the one-level-deep mixers
105                        ["paths","plugins","transforms","staticHasFeatures"].forEach(function(p){
106                                bc[p] = mix(bc[p], src[p]);
107                        });
108
109                        // messages require special handling
110                        if(src.messageCategories){
111                                for(p in src.messageCategories){
112                                        bc.addCategory(p, src.messageCategories[p]);
113                                }
114                        }
115                        (src.messages || []).forEach(function(item){bc.addMessage.apply(bc, item);});
116
117                        // packagePaths and packages require special processing to get their contents into packageMap; do that first...
118                        // process packagePaths before packages before packageMap since packagePaths is less specific than
119                        // packages is less specific than packageMap. Notice that attempts to edit an already-existing package
120                        // only edits specific package properties given (see mixPackage, above)
121                        for(var base in src.packagePaths){
122                                src.packagePaths[base].forEach(function(packageInfo){
123                                        if(isString(packageInfo)){
124                                                packageInfo = {name:packageInfo};
125                                        }
126                                        packageInfo.location = catPath(base, packageInfo.name);
127                                        mixPackage(packageInfo);
128                                });
129                        };
130                        (src.packages || []).forEach(function(packageInfo){
131                                        if(isString(packageInfo)){
132                                                packageInfo = {name:packageInfo};
133                                        }
134                                        mixPackage(packageInfo);
135                        });
136
137                        // defaultConfig requires special handling
138                        for(p in src.defaultConfig){
139                                if(p=="hasCache"){
140                                        mix(bc.defaultConfig.hasCache, src.defaultConfig.hasCache);
141                                }else{
142                                        bc.defaultConfig[p] = src.defaultConfig[p];
143                                }
144                        }
145                };
146
147        argv.args.profiles.forEach(function(item){
148                var temp = mix({}, item),
149                        build = item.build;
150                delete temp.build;
151                mixProfileObject(temp);
152                build && mixProfileObject(build);
153        });
154
155        cleanDeprecated(argv.args, "command line");
156
157        // lastly, explicit command line switches override any evaluated profile objects
158        for(var argName in argv.args) if(argName!="profiles"){
159                bc[argName] = argv.args[argName];
160        }
161
162        // at this point the raw profile object has been fully initialized; clean it up and look for errors...
163        bc.basePath = computePath(bc.basePath, process.cwd());
164        var releaseDir = catPath(bc.releaseDir || "../release", bc.releaseName || "");
165        bc.destBasePath = computePath(releaseDir, bc.basePath);
166
167        // compute global copyright, if any
168        bc.copyright = isNonemptyString(bc.copyright) ? (maybeRead(computePath(bc.copyright, bc.basePath)) || bc.copyright) : "";
169        bc.copyrightLayers = !!bc.copyrightLayers;
170        bc.copyrightNonlayers = !!bc.copyrightNonlayers;
171
172        // compute files, dirs, and trees
173        (function(){
174                for(var property in {files:1, dirs:1, trees:1}){
175                        if(bc[property] instanceof Array){
176                                bc[property] = bc[property].map(function(item){
177                                        return cleanupFilenamePair(item, bc.basePath, bc.destBasePath, property);
178                                });
179                        }
180                }
181        })();
182
183        // cleanup the replacements (if any)
184        (function(){
185                var cleanSet = {}, src, dest;
186                for(src in bc.replacements){
187                        cleanSet[computePath(src, bc.basePath)] = bc.replacements[src];
188                }
189                bc.replacements = cleanSet;
190        })();
191
192        // explicit mini and/or copyTests wins; explicit copyTests ignores explicit mini
193        if(!("mini" in bc)){
194                bc.mini = true;
195        }
196        if(!("copyTests" in bc)){
197                bc.copyTests = !bc.mini;
198        }
199        if(isString(bc.copyTests)){
200                bc.copyTests = bc.copyTests.toLowerCase();
201        }
202        if(bc.copyTests!="build"){
203                // convert to pure boolean
204                bc.copyTests = !!bc.copyTests;
205        }
206
207        function getDiscreteLocales(locale){
208                for(var locales = locale.split("-"), result = [], current = "", i = 0; i<locales.length; i++){
209                        result.push(current += (i ? "-" : "") + locales[i]);
210                }
211                return result;
212        }
213        if(isString(bc.localeList)){
214                bc.localeList = bc.localeList.split(",");
215                if(bc.localeList.length){
216                        bc.localeList = bc.localeList.map(function(locale){ return lang.trim(locale); });
217                }
218        }
219        if(bc.localeList && bc.localeList.length){
220                if(bc.localeList.indexOf("ROOT")==-1){
221                        bc.localeList.push("ROOT");
222                }
223                var localeList = {};
224                bc.localeList.forEach(function(locale){
225                        locale = lang.trim(locale);
226                        localeList[locale] = getDiscreteLocales(locale);
227                });
228                bc.localeList.discreteLocales = localeList;
229        }else{
230                bc.localeList = false;
231        }
232
233
234        (function(){
235                function processPackage(pack){
236                        var packName = pack.name,
237                                basePath = pack.basePath || bc.basePath;
238                        if(!pack.packageJson){
239                                pack.packageJson = argv.readPackageJson(catPath(computePath(pack.location || ("./" + packName), basePath), "package.json"), "missingPackageJson");
240                        }
241                        var packageJson = pack.packageJson;
242                        if(packageJson){
243                                if(packageJson.version){
244                                        bc.log("packageVersion", ["package", packName, "version", packageJson.version]);
245
246                                        // new for 1.7, if version is not provided, the version of the dojo package is used
247                                        if(typeof bc.version=="undefined" && packName=="dojo"){
248                                                bc.version = packageJson.version;
249                                        }
250                                }
251                                if(packageJson.main && !pack.main){
252                                        pack.main= packageJson.main;
253                                }
254                                if(packageJson.directories && packageJson.directories.lib && !pack.location){
255                                        pack.location = catPath(getFilepath(packageJson.selfFilename), packageJson.directories.lib);
256                                }
257                                if("dojoBuild" in packageJson){
258                                        var defaultProfile = argv.readProfile("profile", catPath(getFilepath(packageJson.selfFilename), packageJson.dojoBuild));
259                                        for(var p in defaultProfile){
260                                                if(!(p in pack)){
261                                                        pack[p] = defaultProfile[p];
262                                                }else if(p in {resourceTags:1}){
263                                                        // these are mixed one level deep
264                                                        // TODO: review all profile properties and see if there are any others than resourceTags that ought to go here
265                                                        mix(pack[p], defaultProfile[p]);
266                                                }
267                                        }
268                                }else{
269                                        bc.log("missingProfile", ["package", packageJson.name]);
270                                }
271                        }
272
273                        // build up info to tell all about a package; all properties semantically identical to definitions used by dojo loader/bdLoad
274                        pack.main = isString(pack.main) ? pack.main : "main";
275                        if(pack.main.indexOf("./")==0){
276                                pack.main = pack.main.substring(2);
277                        }
278                        if(pack.destMain && pack.destMain.indexOf("./")==0){
279                                pack.destMain = pack.destMain.substring(2);
280                        }
281
282                        pack.location = computePath(pack.location || ("./" + packName), basePath);
283
284                        pack.copyright = isNonemptyString(pack.copyright) ?
285                                (maybeRead(computePath(pack.copyright, pack.location)) || maybeRead(computePath(pack.copyright, bc.basePath)) || pack.copyright) :
286                                (pack.copyright ? bc.copyright : "");
287                        pack.copyrightLayers = isDefined(pack.copyrightLayers) ? !!pack.copyrightLayers : bc.copyrightLayers;
288                        pack.copyrightNonlayers = isDefined(pack.copyrightNonlayers) ? !!pack.copyrightNonlayers : bc.copyrightNonlayers;
289
290                        // dest says where to output the compiled code stack
291                        var destPack = bc.destPackages[packName] = {
292                                name:pack.destName || packName,
293                                main:pack.destMain || pack.main,
294                                location:computePath(pack.destLocation || ("./" + (pack.destName || packName)), bc.destBasePath)
295                        };
296                        delete pack.destName;
297                        delete pack.destMain;
298                        delete pack.destLocation;
299
300
301                        if(!pack.trees){
302                                // copy the package tree; don't copy any hidden directorys (e.g., .git, .svn) or temp files
303                                pack.trees = [[pack.location, destPack.location, /(\/\.)|(^\.)|(~$)/]];
304                        } // else the user has provided explicit copy instructions
305
306                        // filenames, dirs, trees just like global, except relative to the pack.(src|dest)Location
307                        for(var property in {files:1, dirs:1, trees:1}){
308                                pack[property] = (pack[property] || []).map(function(item){
309                                        return cleanupFilenamePair(item, pack.location, destPack.location, property + " in package " + packName);
310                                });
311                        }
312                }
313
314                // so far, we've been using bc.packageMap to accumulate package info as it is provided by packagePaths and/or packages
315                // in zero to many profile scripts. This routine moves each package config into bc.packages which is a map
316                // from package name to package config (this is different from the array the user uses to pass package config info). Along
317                // the way, each package config object is cleaned up and all default values are calculated.
318                bc.packages = bc.packageMap;
319                delete bc.packageMap;
320                bc.destPackages = {};
321                for(var packageName in bc.packages){
322                        var pack = bc.packages[packageName];
323                        pack.name = pack.name || packageName;
324                        processPackage(pack);
325                }
326
327                // now that we know the dojo path, we can automatically add DOH, if required
328                if(bc.copyTests && !bc.packages.doh){
329                        bc.packages.doh = {
330                                name:"doh",
331                                location:compactPath(bc.packages.dojo.location + "/../util/doh"),
332                                destLocation:"util/doh"
333                        };
334                        processPackage(bc.packages.doh);
335                }
336
337                // get this done too...
338                require.computeAliases(bc.aliases, (bc.aliasesMap = []));
339                require.computeMapProg(bc.paths, (bc.pathsMapProg = []));
340
341                // add some methods to bc to help with resolving AMD module info
342                bc.srcModules = {};
343                bc.destModules = {};
344
345                var trimLastChars = function(text, n){
346                        return text.substring(0, text.length-n);
347                };
348
349                bc.getSrcModuleInfo = function(mid, referenceModule, ignoreFileType){
350                        // notice that aliases and paths are applied, but map is not (and never will be)
351                        if(ignoreFileType){
352                                var result = require.getModuleInfo(mid+"/x", referenceModule, bc.packages, bc.srcModules, bc.basePath + "/", [], bc.pathsMapProg, bc.aliasesMap, true);
353                                result.mid = trimLastChars(result.mid, 2);
354                                if(result.pid!==0){
355                                        // trim /x.js
356                                        result.url = trimLastChars(result.url, 5);
357                                }
358                                return result;
359                        }else{
360                                return require.getModuleInfo(mid, referenceModule, bc.packages, bc.srcModules, bc.basePath + "/", [], bc.pathsMapProg, bc.aliasesMap, true);
361                        }
362                };
363
364
365                bc.getDestModuleInfo = function(mid, referenceModule, ignoreFileType){
366                        // notice no mapping, paths, aliases in the dest getModuleInfo....just send stuff to where it should go without manipulation
367                        if(ignoreFileType){
368                                var result = require.getModuleInfo(mid+"/x", referenceModule, bc.destPackages, bc.destModules, bc.destBasePath + "/", [], [], [], true);
369                                result.mid = trimLastChars(result.mid, 2);
370                                if(result.pid!==0){
371                                        // trim /x.js
372                                        result.url = trimLastChars(result.url, 5);
373                                }
374                                return result;
375                        }else{
376                                return require.getModuleInfo(mid, referenceModule, bc.destPackages, bc.destModules, bc.destBasePath + "/", [], [], [], true);
377                        }
378                };
379               
380                bc.getAmdModule = function(
381                                mid,
382                                referenceModule
383                        ){
384                                var match = mid.match(/^([^\!]+)\!(.*)$/);
385                                if(match){
386                                        var pluginModuleInfo = bc.getSrcModuleInfo(match[1], referenceModule),
387                                                pluginModule = pluginModuleInfo &&      bc.amdResources[pluginModuleInfo.mid],
388                                                pluginId = pluginModule && pluginModule.mid,
389                                                pluginProc = bc.plugins[pluginId];
390                                        if(!pluginModule){
391                                                return 0;
392                                        }else if(!pluginProc){
393                                                if(!pluginModule.noBuildResolver){
394                                                        bc.log("missingPluginResolver", ["module", referenceModule.mid, "plugin", pluginId]);
395                                                }
396                                                return pluginModule;
397                                        }else{
398                                                // flatten the list of modules returned from the plugin
399                                                var modules = [].concat(pluginProc.start(match[2], referenceModule, bc));
400                                                return modules.concat.apply([], modules);
401                                        }
402                                }else{
403                                        var moduleInfo = bc.getSrcModuleInfo(mid, referenceModule),
404                                                module = moduleInfo && bc.amdResources[moduleInfo.mid];
405                                        return module;
406                                }
407                        }
408               
409        })();
410
411
412        if(bc.selectorEngine && bc.defaultConfig && bc.defaultConfig.hasCache){
413                bc.defaultConfig.hasCache["config-selectorEngine"] = bc.selectorEngine;
414        }
415
416        (function(){
417                // a layer is a module that should be written with all of its dependencies, as well as all modules given in
418                // the include vector together with their dependencies, excluding modules contained in the exclude vector and their dependencies
419                var layer, fixedLayers = {};
420                for(var mid in bc.layers){
421                        layer = bc.layers[mid];
422                        layer.exclude = layer.exclude || [];
423                        layer.include = layer.include || [];
424                        layer.boot = !!layer.boot;
425                        layer.discard = !!layer.discard;
426                        layer.compat = layer.compat!==undefined ? layer.compat : (bc.layerCompat ||"");
427                        layer.noref = !!(layer.noref!==undefined ? layer.noref : (layer.compat=="1.6" ? true : bc.noref));
428
429                        var tlm = mid.split("/")[0],
430                                pack = bc.packages[tlm],
431                                packLocation = pack && pack.location,
432                                packCopyright = pack && pack.copyright,
433                                packCopyrightLayers = pack && pack.copyrightLayers;
434                        if(isNonemptyString(layer.copyright)){
435                                // if relative, first try basePath, then try package location, otherwise, just use what's given
436                                layer.copyright = (packLocation && maybeRead(computePath(layer.copyright, packLocation))) || maybeRead(computePath(layer.copyright, bc.basePath)) || layer.copyright;
437                        }else if(isDefined(layer.copyright)){
438                                // some kind of truthy other than a string
439                                layer.copyright = layer.copyright ? (packCopyright || bc.copyright) : "";
440                        }else{
441                                layer.copyright = pack ? (packCopyrightLayers && (packCopyright || bc.copyright)) : (bc.copyrightLayers && bc.copyright);
442                        }
443                        if(!layer.copyright){
444                                layer.copyright = "";
445                        }
446                        fixedLayers[mid] = layer;
447                }
448                bc.layers = fixedLayers;
449
450                // if (and only if) we're doing a build that includes the dojo tree, then ensure the loader layer is defined correctly
451                // and make sure all other layers exclude the loader unless they are marked with custome base
452                if(bc.packages.dojo){
453                        if(!bc.layers["dojo/dojo"]){
454                                bc.layers["dojo/dojo"] = {name:"dojo/dojo", copyright:bc.defaultCopyright + bc.defaultBuildNotice, include:["dojo/main"], exclude:[]};
455                        }
456                        for(var p in bc.layers){
457                                layer = bc.layers[p];
458                                if(p=="dojo/dojo"){
459                                        if(!layer.customBase){
460                                                // the purpose of the layer is to simply add some additional modules to a standard dojo boot
461                                                if(layer.include.indexOf("dojo/main")==-1){
462                                                        layer.include.push("dojo/main");
463                                                }
464                                        }else{
465                                                // this is a custom base dojo.js; it's up the the user to say exactly what they want
466                                        }
467                                }else{
468                                        if((layer.boot || !layer.customBase) && layer.exclude.indexOf("dojo/dojo")==-1){
469                                                // the layer has dojo/dojo if it is booting, or assumes dojo/dojo if its not explicitly saying customBase
470                                                layer.exclude.push("dojo/dojo");
471                                        }
472                                        // by definition...
473                                        layer.customBase = layer.boot;
474                                }
475                        }
476                }
477        })();
478
479
480        // for the static has flags, -1 means its not static; this gives a way of combining several static has flag sets
481        // and still allows later sets to delete flags set in earlier sets
482        var deleteStaticHasFlagSet = [];
483        for(var p in bc.staticHasFeatures) if(bc.staticHasFeatures[p]==-1) deleteStaticHasFlagSet.push(p);
484        deleteStaticHasFlagSet.forEach(function(flag){delete bc.staticHasFeatures[flag];});
485
486        if(bc.action){
487                bc.action.split(/\W|\s/).forEach(function(action){
488                        action = action.match(/\s*(\S+)\s*/)[1];
489                        switch(action){
490                                case "check":
491                                        bc.check = true;
492                                        break;
493                                case "clean":
494                                        bc.clean = true;
495                                        break;
496                                case "release":
497                                        bc.release = true;
498                                        break;
499                                default:
500                                        bc.log("inputUnknownAction", ["action", action]);
501                        }
502                });
503        }
504
505        if(bc.clean){
506                bc.log("cleanRemoved");
507        }
508
509        // understand stripConsole from dojo 1.3 and before
510        var stripConsole = bc.stripConsole;
511        if(!stripConsole || stripConsole=="none"){
512                stripConsole = false;
513        }else if(stripConsole == "normal,warn"){
514                bc.log("inputDeprecatedStripConsole", ["deprecated", "normal,warn", "use", "warn"]);
515                stripConsole = "warn";
516        }else if(stripConsole == "normal,error"){
517                bc.log("inputDeprecatedStripConsole", ["deprecated", "normal,error", "use", "all"]);
518                stripConsole = "all";
519        }else if(!/normal|warn|all|none/.test(stripConsole)){
520                bc.log("inputUnknownStripConsole", ["value", stripConsole]);
521        }
522        bc.stripConsole = stripConsole;
523
524        function fixupOptimize(value){
525                if(value){
526                        value = value + "";
527                        value = value.toLowerCase();
528                        if(!/^(((comments|shrinksafe)(\.keeplines)?)|(closure(\.keeplines)?|uglify(\.keeplines)?))$/.test(value)){
529                                bc.log("inputUnknownOptimize", ["value", value]);
530                                value = 0;
531                        }else{
532                                if(/shrinksafe/.test(value) && stripConsole){
533                                        value+= "." + stripConsole;
534                                }
535                        }
536                }
537                return value;
538        }
539        bc.optimize = fixupOptimize(bc.optimize);
540        bc.layerOptimize = fixupOptimize(bc.layerOptimize);
541
542        (function(){
543                var fixedScopeMap = {dojo:"dojo", dijit:"dijit", dojox:"dojox"};
544                (bc.scopeMap || []).forEach(function(pair){
545                        if(!pair[1]){
546                                delete fixedScopeMap[pair[0]];
547                        }else{
548                                fixedScopeMap[pair[0]] = pair[1];
549                        }
550                });
551                bc.scopeMap = fixedScopeMap;
552
553                bc.scopeNames = [];
554                for(var p in fixedScopeMap){
555                        bc.scopeNames.push(p);
556                }
557        })();
558
559        bc.internSkip = function(){return false;};
560        if(bc.internSkipList){
561                bc.internSkip = function(mid, referenceModule){
562                        return bc.internSkipList.some(function(item){
563                                var result = false;
564                                if(item instanceof RegExp){
565                                        result = item.test(mid);
566                                }else if(item instanceof Function){
567                                        result = item(mid, referenceModule);
568                                }else{
569                                        result = item==mid;
570                                }
571                                if(result){
572                                        bc.log("internStrings", ["module", referenceModule.mid, "skipping", mid]);
573                                }
574                                return result;
575                        });
576                };
577        }
578
579        // dump bc (if requested) before changing gate names to gate ids below
580        if(bc.check){
581                (function(){
582                        var toDump = {
583                                aliases:1,
584                                basePath:1,
585                                buildReportDir:1,
586                                buildReportFilename:1,
587                                closureCompilerPath:1,
588                                copyright:1,
589                                copyrightLayers:1,
590                                copyrightNonlayers:1,
591                                copyTests:1,
592                                destBasePath:1,
593                                destModules:1,
594                                destPackages:1,
595                                destPathTransforms:1,
596                                dirs:1,
597                                discoveryProcs:1,
598                                files:1,
599                                insertAbsMids:1,
600                                internStringsSkipList:1,
601                                layers:1,
602                                localeList:1,
603                                includeLocales: 1,
604                                maxOptimizationProcesses:1,
605                                mini:1,
606                                optimize:1,
607                                layerOptimize:1,
608                                "package":1,
609                                packages:1,
610                                paths:1,
611                                pathsMapProg:1,
612                                plugins:1,
613                                replacements:1,
614                                startTimestamp:1,
615                                staticHasFeatures:1,
616                                stripConsole:1,
617                                trees:1,
618                                useSourceMaps:1
619                        };
620                        for(var p in toDump){
621                                toDump[p] = bc[p];
622                        }
623                        bc.log("pacify", stringify(toDump));
624                })();
625                bc.release = 0;
626        }
627
628        if(bc.writeProfile){
629                // TODO
630                // fs.writeFileSync(bc.writeProfile, "dependencies = " + dojo.toJson(profileProperties, true), "utf8");
631        }
632
633        if(bc.debugCheck){
634                (function(){
635                        var toDump = {};
636                        for(var p in bc){
637                                if(bc[p]!==messages[p] && typeof bc[p]!="function"){
638                                        toDump[p] = bc[p];
639                                }
640                        }
641                        console.log("profile:");
642                        console.log(stringify(toDump));
643                        toDump = {};
644                        for(p in require){
645                                if(p!="modules" && p!="module" && p!="rawConfig" && typeof require[p]!="function"){
646                                        toDump[p] = require[p];
647                                }
648                        }
649                        console.log("require config:");
650                        console.log(stringify(toDump));
651                })();
652                bc.release = 0;
653        }
654
655        // clean up the gates and transforms
656        (function(){
657                // check that each transform references a valid gate
658                for(var gates = {}, i = 0; i<bc.gates.length; i++){
659                        gates[bc.gates[i][1]] = i;
660                }
661                var
662                        transforms = bc.transforms,
663                        gateId;
664                for(var transformId in transforms){
665                        // each item is a [AMD-MID, gateName] pair
666                        gateId = gates[transforms[transformId][1]];
667                        if(typeof gateId == "undefined"){
668                                bc.log("inputUnknownGate", ["transform", transformId, "gate", transforms[transformId][1]]);
669                        }else{
670                                transforms[transformId][1] = gateId;
671                        }
672                }
673        })();
674
675        // clean up the transformJobs
676        (function(){
677                // check that that each transformId referenced in transformJobs references an existing item in transforms
678                // ensure proper gate order of the transforms given in transformJobs; do not disturb order within a given
679                // gate--this is the purview of the user
680                var transforms = bc.transforms;
681                bc.transformJobs.forEach(function(item){
682                        // item is a [predicate, vector of transformId] pairs
683                        var error = false;
684                        var tlist = item[1].map(function(id){
685                                // item is a transformId
686                                if(transforms[id]){
687                                        // return a [trandformId, gateId] pair
688                                        return [id, transforms[id][1]];
689                                }else{
690                                        error = true;
691                                        bc.log("inputUnknownTransform", ["transform", id]);
692                                        return 0;
693                                }
694                        });
695                        // tlist is a vector of [transformId, gateId] pairs than need to be checked for order
696                        if(!error){
697                                for(var i = 0, end = tlist.length - 1; i<end;){
698                                        if(tlist[i][1]>tlist[i+1][1]){
699                                                var t = tlist[i];
700                                                tlist[i] = tlist[i+1];
701                                                tlist[i+1] = t;
702                                                i && i--;
703                                        }else{
704                                                i++;
705                                        }
706                                }
707                                // now replace the vector of transformIds with the sorted list
708                                item[1] = tlist;
709                        }
710                });
711        })();
712
713        if(argv.args.unitTest=="dumpbc"){
714                console.log(stringify(bc) + "\n");
715        }
716
717        if(bc.quiet){
718                (function(){
719                        var delSet = {};
720                        for(var p in bc.pacifySet){
721                                if(bc.messageMap[p][1]>199){
722                                        delSet[p] = 1;
723                                }
724                        }
725                        for(p in delSet){
726                                delete bc.pacifySet[p];
727                        }
728                })();
729        }
730
731        if(bc.unitTestComputedProfile){
732                bc.unitTestComputedProfile();
733                // stop the build
734                bc.release = 0;
735        }
736
737        if(!bc.unitTestComputedProfile && !bc.check && !bc.debugCheck && !bc.clean && !bc.release){
738                bc.log("pacify", "Nothing to do; you must explicitly instruct the application to do something; use the option --help for help.");
739        }
740
741        return bc;
742});
Note: See TracBrowser for help on using the repository browser.