Skip to content

Commit

Permalink
Add leaves option to show modules that do not have dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
avahe-kellenberger committed Mar 9, 2020
1 parent 899f15f commit 97ed27f
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 50 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@ madge('path/to/app.js').then((res) => {
});
```

#### .leaves()

> Return an `Array` of all modules that have no dependencies.
```javascript
const madge = require('madge');

madge('path/to/app.js').then((res) => {
console.log(res.leaves());
});
```

#### .dot()

> Returns a `Promise` resolved with a DOT representation of the module dependency graph.
Expand Down Expand Up @@ -304,6 +316,10 @@ $ madge --depends wheels.js path/src/app.js
$ madge --orphans path/src/
```

```sh
$ madge --leaves path/src/
```

> Excluding modules
```sh
Expand Down
116 changes: 66 additions & 50 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ program
.option('-i, --image <file>', 'write graph to file as an image')
.option('-l, --layout <name>', 'layout engine to use for graph (dot/neato/fdp/sfdp/twopi/circo)')
.option('--orphans', 'show modules that no one is depending on')
.option('--leaves', 'show modules that have no dependencies')
.option('--dot', 'show graph using the DOT language')
.option('--extensions <list>', 'comma separated string of valid file extensions')
.option('--require-config <file>', 'path to RequireJS config')
Expand Down Expand Up @@ -172,56 +173,9 @@ new Promise((resolve, reject) => {
output.getResultSummary(res, startTime);
}

if (program.summary) {
output.summary(res.obj(), {
json: program.json
});

return res;
}

if (program.depends) {
output.modules(res.depends(program.depends), {
json: program.json
});

return res;
}

if (program.orphans) {
output.modules(res.orphans(), {
json: program.json
});

return res;
}

if (program.circular) {
const circular = res.circular();

output.circular(spinner, res, circular, {
json: program.json
});

if (circular.length) {
exitCode = 1;
}

return res;
}

if (program.image) {
return res.image(program.image).then((imagePath) => {
spinner.succeed(`${chalk.bold('Image created at')} ${chalk.cyan.bold(imagePath)}`);
return res;
});
}

if (program.dot) {
return res.dot().then((output) => {
process.stdout.write(output);
return res;
});
const result = createOutputFromOptions(program, res);
if (result !== undefined) {
return result;
}

output.list(res.obj(), {
Expand All @@ -246,3 +200,65 @@ new Promise((resolve, reject) => {
console.log('\n%s %s\n', chalk.red('✖'), err.stack);
process.exit(1);
});

function createOutputFromOptions(program, res) {
if (program.summary) {
output.summary(res.obj(), {
json: program.json
});

return res;
}

if (program.depends) {
output.modules(res.depends(program.depends), {
json: program.json
});

return res;
}

if (program.orphans) {
output.modules(res.orphans(), {
json: program.json
});

return res;
}

if (program.leaves) {
output.modules(res.leaves(), {
json: program.json
});

return res;
}

if (program.circular) {
const circular = res.circular();

output.circular(spinner, res, circular, {
json: program.json
});

if (circular.length) {
exitCode = 1;
}

return res;
}

if (program.image) {
return res.image(program.image).then((imagePath) => {
spinner.succeed(`${chalk.bold('Image created at')} ${chalk.cyan.bold(imagePath)}`);
return res;
});
}

if (program.dot) {
return res.dot().then((output) => {
process.stdout.write(output);
return res;
});
}
}
10 changes: 10 additions & 0 deletions lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@ class Madge {
.filter((dep) => !map[dep]);
}

/**
* Return a list of modules that have no dependencies.
* @api public
* @return {Array}
*/
leaves() {
const tree = this.obj();
return Object.keys(tree).filter((key) => !tree[key].length);
}

/**
* Return the module dependency graph as DOT output.
* @api public
Expand Down
9 changes: 9 additions & 0 deletions test/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,15 @@ describe('API', () => {
});
});

describe('leaves()', () => {
it('returns modules that have no dependencies', (done) => {
madge(__dirname + '/cjs/normal').then((res) => {
res.leaves().should.eql(['d.js']);
done();
}).catch(done);
});
});

describe('svg()', () => {
it('returns a promise resolved with XML SVG output in a Buffer', (done) => {
madge(__dirname + '/cjs/b.js')
Expand Down

0 comments on commit 97ed27f

Please sign in to comment.