diff --git a/.changeset/long-dots-turn.md b/.changeset/long-dots-turn.md new file mode 100644 index 0000000..2fe5141 --- /dev/null +++ b/.changeset/long-dots-turn.md @@ -0,0 +1,5 @@ +--- +"debarrel": minor +--- + +Add metrics diff --git a/codemods/debarrel/scripts/codemod.ts b/codemods/debarrel/scripts/codemod.ts index af982d3..f4d1e73 100644 --- a/codemods/debarrel/scripts/codemod.ts +++ b/codemods/debarrel/scripts/codemod.ts @@ -1,4 +1,5 @@ import type { Codemod, Edit, GetSelector } from "codemod:ast-grep"; +import { useMetricAtom } from "codemod:metrics"; import path from "path"; import type { Language } from "./utils/language.ts"; import { getStringContent } from "./utils/ast.ts"; @@ -16,8 +17,11 @@ import { type BarrelMockInfo, } from "./utils/mocks.ts"; -const codemod: Codemod = async (root) => { +const barrelImport = useMetricAtom("barrel_import"); + +const codemod: Codemod = async (root, options) => { const rootNode = root.root(); + const relativeFilename = root.relativeFilename(); const filename = root.filename(); const edits: Edit[] = []; const barrelRewrites = new Map(); @@ -77,6 +81,14 @@ const codemod: Codemod = async (root) => { if (rewrites.length === 0) continue; + const firstRewrite = rewrites[0]; + if (firstRewrite) { + barrelImport.increment({ + filePath: firstRewrite.resolvedFilePath, + importer: relativeFilename, + }); + } + recordBarrelRewrites(barrelRewrites, importPath, rewrites); const byPath = groupByPath(rewrites); diff --git a/codemods/debarrel/scripts/utils/specifiers.ts b/codemods/debarrel/scripts/utils/specifiers.ts index a208aaa..491bc0c 100644 --- a/codemods/debarrel/scripts/utils/specifiers.ts +++ b/codemods/debarrel/scripts/utils/specifiers.ts @@ -1,4 +1,4 @@ -import type { SgNode } from "codemod:ast-grep"; +import type { SgNode, SgRoot } from "codemod:ast-grep"; import type { Language } from "./language.ts"; import { getStringContent } from "./ast.ts"; import { @@ -15,6 +15,7 @@ export interface SpecRewrite { newImportPath: string; localName: string; importType: "default" | "named" | "namespace"; + resolvedFilePath: string; } /** @@ -24,7 +25,7 @@ export interface SpecRewrite { export function resolveSpecifier( localBinding: SgNode, importPath: string, - def: { kind: string; root: { filename(): string }; node: SgNode }, + def: { kind: string; root: SgRoot; node: SgNode }, ): SpecRewrite | null { if (def.kind !== "external") return null; @@ -51,6 +52,7 @@ export function resolveSpecifier( newImportPath: joinImportPaths(importPath, info.sourceFromBarrel), localName: info.localName, importType: info.importType, + resolvedFilePath: def.root.relativeFilename(), }; } // Import-then-reexport: definition landed on import_specifier in the barrel @@ -72,6 +74,7 @@ export function resolveSpecifier( newImportPath: joinImportPaths(importPath, impPath), localName: originalName, importType: "named", + resolvedFilePath: def.root.relativeFilename(), }; } diff --git a/codemods/debarrel/tests/aliased-reexport/expected/src/metrics.json b/codemods/debarrel/tests/aliased-reexport/expected/src/metrics.json new file mode 100644 index 0000000..decbe44 --- /dev/null +++ b/codemods/debarrel/tests/aliased-reexport/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/aliased-reexport/input/src/metrics.json b/codemods/debarrel/tests/aliased-reexport/input/src/metrics.json new file mode 100644 index 0000000..decbe44 --- /dev/null +++ b/codemods/debarrel/tests/aliased-reexport/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/aliased-reexport/metrics.json b/codemods/debarrel/tests/aliased-reexport/metrics.json new file mode 100644 index 0000000..decbe44 --- /dev/null +++ b/codemods/debarrel/tests/aliased-reexport/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/barrel-with-own-declarations/expected/src/metrics.json b/codemods/debarrel/tests/barrel-with-own-declarations/expected/src/metrics.json new file mode 100644 index 0000000..6fff96d --- /dev/null +++ b/codemods/debarrel/tests/barrel-with-own-declarations/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/barrel-with-own-declarations/input/src/metrics.json b/codemods/debarrel/tests/barrel-with-own-declarations/input/src/metrics.json new file mode 100644 index 0000000..6fff96d --- /dev/null +++ b/codemods/debarrel/tests/barrel-with-own-declarations/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/barrel-with-own-declarations/metrics.json b/codemods/debarrel/tests/barrel-with-own-declarations/metrics.json new file mode 100644 index 0000000..6fff96d --- /dev/null +++ b/codemods/debarrel/tests/barrel-with-own-declarations/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/basic-named-reexport/expected/src/metrics.json b/codemods/debarrel/tests/basic-named-reexport/expected/src/metrics.json new file mode 100644 index 0000000..544b62d --- /dev/null +++ b/codemods/debarrel/tests/basic-named-reexport/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/basic-named-reexport/input/src/metrics.json b/codemods/debarrel/tests/basic-named-reexport/input/src/metrics.json new file mode 100644 index 0000000..544b62d --- /dev/null +++ b/codemods/debarrel/tests/basic-named-reexport/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/basic-named-reexport/metrics.json b/codemods/debarrel/tests/basic-named-reexport/metrics.json new file mode 100644 index 0000000..544b62d --- /dev/null +++ b/codemods/debarrel/tests/basic-named-reexport/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/default-as-named/expected/src/SecondApp.ts b/codemods/debarrel/tests/default-as-named/expected/src/SecondApp.ts new file mode 100644 index 0000000..a0202af --- /dev/null +++ b/codemods/debarrel/tests/default-as-named/expected/src/SecondApp.ts @@ -0,0 +1,3 @@ +import Modal from "./components/Modal"; + +console.log(Modal(), "second file"); diff --git a/codemods/debarrel/tests/default-as-named/expected/src/metrics.json b/codemods/debarrel/tests/default-as-named/expected/src/metrics.json new file mode 100644 index 0000000..7105830 --- /dev/null +++ b/codemods/debarrel/tests/default-as-named/expected/src/metrics.json @@ -0,0 +1,18 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/SecondApp.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/default-as-named/input/src/SecondApp.ts b/codemods/debarrel/tests/default-as-named/input/src/SecondApp.ts new file mode 100644 index 0000000..75964cb --- /dev/null +++ b/codemods/debarrel/tests/default-as-named/input/src/SecondApp.ts @@ -0,0 +1,3 @@ +import { Modal } from "./components"; + +console.log(Modal(), "second file"); diff --git a/codemods/debarrel/tests/default-as-named/input/src/metrics.json b/codemods/debarrel/tests/default-as-named/input/src/metrics.json new file mode 100644 index 0000000..7105830 --- /dev/null +++ b/codemods/debarrel/tests/default-as-named/input/src/metrics.json @@ -0,0 +1,18 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/SecondApp.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/import-then-reexport/expected/src/metrics.json b/codemods/debarrel/tests/import-then-reexport/expected/src/metrics.json new file mode 100644 index 0000000..2f5fa45 --- /dev/null +++ b/codemods/debarrel/tests/import-then-reexport/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/utils/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/import-then-reexport/input/src/metrics.json b/codemods/debarrel/tests/import-then-reexport/input/src/metrics.json new file mode 100644 index 0000000..2f5fa45 --- /dev/null +++ b/codemods/debarrel/tests/import-then-reexport/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/utils/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/import-then-reexport/metrics.json b/codemods/debarrel/tests/import-then-reexport/metrics.json new file mode 100644 index 0000000..2f5fa45 --- /dev/null +++ b/codemods/debarrel/tests/import-then-reexport/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/utils/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/multiple-named-reexports/expected/src/metrics.json b/codemods/debarrel/tests/multiple-named-reexports/expected/src/metrics.json new file mode 100644 index 0000000..0336a10 --- /dev/null +++ b/codemods/debarrel/tests/multiple-named-reexports/expected/src/metrics.json @@ -0,0 +1,18 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/utils/index.ts", + "importer": "src/other.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/utils/index.ts", + "importer": "src/page.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/multiple-named-reexports/input/src/metrics.json b/codemods/debarrel/tests/multiple-named-reexports/input/src/metrics.json new file mode 100644 index 0000000..0336a10 --- /dev/null +++ b/codemods/debarrel/tests/multiple-named-reexports/input/src/metrics.json @@ -0,0 +1,18 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/utils/index.ts", + "importer": "src/other.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/utils/index.ts", + "importer": "src/page.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/multiple-named-reexports/metrics.json b/codemods/debarrel/tests/multiple-named-reexports/metrics.json new file mode 100644 index 0000000..0336a10 --- /dev/null +++ b/codemods/debarrel/tests/multiple-named-reexports/metrics.json @@ -0,0 +1,18 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/utils/index.ts", + "importer": "src/other.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/utils/index.ts", + "importer": "src/page.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/partial-with-type-specifiers/expected/src/metrics.json b/codemods/debarrel/tests/partial-with-type-specifiers/expected/src/metrics.json new file mode 100644 index 0000000..6fff96d --- /dev/null +++ b/codemods/debarrel/tests/partial-with-type-specifiers/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/partial-with-type-specifiers/input/src/metrics.json b/codemods/debarrel/tests/partial-with-type-specifiers/input/src/metrics.json new file mode 100644 index 0000000..6fff96d --- /dev/null +++ b/codemods/debarrel/tests/partial-with-type-specifiers/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/partial-with-type-specifiers/metrics.json b/codemods/debarrel/tests/partial-with-type-specifiers/metrics.json new file mode 100644 index 0000000..6fff96d --- /dev/null +++ b/codemods/debarrel/tests/partial-with-type-specifiers/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/test.config.yaml b/codemods/debarrel/tests/test.config.yaml new file mode 100644 index 0000000..e241c6e --- /dev/null +++ b/codemods/debarrel/tests/test.config.yaml @@ -0,0 +1 @@ +semantic_workspace: true diff --git a/codemods/debarrel/tests/tsconfig-alias-paths/expected/src/metrics.json b/codemods/debarrel/tests/tsconfig-alias-paths/expected/src/metrics.json new file mode 100644 index 0000000..544b62d --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-alias-paths/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/tsconfig-alias-paths/input/src/metrics.json b/codemods/debarrel/tests/tsconfig-alias-paths/input/src/metrics.json new file mode 100644 index 0000000..544b62d --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-alias-paths/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/tsconfig-alias-paths/metrics.json b/codemods/debarrel/tests/tsconfig-alias-paths/metrics.json new file mode 100644 index 0000000..544b62d --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-alias-paths/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/update-test-mocks/expected/src/metrics.json b/codemods/debarrel/tests/update-test-mocks/expected/src/metrics.json new file mode 100644 index 0000000..0e07d8f --- /dev/null +++ b/codemods/debarrel/tests/update-test-mocks/expected/src/metrics.json @@ -0,0 +1,25 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/Button.test.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/Component.test.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/FactoryFn.test.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/update-test-mocks/input/src/metrics.json b/codemods/debarrel/tests/update-test-mocks/input/src/metrics.json new file mode 100644 index 0000000..0e07d8f --- /dev/null +++ b/codemods/debarrel/tests/update-test-mocks/input/src/metrics.json @@ -0,0 +1,25 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/Button.test.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/Component.test.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/FactoryFn.test.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/update-test-mocks/metrics.json b/codemods/debarrel/tests/update-test-mocks/metrics.json new file mode 100644 index 0000000..0e07d8f --- /dev/null +++ b/codemods/debarrel/tests/update-test-mocks/metrics.json @@ -0,0 +1,25 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/Button.test.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/Component.test.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/FactoryFn.test.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/workspace-package-import/expected/src/metrics.json b/codemods/debarrel/tests/workspace-package-import/expected/src/metrics.json new file mode 100644 index 0000000..fcdba32 --- /dev/null +++ b/codemods/debarrel/tests/workspace-package-import/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "packages/package-b/src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/workspace-package-import/input/src/metrics.json b/codemods/debarrel/tests/workspace-package-import/input/src/metrics.json new file mode 100644 index 0000000..fcdba32 --- /dev/null +++ b/codemods/debarrel/tests/workspace-package-import/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "packages/package-b/src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/workspace-package-import/metrics.json b/codemods/debarrel/tests/workspace-package-import/metrics.json new file mode 100644 index 0000000..fcdba32 --- /dev/null +++ b/codemods/debarrel/tests/workspace-package-import/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "packages/package-b/src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94bb217..3194ae6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,8 +7,8 @@ settings: catalogs: default: '@codemod.com/jssg-types': - specifier: ^1.5.2 - version: 1.5.2 + specifier: ^1.6.0 + version: 1.6.0 '@jssg/utils': specifier: ^0.0.4 version: 0.0.4 @@ -32,7 +32,7 @@ importers: devDependencies: '@codemod.com/jssg-types': specifier: 'catalog:' - version: 1.5.2 + version: 1.6.0 typescript: specifier: 'catalog:' version: 6.0.2 @@ -98,8 +98,8 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} - '@codemod.com/jssg-types@1.5.2': - resolution: {integrity: sha512-hZ+CuFL7BzE74VKSOG7xHaxgoRahEoOPdp0N9eg4KAwaYt0gc0YNMI/UvCRZKUTnnRBgTswrwgCbHZMDhjTWoQ==} + '@codemod.com/jssg-types@1.6.0': + resolution: {integrity: sha512-9b6rsL3RZJvOPJ+gUj1W0041mHF6eYwLt+wsa4zqxJWNsxLha0JvFyaQdcw5XfQ5Ldd+H/kV/yZ4dpN+hC9OXw==} '@inquirer/external-editor@1.0.3': resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} @@ -574,7 +574,7 @@ snapshots: human-id: 4.1.3 prettier: 2.8.8 - '@codemod.com/jssg-types@1.5.2': {} + '@codemod.com/jssg-types@1.6.0': {} '@inquirer/external-editor@1.0.3(@types/node@25.5.2)': dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 939551e..905e444 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,5 +2,5 @@ packages: - "codemods/*" catalog: "@jssg/utils": "^0.0.4" - "@codemod.com/jssg-types": "^1.5.2" + "@codemod.com/jssg-types": "^1.6.0" "typescript": "6.0.2" \ No newline at end of file