-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.js
116 lines (106 loc) · 4.05 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
const fs = require('fs');
const path = require('path');
const os = require('os');
const child_process = require('child_process');
const detectManager = require('./libs/detectManager');
const outdated = require('./libs/outdated');
const reStylingJson = require('./libs/reStylingJson');
const filterPackageBySemVer = require('./libs/filterPackageBySemVer');
const buildUpdateCommand = (manager, type, name, version) => {
const flags = type === 'devDependencies' ? '-D ' : '';
if (manager === 'npm') return `npm install ${flags}${name}@${version}`;
if (manager === 'yarn') return `yarn add ${flags}${name}@^${version}`;
};
const RESET_COMMAND = {
npm: 'npm ci',
yarn: `rm -rf ${path.resolve('node_modules')} && yarn install`
};
const LOCKFILE = {
npm: 'package-lock.json',
yarn: 'yarn.lock'
};
const execCommand = (commands, replacer = {}) => {
let comm = '';
if (typeof commands === 'string') {
comm = commands;
} else if (Array.isArray(commands)) {
comm = commands.join('&&');
}
Object.keys(replacer).forEach(key => {
const replace = replacer[key];
comm = comm.replace(`%${key}%`, replace);
});
child_process.execSync(comm, {stdio: [0, 1, 2]});
};
module.exports = (updateSemVer, flags = {}, options = {}) => {
let manager = flags.manager;
if (!manager) manager = detectManager();
let outdatedJson = options.outdatedJson;
if (!outdatedJson) outdatedJson = outdated.json(manager);
if (manager === 'yarn') {
outdatedJson = outdatedJson.split('\n')[1];
}
outdatedJson = reStylingJson(manager, outdatedJson, options.packageFilePath);
let onlyDeps = '';
if (flags.onlyDev) {
onlyDeps = 'devDependencies';
}
if (flags.onlyProd) {
onlyDeps = 'dependencies';
}
if (onlyDeps) {
let r = {};
Object.keys(outdatedJson)
.filter(key => outdatedJson[key].type === onlyDeps)
.forEach(key => {
r[key] = outdatedJson[key];
});
outdatedJson = r;
}
outdatedJson = filterPackageBySemVer(updateSemVer, outdatedJson, flags.break);
const dirPath = fs.mkdtempSync(path.join(os.tmpdir(), 'npm-safety-update-'));
const packageJsonPath = path.resolve('package.json');
const lockFilePath = path.resolve(`${LOCKFILE[manager]}`);
let success = [];
let errors = [];
execCommand(RESET_COMMAND[manager]);
if (options.prepare) execCommand(options.prepare);
Object.keys(outdatedJson)
.forEach((name, index) => {
const copiedPackgeJson = 'package.json-' + index;
const copiedPackageLock = LOCKFILE[manager] + '-' + index;
fs.copyFileSync(packageJsonPath, path.join(dirPath, copiedPackgeJson));
fs.copyFileSync(lockFilePath, path.join(dirPath, copiedPackageLock));
const item = outdatedJson[name];
let {current, goto, type, url} = item;
goto = goto || item.wanted;
let replace = {
PACKAGE_NAME: name,
CURRENT_VERSION: current,
GOTO_VERSION: goto,
DEPS_TYPE: type
};
const command = buildUpdateCommand(manager, type, name, goto);
try {
console.info('RUN:', command);
if (!process.env.DEBUG) execCommand(command, replace);
if (!flags.force && options.testCommand) {
console.info('TEST:', options.testCommand);
execCommand(options.testCommand, replace);
}
success.push([name, current, goto, url]);
if (options.onlySuccess) execCommand(options.onlySuccess, replace);
} catch (e) {
errors.push([e, name]);
console.error('Failed to update:', name);
fs.copyFileSync(path.join(dirPath, copiedPackgeJson), packageJsonPath);
fs.copyFileSync(path.join(dirPath, copiedPackageLock), lockFilePath);
if (options.onlyFailed) execCommand(options.onlyFailed, replace);
}
if (options.afterTest) execCommand(options.afterTest, replace);
execCommand(RESET_COMMAND[manager], replace);
});
console.log('updated info:', updateSemVer.join(','));
console.log(success.map(i => `UPDATE: ${i[0]} to v${i[2]} from v${i[1]} ${i[3]}`).join('\n'));
console.log(`====\nfailed to update\n${errors.map(e => e.name).join('\n')}`);
};