123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- var path = require('path'),
- url = require('url'),
- _ = require('lodash'),
- readdirp = require('readdirp'),
- fs = require('fs');
- function eachConfigFile(root, callback) {
- var result = {files: [], dirs: []};
- readdirp(
- {root: root, entryType: 'both'},
- function (fileInfo) {
- if (fileInfo.stat.isDirectory()) {
- result.dirs[fileInfo.fullPath] = fileInfo.stat;
- } else if (fileInfo.name.match(/\.amd\.json$/)) {
- result.files[fileInfo.fullPath] = fileInfo.stat;
- }
- },
- function (err, res) {
- if (err) callback(err);
- else callback(null, result);
- }
- );
- }
- function transformShimDeps(json) {
- var shimmedList = json.shim && Object.keys(json.shim);
- if (!shimmedList) return;
- for (var i = 0; i < shimmedList.length; i++) {
- var shim = json.shim[shimmedList[i]];
- if (Array.isArray(shim)) {
- json.shim[shimmedList[i]] = {deps: shim};
- }
- }
- }
- function transformPaths(json, root, file, dirs) {
- if (json.paths) {
- var specifier = path.basename(file, ".amd.json");
- var modulePath = specifier === "local" ? path.dirname(file) : dirs[specifier];
- var dir = (path.relative(root, modulePath).split(path.sep).join('/') || ".") + '/';
- transformPathArray(json.paths);
- }
- function transformPathArray(array) {
- var paths = Object.keys(array);
- for (var i = 0; i < paths.length; i++) {
- var key = paths[i];
- var pathValue = array[key];
- switch (typeof pathValue) {
- case "string":
- array[key] = url.resolve(dir, pathValue) || ".";
- break;
- case "object":
- Array.isArray(pathValue) && transformPathArray(pathValue);
- break;
- }
- }
- }
- }
- function isLessDeep(a, b) {
- var bDepth = b ? b.split(path.sep).length : Infinity;
- var aDepth = a ? a.split(path.sep).length : Infinity;
- return aDepth < bDepth;
- }
- function constructDirMap(dirs) {
- var result = {};
- for (var i = 0; i < dirs.length; i++) {
- var dir = dirs[i];
- var basename = path.basename(dir);
- if (isLessDeep(dir, result[basename])) {
- result[basename] = dir;
- }
- }
- return result;
- }
- function queueOfFilesToProcess(files, dirMap) {
- var firstPass = [], secondPass = [];
- for (var i = 0; i < files.length; i++) {
- var file = files[i];
- var specifier = path.basename(file, ".amd.json");
- if (specifier == "" || specifier[0] == ".") {
- continue;
- } else if (specifier == "local") {
- firstPass.push(file);
- } else if (dirMap[specifier]) {
- secondPass.push(file);
- } else {
- throw new Error("No location for " + file);
- }
- }
- return firstPass.concat(secondPass).reverse();
- }
- exports.produceConfigObject = function (root, callback) {
- root = path.resolve(root);
- eachConfigFile(root, function (err, filesAndDirs) {
- if (err) {
- callback(err);
- return;
- }
- var dirMap = constructDirMap(Object.keys(filesAndDirs.dirs));
- var queue;
- try {
- queue = queueOfFilesToProcess(Object.keys(filesAndDirs.files), dirMap);
- } catch (e) {
- callback(e);
- return;
- }
- if (!queue.length) {
- callback(new Error("No .amd.json-type file found"));
- return;
- }
- var result = {};
- for (var i = 0; i < queue.length; i++) {
- var file = queue[i];
- var json = require(file);
- transformShimDeps(json);
- transformPaths(json, root, file, dirMap);
- _.merge(result, json, function (a, b) {
- return _.isArray(a) ? b.concat(a) : undefined;
- });
- }
- callback(null, result);
- });
- };
|