From ae4b764d40e32c61328f1c4a4a1380d19dda855d Mon Sep 17 00:00:00 2001 From: Yoni Shalom Date: Wed, 11 Sep 2013 23:21:30 +0300 Subject: [PATCH] initial requirejs config packages support --- lib/tasks/register.js | 91 +++++++++++++++++++++++++++++++++++---- lib/tasks/tracker.js | 25 ++++------- src/tasks/register.coffee | 63 ++++++++++++++++++++++++--- src/tasks/tracker.coffee | 18 +++----- 4 files changed, 153 insertions(+), 44 deletions(-) diff --git a/lib/tasks/register.js b/lib/tasks/register.js index c40c3fc..05b7f20 100644 --- a/lib/tasks/register.js +++ b/lib/tasks/register.js @@ -31,6 +31,8 @@ module.exports = RequireRegister = (function() { RequireRegister.prototype.mappings = {}; + RequireRegister.prototype.packages = {}; + RequireRegister.prototype.shims = {}; RequireRegister.prototype.originalConfig = {}; @@ -128,6 +130,7 @@ module.exports = RequireRegister = (function() { this.mappings = _.clone(previousTrackingInfo.mappings); this.originalConfig = _.clone(previousTrackingInfo.originalConfig); this.requireFiles = _.clone(previousTrackingInfo.requireFiles); + this.packages = _.clone(previousTrackingInfo.packages); } this.verify = this.config.require.verify.enabled; if (this.rootJavaScriptDir == null) { @@ -268,7 +271,7 @@ module.exports = RequireRegister = (function() { RequireRegister.prototype._require = function(fileName) { var _this = this; return function(deps, callback, errback, optional) { - var config, _ref, _ref1, _ref2, _ref3; + var config, _ref, _ref1, _ref2, _ref3, _ref4; _ref = _this._requireOverride(deps, callback, errback, optional), deps = _ref[0], config = _ref[1]; if (config || deps) { if (__indexOf.call(_this.requireFiles, fileName) < 0) { @@ -278,8 +281,8 @@ module.exports = RequireRegister = (function() { track.requireFiles(_this.requireFiles); } if (config) { - _this._handleConfigPaths(fileName, (_ref1 = config.map) != null ? _ref1 : null, (_ref2 = config.paths) != null ? _ref2 : null); - _this._handleShims(fileName, (_ref3 = config.shim) != null ? _ref3 : null); + _this._handleConfigPaths(fileName, (_ref1 = config.map) != null ? _ref1 : null, (_ref2 = config.paths) != null ? _ref2 : null, (_ref3 = config.packages) != null ? _ref3 : null); + _this._handleShims(fileName, (_ref4 = config.shim) != null ? _ref4 : null); } } if (config != null) { @@ -294,7 +297,7 @@ module.exports = RequireRegister = (function() { RequireRegister.prototype._mergeOriginalConfig = function(config) { var _this = this; - return ["shim", "paths", "map", "config"].forEach(function(name) { + return ["shim", "paths", "map", "packages", "config"].forEach(function(name) { var conf; if (config[name] != null) { conf = _.clone(config[name]); @@ -468,14 +471,16 @@ module.exports = RequireRegister = (function() { } }; - RequireRegister.prototype._handleConfigPaths = function(fileName, maps, paths) { + RequireRegister.prototype._handleConfigPaths = function(fileName, maps, paths, packages) { var deps, file, _ref, _results; + packages = this._normalizeConfigPackages(packages); if (this.config.require.tracking.enabled) { track.aliases(fileName, paths); track.mappings(fileName, maps); + track.packages(fileName, packages); } if (this.startupComplete) { - this._verifyConfigForFile(fileName, maps, paths); + this._verifyConfigForFile(fileName, maps, paths, packages); this.depsRegistry[fileName] = []; _ref = this.depsRegistry; _results = []; @@ -485,6 +490,7 @@ module.exports = RequireRegister = (function() { } return _results; } else { + this.packages[fileName] = packages; this.aliasFiles[fileName] = paths; return this.mappings[fileName] = maps; } @@ -502,9 +508,14 @@ module.exports = RequireRegister = (function() { } }; - RequireRegister.prototype._verifyConfigForFile = function(fileName, maps, paths) { + RequireRegister.prototype._verifyConfigForFile = function(fileName, maps, paths, packages) { var alias, aliasPath; - maps = maps != null ? maps : this.mappings[fileName]; + if (maps == null) { + maps = this.mappings[fileName]; + } + if (packages == null) { + packages = this.packages[fileName]; + } paths = paths ? paths : (paths = {}, this.aliasFiles[fileName] != null ? paths = _.extend(paths, this.aliasFiles[fileName]) : void 0, this.aliasDirectories[fileName] != null ? paths = _.extend(paths, this.aliasDirectories[fileName]) : void 0, paths); this.aliasFiles[fileName] = {}; this.aliasDirectories[fileName] = {}; @@ -512,7 +523,8 @@ module.exports = RequireRegister = (function() { aliasPath = paths[alias]; this._verifyConfigPath(fileName, alias, aliasPath); } - return this._verifyConfigMappings(fileName, maps); + this._verifyConfigMappings(fileName, maps); + return this._verifyConfigPackages(fileName, packages); }; RequireRegister.prototype._verifyConfigMappings = function(fileName, maps) { @@ -559,6 +571,67 @@ module.exports = RequireRegister = (function() { return _results; }; + RequireRegister.prototype._verifyConfigPackages = function(fileName, packages) { + var fullDepPath, pkg, pkgFullDirPath, _i, _len, _results; + logger.debug("Verifying [[ " + fileName + " ]] packages:\n" + (JSON.stringify(packages))); + _results = []; + for (_i = 0, _len = packages.length; _i < _len; _i++) { + pkg = packages[_i]; + pkgFullDirPath = path.join(this.rootJavaScriptDir, pkg.location); + if (fs.existsSync(pkgFullDirPath)) { + if (fs.statSync(pkgFullDirPath).isDirectory()) { + this.aliasDirectories[fileName][pkg.name] = pkgFullDirPath; + } else { + this._logger("location for package [[ " + pkg.name + " ]] was found but is not a directory"); + } + } else { + this._logger("location for package [[ " + pkg.name + " ]] could not be found"); + } + fullDepPath = this._resolvePackagePath(fileName, pkg); + if (fs.existsSync(fullDepPath)) { + _results.push(this.aliasFiles[fileName][pkg.name] = fullDepPath); + } else { + _results.push(this._logger("Mapping inside file [[ " + fileName + " ]], for module [[ " + module + " ]] has path that cannot be found [[ " + aliasPath + " ]].")); + } + } + return _results; + }; + + RequireRegister.prototype._normalizeConfigPackages = function(packages) { + var pkgFormat; + pkgFormat = { + name: '', + location: '', + main: 'main' + }; + if ((packages != null) && Array.isArray(packages)) { + packages = _.filter(packages, function(pkg) { + if (_.isString(pkg) || _.isObject(pkg)) { + return true; + } + return logger.debug("Package defined in unknown way, skipping pkg object of type : [[ " + (typeof pkg) + " ]]"); + }); + packages = _.map(packages, function(pkg) { + if (_.isString(pkg)) { + return _.extend({}, pkgFormat, { + name: pkg + }); + } + return _.extend({}, pkgFormat, pkg); + }); + return packages; + } + logger.debug("Packages defined in unknown way (expected an array) - skipping packages object of type : [[ " + (typeof packages) + " ]]"); + return null; + }; + + RequireRegister.prototype._resolvePackagePath = function(fileName, pkg, alias) { + var pkgPath, relativePath; + relativePath = path.join(pkg.location, pkg.main); + pkgPath = this._resolvePath(fileName, relativePath); + return pkgPath; + }; + RequireRegister.prototype._isWebPath = function(filePath) { return this.webPathRegex.test(filePath); }; diff --git a/lib/tasks/tracker.js b/lib/tasks/tracker.js index 3dc46a3..0ee21f1 100644 --- a/lib/tasks/tracker.js +++ b/lib/tasks/tracker.js @@ -24,7 +24,8 @@ _createEmptyTrackingInfo = function() { aliases: {}, mappings: {}, originalConfig: {}, - requireFiles: [] + requireFiles: [], + packages: [] }; }; @@ -41,7 +42,7 @@ _handlePathPreWrite = function(f) { var truncPath; truncPath = f.replace(config.watch.compiledDir, ''); if (process.platform === 'win32') { - truncPath.split(path.sep).join('/'); + truncPath = truncPath.split(path.sep).join('/'); } return truncPath; }; @@ -69,21 +70,11 @@ _setVals = function(type, fName, _vals) { return _writeTrackingObject(); }; -exports.shims = function(fileName, shims) { - return _setVals('shims', fileName, shims); -}; - -exports.deps = function(fileName, deps) { - return _setVals('deps', fileName, deps); -}; - -exports.aliases = function(fileName, paths) { - return _setVals('aliases', fileName, paths); -}; - -exports.mappings = function(fileName, maps) { - return _setVals('mappings', fileName, maps); -}; +['shims', 'deps', 'aliases', 'mappings', 'packages'].forEach(function(cfgKey) { + return exports[cfgKey] = function(fileName, cfgSegment) { + return _setVals(cfgKey, fileName, cfgSegment); + }; +}); exports.originalConfig = function(_originalConfig) { trackingInfo.originalConfig = _originalConfig; diff --git a/src/tasks/register.coffee b/src/tasks/register.coffee index b9763d7..1219d01 100644 --- a/src/tasks/register.coffee +++ b/src/tasks/register.coffee @@ -14,6 +14,7 @@ module.exports = class RequireRegister requireFiles: [] tree: {} mappings: {} + packages: {} shims: {} originalConfig: {} @@ -85,6 +86,7 @@ module.exports = class RequireRegister @mappings = _.clone previousTrackingInfo.mappings @originalConfig = _.clone previousTrackingInfo.originalConfig @requireFiles = _.clone previousTrackingInfo.requireFiles + @packages = _.clone previousTrackingInfo.packages @verify = @config.require.verify.enabled unless @rootJavaScriptDir? @@ -195,7 +197,7 @@ module.exports = class RequireRegister track.requireFiles @requireFiles if config - @_handleConfigPaths(fileName, config.map ? null, config.paths ? null) + @_handleConfigPaths(fileName, config.map ? null, config.paths ? null, config.packages ? null) @_handleShims(fileName, config.shim ? null) if config? @@ -207,7 +209,7 @@ module.exports = class RequireRegister @_handleDeps(fileName, deps) _mergeOriginalConfig: (config) -> - ["shim", "paths", "map", "config"].forEach (name) => + ["shim", "paths", "map", "packages", "config"].forEach (name) => if config[name]? conf = _.clone config[name] if @originalConfig[name]? @@ -320,18 +322,22 @@ module.exports = class RequireRegister #else #logger.debug "[[ #{aDep} ]] may introduce a circular dependency" - _handleConfigPaths: (fileName, maps, paths) -> + _handleConfigPaths: (fileName, maps, paths, packages) -> + packages = @_normalizeConfigPackages(packages) + if @config.require.tracking.enabled track.aliases fileName, paths track.mappings fileName, maps + track.packages fileName, packages if @startupComplete - @_verifyConfigForFile(fileName, maps, paths) + @_verifyConfigForFile(fileName, maps, paths, packages) # remove the dependencies for the config file as # they'll get checked after the config paths are checked in @depsRegistry[fileName] = [] @_verifyFileDeps(file, deps) for file, deps of @depsRegistry else + @packages[fileName] = packages @aliasFiles[fileName] = paths @mappings[fileName] = maps @@ -345,9 +351,11 @@ module.exports = class RequireRegister else @depsRegistry[fileName] = deps - _verifyConfigForFile: (fileName, maps, paths) -> + _verifyConfigForFile: (fileName, maps, paths, packages) -> # if nothing passed in, then is verify all - maps = maps ? @mappings[fileName] + maps ?= @mappings[fileName] + packages ?= @packages[fileName] + paths = if paths paths else @@ -360,6 +368,7 @@ module.exports = class RequireRegister @aliasDirectories[fileName] = {} @_verifyConfigPath(fileName, alias, aliasPath) for alias, aliasPath of paths @_verifyConfigMappings(fileName, maps) + @_verifyConfigPackages(fileName, packages) _verifyConfigMappings: (fileName, maps) -> #logger.debug "Verifying [[ #{fileName} ]] maps:\n#{JSON.stringify(maps, null, 2)}" @@ -395,6 +404,48 @@ module.exports = class RequireRegister else @_logger "Mapping inside file [[ #{fileName} ]], for module [[ #{module} ]] has path that cannot be found [[ #{aliasPath} ]]." + _verifyConfigPackages: (fileName, packages) -> + logger.debug "Verifying [[ #{fileName} ]] packages:\n#{JSON.stringify(packages)}" + + for pkg in packages + pkgFullDirPath = path.join(this.rootJavaScriptDir, pkg.location) + if (fs.existsSync(pkgFullDirPath)) + if (fs.statSync(pkgFullDirPath).isDirectory()) + @aliasDirectories[fileName][pkg.name] = pkgFullDirPath + else + @_logger "location for package [[ #{pkg.name} ]] was found but is not a directory" + else + @_logger "location for package [[ #{pkg.name} ]] could not be found" + + fullDepPath = @_resolvePackagePath(fileName, pkg) + if fs.existsSync fullDepPath + @aliasFiles[fileName][pkg.name] = fullDepPath + else + @_logger "Mapping inside file [[ #{fileName} ]], for module [[ #{module} ]] has path that cannot be found [[ #{aliasPath} ]]." + + _normalizeConfigPackages:(packages) -> + pkgFormat = { name: '', location: '', main: 'main'} + + if packages? and Array.isArray(packages) + packages = _.filter packages, (pkg) -> + return true if _.isString(pkg) or _.isObject(pkg) + logger.debug "Package defined in unknown way, skipping pkg object of type : [[ #{typeof pkg} ]]" + + packages = _.map packages, (pkg) -> + return _.extend({}, pkgFormat, { name: pkg }) if _.isString(pkg) + _.extend({}, pkgFormat, pkg) + + return packages + + logger.debug "Packages defined in unknown way (expected an array) - skipping packages object of type : [[ #{typeof packages} ]]" + null #return null if this is something we can't understand + + _resolvePackagePath: (fileName, pkg, alias) -> + #logger.debug "Resolving alias [[ #{alias} ]] for package:\n[[ #{JSON.stringify(pkg, null, 2)} ]]\n in file [[#{fileName}]]" + relativePath = path.join pkg.location, pkg.main + pkgPath = @_resolvePath(fileName, relativePath) + return pkgPath + _isWebPath: (filePath) -> @webPathRegex.test filePath diff --git a/src/tasks/tracker.coffee b/src/tasks/tracker.coffee index 3de162f..f1414d9 100644 --- a/src/tasks/tracker.coffee +++ b/src/tasks/tracker.coffee @@ -21,6 +21,7 @@ _createEmptyTrackingInfo = -> mappings:{} originalConfig:{} requireFiles:[] + packages:[] config = {} trackingFilePath = "" @@ -32,7 +33,8 @@ exports.setConfig = (_config) -> _handlePathPreWrite = (f) -> truncPath = f.replace config.watch.compiledDir, '' if process.platform is 'win32' - truncPath.split(path.sep).join('/') + truncPath = truncPath.split(path.sep).join('/') + truncPath exports.requireFiles = (_requireFiles) -> @@ -53,17 +55,9 @@ _setVals = (type, fName, _vals) -> _writeTrackingObject() -exports.shims = (fileName, shims) -> - _setVals 'shims', fileName, shims - -exports.deps = (fileName, deps) -> - _setVals 'deps', fileName, deps - -exports.aliases = (fileName, paths) -> - _setVals 'aliases', fileName, paths - -exports.mappings = (fileName, maps) -> - _setVals 'mappings', fileName, maps +['shims', 'deps', 'aliases', 'mappings', 'packages'].forEach (cfgKey) -> + exports[cfgKey] = (fileName, cfgSegment) -> + _setVals cfgKey, fileName, cfgSegment exports.originalConfig = (_originalConfig) -> trackingInfo.originalConfig = _originalConfig