Skip to content

Commit

Permalink
feat(codemod): migrate turbo.json dependsOn
Browse files Browse the repository at this point in the history
  • Loading branch information
tknickman committed Sep 20, 2022
1 parent 6ea7a8e commit 9575bee
Show file tree
Hide file tree
Showing 10 changed files with 629 additions and 208 deletions.
359 changes: 359 additions & 0 deletions packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,359 @@
import merge from "deepmerge";
import {
hasLegacyEnvVarDependencies,
migratePipeline,
migrateConfig,
} from "../src/transforms/migrate-env-var-dependencies";
import { TurboConfig } from "../src/types";

const getTestTurboConfig = (override: TurboConfig = {}): TurboConfig => {
const config = {
$schema: "./docs/public/schema.json",
globalDependencies: ["$GLOBAL_ENV_KEY"],
pipeline: {
test: {
outputs: ["coverage/**/*"],
dependsOn: ["^build"],
},
lint: {
outputs: [],
},
dev: {
cache: false,
},
build: {
outputs: ["dist/**/*", ".next/**/*"],
dependsOn: ["^build", "$TASK_ENV_KEY", "$ANOTHER_ENV_KEY"],
},
},
};

return merge(config, override, {
arrayMerge: (_, sourceArray) => sourceArray,
});
};

describe("migrate-env-var-dependencies", () => {
describe("hasLegacyEnvVarDependencies", () => {
it("finds env keys in legacy turbo.json - has keys", async () => {
const config = getTestTurboConfig();
const { hasKeys, envVars } = hasLegacyEnvVarDependencies(config);
expect(hasKeys).toEqual(true);
expect(envVars).toMatchInlineSnapshot(`
Array [
"$GLOBAL_ENV_KEY",
"$TASK_ENV_KEY",
"$ANOTHER_ENV_KEY",
]
`);
});

it("finds env keys in legacy turbo.json - multiple pipeline keys", async () => {
const config = getTestTurboConfig({
pipeline: { test: { dependsOn: ["$MY_ENV"] } },
});
const { hasKeys, envVars } = hasLegacyEnvVarDependencies(config);
expect(hasKeys).toEqual(true);
expect(envVars).toMatchInlineSnapshot(`
Array [
"$GLOBAL_ENV_KEY",
"$MY_ENV",
"$TASK_ENV_KEY",
"$ANOTHER_ENV_KEY",
]
`);
});

it("finds env keys in legacy turbo.json - no keys", async () => {
// override to exclude keys
const config = getTestTurboConfig({
globalDependencies: [],
pipeline: { build: { dependsOn: [] } },
});
const { hasKeys, envVars } = hasLegacyEnvVarDependencies(config);
expect(hasKeys).toEqual(false);
expect(envVars).toMatchInlineSnapshot(`Array []`);
});
});

describe("migratePipeline", () => {
it("migrates pipeline with env var dependencies", async () => {
const config = getTestTurboConfig();
const { build } = config?.pipeline ?? {};
const pipeline = migratePipeline(build);
expect(pipeline).toHaveProperty("env");
expect(pipeline?.env).toMatchInlineSnapshot(`
Array [
"$TASK_ENV_KEY",
"$ANOTHER_ENV_KEY",
]
`);
expect(pipeline?.dependsOn).toMatchInlineSnapshot(`
Array [
"^build",
]
`);
});

it("migrates pipeline with no env var dependencies", async () => {
const config = getTestTurboConfig();
const { test } = config?.pipeline ?? {};
const pipeline = migratePipeline(test);
expect(pipeline.env).toBeUndefined();
expect(pipeline?.dependsOn).toMatchInlineSnapshot(`
Array [
"^build",
]
`);
});

it("migrates pipeline with existing env key", async () => {
const config = getTestTurboConfig({
pipeline: { test: { env: ["$MY_ENV"], dependsOn: ["^build"] } },
});
const { test } = config?.pipeline ?? {};
const pipeline = migratePipeline(test);
expect(pipeline).toHaveProperty("env");
expect(pipeline?.env).toMatchInlineSnapshot(`
Array [
"$MY_ENV",
]
`);
expect(pipeline?.dependsOn).toMatchInlineSnapshot(`
Array [
"^build",
]
`);
});

it("migrates pipeline with incomplete env key", async () => {
const config = getTestTurboConfig({
pipeline: {
test: { env: ["$MY_ENV"], dependsOn: ["^build", "$SUPER_COOL"] },
},
});
const { test } = config?.pipeline ?? {};
const pipeline = migratePipeline(test);
expect(pipeline).toHaveProperty("env");
expect(pipeline?.env).toMatchInlineSnapshot(`
Array [
"$MY_ENV",
"$SUPER_COOL",
]
`);
expect(pipeline?.dependsOn).toMatchInlineSnapshot(`
Array [
"^build",
]
`);
});

it("migrates pipeline with duplicate env keys", async () => {
const config = getTestTurboConfig({
pipeline: {
test: { env: ["$MY_ENV"], dependsOn: ["^build", "$MY_ENV"] },
},
});
const { test } = config?.pipeline ?? {};
const pipeline = migratePipeline(test);
expect(pipeline).toHaveProperty("env");
expect(pipeline?.env).toMatchInlineSnapshot(`
Array [
"$MY_ENV",
]
`);
expect(pipeline?.dependsOn).toMatchInlineSnapshot(`
Array [
"^build",
]
`);
});
});

describe("migrateConfig", () => {
it("migrates config with env var dependencies", async () => {
const config = getTestTurboConfig();
const pipeline = migrateConfig(config);
expect(pipeline).toMatchInlineSnapshot(`
Object {
"$schema": "./docs/public/schema.json",
"env": Array [
"$GLOBAL_ENV_KEY",
],
"globalDependencies": Array [],
"pipeline": Object {
"build": Object {
"dependsOn": Array [
"^build",
],
"env": Array [
"$TASK_ENV_KEY",
"$ANOTHER_ENV_KEY",
],
"outputs": Array [
"dist/**/*",
".next/**/*",
],
},
"dev": Object {
"cache": false,
},
"lint": Object {
"outputs": Array [],
},
"test": Object {
"dependsOn": Array [
"^build",
],
"outputs": Array [
"coverage/**/*",
],
},
},
}
`);
});

it("migrates config with no env var dependencies", async () => {
const config = getTestTurboConfig({
globalDependencies: [],
pipeline: {
build: { dependsOn: ["^build"] },
},
});
const pipeline = migrateConfig(config);
expect(pipeline).toMatchInlineSnapshot(`
Object {
"$schema": "./docs/public/schema.json",
"globalDependencies": Array [],
"pipeline": Object {
"build": Object {
"dependsOn": Array [
"^build",
],
"outputs": Array [
"dist/**/*",
".next/**/*",
],
},
"dev": Object {
"cache": false,
},
"lint": Object {
"outputs": Array [],
},
"test": Object {
"dependsOn": Array [
"^build",
],
"outputs": Array [
"coverage/**/*",
],
},
},
}
`);
});

it("migrates config with inconsistent config", async () => {
const config = getTestTurboConfig({
pipeline: {
test: { env: ["$MY_ENV"], dependsOn: ["^build", "$SUPER_COOL"] },
},
});
const pipeline = migrateConfig(config);
expect(pipeline).toMatchInlineSnapshot(`
Object {
"$schema": "./docs/public/schema.json",
"env": Array [
"$GLOBAL_ENV_KEY",
],
"globalDependencies": Array [],
"pipeline": Object {
"build": Object {
"dependsOn": Array [
"^build",
],
"env": Array [
"$TASK_ENV_KEY",
"$ANOTHER_ENV_KEY",
],
"outputs": Array [
"dist/**/*",
".next/**/*",
],
},
"dev": Object {
"cache": false,
},
"lint": Object {
"outputs": Array [],
},
"test": Object {
"dependsOn": Array [
"^build",
],
"env": Array [
"$MY_ENV",
"$SUPER_COOL",
],
"outputs": Array [
"coverage/**/*",
],
},
},
}
`);
});

it("migrates config with duplicate env keys", async () => {
const config = getTestTurboConfig({
pipeline: {
test: { env: ["$MY_ENV"], dependsOn: ["^build", "$MY_ENV"] },
},
});
const pipeline = migrateConfig(config);
expect(pipeline).toMatchInlineSnapshot(`
Object {
"$schema": "./docs/public/schema.json",
"env": Array [
"$GLOBAL_ENV_KEY",
],
"globalDependencies": Array [],
"pipeline": Object {
"build": Object {
"dependsOn": Array [
"^build",
],
"env": Array [
"$TASK_ENV_KEY",
"$ANOTHER_ENV_KEY",
],
"outputs": Array [
"dist/**/*",
".next/**/*",
],
},
"dev": Object {
"cache": false,
},
"lint": Object {
"outputs": Array [],
},
"test": Object {
"dependsOn": Array [
"^build",
],
"env": Array [
"$MY_ENV",
],
"outputs": Array [
"coverage/**/*",
],
},
},
}
`);
});
});
});
4 changes: 4 additions & 0 deletions packages/turbo-codemod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"bin": "dist/index.js",
"scripts": {
"build": "tsup",
"test": "jest",
"lint": "eslint src/**/*.ts",
"check-types": "tsc --noEmit"
},
Expand All @@ -38,9 +39,12 @@
"@types/fs-extra": "^9.0.13",
"@types/gradient-string": "^1.1.2",
"@types/inquirer": "^7.3.1",
"@types/jest": "^27.4.0",
"@types/node": "^16.11.12",
"@types/semver": "^7.3.9",
"deepmerge": "^4.2.2",
"eslint": "^7.23.0",
"jest": "^27.4.3",
"semver": "^7.3.5",
"strip-ansi": "^6.0.1",
"tsconfig": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/turbo-codemod/src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export function checkGitStatus(force: boolean) {
clean = isGitClean.sync(process.cwd());
errorMessage = "Git directory is not clean";
} catch (err: any) {
if (err && err.stderr && err.stderr.indexOf("Not a git repository") >= 0) {
if (err && err.stderr && err.stderr.indexOf("not a git repository") >= 0) {
clean = true;
}
}
Expand Down

0 comments on commit 9575bee

Please sign in to comment.