codemods: implement core-imports codemod

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-06-01 23:01:02 +02:00
parent 20a5c789a4
commit b74d558369
3 changed files with 98 additions and 5 deletions
+3 -1
View File
@@ -26,9 +26,11 @@
"dependencies": {
"@backstage/cli-common": "0.1.1",
"chalk": "^4.0.0",
"jscodeshift": "^0.12.0"
"jscodeshift": "^0.12.0",
"jscodeshift-add-imports": "^1.0.10"
},
"devDependencies": {
"@types/jscodeshift": "^0.11.0",
"@types/node": "^14.14.32",
"commander": "^6.1.0",
"ts-node": "^9.1.1"
+71 -1
View File
@@ -13,4 +13,74 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
console.log('hello');
const addImports = require('jscodeshift-add-imports');
const { resolve: resolvePath } = require('path');
const fs = require('fs');
function findExports(packageName) {
const packagePath = require.resolve(`${packageName}/package.json`);
const typesPath = resolvePath(packagePath, '../dist/index.d.ts');
const content = fs.readFileSync(typesPath, 'utf8');
const [, exportSymbols] = content.match(/export \{ (.*) \};/);
return exportSymbols
.split(', ')
.map(exported => exported.match(/.* as (.*)/)?.[1] || exported);
}
const symbolTable = {
'@backstage/core-app-api': findExports('@backstage/core-app-api'),
'@backstage/core-components': findExports('@backstage/core-components'),
'@backstage/core-plugin-api': findExports('@backstage/core-plugin-api'),
};
const reverseSymbolTable = Object.entries(symbolTable).reduce(
(table, [pkg, symbols]) => {
for (const symbol of symbols) {
table[symbol] = pkg;
}
return table;
},
{},
);
module.exports = (file, /** @type {import('jscodeshift').API} */ api) => {
const j = api.jscodeshift;
const root = j(file.source);
// Find all import statements of @backstage/core
const imports = root.find(j.ImportDeclaration, {
source: {
value: '@backstage/core',
},
});
// Then loop through all the import statement and collects each imported symbol
const importedSymbols = imports.nodes().flatMap(node =>
(node.specifiers || []).flatMap(specifier => ({
name: specifier.imported.name, // The symbol we're importing
local: specifier.local.name, // The local name, usually this is the same
})),
);
// Now that we gathered all the imports we want to add, we get rid of the old one
imports.remove();
// The convert the imports into actual import statements
const newImportStatements = importedSymbols.map(({ name, local }) => {
const targetPackage = reverseSymbolTable[name];
if (!targetPackage) {
throw new Error(`No target package found for import of ${name}`);
}
return j.importDeclaration(
[j.importSpecifier(j.identifier(name), j.identifier(local))],
j.literal(targetPackage),
);
});
// And add the new imports. `addImports` will take care of resolving duplicates
addImports(root, newImportStatements);
return root.toSource();
};
+24 -3
View File
@@ -1879,7 +1879,7 @@
debug "^4.1.0"
globals "^11.1.0"
"@babel/traverse@^7.14.0", "@babel/traverse@^7.14.2":
"@babel/traverse@^7.14.0", "@babel/traverse@^7.14.2", "@babel/traverse@^7.4.5":
version "7.14.2"
resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz#9201a8d912723a831c2679c7ebbf2fe1416d765b"
integrity sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==
@@ -6504,6 +6504,14 @@
resolved "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.0.tgz#d1a11688112091f2c711674df3a65ea2f47b5dfb"
integrity sha512-4vlpCM5KPCL5CfGmTbpjwVKbISRYhduEJvvUWsH5EB7QInhEj94XPZ3ts/9FPiLZFqYO0xoW4ZL8z2AabTGgJA==
"@types/jscodeshift@^0.11.0":
version "0.11.0"
resolved "https://registry.npmjs.org/@types/jscodeshift/-/jscodeshift-0.11.0.tgz#7224cf1a4d0383b4fb2694ffed52f57b45c3325b"
integrity sha512-OcJgr5GznWCEx2Oeg4eMUZYwssTHFj/tU8grrNCKdFQtAEAa0ezDiPHbCdSkyWrRSurXrYbNbHdhxbbB76pXNg==
dependencies:
ast-types "^0.14.1"
recast "^0.20.3"
"@types/json-schema-merge-allof@^0.6.0":
version "0.6.0"
resolved "https://registry.npmjs.org/@types/json-schema-merge-allof/-/json-schema-merge-allof-0.6.0.tgz#0f587d8a3bcb41a55ef2e91d3ba96430c9bc1813"
@@ -8444,7 +8452,7 @@ ast-types-flow@^0.0.7:
resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
ast-types@0.14.2, ast-types@^0.14.2:
ast-types@0.14.2, ast-types@^0.14.1, ast-types@^0.14.2:
version "0.14.2"
resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd"
integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==
@@ -17184,6 +17192,19 @@ jsbn@~0.1.0:
resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
jscodeshift-add-imports@^1.0.10:
version "1.0.10"
resolved "https://registry.npmjs.org/jscodeshift-add-imports/-/jscodeshift-add-imports-1.0.10.tgz#3d0f99d539d492cfa037aa4a63f04c4a626bcff5"
integrity sha512-VUe9DJ3zkWIR62zSRQnmsOVeyt77yD8knvYNna/PzRZlF9j799hJw5sqTZu4EX16XLIqS3FxWz3nXuGuiw9iyQ==
dependencies:
"@babel/traverse" "^7.4.5"
jscodeshift-find-imports "^2.0.2"
jscodeshift-find-imports@^2.0.2:
version "2.0.4"
resolved "https://registry.npmjs.org/jscodeshift-find-imports/-/jscodeshift-find-imports-2.0.4.tgz#4dc427bff6c8f8c6c766a19043cdbee4e1d10782"
integrity sha512-HxOzjWDOFFSCf8EKSTQGqCxXeRFqZszOywnZ0HuMB9YPDFHVpxftGRsY+QS+Qq8o2qUojlmNU3JEHts5DWYS1A==
jscodeshift@^0.12.0:
version "0.12.0"
resolved "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.12.0.tgz#de7302f3d3e1f4b3b36f9e484f451ba4ab7cc1f4"
@@ -23074,7 +23095,7 @@ readdirp@~3.5.0:
dependencies:
picomatch "^2.2.1"
recast@^0.20.4:
recast@^0.20.3, recast@^0.20.4:
version "0.20.4"
resolved "https://registry.npmjs.org/recast/-/recast-0.20.4.tgz#db55983eac70c46b3fff96c8e467d65ffb4a7abc"
integrity sha512-6qLIBGGRcwjrTZGIiBpJVC/NeuXpogXNyRQpqU1zWPUigCphvApoCs9KIwDYh1eDuJ6dAFlQoi/QUyE5KQ6RBQ==