You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
759 lines
24 KiB
759 lines
24 KiB
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); |
|
|
|
if(/closure/.test(bc.optimize) || /closure/.test(bc.layerOptimize)){ |
|
bc.optimizeOptions = bc.optimizeOptions || {}; |
|
// ECMASCRIPT_2017 is necessary to avoid throwing errors on block-scoped functions |
|
// https://github.com/google/closure-compiler/issues/3189 |
|
bc.optimizeOptions.languageIn = bc.optimizeOptions.languageIn || 'ECMASCRIPT_2017'; |
|
// ECMASCRIPT3 is necessary to preserve compatibility with older browsers/JS runtimes |
|
bc.optimizeOptions.languageOut = bc.optimizeOptions.languageOut || 'ECMASCRIPT3'; |
|
} |
|
|
|
(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; |
|
});
|
|
|