751 lines
24 KiB
JavaScript
751 lines
24 KiB
JavaScript
define([
|
|
"require",
|
|
"dojo/_base/lang",
|
|
"./argv",
|
|
"./fs",
|
|
"./fileUtils",
|
|
"./buildControlDefault",
|
|
"./v1xProfiles",
|
|
"./stringify",
|
|
"./process",
|
|
"./messages",
|
|
"dojo/text!./help.txt"
|
|
], function(require, lang, argv, fs, fileUtils, bc, v1xProfiles, stringify, process, messages, helpText){
|
|
//
|
|
// Process the arguments given on the command line to build up a profile object that is used to instruct and control
|
|
// the build process.
|
|
//
|
|
// This modules is a bit tedious. Is methodically goes through each option set, cleaning and conditioning user input making it
|
|
// easy to use for the remainder of the program. Readers are advised to tackle it top-to-bottom. There is no magic...just
|
|
// a whole bunch of imperative programming.
|
|
//
|
|
|
|
if(!isNaN(argv)){
|
|
// if argv is a number, then it's an exit code
|
|
bc.exitCode = argv;
|
|
return bc;
|
|
}
|
|
|
|
eval(require.scopeify("./fs, ./fileUtils, ./v1xProfiles"));
|
|
var
|
|
isString = function(it){
|
|
return typeof it === "string";
|
|
},
|
|
|
|
isNonemptyString = function(it){
|
|
return isString(it) && it.length;
|
|
},
|
|
|
|
isDefined = function(it){
|
|
return typeof it !="undefined";
|
|
},
|
|
|
|
cleanupFilenamePair = function(item, srcBasePath, destBasePath, hint){
|
|
var result;
|
|
if(isString(item)){
|
|
result = [computePath(item, srcBasePath), computePath(item, destBasePath)];
|
|
}else{
|
|
result = [computePath(item[0], srcBasePath), computePath(item[1], destBasePath)].concat(item.slice(2));
|
|
}
|
|
if(!isAbsolutePath(result[0]) || !isAbsolutePath(result[1])){
|
|
bc.log("inputInvalidPath", ["path", item, "hint", hint]);
|
|
}
|
|
return result;
|
|
},
|
|
|
|
slashTerminate = function(path){
|
|
return path + /\/$/.test(path) ? "" : "/";
|
|
},
|
|
|
|
isEmpty = function(it){
|
|
for(var p in it) return false;
|
|
return true;
|
|
},
|
|
|
|
cleanDeprecated = function(o, inputFile){
|
|
var deprecated = [];
|
|
for(var p in o){
|
|
if(/^(log|loader|xdDojoPath|scopeDjConfig|xdScopeArgs|xdDojoScopeName|expandProvide|buildLayers|query|removeDefaultNameSpaces|addGuards)$/.test(p)){
|
|
deprecated.push(p);
|
|
bc.log("inputDeprecated", ["switch", p, inputFile]);
|
|
}
|
|
}
|
|
deprecated.forEach(function(p){
|
|
delete o[p];
|
|
});
|
|
},
|
|
|
|
mix = function(dest, src){
|
|
dest = dest || {};
|
|
src = src || {};
|
|
for(var p in src) dest[p] = src[p];
|
|
return dest;
|
|
},
|
|
|
|
mixPackage = function(packageInfo){
|
|
var name = packageInfo.name;
|
|
bc.packageMap[name] = mix(bc.packageMap[name], packageInfo);
|
|
},
|
|
|
|
// mix a profile object into the global profile object
|
|
mixProfileObject = function(src){
|
|
cleanDeprecated(src, src.selfFilename);
|
|
|
|
// the profile properties...
|
|
// paths, plugins, transforms, staticHasFeatures
|
|
// ...are mixed one level deep; messageCategories, messages, packages, and packagePaths require special handling; all others are over-written
|
|
// FIXME: the only way to modify the transformJobs vector is to create a whole new vector?
|
|
for(var p in src){
|
|
if(!/paths|plugins|messages|transforms|staticHasFeatures|packages|packagePaths|defaultConfig/.test(p)){
|
|
bc[p] = src[p];
|
|
}
|
|
}
|
|
|
|
// the one-level-deep mixers
|
|
["paths","plugins","transforms","staticHasFeatures"].forEach(function(p){
|
|
bc[p] = mix(bc[p], src[p]);
|
|
});
|
|
|
|
// messages require special handling
|
|
if(src.messageCategories){
|
|
for(p in src.messageCategories){
|
|
bc.addCategory(p, src.messageCategories[p]);
|
|
}
|
|
}
|
|
(src.messages || []).forEach(function(item){bc.addMessage.apply(bc, item);});
|
|
|
|
// packagePaths and packages require special processing to get their contents into packageMap; do that first...
|
|
// process packagePaths before packages before packageMap since packagePaths is less specific than
|
|
// packages is less specific than packageMap. Notice that attempts to edit an already-existing package
|
|
// only edits specific package properties given (see mixPackage, above)
|
|
for(var base in src.packagePaths){
|
|
src.packagePaths[base].forEach(function(packageInfo){
|
|
if(isString(packageInfo)){
|
|
packageInfo = {name:packageInfo};
|
|
}
|
|
packageInfo.location = catPath(base, packageInfo.name);
|
|
mixPackage(packageInfo);
|
|
});
|
|
}
|
|
(src.packages || []).forEach(function(packageInfo){
|
|
if(isString(packageInfo)){
|
|
packageInfo = {name:packageInfo};
|
|
}
|
|
mixPackage(packageInfo);
|
|
});
|
|
|
|
// defaultConfig requires special handling
|
|
for(p in src.defaultConfig){
|
|
if(p=="hasCache"){
|
|
mix(bc.defaultConfig.hasCache, src.defaultConfig.hasCache);
|
|
}else{
|
|
bc.defaultConfig[p] = src.defaultConfig[p];
|
|
}
|
|
}
|
|
};
|
|
|
|
argv.args.profiles.forEach(function(item){
|
|
var temp = mix({}, item),
|
|
build = item.build;
|
|
delete temp.build;
|
|
mixProfileObject(temp);
|
|
build && mixProfileObject(build);
|
|
});
|
|
|
|
cleanDeprecated(argv.args, "command line");
|
|
|
|
// lastly, explicit command line switches override any evaluated profile objects
|
|
for(var argName in argv.args) if(argName!="profiles"){
|
|
bc[argName] = argv.args[argName];
|
|
}
|
|
|
|
// at this point the raw profile object has been fully initialized; clean it up and look for errors...
|
|
bc.basePath = computePath(bc.basePath, process.cwd());
|
|
var releaseDir = catPath(bc.releaseDir || "../release", bc.releaseName || "");
|
|
bc.destBasePath = computePath(releaseDir, bc.basePath);
|
|
|
|
// compute global copyright, if any
|
|
bc.copyright = isNonemptyString(bc.copyright) ? (maybeRead(computePath(bc.copyright, bc.basePath)) || bc.copyright) : "";
|
|
bc.copyrightLayers = !!bc.copyrightLayers;
|
|
bc.copyrightNonlayers = !!bc.copyrightNonlayers;
|
|
|
|
// compute files, dirs, and trees
|
|
(function(){
|
|
for(var property in {files:1, dirs:1, trees:1}){
|
|
if(bc[property] instanceof Array){
|
|
bc[property] = bc[property].map(function(item){
|
|
return cleanupFilenamePair(item, bc.basePath, bc.destBasePath, property);
|
|
});
|
|
}
|
|
}
|
|
})();
|
|
|
|
// cleanup the replacements (if any)
|
|
(function(){
|
|
var cleanSet = {}, src, dest;
|
|
for(src in bc.replacements){
|
|
cleanSet[computePath(src, bc.basePath)] = bc.replacements[src];
|
|
}
|
|
bc.replacements = cleanSet;
|
|
})();
|
|
|
|
// explicit mini and/or copyTests wins; explicit copyTests ignores explicit mini
|
|
if(!("mini" in bc)){
|
|
bc.mini = true;
|
|
}
|
|
if(!("copyTests" in bc)){
|
|
bc.copyTests = !bc.mini;
|
|
}
|
|
if(isString(bc.copyTests)){
|
|
bc.copyTests = bc.copyTests.toLowerCase();
|
|
}
|
|
if(bc.copyTests!="build"){
|
|
// convert to pure boolean
|
|
bc.copyTests = !!bc.copyTests;
|
|
}
|
|
|
|
function getDiscreteLocales(locale){
|
|
for(var locales = locale.split("-"), result = [], current = "", i = 0; i<locales.length; i++){
|
|
result.push(current += (i ? "-" : "") + locales[i]);
|
|
}
|
|
return result;
|
|
}
|
|
if(isString(bc.localeList)){
|
|
bc.localeList = bc.localeList.split(",");
|
|
if(bc.localeList.length){
|
|
bc.localeList = bc.localeList.map(function(locale){ return lang.trim(locale); });
|
|
}
|
|
}
|
|
if(bc.localeList && bc.localeList.length){
|
|
if(bc.localeList.indexOf("ROOT")==-1){
|
|
bc.localeList.push("ROOT");
|
|
}
|
|
var localeList = {};
|
|
bc.localeList.forEach(function(locale){
|
|
locale = lang.trim(locale);
|
|
localeList[locale] = getDiscreteLocales(locale);
|
|
});
|
|
bc.localeList.discreteLocales = localeList;
|
|
}else{
|
|
bc.localeList = false;
|
|
}
|
|
|
|
|
|
(function(){
|
|
function processPackage(pack){
|
|
var packName = pack.name,
|
|
basePath = pack.basePath || bc.basePath;
|
|
if(!pack.packageJson){
|
|
pack.packageJson = argv.readPackageJson(catPath(computePath(pack.location || ("./" + packName), basePath), "package.json"), "missingPackageJson");
|
|
}
|
|
var packageJson = pack.packageJson;
|
|
if(packageJson){
|
|
if(packageJson.version){
|
|
bc.log("packageVersion", ["package", packName, "version", packageJson.version]);
|
|
|
|
// new for 1.7, if version is not provided, the version of the dojo package is used
|
|
if(typeof bc.version=="undefined" && packName=="dojo"){
|
|
bc.version = packageJson.version;
|
|
}
|
|
}
|
|
if(packageJson.main && !pack.main){
|
|
pack.main= packageJson.main;
|
|
}
|
|
if(packageJson.directories && packageJson.directories.lib && !pack.location){
|
|
pack.location = catPath(getFilepath(packageJson.selfFilename), packageJson.directories.lib);
|
|
}
|
|
if("dojoBuild" in packageJson){
|
|
var defaultProfile = argv.readProfile("profile", catPath(getFilepath(packageJson.selfFilename), packageJson.dojoBuild));
|
|
for(var p in defaultProfile){
|
|
if(!(p in pack)){
|
|
pack[p] = defaultProfile[p];
|
|
}else if(p in {resourceTags:1}){
|
|
// these are mixed one level deep
|
|
// TODO: review all profile properties and see if there are any others than resourceTags that ought to go here
|
|
mix(pack[p], defaultProfile[p]);
|
|
}
|
|
}
|
|
}else{
|
|
bc.log("missingProfile", ["package", packageJson.name]);
|
|
}
|
|
}
|
|
|
|
// build up info to tell all about a package; all properties semantically identical to definitions used by dojo loader/bdLoad
|
|
pack.main = isString(pack.main) ? pack.main : "main";
|
|
if(pack.main.indexOf("./")===0){
|
|
pack.main = pack.main.substring(2);
|
|
}
|
|
if(pack.destMain && pack.destMain.indexOf("./")===0){
|
|
pack.destMain = pack.destMain.substring(2);
|
|
}
|
|
|
|
pack.location = computePath(pack.location || ("./" + packName), basePath);
|
|
|
|
pack.copyright = isNonemptyString(pack.copyright) ?
|
|
(maybeRead(computePath(pack.copyright, pack.location)) || maybeRead(computePath(pack.copyright, bc.basePath)) || pack.copyright) :
|
|
(pack.copyright ? bc.copyright : "");
|
|
pack.copyrightLayers = isDefined(pack.copyrightLayers) ? !!pack.copyrightLayers : bc.copyrightLayers;
|
|
pack.copyrightNonlayers = isDefined(pack.copyrightNonlayers) ? !!pack.copyrightNonlayers : bc.copyrightNonlayers;
|
|
|
|
// dest says where to output the compiled code stack
|
|
var destPack = bc.destPackages[packName] = {
|
|
name:pack.destName || packName,
|
|
main:pack.destMain || pack.main,
|
|
location:computePath(pack.destLocation || ("./" + (pack.destName || packName)), bc.destBasePath)
|
|
};
|
|
delete pack.destName;
|
|
delete pack.destMain;
|
|
delete pack.destLocation;
|
|
|
|
|
|
if(!pack.trees){
|
|
// copy the package tree; don't copy any hidden directorys (e.g., .git, .svn) or temp files
|
|
pack.trees = [[pack.location, destPack.location, /(\/\.)|(^\.)|(~$)/]];
|
|
} // else the user has provided explicit copy instructions
|
|
|
|
// filenames, dirs, trees just like global, except relative to the pack.(src|dest)Location
|
|
for(var property in {files:1, dirs:1, trees:1}){
|
|
pack[property] = (pack[property] || []).map(function(item){
|
|
return cleanupFilenamePair(item, pack.location, destPack.location, property + " in package " + packName);
|
|
});
|
|
}
|
|
}
|
|
|
|
// so far, we've been using bc.packageMap to accumulate package info as it is provided by packagePaths and/or packages
|
|
// in zero to many profile scripts. This routine moves each package config into bc.packages which is a map
|
|
// from package name to package config (this is different from the array the user uses to pass package config info). Along
|
|
// the way, each package config object is cleaned up and all default values are calculated.
|
|
bc.packages = bc.packageMap;
|
|
delete bc.packageMap;
|
|
bc.destPackages = {};
|
|
for(var packageName in bc.packages){
|
|
var pack = bc.packages[packageName];
|
|
pack.name = pack.name || packageName;
|
|
processPackage(pack);
|
|
}
|
|
|
|
// now that we know the dojo path, we can automatically add DOH, if required
|
|
if(bc.copyTests && !bc.packages.doh){
|
|
bc.packages.doh = {
|
|
name:"doh",
|
|
location:compactPath(bc.packages.dojo.location + "/../util/doh"),
|
|
destLocation:"util/doh"
|
|
};
|
|
processPackage(bc.packages.doh);
|
|
}
|
|
|
|
// get this done too...
|
|
require.computeAliases(bc.aliases, (bc.aliasesMap = []));
|
|
require.computeMapProg(bc.paths, (bc.pathsMapProg = []));
|
|
|
|
bc.mapProgs = [];
|
|
require.computeMapProg(bc.map, bc.mapProgs);
|
|
bc.mapProgs.forEach(function(item){
|
|
item[1] = require.computeMapProg(item[1], []);
|
|
if(item[0]=="*"){
|
|
bc.mapProgs.star = item;
|
|
}
|
|
});
|
|
|
|
// add some methods to bc to help with resolving AMD module info
|
|
bc.srcModules = {};
|
|
bc.destModules = {};
|
|
|
|
var trimLastChars = function(text, n){
|
|
return text.substring(0, text.length-n);
|
|
};
|
|
|
|
bc.getSrcModuleInfo = function(mid, referenceModule, ignoreFileType){
|
|
if(ignoreFileType){
|
|
var result = require.getModuleInfo(mid+"/x", referenceModule, bc.packages, bc.srcModules, bc.basePath + "/", bc.mapProgs, bc.pathsMapProg, bc.aliasesMap, true);
|
|
result.mid = trimLastChars(result.mid, 2);
|
|
if(result.pid!==0){
|
|
// trim /x.js
|
|
result.url = trimLastChars(result.url, 5);
|
|
}
|
|
return result;
|
|
}else{
|
|
return require.getModuleInfo(mid, referenceModule, bc.packages, bc.srcModules, bc.basePath + "/", bc.mapProgs, bc.pathsMapProg, bc.aliasesMap, true);
|
|
}
|
|
};
|
|
|
|
|
|
bc.getDestModuleInfo = function(mid, referenceModule, ignoreFileType){
|
|
// notice no mapping, paths, aliases in the dest getModuleInfo....just send stuff to where it should go without manipulation
|
|
if(ignoreFileType){
|
|
var result = require.getModuleInfo(mid+"/x", referenceModule, bc.destPackages, bc.destModules, bc.destBasePath + "/", [], [], [], true);
|
|
result.mid = trimLastChars(result.mid, 2);
|
|
if(result.pid!==0){
|
|
// trim /x.js
|
|
result.url = trimLastChars(result.url, 5);
|
|
}
|
|
return result;
|
|
}else{
|
|
return require.getModuleInfo(mid, referenceModule, bc.destPackages, bc.destModules, bc.destBasePath + "/", [], [], [], true);
|
|
}
|
|
};
|
|
|
|
bc.getAmdModule = function(
|
|
mid,
|
|
referenceModule
|
|
){
|
|
var match = mid.match(/^([^\!]+)\!(.*)$/);
|
|
if(match){
|
|
var pluginModuleInfo = bc.getSrcModuleInfo(match[1], referenceModule),
|
|
pluginModule = pluginModuleInfo && bc.amdResources[pluginModuleInfo.mid],
|
|
pluginId = pluginModule && pluginModule.mid,
|
|
pluginProc = bc.plugins[pluginId];
|
|
if(!pluginModule){
|
|
return 0;
|
|
}else if(!pluginProc){
|
|
if(!pluginModule.noBuildResolver){
|
|
bc.log("missingPluginResolver", ["module", referenceModule.mid, "plugin", pluginId]);
|
|
}
|
|
return pluginModule;
|
|
}else{
|
|
// flatten the list of modules returned from the plugin
|
|
var modules = [].concat(pluginProc.start(match[2], referenceModule, bc));
|
|
return modules.concat.apply([], modules);
|
|
}
|
|
}else{
|
|
var moduleInfo = bc.getSrcModuleInfo(mid, referenceModule),
|
|
module = moduleInfo && bc.amdResources[moduleInfo.mid];
|
|
return module;
|
|
}
|
|
};
|
|
|
|
})();
|
|
|
|
|
|
if(bc.selectorEngine && bc.defaultConfig && bc.defaultConfig.hasCache){
|
|
bc.defaultConfig.hasCache["config-selectorEngine"] = bc.selectorEngine;
|
|
}
|
|
|
|
(function(){
|
|
// a layer is a module that should be written with all of its dependencies, as well as all modules given in
|
|
// the include vector together with their dependencies, excluding modules contained in the exclude vector and their dependencies
|
|
var layer, fixedLayers = {};
|
|
for(var mid in bc.layers){
|
|
layer = bc.layers[mid];
|
|
layer.exclude = layer.exclude || [];
|
|
layer.include = layer.include || [];
|
|
layer.boot = !!layer.boot;
|
|
layer.discard = !!layer.discard;
|
|
layer.compat = layer.compat!==undefined ? layer.compat : (bc.layerCompat ||"");
|
|
layer.noref = !!(layer.noref!==undefined ? layer.noref : (layer.compat=="1.6" ? true : bc.noref));
|
|
|
|
var tlm = mid.split("/")[0],
|
|
pack = bc.packages[tlm],
|
|
packLocation = pack && pack.location,
|
|
packCopyright = pack && pack.copyright,
|
|
packCopyrightLayers = pack && pack.copyrightLayers;
|
|
if(isNonemptyString(layer.copyright)){
|
|
// if relative, first try basePath, then try package location, otherwise, just use what's given
|
|
layer.copyright = (packLocation && maybeRead(computePath(layer.copyright, packLocation))) || maybeRead(computePath(layer.copyright, bc.basePath)) || layer.copyright;
|
|
}else if(isDefined(layer.copyright)){
|
|
// some kind of truthy other than a string
|
|
layer.copyright = layer.copyright ? (packCopyright || bc.copyright) : "";
|
|
}else{
|
|
layer.copyright = pack ? (packCopyrightLayers && (packCopyright || bc.copyright)) : (bc.copyrightLayers && bc.copyright);
|
|
}
|
|
if(!layer.copyright){
|
|
layer.copyright = "";
|
|
}
|
|
fixedLayers[mid] = layer;
|
|
}
|
|
bc.layers = fixedLayers;
|
|
|
|
// if (and only if) we're doing a build that includes the dojo tree, then ensure the loader layer is defined correctly
|
|
// and make sure all other layers exclude the loader unless they are marked with custome base
|
|
if(bc.packages.dojo){
|
|
if(!bc.layers["dojo/dojo"]){
|
|
bc.layers["dojo/dojo"] = {name:"dojo/dojo", copyright:bc.defaultCopyright + bc.defaultBuildNotice, include:["dojo/main"], exclude:[]};
|
|
}
|
|
for(var p in bc.layers){
|
|
layer = bc.layers[p];
|
|
if(p=="dojo/dojo"){
|
|
if(!layer.customBase){
|
|
// the purpose of the layer is to simply add some additional modules to a standard dojo boot
|
|
if(layer.include.indexOf("dojo/main")==-1){
|
|
layer.include.push("dojo/main");
|
|
}
|
|
}else{
|
|
// this is a custom base dojo.js; it's up the the user to say exactly what they want
|
|
}
|
|
}else{
|
|
if((layer.boot || !layer.customBase) && layer.exclude.indexOf("dojo/dojo")==-1){
|
|
// the layer has dojo/dojo if it is booting, or assumes dojo/dojo if its not explicitly saying customBase
|
|
layer.exclude.push("dojo/dojo");
|
|
}
|
|
// by definition...
|
|
layer.customBase = layer.boot;
|
|
}
|
|
}
|
|
}
|
|
})();
|
|
|
|
|
|
// for the static has flags, -1 means its not static; this gives a way of combining several static has flag sets
|
|
// and still allows later sets to delete flags set in earlier sets
|
|
var deleteStaticHasFlagSet = [];
|
|
for(var p in bc.staticHasFeatures) if(bc.staticHasFeatures[p]==-1) deleteStaticHasFlagSet.push(p);
|
|
deleteStaticHasFlagSet.forEach(function(flag){delete bc.staticHasFeatures[flag];});
|
|
|
|
if(bc.action){
|
|
bc.action.split(/\W|\s/).forEach(function(action){
|
|
action = action.match(/\s*(\S+)\s*/)[1];
|
|
switch(action){
|
|
case "check":
|
|
bc.check = true;
|
|
break;
|
|
case "clean":
|
|
bc.clean = true;
|
|
break;
|
|
case "release":
|
|
bc.release = true;
|
|
break;
|
|
default:
|
|
bc.log("inputUnknownAction", ["action", action]);
|
|
}
|
|
});
|
|
}
|
|
|
|
if(bc.clean){
|
|
bc.log("cleanRemoved");
|
|
}
|
|
|
|
// understand stripConsole from dojo 1.3 and before
|
|
var stripConsole = bc.stripConsole;
|
|
if(!stripConsole || stripConsole=="none"){
|
|
stripConsole = false;
|
|
}else if(stripConsole == "normal,warn"){
|
|
bc.log("inputDeprecatedStripConsole", ["deprecated", "normal,warn", "use", "warn"]);
|
|
stripConsole = "warn";
|
|
}else if(stripConsole == "normal,error"){
|
|
bc.log("inputDeprecatedStripConsole", ["deprecated", "normal,error", "use", "all"]);
|
|
stripConsole = "all";
|
|
}else if(!/normal|warn|all|none/.test(stripConsole)){
|
|
bc.log("inputUnknownStripConsole", ["value", stripConsole]);
|
|
}
|
|
bc.stripConsole = stripConsole;
|
|
|
|
function fixupOptimize(value){
|
|
if(value){
|
|
value = value + "";
|
|
value = value.toLowerCase();
|
|
if(!/^(((comments|shrinksafe)(\.keeplines)?)|(closure(\.keeplines)?|uglify(\.keeplines)?))$/.test(value)){
|
|
bc.log("inputUnknownOptimize", ["value", value]);
|
|
value = 0;
|
|
}else{
|
|
if(/shrinksafe/.test(value) && stripConsole){
|
|
value+= "." + stripConsole;
|
|
}
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
bc.optimize = fixupOptimize(bc.optimize);
|
|
bc.layerOptimize = fixupOptimize(bc.layerOptimize);
|
|
|
|
(function(){
|
|
var fixedScopeMap = {dojo:"dojo", dijit:"dijit", dojox:"dojox"};
|
|
(bc.scopeMap || []).forEach(function(pair){
|
|
if(!pair[1]){
|
|
delete fixedScopeMap[pair[0]];
|
|
}else{
|
|
fixedScopeMap[pair[0]] = pair[1];
|
|
}
|
|
});
|
|
bc.scopeMap = fixedScopeMap;
|
|
|
|
bc.scopeNames = [];
|
|
for(var p in fixedScopeMap){
|
|
bc.scopeNames.push(p);
|
|
}
|
|
})();
|
|
|
|
bc.internSkip = function(){return false;};
|
|
if(bc.internSkipList){
|
|
bc.internSkip = function(mid, referenceModule){
|
|
return bc.internSkipList.some(function(item){
|
|
var result = false;
|
|
if(item instanceof RegExp){
|
|
result = item.test(mid);
|
|
}else if(item instanceof Function){
|
|
result = item(mid, referenceModule);
|
|
}else{
|
|
result = item==mid;
|
|
}
|
|
if(result){
|
|
bc.log("internStrings", ["module", referenceModule.mid, "skipping", mid]);
|
|
}
|
|
return result;
|
|
});
|
|
};
|
|
}
|
|
|
|
// dump bc (if requested) before changing gate names to gate ids below
|
|
if(bc.check){
|
|
(function(){
|
|
var toDump = {
|
|
aliases:1,
|
|
basePath:1,
|
|
buildReportDir:1,
|
|
buildReportFilename:1,
|
|
closureCompilerPath:1,
|
|
copyright:1,
|
|
copyrightLayers:1,
|
|
copyrightNonlayers:1,
|
|
copyTests:1,
|
|
destBasePath:1,
|
|
destModules:1,
|
|
destPackages:1,
|
|
destPathTransforms:1,
|
|
dirs:1,
|
|
discoveryProcs:1,
|
|
files:1,
|
|
insertAbsMids:1,
|
|
internStringsSkipList:1,
|
|
layers:1,
|
|
localeList:1,
|
|
includeLocales: 1,
|
|
maxOptimizationProcesses:1,
|
|
mini:1,
|
|
optimize:1,
|
|
layerOptimize:1,
|
|
"package":1,
|
|
packages:1,
|
|
paths:1,
|
|
pathsMapProg:1,
|
|
plugins:1,
|
|
replacements:1,
|
|
startTimestamp:1,
|
|
staticHasFeatures:1,
|
|
stripConsole:1,
|
|
trees:1,
|
|
useSourceMaps:1
|
|
};
|
|
for(var p in toDump){
|
|
toDump[p] = bc[p];
|
|
}
|
|
bc.log("pacify", stringify(toDump));
|
|
})();
|
|
bc.release = 0;
|
|
}
|
|
|
|
if(bc.writeProfile){
|
|
// TODO
|
|
// fs.writeFileSync(bc.writeProfile, "dependencies = " + dojo.toJson(profileProperties, true), "utf8");
|
|
}
|
|
|
|
if(bc.debugCheck){
|
|
(function(){
|
|
var toDump = {};
|
|
for(var p in bc){
|
|
if(bc[p]!==messages[p] && typeof bc[p]!="function"){
|
|
toDump[p] = bc[p];
|
|
}
|
|
}
|
|
console.log("profile:");
|
|
console.log(stringify(toDump));
|
|
toDump = {};
|
|
for(p in require){
|
|
if(p!="modules" && p!="module" && p!="rawConfig" && typeof require[p]!="function"){
|
|
toDump[p] = require[p];
|
|
}
|
|
}
|
|
console.log("require config:");
|
|
console.log(stringify(toDump));
|
|
})();
|
|
bc.release = 0;
|
|
}
|
|
|
|
// clean up the gates and transforms
|
|
(function(){
|
|
// check that each transform references a valid gate
|
|
for(var gates = {}, i = 0; i<bc.gates.length; i++){
|
|
gates[bc.gates[i][1]] = i;
|
|
}
|
|
var
|
|
transforms = bc.transforms,
|
|
gateId;
|
|
for(var transformId in transforms){
|
|
// each item is a [AMD-MID, gateName] pair
|
|
gateId = gates[transforms[transformId][1]];
|
|
if(typeof gateId == "undefined"){
|
|
bc.log("inputUnknownGate", ["transform", transformId, "gate", transforms[transformId][1]]);
|
|
}else{
|
|
transforms[transformId][1] = gateId;
|
|
}
|
|
}
|
|
})();
|
|
|
|
// clean up the transformJobs
|
|
(function(){
|
|
// check that that each transformId referenced in transformJobs references an existing item in transforms
|
|
// ensure proper gate order of the transforms given in transformJobs; do not disturb order within a given
|
|
// gate--this is the purview of the user
|
|
var transforms = bc.transforms;
|
|
bc.transformJobs.forEach(function(item){
|
|
// item is a [predicate, vector of transformId] pairs
|
|
var error = false;
|
|
var tlist = item[1].map(function(id){
|
|
// item is a transformId
|
|
if(transforms[id]){
|
|
// return a [trandformId, gateId] pair
|
|
return [id, transforms[id][1]];
|
|
}else{
|
|
error = true;
|
|
bc.log("inputUnknownTransform", ["transform", id]);
|
|
return 0;
|
|
}
|
|
});
|
|
// tlist is a vector of [transformId, gateId] pairs than need to be checked for order
|
|
if(!error){
|
|
for(var i = 0, end = tlist.length - 1; i<end;){
|
|
if(tlist[i][1]>tlist[i+1][1]){
|
|
var t = tlist[i];
|
|
tlist[i] = tlist[i+1];
|
|
tlist[i+1] = t;
|
|
i && i--;
|
|
}else{
|
|
i++;
|
|
}
|
|
}
|
|
// now replace the vector of transformIds with the sorted list
|
|
item[1] = tlist;
|
|
}
|
|
});
|
|
})();
|
|
|
|
if(argv.args.unitTest=="dumpbc"){
|
|
console.log(stringify(bc) + "\n");
|
|
}
|
|
|
|
if(bc.quiet){
|
|
(function(){
|
|
var delSet = {};
|
|
for(var p in bc.pacifySet){
|
|
if(bc.messageMap[p][1]>199){
|
|
delSet[p] = 1;
|
|
}
|
|
}
|
|
for(p in delSet){
|
|
delete bc.pacifySet[p];
|
|
}
|
|
})();
|
|
}
|
|
|
|
if(bc.unitTestComputedProfile){
|
|
bc.unitTestComputedProfile();
|
|
// stop the build
|
|
bc.release = 0;
|
|
}
|
|
|
|
if(!bc.unitTestComputedProfile && !bc.check && !bc.debugCheck && !bc.clean && !bc.release){
|
|
bc.log("pacify", "Nothing to do; you must explicitly instruct the application to do something; use the option --help for help.");
|
|
}
|
|
|
|
return bc;
|
|
});
|