Permalink
Browse files

Merge branch 'review' into l18nplugin

  • Loading branch information...
2 parents 35087a5 + d20acf7 commit 22d1c39615bafb4d860941df8128638405608659 @joewalker joewalker committed Sep 1, 2011
Showing with 290 additions and 61 deletions.
  1. +1 −0 .gitignore
  2. +28 −5 README.md
  3. +101 −56 lib/dryice/index.js
  4. +160 −0 lib/dryice/mini_require.js
View
@@ -13,3 +13,4 @@
# A handy place to put stuff that git should ignore:
/ignore/
/build/
+/node_modules/
View
@@ -145,10 +145,12 @@ And you can mix and match your inputs:
Common JS project dependency tracking:
- var project = copy.createCommonJsProject([
- '/path/to/source/tree/lib',
- '/some/other/project/lib'
- ]);
+ var project = copy.createCommonJsProject({
+ roots: [
+ '/path/to/source/tree/lib',
+ '/some/other/project/lib'
+ ]
+ });
copy({
source: copy.source.commonjs({
project: project,
@@ -239,7 +241,7 @@ Where the parameters are as follows:
}
or
-
+
if (location.base) {
location = location.base + location.path;
}
@@ -275,6 +277,27 @@ The dest property should be either a filename to which the output should be
written (existing files will be over-written without warning), or a data object
to which the data should be appended.
+CommonJS Projects
+-----------------
+
+CommonJS projects take a single object with the following properties:
+
+* `roots`: This is required. An array of directories that should be searched for
+ your required modules and dependencies.
+
+* `ignores`: This is optional. An array of modules or dependencies that are
+ required by your project that you would not like to be included in the
+ build. For example, if you were making a build which did not need to support
+ IE, you could do something like the following
+
+ copy.createCommonJsProject({
+ roots: [ '/path/to/project' ],
+ ignores: [ 'dom/ie-compat', 'event/ie-compat' ]
+ });
+
+ then wherever you had `require('dom/ie-compat')` or
+ `require('event/ie-compat')` inside your build, `undefined` would be returned
+ by `require`.
Where (is the project going)?
-----------------------------
View
@@ -38,9 +38,9 @@
* ***** END LICENSE BLOCK ***** */
var fs = require("fs");
+var path = require("path");
var ujs = require("uglify-js");
-
/**
* See https://github.com/mozilla/dryice for usage instructions.
*/
@@ -122,7 +122,7 @@ function addSourceFile(obj, filename) {
}
function addSourceBase(obj, baseObj) {
- var read = fs.readFileSync(baseObj.base + baseObj.path);
+ var read = fs.readFileSync(path.join(baseObj.base, baseObj.path));
obj.sources.push({
name: baseObj,
value: runFilters(read, obj.filter, true, baseObj)
@@ -163,6 +163,15 @@ copy.createDataObject = function() {
};
/**
+ * Read mini_require.js to go with the required modules.
+ */
+copy.getMiniRequire = function() {
+ return {
+ value: fs.readFileSync(__dirname + '/mini_require.js').toString('utf8')
+ };
+};
+
+/**
* An object that contains include and exclude object
*/
copy.findFiles = function(obj, findObj) {
@@ -300,7 +309,6 @@ function CommonJsProject(opts) {
var ignoredNames = Object.keys(this.ignoredFiles);
if (ignoredNames.length > 0) {
ignoredNames.forEach(function(module) {
- var deps = this.ignoredFiles[module].deps.length;
reply += ' - ' + module + '\n';
}, this);
}
@@ -323,38 +331,38 @@ function CommonJsProject(opts) {
* Create an experimental GraphML string declaring the node dependencies.
*/
CommonJsProject.prototype.getDependencyGraphML = function() {
- var nodes = '';
- var edges = '';
- var moduleNames = Object.keys(this.currentFiles);
- moduleNames.forEach(function(module) {
- nodes += ' <node id="' + module + '">\n';
- nodes += ' <data key="d0">\n';
- nodes += ' <y:ShapeNode>\n';
- nodes += ' <y:NodeLabel textColor="#000000">' + module + '</y:NodeLabel>\n';
- nodes += ' </y:ShapeNode>\n';
- nodes += ' </data>\n';
- nodes += ' </node>\n';
- var deps = Object.keys(this.currentFiles[module].deps);
- deps.forEach(function(dep) {
- edges += ' <edge source="' + module + '" target="' + dep + '"/>\n';
- });
- }, this);
-
- var reply = '<?xml version="1.0" encoding="UTF-8"?>\n';
- reply += '<graphml\n';
- reply += ' xmlns="http://graphml.graphdrawing.org/xmlns/graphml"\n';
- reply += ' xmlns:y="http://www.yworks.com/xml/graphml"\n';
- reply += ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n';
- reply += ' xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"\n';
- reply += ' >\n';
- reply += ' <key id="d0" for="node" yfiles.type="nodegraphics"/>\n';
- reply += ' <key id="d1" for="edge" yfiles.type="edgegraphics"/>\n';
- reply += ' <graph id="commonjs" edgedefault="undirected">\n';
- reply += nodes;
- reply += edges;
- reply += ' </graph>\n';
- reply += '</graphml>\n';
- return reply;
+ var nodes = '';
+ var edges = '';
+ var moduleNames = Object.keys(this.currentFiles);
+ moduleNames.forEach(function(module) {
+ nodes += ' <node id="' + module + '">\n';
+ nodes += ' <data key="d0">\n';
+ nodes += ' <y:ShapeNode>\n';
+ nodes += ' <y:NodeLabel textColor="#000000">' + module + '</y:NodeLabel>\n';
+ nodes += ' </y:ShapeNode>\n';
+ nodes += ' </data>\n';
+ nodes += ' </node>\n';
+ var deps = Object.keys(this.currentFiles[module].deps);
+ deps.forEach(function(dep) {
+ edges += ' <edge source="' + module + '" target="' + dep + '"/>\n';
+ });
+ }, this);
+
+ var reply = '<?xml version="1.0" encoding="UTF-8"?>\n';
+ reply += '<graphml\n';
+ reply += ' xmlns="http://graphml.graphdrawing.org/xmlns/graphml"\n';
+ reply += ' xmlns:y="http://www.yworks.com/xml/graphml"\n';
+ reply += ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n';
+ reply += ' xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"\n';
+ reply += ' >\n';
+ reply += ' <key id="d0" for="node" yfiles.type="nodegraphics"/>\n';
+ reply += ' <key id="d1" for="edge" yfiles.type="edgegraphics"/>\n';
+ reply += ' <graph id="commonjs" edgedefault="undirected">\n';
+ reply += nodes;
+ reply += edges;
+ reply += ' </graph>\n';
+ reply += '</graphml>\n';
+ return reply;
};
CommonJsProject.prototype.assumeAllFilesLoaded = function() {
@@ -382,30 +390,66 @@ function CommonJsProject(opts) {
this.roots.push(root);
};
- function findModuleAt(baseObj, base, path) {
- if (isFile(base + path)) {
+ function findModuleAt(baseObj, base, somePath) {
+ // Checking for absolute requires and relative requires that previously
+ // had been resolved to absolute paths.
+ if (/^\//.test(somePath)) {
+ if (isFile(somePath)) {
+ baseObj = { base: '/', path: somePath };
+ return baseObj;
+ }
+ }
+
+ if (isFile(path.join(base, somePath))) {
if (baseObj) {
console.log('- Found several matches for ' + module +
' (ignoring 2nd)');
- console.log(' - ' + baseObj.base + baseObj.path);
- console.log(' - ' + base + path);
+ console.log(' - ' + path.join(baseObj.base, baseObj.path));
+ console.log(' - ' + path.join(base, somePath));
}
else {
- baseObj = { base: base, path: path };
+ baseObj = { base: base, path: somePath };
}
}
return baseObj;
}
+ function relative(pathA, pathB) {
+ pathA = pathA.split('/');
+ pathB = pathB.split('/');
+ var aLen = pathA.length;
+ var bLen = pathB.length;
+
+ // Increment i to the first place where the paths diverge.
+ for (var i = 0;
+ i < aLen && i < bLen && pathA[i] === pathB[i];
+ i++)
+ ;
+
+ // Remove the redundant parts of the paths.
+ function isntEmptyString(s) {
+ return s !== '';
+ }
+ pathA = pathA.slice(i).filter(isntEmptyString);
+ pathB = pathB.slice(i).filter(isntEmptyString);
+
+ var result = [];
+ for (i = 0; i < pathA.length; i++) {
+ result.push('..');
+ }
+ return result.concat(pathB).join('/');
+ }
+
function findRequires(baseObj) {
- var code = fs.readFileSync(baseObj.base + baseObj.path).toString();
+ var code = fs.readFileSync(path.join(baseObj.base, baseObj.path)).toString();
var ast;
try {
ast = ujs.parser.parse(code, false);
}
catch (ex) {
console.error('- Failed to compile ' + baseObj.path + ': ' + ex);
+ return;
}
var reply = [];
@@ -418,9 +462,20 @@ function CommonJsProject(opts) {
// via a different name. that was a useful escape system, but
// now we detect computed requires, it's not needed.
if (expr[1] === 'require') {
- var arg0 = args[0];
if (args[0][0] === 'string') {
- reply.push(args[0][1]);
+ if (/^\./.test(args[0][1])) {
+ var requirersDirectory = path.dirname(path.join(baseObj.base, baseObj.path));
+ var pathToRequiredModule = path.join(requirersDirectory,
+ args[0][1]);
+ // The call to `define` which makes the module being
+ // relatively required isn't the full relative path,
+ // but the path relative from the base.
+ reply.push(relative(baseObj.base,
+ pathToRequiredModule));
+ }
+ else {
+ reply.push(args[0][1]);
+ }
}
else {
console.log('- ' + baseObj.path + ' has require(...) ' +
@@ -695,7 +750,7 @@ copy.filter.moduleDefines = function(input, source) {
}
source = source.replace(/\.js$/, '');
- return input.replace(/\bdefine\(\s*function\(require,\s*exports,\s*module\)\s*\{/,
+ return input.replace(/\bdefine\(\s*function\s*\(require,\s*exports,\s*module\)\s*\{/,
"define('" + source + "', ['require', 'exports', 'module' " + deps + "], function(require, exports, module) {");
};
copy.filter.moduleDefines.onRead = true;
@@ -705,25 +760,15 @@ copy.filter.moduleDefines.onRead = true;
* exists()?
*/
function isFile(fullPath) {
- try {
- return fs.statSync(fullPath).isFile();
- }
- catch (ex) {
- return false;
- }
+ return path.existsSync(fullPath) && fs.statSync(fullPath).isFile();
}
/**
* Why does node throw an exception for statSync(), especially when it has no
* exists()?
*/
function isDirectory(fullPath) {
- try {
- return fs.statSync(fullPath).isDirectory();
- }
- catch (ex) {
- return false;
- }
+ return path.existsSync(fullPath) && fs.statSync(fullPath).isDirectory();
}
/**
Oops, something went wrong.

0 comments on commit 22d1c39

Please sign in to comment.