-
Notifications
You must be signed in to change notification settings - Fork 218
/
index.ts
117 lines (94 loc) · 3.73 KB
/
index.ts
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
import { createProject } from '@ts-morph/bootstrap';
import ts from 'typescript';
import path from 'path';
import log from 'updatable-log';
import MigrateConfig from './MigrateConfig';
import PerfTimer from '../utils/PerfTimer';
import { PluginParams } from '../../types';
interface MigrateParams {
rootDir: string;
tsConfigDir?: string;
config: MigrateConfig;
sources?: string | string[];
}
export default async function migrate({
rootDir,
tsConfigDir = rootDir,
config,
sources,
}: MigrateParams): Promise<number> {
let exitCode = 0;
log.info(`TypeScript version: ${ts.version}`);
const serverInitTimer = new PerfTimer();
// Normalize sources to be an array of full paths.
if (sources !== undefined) {
sources = Array.isArray(sources) ? sources : [sources];
sources = sources.map((source) => path.join(rootDir, source));
log.info(`Ignoring sources from tsconfig.json, using the ones provided manually instead.`);
}
const tsConfigFilePath = path.join(tsConfigDir, 'tsconfig.json');
const project = await createProject({
tsConfigFilePath,
skipAddingFilesFromTsConfig: sources !== undefined,
});
// If we passed in our own sources, let's add them to the project.
// If not, let's just get all the sources in the project.
if (sources) {
await project.addSourceFilesByPaths(sources);
}
log.info(`Initialized tsserver project in ${serverInitTimer.elapsedStr()}.`);
log.info('Start...');
const pluginsTimer = new PerfTimer();
const updatedSourceFiles = new Set<string>();
for (let i = 0; i < config.plugins.length; i += 1) {
const { plugin, options: pluginOptions } = config.plugins[i];
const pluginLogPrefix = `[${plugin.name}]`;
const pluginTimer = new PerfTimer();
log.info(`${pluginLogPrefix} Plugin ${i + 1} of ${config.plugins.length}. Start...`);
const sourceFiles = project
.getSourceFiles()
.filter(({ fileName }) => !/(\.d\.ts|\.json)$|node_modules/.test(fileName));
// eslint-disable-next-line no-restricted-syntax
for (const sourceFile of sourceFiles) {
const { fileName } = sourceFile;
// const fileTimer = new PerfTimer();
const relFile = path.relative(rootDir, sourceFile.fileName);
const fileLogPrefix = `${pluginLogPrefix}[${relFile}]`;
const getLanguageService = () => project.getLanguageService();
const params: PluginParams<unknown> = {
fileName,
rootDir,
sourceFile,
text: sourceFile.text,
options: pluginOptions,
getLanguageService,
};
try {
// eslint-disable-next-line no-await-in-loop
const newText = await plugin.run(params);
if (typeof newText === 'string' && newText !== sourceFile.text) {
project.updateSourceFile(fileName, newText);
updatedSourceFiles.add(sourceFile.fileName);
}
} catch (pluginErr) {
log.error(`${fileLogPrefix} Error:\n`, pluginErr);
exitCode = -1;
}
// log.info(`${fileLogPrefix} Finished in ${fileTimer.elapsedStr()}.`);
}
log.info(`${pluginLogPrefix} Finished in ${pluginTimer.elapsedStr()}.`);
}
log.info(`Finished in ${pluginsTimer.elapsedStr()}, for ${config.plugins.length} plugin(s).`);
const writeTimer = new PerfTimer();
log.info(`Writing ${updatedSourceFiles.size} updated file(s)...`);
const writes = [];
// eslint-disable-next-line no-restricted-syntax
for (const fileName of updatedSourceFiles) {
const sourceFile = project.getSourceFileOrThrow(fileName);
writes.push(project.fileSystem.writeFile(sourceFile.fileName, sourceFile.text));
}
await Promise.all(writes);
log.info(`Wrote ${updatedSourceFiles.size} updated file(s) in ${writeTimer.elapsedStr()}.`);
return exitCode;
}
export { MigrateConfig };