Skip to content

Commit 88768b8

Browse files
authored
Merge branch 'master' into depth-limit
2 parents 77ddee5 + c2191a1 commit 88768b8

File tree

13 files changed

+525
-282
lines changed

13 files changed

+525
-282
lines changed

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
13.6.0
1+
18

.release-it.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"pkgFiles": ["package.json", "package-lock.json"],
3+
"git": {
4+
"requireCleanWorkingDir": false
5+
},
6+
"hooks": {
7+
"after:bump": "auto-changelog --hide-credit --package"
8+
}
9+
}

.travis.yml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
11
language: node_js
22
node_js:
3-
- 10
4-
- 12
5-
- 13
3+
- 14
4+
- 16
5+
- 18
66
sudo: false
7-
dist: bionic
7+
dist: focal
88
addons:
99
apt:
1010
packages:
1111
- graphviz
1212
script:
1313
- npm test
1414
- npm run debug
15-
deploy:
16-
provider: npm
17-
18-
api_key:
19-
secure: nArcGw6OdS7J1bC+BuXk/2ER7z2Cc+Rjk0oBE/hoTsYo4+ry2LUzWM+nl28om5pF1xtXWwe0fb1rG4f3Ls28iHpH7E5Uz5+RfVfB4VH9w1HL4nBfLW5Ljj9J0ViQzSN1OPJ45B2lwHU8JH7N2c62FDJ5kqLn83WTGdb7Bgyau6o=
20-
on:
21-
tags: true

CHANGELOG.md

Lines changed: 369 additions & 197 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,9 @@
44

55
<p align="center">
66
<img alt="Last version" src="https://img.shields.io/github/tag/pahen/madge.svg?style=flat-square" />
7-
<a href="https://travis-ci.com/pahen/madge">
7+
<a href="https://app.travis-ci.com/github/pahen/madge">
88
<img alt="Build Status" src="http://img.shields.io/travis/pahen/madge/master.svg?style=flat-square" />
99
</a>
10-
<a href="https://david-dm.org/pahen/madge">
11-
<img alt="Dependency status" src="http://img.shields.io/david/pahen/madge.svg?style=flat-square" />
12-
</a>
13-
<a href="https://david-dm.org/pahen/madge#info=devDependencies">
14-
<img alg="Dev Dependencies status" src="http://img.shields.io/david/dev/pahen/madge.svg?style=flat-square" />
15-
</a>
1610
<a href="https://www.npmjs.org/package/madge">
1711
<img alg="NPM Status" src="http://img.shields.io/npm/dm/madge.svg?style=flat-square" />
1812
</a>
@@ -33,7 +27,7 @@
3327

3428
Read the [changelog](CHANGELOG.md) for latest changes.
3529

36-
> I've worked with Madge on my free time for the last couple of years and it's been a great experience. It started as an experiment but turned out to be a very useful tool for many developers. I have many ideas for the project and it would definitely be easier to dedicate more time to it with some [financial support](#donations) 🙏
30+
> I've worked with Madge on my free time for the last couple of years and it's been a great experience. It started as an experiment but turned out to be a very useful tool for many developers. I have many ideas for the project and it would definitely be easier to dedicate more time to it with some [financial support](#donations-%EF%B8%8F) 🙏
3731
>
3832
> Regardless of your contribution, thanks for your support!
3933
@@ -243,7 +237,7 @@ Property | Type | Default | Description
243237
`graphVizOptions` | Object | false | Custom Graphviz [options](https://graphviz.gitlab.io/_pages/doc/info/attrs.html)
244238
`graphVizPath` | String | null | Custom Graphviz path
245239
`detectiveOptions` | Object | false | Custom `detective` options for [dependency-tree](https://github.com/dependents/node-dependency-tree) and [precinct](https://github.com/dependents/node-precinct#usage)
246-
`dependencyFilter` | Function | false | Function called with a dependency filepath (exclude substree by returning false)
240+
`dependencyFilter` | Function | false | Function called with a dependency filepath (exclude subtrees by returning false)
247241

248242
You can use configuration file either in `.madgerc` in your project or home folder or directly in `package.json`. Look [here](https://github.com/dominictarr/rc#standards) for alternative locations for the file.
249243

@@ -380,6 +374,12 @@ npm install
380374
npm test
381375
```
382376

377+
# Creating a release
378+
379+
```sh
380+
npm run release
381+
```
382+
383383
# FAQ
384384

385385
## Missing dependencies?
@@ -444,6 +444,20 @@ Put this in your madge config.
444444
}
445445
```
446446

447+
## How to ignore dynamic imports in Typescript?
448+
449+
Put this in your madge config.
450+
451+
```json
452+
{
453+
"detectiveOptions": {
454+
"ts": {
455+
"skipAsyncImports": true
456+
}
457+
}
458+
}
459+
```
460+
447461
## Mixing TypesScript and Javascript imports?
448462

449463
Ensure you have this in your `.tsconfig` file.
@@ -497,7 +511,7 @@ This project exists thanks to all the people who contribute.
497511

498512
## Donations ❤️
499513

500-
Thanks to the awesome people below for making donations! 🙏[[Donate](https://paypal.me/pahen)]
514+
Thanks to the awesome people below for making donations! 🙏[Donate](https://paypal.me/pahen)
501515

502516
<p>
503517
<a href="https://github.com/BeroBurny" target="_blank">

bin/cli.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ program
2727
.option('--orphans', 'show modules that no one is depending on')
2828
.option('--leaves', 'show modules that have no dependencies')
2929
.option('--dot', 'show graph using the DOT language')
30+
.option('--rankdir <direction>', 'set the direction of the graph layout')
3031
.option('--extensions <list>', 'comma separated string of valid file extensions')
3132
.option('--require-config <file>', 'path to RequireJS config')
3233
.option('--webpack-config <file>', 'path to webpack config')
@@ -75,7 +76,7 @@ const spinner = ora({
7576
text: 'Finding files',
7677
color: 'white',
7778
interval: 100000,
78-
isEnabled: program.spinner
79+
isEnabled: program.spinner === 'false' ? false : null
7980
});
8081

8182
let exitCode = 0;
@@ -144,6 +145,10 @@ if (!program.color) {
144145
config.edgeColor = '#757575';
145146
}
146147

148+
if (program.rankdir) {
149+
config.rankdir = program.rankdir;
150+
}
151+
147152
function dependencyFilter() {
148153
let prevFile;
149154

@@ -153,10 +158,8 @@ function dependencyFilter() {
153158
const dir = path.dirname(relPath) + '/';
154159
const file = path.basename(relPath);
155160

156-
if (program.spinner) {
157-
spinner.text = chalk.grey(dir) + chalk.cyan(file);
158-
spinner.render();
159-
}
161+
spinner.text = chalk.grey(dir) + chalk.cyan(file);
162+
160163
prevFile = traversedFilePath;
161164
}
162165
};

lib/api.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22

3+
const path_ = require('path');
34
const tree = require('./tree');
45
const cyclic = require('./cyclic');
56
const graph = require('./graph');
@@ -47,6 +48,16 @@ class Madge {
4748
}
4849

4950
this.config = Object.assign({}, defaultConfig, config);
51+
if (typeof this.config.tsConfig === 'string') {
52+
const ts = require('typescript');
53+
const tsParsedConfig = ts.readJsonConfigFile(this.config.tsConfig, ts.sys.readFile);
54+
const obj = ts.parseJsonSourceFileConfigFileContent(tsParsedConfig, ts.sys, path_.dirname(config.tsConfig));
55+
this.config.tsConfig = {
56+
...obj.raw,
57+
compilerOptions: obj.options
58+
};
59+
log('using tsconfig %o', this.config.tsConfig);
60+
}
5061

5162
if (typeof path === 'object' && !Array.isArray(path)) {
5263
this.tree = path;

lib/graph.js

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
const path = require('path');
44
const {promisify} = require('util');
5-
const graphviz = require('graphviz');
6-
5+
const gv = require('ts-graphviz');
6+
const adapter = require('ts-graphviz/adapter');
7+
const toArray = require('stream-to-array');
78
const exec = promisify(require('child_process').execFile);
89
const writeFile = promisify(require('fs').writeFile);
910

@@ -13,8 +14,8 @@ const writeFile = promisify(require('fs').writeFile);
1314
* @param {String} color
1415
*/
1516
function setNodeColor(node, color) {
16-
node.set('color', color);
17-
node.set('fontcolor', color);
17+
node.attributes.set('color', color);
18+
node.attributes.set('fontcolor', color);
1819
}
1920

2021
/**
@@ -45,28 +46,31 @@ function createGraphvizOptions(config) {
4546
const graphVizOptions = config.graphVizOptions || {};
4647

4748
return {
48-
// Graph
49-
G: Object.assign({
50-
overlap: false,
51-
pad: 0.3,
52-
rankdir: config.rankdir,
53-
layout: config.layout,
54-
bgcolor: config.backgroundColor
55-
}, graphVizOptions.G),
56-
// Edge
57-
E: Object.assign({
58-
color: config.edgeColor
59-
}, graphVizOptions.E),
60-
// Node
61-
N: Object.assign({
62-
fontname: config.fontName,
63-
fontsize: config.fontSize,
64-
color: config.nodeColor,
65-
shape: config.nodeShape,
66-
style: config.nodeStyle,
67-
height: 0,
68-
fontcolor: config.nodeColor
69-
}, graphVizOptions.N)
49+
dotCommand: config.graphVizPath ? config.graphVizPath : null,
50+
attributes: {
51+
// Graph
52+
graph: Object.assign({
53+
overlap: false,
54+
pad: 0.3,
55+
rankdir: config.rankdir,
56+
layout: config.layout,
57+
bgcolor: config.backgroundColor
58+
}, graphVizOptions.G),
59+
// Edge
60+
edge: Object.assign({
61+
color: config.edgeColor
62+
}, graphVizOptions.E),
63+
// Node
64+
node: Object.assign({
65+
fontname: config.fontName,
66+
fontsize: config.fontSize,
67+
color: config.nodeColor,
68+
shape: config.nodeShape,
69+
style: config.nodeStyle,
70+
height: 0,
71+
fontcolor: config.nodeColor
72+
}, graphVizOptions.N)
73+
}
7074
};
7175
}
7276

@@ -79,16 +83,12 @@ function createGraphvizOptions(config) {
7983
* @return {Promise}
8084
*/
8185
function createGraph(modules, circular, config, options) {
82-
const g = graphviz.digraph('G');
86+
const g = gv.digraph('G');
8387
const nodes = {};
8488
const cyclicModules = circular.reduce((a, b) => a.concat(b), []);
8589

86-
if (config.graphVizPath) {
87-
g.setGraphVizPath(config.graphVizPath);
88-
}
89-
9090
Object.keys(modules).forEach((id) => {
91-
nodes[id] = nodes[id] || g.addNode(id);
91+
nodes[id] = nodes[id] || g.createNode(id);
9292

9393
if (!modules[id].length) {
9494
setNodeColor(nodes[id], config.noDependencyColor);
@@ -97,21 +97,20 @@ function createGraph(modules, circular, config, options) {
9797
}
9898

9999
modules[id].forEach((depId) => {
100-
nodes[depId] = nodes[depId] || g.addNode(depId);
100+
nodes[depId] = nodes[depId] || g.createNode(depId);
101101

102102
if (!modules[depId]) {
103103
setNodeColor(nodes[depId], config.noDependencyColor);
104104
}
105105

106-
g.addEdge(nodes[id], nodes[depId]);
107-
});
108-
});
109-
110-
return new Promise((resolve, reject) => {
111-
g.output(options, resolve, (code, out, err) => {
112-
reject(new Error(err));
106+
g.createEdge([nodes[id], nodes[depId]]);
113107
});
114108
});
109+
const dot = gv.toDot(g);
110+
return adapter
111+
.toStream(dot, options)
112+
.then(toArray)
113+
.then(Buffer.concat);
115114
}
116115

117116
/**
@@ -124,7 +123,7 @@ function createGraph(modules, circular, config, options) {
124123
module.exports.svg = function (modules, circular, config) {
125124
const options = createGraphvizOptions(config);
126125

127-
options.type = 'svg';
126+
options.format = 'svg';
128127

129128
return checkGraphvizInstalled(config)
130129
.then(() => createGraph(modules, circular, config, options));
@@ -141,7 +140,7 @@ module.exports.svg = function (modules, circular, config) {
141140
module.exports.image = function (modules, circular, imagePath, config) {
142141
const options = createGraphvizOptions(config);
143142

144-
options.type = path.extname(imagePath).replace('.', '') || 'png';
143+
options.format = path.extname(imagePath).replace('.', '') || 'png';
145144

146145
return checkGraphvizInstalled(config)
147146
.then(() => {
@@ -161,7 +160,7 @@ module.exports.image = function (modules, circular, imagePath, config) {
161160
module.exports.dot = function (modules, circular, config) {
162161
const options = createGraphvizOptions(config);
163162

164-
options.type = 'dot';
163+
options.format = 'dot';
165164

166165
return checkGraphvizInstalled(config)
167166
.then(() => createGraph(modules, circular, config, options))

0 commit comments

Comments
 (0)