aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts
diff options
context:
space:
mode:
author简律纯 <hsiangnianian@outlook.com>2023-04-28 01:36:44 +0800
committer简律纯 <hsiangnianian@outlook.com>2023-04-28 01:36:44 +0800
commitdd84b9d64fb98746a230cd24233ff50a562c39c9 (patch)
treeb583261ef00b3afe72ec4d6dacb31e57779a6faf /packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts
parent0b46fcd72ac34382387b2bcf9095233efbcc52f4 (diff)
downloadHydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.tar.gz
HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.zip
Diffstat (limited to 'packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts')
-rw-r--r--packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts758
1 files changed, 758 insertions, 0 deletions
diff --git a/packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts b/packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts
new file mode 100644
index 0000000..fbc5d8d
--- /dev/null
+++ b/packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts
@@ -0,0 +1,758 @@
+import merge from "deepmerge";
+import {
+ hasLegacyEnvVarDependencies,
+ migratePipeline,
+ migrateConfig,
+ transformer,
+} from "../src/transforms/migrate-env-var-dependencies";
+import { setupTestFixtures } from "@turbo/test-utils";
+import type { Schema } from "@turbo/types";
+
+const getTestTurboConfig = (override: Schema = { pipeline: {} }): Schema => {
+ 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/**/*", "!.next/cache/**"],
+ dependsOn: ["^build", "$TASK_ENV_KEY", "$ANOTHER_ENV_KEY"],
+ },
+ },
+ };
+
+ return merge(config, override, {
+ arrayMerge: (_, sourceArray) => sourceArray,
+ });
+};
+
+describe("migrate-env-var-dependencies", () => {
+ describe("hasLegacyEnvVarDependencies - utility", () => {
+ 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 []`);
+ });
+
+ it("finds env keys in turbo.json - no global", async () => {
+ const { hasKeys, envVars } = hasLegacyEnvVarDependencies({
+ pipeline: { build: { dependsOn: ["$cool"] } },
+ });
+ expect(hasKeys).toEqual(true);
+ expect(envVars).toMatchInlineSnapshot(`
+ Array [
+ "$cool",
+ ]
+ `);
+ });
+ });
+
+ describe("migratePipeline - utility", () => {
+ 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",
+ "MY_ENV",
+ ]
+ `);
+ expect(pipeline?.dependsOn).toMatchInlineSnapshot(`
+ Array [
+ "^build",
+ ]
+ `);
+ });
+ });
+
+ describe("migrateConfig - utility", () => {
+ it("migrates config with env var dependencies", async () => {
+ const config = getTestTurboConfig();
+ const pipeline = migrateConfig(config);
+ expect(pipeline).toMatchInlineSnapshot(`
+ Object {
+ "$schema": "./docs/public/schema.json",
+ "globalEnv": Array [
+ "GLOBAL_ENV_KEY",
+ ],
+ "pipeline": Object {
+ "build": Object {
+ "dependsOn": Array [
+ "^build",
+ ],
+ "env": Array [
+ "TASK_ENV_KEY",
+ "ANOTHER_ENV_KEY",
+ ],
+ "outputs": Array [
+ "dist/**/*",
+ ".next/**/*",
+ "!.next/cache/**",
+ ],
+ },
+ "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",
+ "pipeline": Object {
+ "build": Object {
+ "dependsOn": Array [
+ "^build",
+ ],
+ "outputs": Array [
+ "dist/**/*",
+ ".next/**/*",
+ "!.next/cache/**",
+ ],
+ },
+ "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",
+ "globalEnv": Array [
+ "GLOBAL_ENV_KEY",
+ ],
+ "pipeline": Object {
+ "build": Object {
+ "dependsOn": Array [
+ "^build",
+ ],
+ "env": Array [
+ "TASK_ENV_KEY",
+ "ANOTHER_ENV_KEY",
+ ],
+ "outputs": Array [
+ "dist/**/*",
+ ".next/**/*",
+ "!.next/cache/**",
+ ],
+ },
+ "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",
+ "globalEnv": Array [
+ "GLOBAL_ENV_KEY",
+ ],
+ "pipeline": Object {
+ "build": Object {
+ "dependsOn": Array [
+ "^build",
+ ],
+ "env": Array [
+ "TASK_ENV_KEY",
+ "ANOTHER_ENV_KEY",
+ ],
+ "outputs": Array [
+ "dist/**/*",
+ ".next/**/*",
+ "!.next/cache/**",
+ ],
+ },
+ "dev": Object {
+ "cache": false,
+ },
+ "lint": Object {
+ "outputs": Array [],
+ },
+ "test": Object {
+ "dependsOn": Array [
+ "^build",
+ ],
+ "env": Array [
+ "$MY_ENV",
+ "MY_ENV",
+ ],
+ "outputs": Array [
+ "coverage/**/*",
+ ],
+ },
+ },
+ }
+ `);
+ });
+ });
+
+ describe("transform", () => {
+ const { useFixture } = setupTestFixtures({
+ directory: __dirname,
+ test: "migrate-env-var-dependencies",
+ });
+
+ it("migrates turbo.json env var dependencies - basic", async () => {
+ // load the fixture for the test
+ const { root, read } = useFixture({
+ fixture: "env-dependencies",
+ });
+
+ // run the transformer
+ const result = transformer({
+ root,
+ options: { force: false, dry: false, print: false },
+ });
+
+ expect(JSON.parse(read("turbo.json") || "{}")).toStrictEqual({
+ $schema: "https://turbo.build/schema.json",
+ globalDependencies: [".env"],
+ globalEnv: ["NEXT_PUBLIC_API_KEY", "STRIPE_API_KEY"],
+ pipeline: {
+ build: {
+ dependsOn: ["^build"],
+ env: ["PROD_API_KEY"],
+ outputs: [".next/**", "!.next/cache/**"],
+ },
+ dev: {
+ cache: false,
+ },
+ lint: {
+ dependsOn: [],
+ env: ["IS_CI"],
+ outputs: [],
+ },
+ test: {
+ dependsOn: ["test"],
+ env: ["IS_CI"],
+ outputs: [],
+ },
+ },
+ });
+
+ expect(result.fatalError).toBeUndefined();
+ expect(result.changes).toMatchInlineSnapshot(`
+ Object {
+ "turbo.json": Object {
+ "action": "modified",
+ "additions": 4,
+ "deletions": 4,
+ },
+ }
+ `);
+ });
+
+ it("migrates turbo.json env var dependencies - workspace configs", async () => {
+ // load the fixture for the test
+ const { root, readJson } = useFixture({
+ fixture: "workspace-configs",
+ });
+
+ // run the transformer
+ const result = transformer({
+ root,
+ options: { force: false, dry: false, print: false },
+ });
+
+ expect(readJson("turbo.json") || "{}").toStrictEqual({
+ $schema: "https://turbo.build/schema.json",
+ globalDependencies: [".env"],
+ globalEnv: ["NEXT_PUBLIC_API_KEY", "STRIPE_API_KEY"],
+ pipeline: {
+ build: {
+ dependsOn: ["^build"],
+ env: ["PROD_API_KEY"],
+ outputs: [".next/**", "!.next/cache/**"],
+ },
+ dev: {
+ cache: false,
+ },
+ lint: {
+ dependsOn: [],
+ env: ["IS_TEST"],
+ outputs: [],
+ },
+ test: {
+ dependsOn: ["test"],
+ env: ["IS_CI"],
+ outputs: [],
+ },
+ },
+ });
+
+ expect(readJson("apps/web/turbo.json") || "{}").toStrictEqual({
+ $schema: "https://turbo.build/schema.json",
+ extends: ["//"],
+ pipeline: {
+ build: {
+ // old
+ dependsOn: ["build"],
+ // new
+ env: ["ENV_1", "ENV_2"],
+ },
+ },
+ });
+
+ expect(readJson("packages/ui/turbo.json") || "{}").toStrictEqual({
+ $schema: "https://turbo.build/schema.json",
+ extends: ["//"],
+ pipeline: {
+ build: {
+ dependsOn: [],
+ env: ["IS_SERVER"],
+ },
+ },
+ });
+
+ expect(result.fatalError).toBeUndefined();
+ expect(result.changes).toMatchInlineSnapshot(`
+ Object {
+ "apps/web/turbo.json": Object {
+ "action": "modified",
+ "additions": 1,
+ "deletions": 0,
+ },
+ "packages/ui/turbo.json": Object {
+ "action": "modified",
+ "additions": 1,
+ "deletions": 1,
+ },
+ "turbo.json": Object {
+ "action": "modified",
+ "additions": 4,
+ "deletions": 4,
+ },
+ }
+ `);
+ });
+
+ it("migrates turbo.json env var dependencies - repeat run", async () => {
+ // load the fixture for the test
+ const { root, read } = useFixture({
+ fixture: "env-dependencies",
+ });
+
+ // run the transformer
+ const result = transformer({
+ root,
+ options: { force: false, dry: false, print: false },
+ });
+
+ expect(JSON.parse(read("turbo.json") || "{}")).toStrictEqual({
+ $schema: "https://turbo.build/schema.json",
+ globalDependencies: [".env"],
+ globalEnv: ["NEXT_PUBLIC_API_KEY", "STRIPE_API_KEY"],
+ pipeline: {
+ build: {
+ dependsOn: ["^build"],
+ env: ["PROD_API_KEY"],
+ outputs: [".next/**", "!.next/cache/**"],
+ },
+ dev: {
+ cache: false,
+ },
+ lint: {
+ dependsOn: [],
+ env: ["IS_CI"],
+ outputs: [],
+ },
+ test: {
+ dependsOn: ["test"],
+ env: ["IS_CI"],
+ outputs: [],
+ },
+ },
+ });
+
+ expect(result.fatalError).toBeUndefined();
+ expect(result.changes).toMatchInlineSnapshot(`
+ Object {
+ "turbo.json": Object {
+ "action": "modified",
+ "additions": 4,
+ "deletions": 4,
+ },
+ }
+ `);
+
+ // run the transformer
+ const repeatResult = transformer({
+ root,
+ options: { force: false, dry: false, print: false },
+ });
+
+ expect(repeatResult.fatalError).toBeUndefined();
+ expect(repeatResult.changes).toMatchInlineSnapshot(`
+ Object {
+ "turbo.json": Object {
+ "action": "unchanged",
+ "additions": 0,
+ "deletions": 0,
+ },
+ }
+ `);
+ });
+
+ it("migrates turbo.json env var dependencies - dry", async () => {
+ // load the fixture for the test
+ const { root, read } = useFixture({
+ fixture: "env-dependencies",
+ });
+
+ const turboJson = JSON.parse(read("turbo.json") || "{}");
+
+ // run the transformer
+ const result = transformer({
+ root,
+ options: { force: false, dry: true, print: false },
+ });
+
+ // make sure it didn't change
+ expect(JSON.parse(read("turbo.json") || "{}")).toEqual(turboJson);
+
+ expect(result.fatalError).toBeUndefined();
+ expect(result.changes).toMatchInlineSnapshot(`
+ Object {
+ "turbo.json": Object {
+ "action": "skipped",
+ "additions": 4,
+ "deletions": 4,
+ },
+ }
+ `);
+ });
+
+ it("migrates turbo.json env var dependencies - print", async () => {
+ // load the fixture for the test
+ const { root, read } = useFixture({
+ fixture: "env-dependencies",
+ });
+
+ // run the transformer
+ const result = transformer({
+ root,
+ options: { force: false, dry: false, print: true },
+ });
+
+ expect(JSON.parse(read("turbo.json") || "{}")).toStrictEqual({
+ $schema: "https://turbo.build/schema.json",
+ globalEnv: ["NEXT_PUBLIC_API_KEY", "STRIPE_API_KEY"],
+ globalDependencies: [".env"],
+ pipeline: {
+ build: {
+ dependsOn: ["^build"],
+ env: ["PROD_API_KEY"],
+ outputs: [".next/**", "!.next/cache/**"],
+ },
+ dev: {
+ cache: false,
+ },
+ lint: {
+ dependsOn: [],
+ env: ["IS_CI"],
+ outputs: [],
+ },
+ test: {
+ dependsOn: ["test"],
+ env: ["IS_CI"],
+ outputs: [],
+ },
+ },
+ });
+
+ expect(result.fatalError).toBeUndefined();
+ expect(result.changes).toMatchInlineSnapshot(`
+ Object {
+ "turbo.json": Object {
+ "action": "modified",
+ "additions": 4,
+ "deletions": 4,
+ },
+ }
+ `);
+ });
+
+ it("migrates turbo.json env var dependencies - dry & print", async () => {
+ // load the fixture for the test
+ const { root, read } = useFixture({
+ fixture: "env-dependencies",
+ });
+
+ const turboJson = JSON.parse(read("turbo.json") || "{}");
+
+ // run the transformer
+ const result = transformer({
+ root,
+ options: { force: false, dry: true, print: true },
+ });
+
+ // make sure it didn't change
+ expect(JSON.parse(read("turbo.json") || "{}")).toEqual(turboJson);
+
+ expect(result.fatalError).toBeUndefined();
+ expect(result.changes).toMatchInlineSnapshot(`
+ Object {
+ "turbo.json": Object {
+ "action": "skipped",
+ "additions": 4,
+ "deletions": 4,
+ },
+ }
+ `);
+ });
+
+ it("does not change turbo.json if already migrated", async () => {
+ // load the fixture for the test
+ const { root, read } = useFixture({
+ fixture: "migrated-env-dependencies",
+ });
+
+ const turboJson = JSON.parse(read("turbo.json") || "{}");
+
+ // run the transformer
+ const result = transformer({
+ root,
+ options: { force: false, dry: false, print: false },
+ });
+
+ expect(JSON.parse(read("turbo.json") || "{}")).toEqual(turboJson);
+
+ expect(result.fatalError).toBeUndefined();
+ expect(result.changes).toMatchInlineSnapshot(`
+ Object {
+ "turbo.json": Object {
+ "action": "unchanged",
+ "additions": 0,
+ "deletions": 0,
+ },
+ }
+ `);
+ });
+
+ it("errors if no turbo.json can be found", async () => {
+ // load the fixture for the test
+ const { root, read } = useFixture({
+ fixture: "no-turbo-json",
+ });
+
+ expect(read("turbo.json")).toBeUndefined();
+
+ // run the transformer
+ const result = transformer({
+ root,
+ options: { force: false, dry: false, print: false },
+ });
+
+ expect(read("turbo.json")).toBeUndefined();
+ expect(result.fatalError).toBeDefined();
+ expect(result.fatalError?.message).toMatch(
+ /No turbo\.json found at .*?\. Is the path correct\?/
+ );
+ });
+
+ it("errors if package.json config exists and has not been migrated", async () => {
+ // load the fixture for the test
+ const { root } = useFixture({
+ fixture: "old-config",
+ });
+
+ // run the transformer
+ const result = transformer({
+ root,
+ options: { force: false, dry: false, print: false },
+ });
+
+ expect(result.fatalError).toBeDefined();
+ expect(result.fatalError?.message).toMatch(
+ 'turbo" key detected in package.json. Run `npx @turbo/codemod transform create-turbo-config` first'
+ );
+ });
+ });
+});