Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion codemods/debarrel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"check-types": "tsc --noEmit"
},
"dependencies": {
"@jssg/utils": "catalog:"
"@jssg/utils": "catalog:",
"codemodctl": "0.1.17"
},
"devDependencies": {
"@codemod.com/jssg-types": "catalog:",
Expand Down
32 changes: 30 additions & 2 deletions codemods/debarrel/scripts/codemod.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Transform, Edit, SgNode } from "codemod:ast-grep";
import type { Transform, Edit, SgNode, GetSelector } from "codemod:ast-grep";
import type TSX from "codemod:ast-grep/langs/tsx";
import type TypeScript from "codemod:ast-grep/langs/typescript";
import type JavaScript from "codemod:ast-grep/langs/javascript";
import { addImport, removeImport } from "@jssg/utils/javascript/imports";
import { fitsInShard } from "codemodctl/sharding";
import path from "path";
import fs from "fs";

Expand Down Expand Up @@ -72,6 +73,20 @@ function isInsideNodeModules(filename: string): boolean {
);
}

function getRelativePath(from: string, to: string): string {
const fromParts = from.split(/[/\\]/).filter(Boolean);
const toParts = to.split(/[/\\]/).filter(Boolean);
let i = 0;
while (i < fromParts.length && i < toParts.length && fromParts[i] === toParts[i]) {
i++;
}
const upCount = fromParts.length - i;
const downParts = toParts.slice(i);
const upParts = Array(upCount).fill("..");
const relativeParts = [...upParts, ...downParts];
return relativeParts.length === 0 ? "." : relativeParts.join("/");
}

function fileExists(filePath: string): boolean {
try {
fs.accessSync(filePath);
Expand Down Expand Up @@ -331,9 +346,18 @@ function addImportsFromRewrites(
}
}

const transform: Transform<Language> = async (root) => {
const transform: Transform<Language> = async (root, options) => {
const rootNode = root.root();
const filename = root.filename();
const projectRoot = process.cwd();
const relativeFilename = getRelativePath(projectRoot, filename);

if (options.matrixValues?.shard && options.matrixValues._meta_files) {
const fits = fitsInShard(relativeFilename, options.matrixValues as {_meta_files: string[] });
if (!fits) {
return null;
}
}
const edits: Edit[] = [];

for (const importStmt of rootNode.findAll({
Expand Down Expand Up @@ -432,4 +456,8 @@ const transform: Transform<Language> = async (root) => {
return rootNode.commitEdits(edits);
};

export const getSelector: GetSelector<Language> = () => {
return {rule: { kind: "import_statement" } };
};

export default transform;
5 changes: 2 additions & 3 deletions codemods/debarrel/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
"types": ["@codemod.com/jssg-types"],
"allowImportingTsExtensions": true,
"noEmit": true,
"verbatimModuleSyntax": true,
"erasableSyntaxOnly": true,
"strict": true,
"strictNullChecks": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true
"noUncheckedIndexedAccess": true,
"skipLibCheck": true
},
"exclude": ["tests"]
}
82 changes: 79 additions & 3 deletions codemods/debarrel/workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,95 @@

version: "1"

state:
schema:
shards:
type: array
items:
type: object
properties:
team:
type: string
shard:
type: string
shardId:
type: string

params:
schema:
shardingMethod:
name: "Sharding Method"
description: "The method to use for sharding"
type: string
default: "codeowner"
oneOf:
- type: string
enum:
- "codeowner"
- "directory"
shardingDirectoryTarget:
name: "Sharding Directory Target"
description: "When sharding by directory, the directory to target for the codemod"
type: string
default: "./src"
prSize:
type: number
default: 30
name: "PR Size"
description: "The size of the PR to create"

nodes:
- id: evaluate-shards
name: Evaluate Shards
trigger:
type: automatic
steps:
- name: "Evaluate shards by directory"
if: params.shardingMethod == "directory"
run: |
echo "Evaluating shards by directory"
npx -y codemodctl@latest shard directory -l typescript -c "$CODEMOD_PATH/scripts/codemod.ts" -s ${{ params.prSize }} --stateProp shards --target ${{ params.shardingDirectoryTarget }}
echo "Shards evaluated by directory"
- name: "Evaluate shards by codeowner"
if: params.shardingMethod == "codeowner"
run: |
echo "Evaluating shards by codeowner"
npx -y codemodctl@latest shard codeowner -l typescript -c "$CODEMOD_PATH/scripts/codemod.ts" -s ${{ params.prSize }} --stateProp shards
echo "Shards evaluated by codeowner"
- id: apply-transforms
name: Apply AST Transformations
type: automatic
trigger:
type: manual
depends_on:
- evaluate-shards
strategy:
type: matrix
from_state: shards
steps:
- id: debarrel-js-ast-grep
name: "Debarrel: rewrite imports and clean up barrels"
js-ast-grep:
js_file: scripts/codemod.ts
language: "typescript"
semantic_analysis: workspace
- id: install-package-skill
name: Install package skill
- name: "Create pull request"
run: |
echo "Creating pull request"
npx -y codemodctl@latest git create-pr \
--commitMessage "[DRAFT] refactor: Run $CODEMOD_PROJECT_NAME shard $MATRIX_NAME" \
--title "[DRAFT] refactor: Run $CODEMOD_PROJECT_NAME shard $MATRIX_NAME" \
--body "This is a pull request for the $CODEMOD_PROJECT_NAME campaign targeting $MATRIX_TEAM $MATRIX_DIRECTORY shard $MATRIX_SHARDID $MATRIX_NAME" \
--push
- id: install-skill
name: Install Skill
trigger:
type: manual
depends_on:
- apply-transforms
steps:
- name: "Install debarrel skill"
install-skill:
package: "debarrel"
path: "./agents/skill/SKILL.md"
Loading
Loading