-
-
Notifications
You must be signed in to change notification settings - Fork 620
/
Copy pathmigrate.js
152 lines (143 loc) · 3.78 KB
/
migrate.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
"use strict";
const fs = require("fs");
const chalk = require("chalk");
const diff = require("diff");
const inquirer = require("inquirer");
const PLazy = require("p-lazy");
const Listr = require("listr");
const validate = require("webpack").validate;
const WebpackOptionsValidationError = require("webpack")
.WebpackOptionsValidationError;
const runPrettier = require("../utils/run-prettier");
/**
*
* Runs migration on a given configuration using AST's and promises
* to sequentially transform a configuration file.
*
* @param {String} currentConfigPath - Location of the configuration to be migrated
* @param {String} outputConfigPath - Location to where the configuration should be written
* @param {Object} options - Any additional options regarding code style of the written configuration
* @returns {Promise} Runs the migration using a promise that will throw any errors during each transform
* or output if the user decides to abort the migration
*/
module.exports = function migrate(
currentConfigPath,
outputConfigPath,
options
) {
const recastOptions = Object.assign(
{
quote: "single"
},
options
);
const tasks = new Listr([
{
title: "Reading webpack config",
task: ctx =>
new PLazy((resolve, reject) => {
fs.readFile(currentConfigPath, "utf8", (err, content) => {
if (err) {
reject(err);
}
try {
const jscodeshift = require("jscodeshift");
ctx.source = content;
ctx.ast = jscodeshift(content);
resolve();
} catch (err) {
reject("Error generating AST", err);
}
});
})
},
{
title: "Migrating config from v1 to v2",
task: ctx => {
const transformations = require("../migrate").transformations;
return new Listr(
Object.keys(transformations).map(key => {
const transform = transformations[key];
return {
title: key,
task: _ => transform(ctx.ast, ctx.source)
};
})
);
}
}
]);
tasks
.run()
.then(ctx => {
const result = ctx.ast.toSource(recastOptions);
const diffOutput = diff.diffLines(ctx.source, result);
diffOutput.forEach(diffLine => {
if (diffLine.added) {
process.stdout.write(chalk.green(`+ ${diffLine.value}`));
} else if (diffLine.removed) {
process.stdout.write(chalk.red(`- ${diffLine.value}`));
}
});
return inquirer
.prompt([
{
type: "confirm",
name: "confirmMigration",
message: "Are you sure these changes are fine?",
default: "Y"
}
])
.then(answers => {
if (answers["confirmMigration"]) {
return inquirer.prompt([
{
type: "confirm",
name: "confirmValidation",
message:
"Do you want to validate your configuration? " +
"(If you're using webpack merge, validation isn't useful)",
default: "Y"
}
]);
} else {
console.log(chalk.red("✖ Migration aborted"));
}
})
.then(answer => {
if (!answer) return;
runPrettier(outputConfigPath, result, err => {
if (err) {
throw err;
}
});
if (answer["confirmValidation"]) {
const webpackOptionsValidationErrors = validate(
require(outputConfigPath)
);
if (webpackOptionsValidationErrors.length) {
console.log(
chalk.red(
"\n✖ Your configuration validation wasn't successful \n"
)
);
console.error(
new WebpackOptionsValidationError(
webpackOptionsValidationErrors
).message
);
}
}
console.log(
chalk.green(
`\n ✔︎ New webpack v2 config file is at ${outputConfigPath}`
)
);
});
})
.catch(err => {
console.log(chalk.red("✖ ︎Migration aborted due to some errors"));
console.error(err);
process.exitCode = 1;
});
};