Skip to content

Commit

Permalink
Complete path in circular dependencies is now printed (and marked as …
Browse files Browse the repository at this point in the history
…red in image graphs). Fixes #4
  • Loading branch information
pahen committed Sep 3, 2012
1 parent 93b9d37 commit 0b44a73
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 13 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ Coming soon ..

# Release Notes

## v0.1.0 (September 3, 2012)
Complete path in circular dependencies is now printed (and marked as red in image graphs).

## v0.0.5 (August 8, 2012)
Added support for CoffeeScript. Files with extension .coffee will automatically be compiled on-the-fly.

Expand Down
Binary file modified examples/small.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 36 additions & 3 deletions lib/analysis/circular.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
'use strict';

/**
* Get path to the circular dependency.
* @param {Object} unresolved
* @return {Array}
*/
function getPath(unresolved) {
return Object.keys(unresolved).filter(function (module) {
return unresolved[module];
});
}

/**
* A circular dependency is occurring when we see a software package
* more than once, unless that software package has all its dependencies resolved.
Expand All @@ -16,7 +27,7 @@ function resolver(id, modules, circular, resolved, unresolved) {
modules[id].forEach(function (dependency) {
if (!resolved[dependency]) {
if (unresolved[dependency]) {
circular[id] = dependency;
circular.push(getPath(unresolved));
return;
}
resolver(dependency, modules, circular, resolved, unresolved);
Expand All @@ -34,13 +45,35 @@ function resolver(id, modules, circular, resolved, unresolved) {
* @return {Object}
*/
module.exports = function (modules) {
var circular = {},
var circular = [],
resolved = {},
unresolved = {};

Object.keys(modules).forEach(function (id) {
resolver(id, modules, circular, resolved, unresolved);
});

return circular;
return {
/**
* Expose the circular dependency array.
* @return {Array}
*/
getArray: function () {
return circular;
},

/**
* Check if the given module is part of a circular dependency.
* @return {Boolean}
*/
isCyclic: function (id) {
var cyclic = false;
circular.forEach(function (path) {
if (path.indexOf(id) >= 0) {
cyclic = true;
}
});
return cyclic;
}
};
};
4 changes: 2 additions & 2 deletions lib/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ module.exports.image = function (modules, opts, callback) {
if (opts.colors && modules[id]) {
if (!modules[id].length) {
noDependencyNode(nodes[id], colors.noDependencies);
} else if (circular[id]) {
} else if (circular.isCyclic(id)) {
nodeColor(nodes[id], (colors.circular || '#ff6c60'));
}
}
Expand Down Expand Up @@ -97,7 +97,7 @@ module.exports.image = function (modules, opts, callback) {
*/
module.exports.dot = function (modules) {
var nodes = {};

checkGraphvizInstalled();

Object.keys(modules).forEach(function (id) {
Expand Down
17 changes: 12 additions & 5 deletions lib/print.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,23 @@ module.exports.summary = function (modules, opts) {
* @param {Object} circular
* @param {Object} opts
*/
module.exports.circular = function (modules, opts) {
module.exports.circular = function (circular, opts) {
var arr = circular.getArray();
if (opts.output === 'json') {
return process.stdout.write(toJSON(modules));
return process.stdout.write(toJSON(arr));
}

if (!Object.keys(modules).length) {
if (!arr.length) {
console.log(c('No circular references found', 'green', opts.colors));
} else {
Object.keys(modules).forEach(function (id) {
console.log(c(id, 'grey', opts.colors) + c(' -> ', 'cyan', opts.colors) + c(modules[id], 'grey', opts.colors));
arr.forEach(function (path, idx) {
path.forEach(function (module, idx) {
if (idx) {
process.stdout.write(c(' -> ', 'cyan', opts.colors));
}
process.stdout.write(c(module, 'grey', opts.colors));
});
process.stdout.write('\n');
});
}
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "madge",
"version": "0.0.5",
"version": "0.1.0",
"author": "Patrik Henningsson <patrik.henningsson@gmail.com>",
"repository": "git://github.com/pahen/node-madge",
"homepage" : "https://github.com/pahen/node-madge",
Expand Down
2 changes: 1 addition & 1 deletion test/amd.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('module format (AMD)', function () {
});

it('should find circular dependencies', function () {
madge([__dirname + '/files/amd/circular'], {format: 'amd'}).circular().should.eql({ c: 'a' });
madge([__dirname + '/files/amd/circular'], {format: 'amd'}).circular().getArray().should.eql([ ['a', 'c'], ['e', 'f', 'g'] ]);
});

it('should find modules that depends on another', function () {
Expand Down
2 changes: 1 addition & 1 deletion test/cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('module format (CommonJS)', function () {
});

it('should find circular dependencies', function () {
madge([__dirname + '/files/cjs/circular']).circular().should.eql({ 'c': 'a' });
madge([__dirname + '/files/cjs/circular']).circular().getArray().should.eql([ ['a', 'b', 'c'] ]);
});

it('should compile coffeescript on-the-fly', function () {
Expand Down
3 changes: 3 additions & 0 deletions test/files/amd/circular/e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
define(['f'], function (F) {
return 'E';
});
3 changes: 3 additions & 0 deletions test/files/amd/circular/f.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
define(['g'], function (G) {
return 'F';
});
3 changes: 3 additions & 0 deletions test/files/amd/circular/g.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
define(['e'], function (E) {
return 'G';
});

0 comments on commit 0b44a73

Please sign in to comment.