1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | 'use strict';
|
9 |
|
10 | var PluginError = require('plugin-error');
|
11 | var colors = require('ansi-colors');
|
12 | var fancyLog = require('fancy-log');
|
13 | var path = require('path');
|
14 | var semver = require('semver');
|
15 | var spawn = require('cross-spawn');
|
16 | var through = require('through2');
|
17 |
|
18 | var PLUGIN_NAME = 'check-dependencies';
|
19 |
|
20 | module.exports = function(opts) {
|
21 | function read(file, enc, cb) {
|
22 | var cwd = path.dirname(file.path);
|
23 | var pkgData = JSON.parse(file.contents.toString());
|
24 | var outdated = spawn(
|
25 | 'yarn',
|
26 | ['outdated', '--json'],
|
27 | { cwd: cwd }
|
28 | );
|
29 | var data = '';
|
30 |
|
31 | outdated.stdout.on('data', function(chunk) {
|
32 | data += chunk.toString();
|
33 | });
|
34 |
|
35 | outdated.on('exit', function(code) {
|
36 | try {
|
37 |
|
38 | var outdatedData = data
|
39 | .split('\n')
|
40 | .filter(Boolean)
|
41 | .map(d => JSON.parse(d))
|
42 | .filter(j => j.type === 'table')[0].data;
|
43 | } catch (e) {
|
44 | console.log('error', e)
|
45 | cb(new PluginError(PLUGIN_NAME, 'npm broke'));
|
46 | }
|
47 |
|
48 |
|
49 | const name2idx = {};
|
50 | outdatedData.head.forEach((key, idx) => name2idx[key] = idx);
|
51 | const {
|
52 | Package: NAME,
|
53 | Current: CURRENT,
|
54 | "Package Type": TYPE
|
55 | } = name2idx;
|
56 |
|
57 | var failures = [];
|
58 | outdatedData.body.forEach(function(row) {
|
59 | var name = row[NAME];
|
60 | var current = row[CURRENT];
|
61 | var type = row[TYPE];
|
62 | var pkgDeps = pkgData[type];
|
63 |
|
64 | if (!pkgDeps) {
|
65 | fancyLog(`Found missing dependency category ${type}.`);
|
66 | return;
|
67 | }
|
68 |
|
69 | var requested = pkgDeps[name];
|
70 |
|
71 | if (!requested) {
|
72 | fancyLog('Found extraneous outdated dependency. Consider running `npm prune`');
|
73 | return;
|
74 | }
|
75 |
|
76 | if (!requested.startsWith('file:') && !semver.satisfies(current, requested)) {
|
77 |
|
78 | failures.push({name, current, requested});
|
79 | }
|
80 | });
|
81 |
|
82 | if (failures.length) {
|
83 | failures.forEach((failure) => {
|
84 | fancyLog(
|
85 | `${colors.bold(failure.name)} is outdated ` +
|
86 | `(${colors.red(failure.current)} does not satisfy ` +
|
87 | `${colors.yellow(failure.requested)})`
|
88 | );
|
89 | });
|
90 | var msg =
|
91 | 'Some of your dependencies are outdated. Please run ' +
|
92 | `${colors.bold('npm update')} to ensure you are up to date.`;
|
93 | cb(new PluginError(PLUGIN_NAME, msg));
|
94 | return;
|
95 | }
|
96 |
|
97 | cb();
|
98 | });
|
99 | }
|
100 |
|
101 | return through.obj(read);
|
102 | };
|