From 9029588590bea8b10451575c5142dcde77ecd1b5 Mon Sep 17 00:00:00 2001 From: 简律纯 Date: Fri, 3 Nov 2023 21:25:40 +0800 Subject: chore: delete useless files --- packages/create-turbo/.gitignore | 1 - packages/create-turbo/LICENSE | 373 ---------- packages/create-turbo/README.md | 13 - packages/create-turbo/__tests__/examples.test.ts | 134 ---- packages/create-turbo/__tests__/git.test.ts | 239 ------- packages/create-turbo/__tests__/index.test.ts | 90 --- .../create-turbo/__tests__/isFolderEmpty.test.ts | 41 -- packages/create-turbo/__tests__/isWritable.test.ts | 35 - packages/create-turbo/__tests__/test-utils.ts | 34 - packages/create-turbo/jest.config.js | 11 - packages/create-turbo/package.json | 65 -- packages/create-turbo/src/cli.ts | 65 -- .../src/commands/create/createProject.ts | 192 ------ packages/create-turbo/src/commands/create/index.ts | 243 ------- .../create-turbo/src/commands/create/prompts.ts | 124 ---- packages/create-turbo/src/commands/create/types.ts | 8 - packages/create-turbo/src/commands/index.ts | 1 - packages/create-turbo/src/logger.ts | 32 - packages/create-turbo/src/transforms/errors.ts | 17 - packages/create-turbo/src/transforms/git-ignore.ts | 30 - packages/create-turbo/src/transforms/index.ts | 13 - .../src/transforms/official-starter.ts | 73 -- .../create-turbo/src/transforms/package-manager.ts | 26 - packages/create-turbo/src/transforms/types.ts | 30 - packages/create-turbo/src/utils/examples.ts | 139 ---- packages/create-turbo/src/utils/git.ts | 90 --- .../create-turbo/src/utils/isDefaultExample.ts | 5 - packages/create-turbo/src/utils/isFolderEmpty.ts | 37 - packages/create-turbo/src/utils/isOnline.ts | 40 -- packages/create-turbo/src/utils/isWriteable.ts | 10 - packages/create-turbo/src/utils/notifyUpdate.ts | 22 - packages/create-turbo/tsconfig.json | 7 - packages/create-turbo/tsup.config.ts | 9 - packages/create-turbo/turbo.json | 12 - packages/eslint-config-turbo/LICENSE | 373 ---------- packages/eslint-config-turbo/README.md | 27 - packages/eslint-config-turbo/index.js | 3 - packages/eslint-config-turbo/package.json | 32 - packages/eslint-plugin-turbo/LICENSE | 373 ---------- packages/eslint-plugin-turbo/README.md | 53 -- .../__fixtures__/configs/single/turbo.json | 25 - .../workspace-configs/apps/docs/index.js | 6 - .../workspace-configs/apps/docs/package.json | 4 - .../workspace-configs/apps/docs/turbo.json | 9 - .../workspace-configs/apps/web/index.js | 6 - .../workspace-configs/apps/web/package.json | 4 - .../workspace-configs/apps/web/turbo.json | 9 - .../__fixtures__/workspace-configs/package.json | 14 - .../workspace-configs/packages/ui/index.js | 6 - .../workspace-configs/packages/ui/package.json | 4 - .../workspace-configs/packages/ui/turbo.json | 9 - .../__fixtures__/workspace-configs/turbo.json | 9 - .../__fixtures__/workspace/.eslintrc.js | 4 - .../__fixtures__/workspace/child/child.js | 2 - .../__fixtures__/workspace/package-lock.json | 58 -- .../__fixtures__/workspace/package.json | 5 - .../__fixtures__/workspace/peer.js | 1 - .../__fixtures__/workspace/turbo.json | 34 - packages/eslint-plugin-turbo/__tests__/cwd.test.ts | 88 --- .../__tests__/lib/no-undeclared-env-vars.test.ts | 433 ------------ .../docs/rules/no-undeclared-env-vars.md | 74 -- packages/eslint-plugin-turbo/jest.config.js | 12 - .../eslint-plugin-turbo/lib/configs/recommended.ts | 26 - packages/eslint-plugin-turbo/lib/constants.ts | 5 - packages/eslint-plugin-turbo/lib/index.ts | 17 - .../lib/rules/no-undeclared-env-vars.ts | 187 ----- .../lib/utils/getEnvVarDependencies.ts | 75 -- packages/eslint-plugin-turbo/package.json | 51 -- packages/eslint-plugin-turbo/tsconfig.json | 6 - packages/eslint-plugin-turbo/tsup.config.ts | 8 - packages/eslint-plugin-turbo/turbo.json | 9 - packages/node-module-trace/package.json | 10 - packages/tsconfig/README.md | 3 - packages/tsconfig/base.json | 20 - packages/tsconfig/library.json | 12 - packages/tsconfig/package.json | 5 - packages/turbo-codemod/LICENSE | 373 ---------- packages/turbo-codemod/README.md | 55 -- .../has-package-manager/package.json | 7 - .../no-package-manager/package.json | 6 - .../wrong-package-manager/package.json | 7 - .../create-turbo-config/both-configs/package.json | 28 - .../create-turbo-config/both-configs/turbo.json | 18 - .../no-package-json-config/package.json | 7 - .../no-package-json-file/a-random-file.txt | 1 - .../no-turbo-json-config/package.json | 24 - .../turbo-json-config/package.json | 7 - .../turbo-json-config/turbo.json | 18 - .../get-turbo-upgrade-command/no-deps/package.json | 4 - .../get-turbo-upgrade-command/no-package/README.md | 1 - .../no-turbo/package.json | 6 - .../normal-workspaces-dev-install/package.json | 12 - .../normal-workspaces/package.json | 12 - .../pnpm-workspaces-dev-install/package.json | 8 - .../pnpm-workspace.yaml | 3 - .../pnpm-workspaces/package.json | 8 - .../pnpm-workspaces/pnpm-workspace.yaml | 3 - .../single-package-dev-install/package.json | 8 - .../single-package/package.json | 8 - .../env-dependencies/turbo.json | 21 - .../migrated-env-dependencies/turbo.json | 25 - .../no-turbo-json/package.json | 7 - .../old-config/package.json | 20 - .../old-config/turbo.json | 12 - .../workspace-configs/apps/docs/index.js | 6 - .../workspace-configs/apps/docs/package.json | 4 - .../workspace-configs/apps/docs/turbo.json | 9 - .../workspace-configs/apps/web/index.js | 6 - .../workspace-configs/apps/web/package.json | 4 - .../workspace-configs/apps/web/turbo.json | 12 - .../workspace-configs/package.json | 14 - .../workspace-configs/packages/ui/index.js | 6 - .../workspace-configs/packages/ui/package.json | 4 - .../workspace-configs/packages/ui/turbo.json | 9 - .../workspace-configs/turbo.json | 21 - .../__fixtures__/migrate/no-repo/README.md | 1 - .../__fixtures__/migrate/old-turbo/package.json | 26 - .../invalid-outputs/package.json | 7 - .../set-default-outputs/invalid-outputs/turbo.json | 36 - .../set-default-outputs/no-outputs/package.json | 7 - .../set-default-outputs/no-outputs/turbo.json | 14 - .../set-default-outputs/no-pipeline/package.json | 7 - .../set-default-outputs/no-pipeline/turbo.json | 5 - .../set-default-outputs/no-turbo-json/package.json | 7 - .../set-default-outputs/old-config/package.json | 20 - .../set-default-outputs/old-config/turbo.json | 12 - .../set-default-outputs/old-outputs/package.json | 7 - .../set-default-outputs/old-outputs/turbo.json | 12 - .../workspace-configs/apps/docs/index.js | 6 - .../workspace-configs/apps/docs/package.json | 4 - .../workspace-configs/apps/docs/turbo.json | 7 - .../workspace-configs/apps/web/index.js | 6 - .../workspace-configs/apps/web/package.json | 4 - .../workspace-configs/apps/web/turbo.json | 10 - .../workspace-configs/package.json | 14 - .../workspace-configs/packages/ui/index.js | 6 - .../workspace-configs/packages/ui/package.json | 4 - .../workspace-configs/packages/ui/turbo.json | 7 - .../workspace-configs/turbo.json | 12 - .../__fixtures__/transform/basic/package.json | 8 - .../__tests__/add-package-manager.test.ts | 504 -------------- .../__tests__/create-turbo-config.test.ts | 416 ----------- .../__tests__/get-turbo-upgrade-command.test.ts | 576 ---------------- .../__tests__/migrate-env-var-dependencies.test.ts | 758 -------------------- packages/turbo-codemod/__tests__/migrate.test.ts | 761 --------------------- .../__tests__/set-default-outputs.test.ts | 391 ----------- packages/turbo-codemod/__tests__/transform.test.ts | 172 ----- packages/turbo-codemod/index.d.ts | 1 - packages/turbo-codemod/jest.config.js | 18 - packages/turbo-codemod/package.json | 67 -- packages/turbo-codemod/plopfile.js | 46 -- packages/turbo-codemod/src/cli.ts | 73 -- packages/turbo-codemod/src/commands/index.ts | 11 - .../turbo-codemod/src/commands/migrate/index.ts | 215 ------ .../commands/migrate/steps/getCurrentVersion.ts | 45 -- .../src/commands/migrate/steps/getLatestVersion.ts | 31 - .../migrate/steps/getTransformsForMigration.ts | 25 - .../migrate/steps/getTurboUpgradeCommand.ts | 182 ----- .../turbo-codemod/src/commands/migrate/types.ts | 9 - .../turbo-codemod/src/commands/migrate/utils.ts | 16 - .../turbo-codemod/src/commands/transform/index.ts | 101 --- .../turbo-codemod/src/commands/transform/types.ts | 7 - packages/turbo-codemod/src/runner/FileTransform.ts | 94 --- packages/turbo-codemod/src/runner/Runner.ts | 132 ---- packages/turbo-codemod/src/runner/index.ts | 3 - packages/turbo-codemod/src/runner/types.ts | 40 -- packages/turbo-codemod/src/transforms/README.md | 36 - .../src/transforms/add-package-manager.ts | 75 -- .../src/transforms/create-turbo-config.ts | 70 -- .../src/transforms/migrate-env-var-dependencies.ts | 181 ----- .../src/transforms/set-default-outputs.ts | 97 --- packages/turbo-codemod/src/types.ts | 24 - packages/turbo-codemod/src/utils/checkGitStatus.ts | 40 -- packages/turbo-codemod/src/utils/directoryInfo.ts | 10 - .../turbo-codemod/src/utils/getPackageManager.ts | 42 -- .../src/utils/getPackageManagerVersion.ts | 16 - .../src/utils/getTransformerHelpers.ts | 23 - .../turbo-codemod/src/utils/loadTransformers.ts | 27 - packages/turbo-codemod/src/utils/logger.ts | 47 -- packages/turbo-codemod/src/utils/looksLikeRepo.ts | 12 - packages/turbo-codemod/src/utils/notifyUpdate.ts | 35 - packages/turbo-codemod/templates/transformer.hbs | 45 -- .../turbo-codemod/templates/transformer.test.hbs | 25 - packages/turbo-codemod/tsconfig.json | 6 - packages/turbo-codemod/tsup.config.ts | 9 - packages/turbo-ignore/README.md | 99 --- .../turbo-ignore/__fixtures__/app/package.json | 11 - .../__fixtures__/invalid-app/package.json | 10 - packages/turbo-ignore/__fixtures__/no-app/index.js | 0 packages/turbo-ignore/__tests__/args.test.ts | 109 --- .../turbo-ignore/__tests__/checkCommit.test.ts | 229 ------- packages/turbo-ignore/__tests__/errors.test.ts | 46 -- .../turbo-ignore/__tests__/getComparison.test.ts | 61 -- packages/turbo-ignore/__tests__/getTask.test.ts | 27 - .../turbo-ignore/__tests__/getWorkspace.test.ts | 62 -- packages/turbo-ignore/__tests__/ignore.test.ts | 578 ---------------- packages/turbo-ignore/jest.config.js | 18 - packages/turbo-ignore/package.json | 40 -- packages/turbo-ignore/src/args.ts | 89 --- packages/turbo-ignore/src/checkCommit.ts | 104 --- packages/turbo-ignore/src/errors.ts | 43 -- packages/turbo-ignore/src/getComparison.ts | 39 -- packages/turbo-ignore/src/getTask.ts | 13 - packages/turbo-ignore/src/getWorkspace.ts | 37 - packages/turbo-ignore/src/ignore.ts | 125 ---- packages/turbo-ignore/src/index.ts | 6 - packages/turbo-ignore/src/logger.ts | 16 - packages/turbo-ignore/src/types.ts | 23 - packages/turbo-ignore/tsconfig.json | 6 - packages/turbo-ignore/tsup.config.ts | 9 - packages/turbo-test-utils/README.md | 3 - packages/turbo-test-utils/package.json | 40 -- packages/turbo-test-utils/src/index.ts | 9 - packages/turbo-test-utils/src/mockEnv.ts | 12 - packages/turbo-test-utils/src/spyConsole.ts | 25 - packages/turbo-test-utils/src/spyExit.ts | 21 - packages/turbo-test-utils/src/useFixtures.ts | 89 --- packages/turbo-test-utils/src/validateLogs.ts | 27 - packages/turbo-test-utils/tsconfig.json | 6 - packages/turbo-tracing-next-plugin/README.md | 39 -- packages/turbo-tracing-next-plugin/package.json | 25 - packages/turbo-tracing-next-plugin/src/index.ts | 27 - .../test/with-mongodb-mongoose/.env.local.example | 1 - .../test/with-mongodb-mongoose/.gitignore | 34 - .../test/with-mongodb-mongoose/README.md | 5 - .../test/with-mongodb-mongoose/components/Form.js | 202 ------ .../test/with-mongodb-mongoose/css/form.css | 39 -- .../test/with-mongodb-mongoose/css/style.css | 184 ----- .../test/with-mongodb-mongoose/lib/dbConnect.js | 40 -- .../test/with-mongodb-mongoose/models/Pet.js | 59 -- .../test/with-mongodb-mongoose/next.config.js | 12 - .../test/with-mongodb-mongoose/package.json | 20 - .../test/with-mongodb-mongoose/pages/[id]/edit.js | 33 - .../test/with-mongodb-mongoose/pages/[id]/index.js | 75 -- .../test/with-mongodb-mongoose/pages/_app.js | 36 - .../with-mongodb-mongoose/pages/api/pets/[id].js | 56 -- .../with-mongodb-mongoose/pages/api/pets/index.js | 32 - .../test/with-mongodb-mongoose/pages/index.js | 65 -- .../test/with-mongodb-mongoose/pages/new.js | 19 - .../test/with-mongodb-mongoose/public/favicon.ico | Bin 15086 -> 0 bytes .../test/with-mongodb-mongoose/public/zeit.svg | 10 - packages/turbo-tracing-next-plugin/tsconfig.json | 14 - packages/turbo-types/package.json | 19 - packages/turbo-types/src/index.ts | 1 - packages/turbo-types/src/scripts/codegen.js | 22 - packages/turbo-types/src/types/config.ts | 231 ------- packages/turbo-types/tsconfig.json | 6 - packages/turbo-types/turbo.json | 8 - packages/turbo-utils/LICENSE | 373 ---------- packages/turbo-utils/README.md | 3 - .../common/single-package/child/child.js | 2 - .../common/single-package/package.json | 3 - .../__fixtures__/common/single-package/turbo.json | 34 - .../common/workspace-configs/apps/docs/index.js | 6 - .../workspace-configs/apps/docs/package.json | 4 - .../common/workspace-configs/apps/web/index.js | 6 - .../common/workspace-configs/apps/web/package.json | 4 - .../common/workspace-configs/apps/web/turbo.json | 9 - .../common/workspace-configs/package.json | 14 - .../common/workspace-configs/packages/ui/index.js | 6 - .../workspace-configs/packages/ui/package.json | 4 - .../workspace-configs/packages/ui/turbo.json | 9 - .../workspace-configs/packages/utils/index.js | 6 - .../workspace-configs/packages/utils/package.json | 4 - .../workspace-configs/packages/utils/turbo.json | 9 - .../common/workspace-configs/turbo.json | 9 - .../turbo-utils/__tests__/getTurboConfigs.test.ts | 112 --- .../turbo-utils/__tests__/getTurboRoot.test.ts | 33 - packages/turbo-utils/jest.config.js | 7 - packages/turbo-utils/package.json | 45 -- packages/turbo-utils/src/getTurboConfigs.ts | 106 --- packages/turbo-utils/src/getTurboRoot.ts | 49 -- packages/turbo-utils/src/index.ts | 8 - packages/turbo-utils/src/managers.ts | 53 -- packages/turbo-utils/src/searchUp.ts | 44 -- packages/turbo-utils/tsconfig.json | 6 - packages/turbo-utils/tsup.config.ts | 12 - packages/turbo-workspaces/LICENSE | 373 ---------- packages/turbo-workspaces/README.md | 49 -- .../turbo-workspaces/__fixtures__/invalid/index.js | 1 - .../npm/monorepo/apps/docs/package.json | 11 - .../npm/monorepo/apps/web/package.json | 11 - .../__fixtures__/npm/monorepo/package-lock.json | 385 ----------- .../__fixtures__/npm/monorepo/package.json | 14 - .../npm/monorepo/packages/tsconfig/package.json | 5 - .../npm/monorepo/packages/ui/package.json | 7 - .../npm/non-monorepo/package-lock.json | 12 - .../__fixtures__/npm/non-monorepo/package.json | 6 - .../pnpm/monorepo/apps/docs/package.json | 11 - .../pnpm/monorepo/apps/web/package.json | 11 - .../__fixtures__/pnpm/monorepo/package.json | 10 - .../pnpm/monorepo/packages/tsconfig/package.json | 5 - .../pnpm/monorepo/packages/ui/package.json | 7 - .../__fixtures__/pnpm/monorepo/pnpm-lock.yaml | 33 - .../__fixtures__/pnpm/monorepo/pnpm-workspace.yaml | 3 - .../__fixtures__/pnpm/non-monorepo/package.json | 8 - .../__fixtures__/pnpm/non-monorepo/pnpm-lock.yaml | 33 - .../yarn/monorepo/apps/docs/package.json | 11 - .../yarn/monorepo/apps/web/package.json | 11 - .../__fixtures__/yarn/monorepo/package.json | 14 - .../yarn/monorepo/packages/tsconfig/package.json | 5 - .../yarn/monorepo/packages/ui/package.json | 7 - .../__fixtures__/yarn/monorepo/yarn.lock | 4 - .../__fixtures__/yarn/non-monorepo/package.json | 8 - .../__fixtures__/yarn/non-monorepo/yarn.lock | 4 - packages/turbo-workspaces/__tests__/index.test.ts | 85 --- .../turbo-workspaces/__tests__/managers.test.ts | 285 -------- packages/turbo-workspaces/__tests__/test-utils.ts | 153 ----- packages/turbo-workspaces/jest.config.js | 19 - packages/turbo-workspaces/package.json | 66 -- packages/turbo-workspaces/src/cli.ts | 53 -- .../turbo-workspaces/src/commands/convert/index.ts | 109 --- .../turbo-workspaces/src/commands/convert/types.ts | 6 - packages/turbo-workspaces/src/commands/index.ts | 8 - .../turbo-workspaces/src/commands/summary/index.ts | 98 --- .../turbo-workspaces/src/commands/summary/types.ts | 1 - packages/turbo-workspaces/src/convert.ts | 61 -- packages/turbo-workspaces/src/errors.ts | 31 - .../turbo-workspaces/src/getWorkspaceDetails.ts | 35 - packages/turbo-workspaces/src/index.ts | 58 -- packages/turbo-workspaces/src/install.ts | 125 ---- packages/turbo-workspaces/src/logger.ts | 109 --- packages/turbo-workspaces/src/managers/index.ts | 11 - packages/turbo-workspaces/src/managers/npm.ts | 223 ------ packages/turbo-workspaces/src/managers/pnpm.ts | 238 ------- packages/turbo-workspaces/src/managers/yarn.ts | 222 ------ packages/turbo-workspaces/src/types.ts | 127 ---- .../turbo-workspaces/src/updateDependencies.ts | 135 ---- packages/turbo-workspaces/src/utils.ts | 197 ------ packages/turbo-workspaces/tsconfig.json | 6 - packages/turbo-workspaces/tsup.config.ts | 10 - packages/turbo-workspaces/turbo.json | 9 - packages/turbo/.dev-mode | 3 - packages/turbo/README.md | 54 -- packages/turbo/bin/turbo | 14 - packages/turbo/bump-version.js | 21 - packages/turbo/install.js | 331 --------- packages/turbo/node-platform.js | 257 ------- packages/turbo/package.json | 29 - packages/webpack-nmt/package.json | 26 - packages/webpack-nmt/src/index.ts | 173 ----- packages/webpack-nmt/tsconfig.json | 9 - 342 files changed, 19721 deletions(-) delete mode 100644 packages/create-turbo/.gitignore delete mode 100644 packages/create-turbo/LICENSE delete mode 100644 packages/create-turbo/README.md delete mode 100644 packages/create-turbo/__tests__/examples.test.ts delete mode 100644 packages/create-turbo/__tests__/git.test.ts delete mode 100644 packages/create-turbo/__tests__/index.test.ts delete mode 100644 packages/create-turbo/__tests__/isFolderEmpty.test.ts delete mode 100644 packages/create-turbo/__tests__/isWritable.test.ts delete mode 100644 packages/create-turbo/__tests__/test-utils.ts delete mode 100644 packages/create-turbo/jest.config.js delete mode 100644 packages/create-turbo/package.json delete mode 100644 packages/create-turbo/src/cli.ts delete mode 100644 packages/create-turbo/src/commands/create/createProject.ts delete mode 100644 packages/create-turbo/src/commands/create/index.ts delete mode 100644 packages/create-turbo/src/commands/create/prompts.ts delete mode 100644 packages/create-turbo/src/commands/create/types.ts delete mode 100644 packages/create-turbo/src/commands/index.ts delete mode 100644 packages/create-turbo/src/logger.ts delete mode 100644 packages/create-turbo/src/transforms/errors.ts delete mode 100644 packages/create-turbo/src/transforms/git-ignore.ts delete mode 100644 packages/create-turbo/src/transforms/index.ts delete mode 100644 packages/create-turbo/src/transforms/official-starter.ts delete mode 100644 packages/create-turbo/src/transforms/package-manager.ts delete mode 100644 packages/create-turbo/src/transforms/types.ts delete mode 100644 packages/create-turbo/src/utils/examples.ts delete mode 100644 packages/create-turbo/src/utils/git.ts delete mode 100644 packages/create-turbo/src/utils/isDefaultExample.ts delete mode 100644 packages/create-turbo/src/utils/isFolderEmpty.ts delete mode 100644 packages/create-turbo/src/utils/isOnline.ts delete mode 100644 packages/create-turbo/src/utils/isWriteable.ts delete mode 100644 packages/create-turbo/src/utils/notifyUpdate.ts delete mode 100644 packages/create-turbo/tsconfig.json delete mode 100644 packages/create-turbo/tsup.config.ts delete mode 100644 packages/create-turbo/turbo.json delete mode 100644 packages/eslint-config-turbo/LICENSE delete mode 100644 packages/eslint-config-turbo/README.md delete mode 100644 packages/eslint-config-turbo/index.js delete mode 100644 packages/eslint-config-turbo/package.json delete mode 100644 packages/eslint-plugin-turbo/LICENSE delete mode 100644 packages/eslint-plugin-turbo/README.md delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/configs/single/turbo.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/index.js delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/package.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/turbo.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/index.js delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/package.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/turbo.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/package.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/index.js delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/package.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/turbo.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace-configs/turbo.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace/.eslintrc.js delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace/child/child.js delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace/package-lock.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace/package.json delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace/peer.js delete mode 100644 packages/eslint-plugin-turbo/__fixtures__/workspace/turbo.json delete mode 100644 packages/eslint-plugin-turbo/__tests__/cwd.test.ts delete mode 100644 packages/eslint-plugin-turbo/__tests__/lib/no-undeclared-env-vars.test.ts delete mode 100644 packages/eslint-plugin-turbo/docs/rules/no-undeclared-env-vars.md delete mode 100644 packages/eslint-plugin-turbo/jest.config.js delete mode 100644 packages/eslint-plugin-turbo/lib/configs/recommended.ts delete mode 100644 packages/eslint-plugin-turbo/lib/constants.ts delete mode 100644 packages/eslint-plugin-turbo/lib/index.ts delete mode 100644 packages/eslint-plugin-turbo/lib/rules/no-undeclared-env-vars.ts delete mode 100644 packages/eslint-plugin-turbo/lib/utils/getEnvVarDependencies.ts delete mode 100644 packages/eslint-plugin-turbo/package.json delete mode 100644 packages/eslint-plugin-turbo/tsconfig.json delete mode 100644 packages/eslint-plugin-turbo/tsup.config.ts delete mode 100644 packages/eslint-plugin-turbo/turbo.json delete mode 100644 packages/node-module-trace/package.json delete mode 100644 packages/tsconfig/README.md delete mode 100644 packages/tsconfig/base.json delete mode 100644 packages/tsconfig/library.json delete mode 100644 packages/tsconfig/package.json delete mode 100644 packages/turbo-codemod/LICENSE delete mode 100644 packages/turbo-codemod/README.md delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/has-package-manager/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/no-package-manager/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/wrong-package-manager/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/both-configs/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/both-configs/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-package-json-config/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-package-json-file/a-random-file.txt delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-turbo-json-config/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/turbo-json-config/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/turbo-json-config/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-deps/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-package/README.md delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-turbo/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/normal-workspaces-dev-install/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/normal-workspaces/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces-dev-install/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces-dev-install/pnpm-workspace.yaml delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces/pnpm-workspace.yaml delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/single-package-dev-install/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/single-package/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/env-dependencies/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/migrated-env-dependencies/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/no-turbo-json/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/old-config/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/old-config/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/index.js delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/index.js delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/index.js delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate/no-repo/README.md delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/migrate/old-turbo/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/invalid-outputs/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/invalid-outputs/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-outputs/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-outputs/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-pipeline/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-pipeline/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-turbo-json/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-config/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-config/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-outputs/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-outputs/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/index.js delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/index.js delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/index.js delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/package.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/turbo.json delete mode 100644 packages/turbo-codemod/__tests__/__fixtures__/transform/basic/package.json delete mode 100644 packages/turbo-codemod/__tests__/add-package-manager.test.ts delete mode 100644 packages/turbo-codemod/__tests__/create-turbo-config.test.ts delete mode 100644 packages/turbo-codemod/__tests__/get-turbo-upgrade-command.test.ts delete mode 100644 packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts delete mode 100644 packages/turbo-codemod/__tests__/migrate.test.ts delete mode 100644 packages/turbo-codemod/__tests__/set-default-outputs.test.ts delete mode 100644 packages/turbo-codemod/__tests__/transform.test.ts delete mode 100644 packages/turbo-codemod/index.d.ts delete mode 100644 packages/turbo-codemod/jest.config.js delete mode 100644 packages/turbo-codemod/package.json delete mode 100644 packages/turbo-codemod/plopfile.js delete mode 100644 packages/turbo-codemod/src/cli.ts delete mode 100644 packages/turbo-codemod/src/commands/index.ts delete mode 100644 packages/turbo-codemod/src/commands/migrate/index.ts delete mode 100644 packages/turbo-codemod/src/commands/migrate/steps/getCurrentVersion.ts delete mode 100644 packages/turbo-codemod/src/commands/migrate/steps/getLatestVersion.ts delete mode 100644 packages/turbo-codemod/src/commands/migrate/steps/getTransformsForMigration.ts delete mode 100644 packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts delete mode 100644 packages/turbo-codemod/src/commands/migrate/types.ts delete mode 100644 packages/turbo-codemod/src/commands/migrate/utils.ts delete mode 100644 packages/turbo-codemod/src/commands/transform/index.ts delete mode 100644 packages/turbo-codemod/src/commands/transform/types.ts delete mode 100644 packages/turbo-codemod/src/runner/FileTransform.ts delete mode 100644 packages/turbo-codemod/src/runner/Runner.ts delete mode 100644 packages/turbo-codemod/src/runner/index.ts delete mode 100644 packages/turbo-codemod/src/runner/types.ts delete mode 100644 packages/turbo-codemod/src/transforms/README.md delete mode 100644 packages/turbo-codemod/src/transforms/add-package-manager.ts delete mode 100644 packages/turbo-codemod/src/transforms/create-turbo-config.ts delete mode 100644 packages/turbo-codemod/src/transforms/migrate-env-var-dependencies.ts delete mode 100644 packages/turbo-codemod/src/transforms/set-default-outputs.ts delete mode 100644 packages/turbo-codemod/src/types.ts delete mode 100644 packages/turbo-codemod/src/utils/checkGitStatus.ts delete mode 100644 packages/turbo-codemod/src/utils/directoryInfo.ts delete mode 100644 packages/turbo-codemod/src/utils/getPackageManager.ts delete mode 100644 packages/turbo-codemod/src/utils/getPackageManagerVersion.ts delete mode 100644 packages/turbo-codemod/src/utils/getTransformerHelpers.ts delete mode 100644 packages/turbo-codemod/src/utils/loadTransformers.ts delete mode 100644 packages/turbo-codemod/src/utils/logger.ts delete mode 100644 packages/turbo-codemod/src/utils/looksLikeRepo.ts delete mode 100644 packages/turbo-codemod/src/utils/notifyUpdate.ts delete mode 100644 packages/turbo-codemod/templates/transformer.hbs delete mode 100644 packages/turbo-codemod/templates/transformer.test.hbs delete mode 100644 packages/turbo-codemod/tsconfig.json delete mode 100644 packages/turbo-codemod/tsup.config.ts delete mode 100644 packages/turbo-ignore/README.md delete mode 100644 packages/turbo-ignore/__fixtures__/app/package.json delete mode 100644 packages/turbo-ignore/__fixtures__/invalid-app/package.json delete mode 100644 packages/turbo-ignore/__fixtures__/no-app/index.js delete mode 100644 packages/turbo-ignore/__tests__/args.test.ts delete mode 100644 packages/turbo-ignore/__tests__/checkCommit.test.ts delete mode 100644 packages/turbo-ignore/__tests__/errors.test.ts delete mode 100644 packages/turbo-ignore/__tests__/getComparison.test.ts delete mode 100644 packages/turbo-ignore/__tests__/getTask.test.ts delete mode 100644 packages/turbo-ignore/__tests__/getWorkspace.test.ts delete mode 100644 packages/turbo-ignore/__tests__/ignore.test.ts delete mode 100644 packages/turbo-ignore/jest.config.js delete mode 100644 packages/turbo-ignore/package.json delete mode 100644 packages/turbo-ignore/src/args.ts delete mode 100644 packages/turbo-ignore/src/checkCommit.ts delete mode 100644 packages/turbo-ignore/src/errors.ts delete mode 100644 packages/turbo-ignore/src/getComparison.ts delete mode 100644 packages/turbo-ignore/src/getTask.ts delete mode 100644 packages/turbo-ignore/src/getWorkspace.ts delete mode 100644 packages/turbo-ignore/src/ignore.ts delete mode 100644 packages/turbo-ignore/src/index.ts delete mode 100644 packages/turbo-ignore/src/logger.ts delete mode 100644 packages/turbo-ignore/src/types.ts delete mode 100644 packages/turbo-ignore/tsconfig.json delete mode 100644 packages/turbo-ignore/tsup.config.ts delete mode 100644 packages/turbo-test-utils/README.md delete mode 100644 packages/turbo-test-utils/package.json delete mode 100644 packages/turbo-test-utils/src/index.ts delete mode 100644 packages/turbo-test-utils/src/mockEnv.ts delete mode 100644 packages/turbo-test-utils/src/spyConsole.ts delete mode 100644 packages/turbo-test-utils/src/spyExit.ts delete mode 100644 packages/turbo-test-utils/src/useFixtures.ts delete mode 100644 packages/turbo-test-utils/src/validateLogs.ts delete mode 100644 packages/turbo-test-utils/tsconfig.json delete mode 100644 packages/turbo-tracing-next-plugin/README.md delete mode 100644 packages/turbo-tracing-next-plugin/package.json delete mode 100644 packages/turbo-tracing-next-plugin/src/index.ts delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.env.local.example delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.gitignore delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/README.md delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/components/Form.js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/css/form.css delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/css/style.css delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/lib/dbConnect.js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/models/Pet.js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/next.config.js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/package.json delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/pages/[id]/edit.js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/pages/[id]/index.js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/pages/_app.js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/pages/api/pets/[id].js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/pages/api/pets/index.js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/pages/index.js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/pages/new.js delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/public/favicon.ico delete mode 100644 packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/public/zeit.svg delete mode 100644 packages/turbo-tracing-next-plugin/tsconfig.json delete mode 100644 packages/turbo-types/package.json delete mode 100644 packages/turbo-types/src/index.ts delete mode 100644 packages/turbo-types/src/scripts/codegen.js delete mode 100644 packages/turbo-types/src/types/config.ts delete mode 100644 packages/turbo-types/tsconfig.json delete mode 100644 packages/turbo-types/turbo.json delete mode 100644 packages/turbo-utils/LICENSE delete mode 100644 packages/turbo-utils/README.md delete mode 100644 packages/turbo-utils/__fixtures__/common/single-package/child/child.js delete mode 100644 packages/turbo-utils/__fixtures__/common/single-package/package.json delete mode 100644 packages/turbo-utils/__fixtures__/common/single-package/turbo.json delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/apps/docs/index.js delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/apps/docs/package.json delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/apps/web/index.js delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/apps/web/package.json delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/apps/web/turbo.json delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/package.json delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/packages/ui/index.js delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/packages/ui/package.json delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/packages/ui/turbo.json delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/packages/utils/index.js delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/packages/utils/package.json delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/packages/utils/turbo.json delete mode 100644 packages/turbo-utils/__fixtures__/common/workspace-configs/turbo.json delete mode 100644 packages/turbo-utils/__tests__/getTurboConfigs.test.ts delete mode 100644 packages/turbo-utils/__tests__/getTurboRoot.test.ts delete mode 100644 packages/turbo-utils/jest.config.js delete mode 100644 packages/turbo-utils/package.json delete mode 100644 packages/turbo-utils/src/getTurboConfigs.ts delete mode 100644 packages/turbo-utils/src/getTurboRoot.ts delete mode 100644 packages/turbo-utils/src/index.ts delete mode 100644 packages/turbo-utils/src/managers.ts delete mode 100644 packages/turbo-utils/src/searchUp.ts delete mode 100644 packages/turbo-utils/tsconfig.json delete mode 100644 packages/turbo-utils/tsup.config.ts delete mode 100644 packages/turbo-workspaces/LICENSE delete mode 100644 packages/turbo-workspaces/README.md delete mode 100644 packages/turbo-workspaces/__fixtures__/invalid/index.js delete mode 100644 packages/turbo-workspaces/__fixtures__/npm/monorepo/apps/docs/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/npm/monorepo/apps/web/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/npm/monorepo/package-lock.json delete mode 100644 packages/turbo-workspaces/__fixtures__/npm/monorepo/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/npm/monorepo/packages/tsconfig/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/npm/monorepo/packages/ui/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/npm/non-monorepo/package-lock.json delete mode 100644 packages/turbo-workspaces/__fixtures__/npm/non-monorepo/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/pnpm/monorepo/apps/docs/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/pnpm/monorepo/apps/web/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/pnpm/monorepo/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/pnpm/monorepo/packages/tsconfig/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/pnpm/monorepo/packages/ui/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/pnpm/monorepo/pnpm-lock.yaml delete mode 100644 packages/turbo-workspaces/__fixtures__/pnpm/monorepo/pnpm-workspace.yaml delete mode 100644 packages/turbo-workspaces/__fixtures__/pnpm/non-monorepo/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/pnpm/non-monorepo/pnpm-lock.yaml delete mode 100644 packages/turbo-workspaces/__fixtures__/yarn/monorepo/apps/docs/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/yarn/monorepo/apps/web/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/yarn/monorepo/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/yarn/monorepo/packages/tsconfig/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/yarn/monorepo/packages/ui/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/yarn/monorepo/yarn.lock delete mode 100644 packages/turbo-workspaces/__fixtures__/yarn/non-monorepo/package.json delete mode 100644 packages/turbo-workspaces/__fixtures__/yarn/non-monorepo/yarn.lock delete mode 100644 packages/turbo-workspaces/__tests__/index.test.ts delete mode 100644 packages/turbo-workspaces/__tests__/managers.test.ts delete mode 100644 packages/turbo-workspaces/__tests__/test-utils.ts delete mode 100644 packages/turbo-workspaces/jest.config.js delete mode 100644 packages/turbo-workspaces/package.json delete mode 100644 packages/turbo-workspaces/src/cli.ts delete mode 100644 packages/turbo-workspaces/src/commands/convert/index.ts delete mode 100644 packages/turbo-workspaces/src/commands/convert/types.ts delete mode 100644 packages/turbo-workspaces/src/commands/index.ts delete mode 100644 packages/turbo-workspaces/src/commands/summary/index.ts delete mode 100644 packages/turbo-workspaces/src/commands/summary/types.ts delete mode 100644 packages/turbo-workspaces/src/convert.ts delete mode 100644 packages/turbo-workspaces/src/errors.ts delete mode 100644 packages/turbo-workspaces/src/getWorkspaceDetails.ts delete mode 100644 packages/turbo-workspaces/src/index.ts delete mode 100644 packages/turbo-workspaces/src/install.ts delete mode 100644 packages/turbo-workspaces/src/logger.ts delete mode 100644 packages/turbo-workspaces/src/managers/index.ts delete mode 100644 packages/turbo-workspaces/src/managers/npm.ts delete mode 100644 packages/turbo-workspaces/src/managers/pnpm.ts delete mode 100644 packages/turbo-workspaces/src/managers/yarn.ts delete mode 100644 packages/turbo-workspaces/src/types.ts delete mode 100644 packages/turbo-workspaces/src/updateDependencies.ts delete mode 100644 packages/turbo-workspaces/src/utils.ts delete mode 100644 packages/turbo-workspaces/tsconfig.json delete mode 100644 packages/turbo-workspaces/tsup.config.ts delete mode 100644 packages/turbo-workspaces/turbo.json delete mode 100644 packages/turbo/.dev-mode delete mode 100644 packages/turbo/README.md delete mode 100644 packages/turbo/bin/turbo delete mode 100644 packages/turbo/bump-version.js delete mode 100644 packages/turbo/install.js delete mode 100644 packages/turbo/node-platform.js delete mode 100644 packages/turbo/package.json delete mode 100644 packages/webpack-nmt/package.json delete mode 100644 packages/webpack-nmt/src/index.ts delete mode 100644 packages/webpack-nmt/tsconfig.json diff --git a/packages/create-turbo/.gitignore b/packages/create-turbo/.gitignore deleted file mode 100644 index 47f732d..0000000 --- a/packages/create-turbo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!templates/*/.npmrc diff --git a/packages/create-turbo/LICENSE b/packages/create-turbo/LICENSE deleted file mode 100644 index fa0086a..0000000 --- a/packages/create-turbo/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. \ No newline at end of file diff --git a/packages/create-turbo/README.md b/packages/create-turbo/README.md deleted file mode 100644 index 485485f..0000000 --- a/packages/create-turbo/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Welcome to Turborepo - -[Turborepo](https://turbo.build/repo) is a high-performance monorepo build-system for modern JavaScript and TypeScript codebases. - -To get started, open a new shell and run: - -```sh -npx create-turbo@latest -``` - -Then follow the prompts you see in your terminal. - -For more information about Turborepo, [visit turbo.build/repo](https://turbo.build/repo) and follow us on Twitter ([@turborepo](https://twitter.com/turborepo))! diff --git a/packages/create-turbo/__tests__/examples.test.ts b/packages/create-turbo/__tests__/examples.test.ts deleted file mode 100644 index 20d4464..0000000 --- a/packages/create-turbo/__tests__/examples.test.ts +++ /dev/null @@ -1,134 +0,0 @@ -import got from "got"; -import * as Got from "got"; -import { isUrlOk, getRepoInfo, hasRepo } from "../src/utils/examples"; - -jest.mock("got", () => ({ - __esModule: true, - ...jest.requireActual("got"), -})); - -describe("examples", () => { - describe("isUrlOk", () => { - it("returns true if url returns 200", async () => { - const mockGot = jest - .spyOn(got, "head") - .mockReturnValue({ statusCode: 200 } as any); - - const url = "https://github.com/vercel/turbo/"; - const result = await isUrlOk(url); - expect(result).toBe(true); - - expect(mockGot).toHaveBeenCalledWith(url); - mockGot.mockRestore(); - }); - - it("returns false if url returns status != 200", async () => { - const mockGot = jest - .spyOn(got, "head") - .mockReturnValue({ statusCode: 401 } as any); - - const url = "https://not-github.com/vercel/turbo/"; - const result = await isUrlOk(url); - expect(result).toBe(false); - - expect(mockGot).toHaveBeenCalledWith(url); - mockGot.mockRestore(); - }); - }); - - describe("getRepoInfo", () => { - test.each([ - { - repoUrl: "https://github.com/vercel/turbo/", - examplePath: undefined, - defaultBranch: "main", - expectBranchLookup: true, - expected: { - username: "vercel", - name: "turbo", - branch: "main", - filePath: "", - }, - }, - { - repoUrl: - "https://github.com/vercel/turbo/tree/canary/examples/kitchen-sink", - examplePath: undefined, - defaultBranch: "canary", - expectBranchLookup: false, - expected: { - username: "vercel", - name: "turbo", - branch: "canary", - filePath: "examples/kitchen-sink", - }, - }, - { - repoUrl: "https://github.com/vercel/turbo/tree/tek/test-branch/", - examplePath: "examples/basic", - defaultBranch: "canary", - expectBranchLookup: false, - expected: { - username: "vercel", - name: "turbo", - branch: "tek/test-branch", - filePath: "examples/basic", - }, - }, - ])( - "retrieves repo info for $repoUrl and $examplePath", - async ({ - repoUrl, - examplePath, - defaultBranch, - expectBranchLookup, - expected, - }) => { - const mockGot = jest.spyOn(Got, "default").mockReturnValue({ - body: JSON.stringify({ default_branch: defaultBranch }), - } as any); - - const url = new URL(repoUrl); - const result = await getRepoInfo(url, examplePath); - expect(result).toMatchObject(expected); - - if (result && expectBranchLookup) { - expect(mockGot).toHaveBeenCalledWith( - `https://api.github.com/repos/${result.username}/${result.name}` - ); - } - - mockGot.mockRestore(); - } - ); - }); - - describe("hasRepo", () => { - test.each([ - { - repoInfo: { - username: "vercel", - name: "turbo", - branch: "main", - filePath: "", - }, - expected: true, - expectedUrl: - "https://api.github.com/repos/vercel/turbo/contents/package.json?ref=main", - }, - ])( - "checks repo at $expectedUrl", - async ({ expected, repoInfo, expectedUrl }) => { - const mockGot = jest - .spyOn(got, "head") - .mockReturnValue({ statusCode: 200 } as any); - - const result = await hasRepo(repoInfo); - expect(result).toBe(expected); - - expect(mockGot).toHaveBeenCalledWith(expectedUrl); - mockGot.mockRestore(); - } - ); - }); -}); diff --git a/packages/create-turbo/__tests__/git.test.ts b/packages/create-turbo/__tests__/git.test.ts deleted file mode 100644 index 27ac118..0000000 --- a/packages/create-turbo/__tests__/git.test.ts +++ /dev/null @@ -1,239 +0,0 @@ -import path from "path"; -import { - DEFAULT_IGNORE, - GIT_REPO_COMMAND, - HG_REPO_COMMAND, - isInGitRepository, - isInMercurialRepository, - tryGitInit, -} from "../src/utils/git"; -import childProcess from "child_process"; -import { setupTestFixtures } from "@turbo/test-utils"; - -describe("git", () => { - // just to make sure this doesn't get lost - it("default .gitignore includes .turbo", async () => { - expect(DEFAULT_IGNORE).toContain(".turbo"); - }); - - describe("isInGitRepository", () => { - it("returns true when in a repo", async () => { - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockReturnValue("true"); - - const result = isInGitRepository(); - expect(result).toBe(true); - - expect(mockExecSync).toHaveBeenCalledWith(GIT_REPO_COMMAND, { - stdio: "ignore", - }); - mockExecSync.mockRestore(); - }); - - it("returns false when not in a repo", async () => { - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockImplementation(() => { - throw new Error( - "fatal: not a git repository (or any of the parent directories): .git" - ); - }); - - const result = isInGitRepository(); - expect(result).toBe(false); - - expect(mockExecSync).toHaveBeenCalledWith(GIT_REPO_COMMAND, { - stdio: "ignore", - }); - mockExecSync.mockRestore(); - }); - - it("returns false on error", async () => { - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockImplementation(() => { - throw new Error("unknown error"); - }); - - const result = isInGitRepository(); - expect(result).toBe(false); - - expect(mockExecSync).toHaveBeenCalledWith(GIT_REPO_COMMAND, { - stdio: "ignore", - }); - mockExecSync.mockRestore(); - }); - }); - - describe("isInMercurialRepository", () => { - it("returns true when in a repo", async () => { - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockReturnValue("true"); - - const result = isInMercurialRepository(); - expect(result).toBe(true); - - expect(mockExecSync).toHaveBeenCalledWith(HG_REPO_COMMAND, { - stdio: "ignore", - }); - mockExecSync.mockRestore(); - }); - - it("returns false when not in a repo", async () => { - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockImplementation(() => { - throw new Error("abort: no repository found (.hg not found)"); - }); - - const result = isInMercurialRepository(); - expect(result).toBe(false); - - expect(mockExecSync).toHaveBeenCalledWith(HG_REPO_COMMAND, { - stdio: "ignore", - }); - mockExecSync.mockRestore(); - }); - - it("returns false on error", async () => { - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockImplementation(() => { - throw new Error("unknown error"); - }); - - const result = isInMercurialRepository(); - expect(result).toBe(false); - - expect(mockExecSync).toHaveBeenCalledWith(HG_REPO_COMMAND, { - stdio: "ignore", - }); - mockExecSync.mockRestore(); - }); - }); - - describe("tryGitInit", () => { - const { useFixture } = setupTestFixtures({ - directory: path.join(__dirname, "../"), - }); - - it("inits a repo succesfully", async () => { - const { root } = useFixture({ fixture: `git` }); - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockReturnValueOnce("git version 2.38.1") - .mockImplementationOnce(() => { - throw new Error( - "fatal: not a git repository (or any of the parent directories): .git" - ); - }) - .mockImplementationOnce(() => { - throw new Error("abort: no repository found (.hg not found)"); - }) - .mockReturnValue("success"); - - const result = tryGitInit(root, "test commit"); - expect(result).toBe(true); - - const calls = [ - "git --version", - "git init", - "git checkout -b main", - "git add -A", - 'git commit -m "test commit"', - ]; - expect(mockExecSync).toHaveBeenCalledTimes(calls.length + 2); - calls.forEach((call) => { - expect(mockExecSync).toHaveBeenCalledWith(call, { - stdio: "ignore", - }); - }); - mockExecSync.mockRestore(); - }); - - it("skips init if already in a repo", async () => { - const { root } = useFixture({ fixture: `git` }); - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockReturnValueOnce("git version 2.38.1") - .mockReturnValueOnce("true") - .mockReturnValue("success"); - - const result = tryGitInit(root, "test commit"); - expect(result).toBe(false); - - const calls = ["git --version"]; - - // 1 call for git --version, 1 call for isInGitRepository - expect(mockExecSync).toHaveBeenCalledTimes(calls.length + 1); - calls.forEach((call) => { - expect(mockExecSync).toHaveBeenCalledWith(call, { - stdio: "ignore", - }); - }); - mockExecSync.mockRestore(); - }); - - it("returns false on unexpected error", async () => { - const { root } = useFixture({ fixture: `git` }); - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockImplementationOnce(() => { - throw new Error("fatal: unknown command git"); - }); - - const result = tryGitInit(root, "test commit"); - expect(result).toBe(false); - - const calls = ["git --version"]; - - expect(mockExecSync).toHaveBeenCalledTimes(calls.length); - calls.forEach((call) => { - expect(mockExecSync).toHaveBeenCalledWith(call, { - stdio: "ignore", - }); - }); - mockExecSync.mockRestore(); - }); - - it("cleans up from partial init on failure", async () => { - const { root } = useFixture({ fixture: `git` }); - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockReturnValueOnce("git version 2.38.1") - .mockImplementationOnce(() => { - throw new Error( - "fatal: not a git repository (or any of the parent directories): .git" - ); - }) - .mockImplementationOnce(() => { - throw new Error("abort: no repository found (.hg not found)"); - }) - .mockReturnValueOnce("success") - .mockReturnValueOnce("success") - .mockImplementationOnce(() => { - throw new Error("fatal: could not add files"); - }); - - const result = tryGitInit(root, "test commit"); - expect(result).toBe(false); - - const calls = [ - "git --version", - "git init", - "git checkout -b main", - "git add -A", - ]; - - expect(mockExecSync).toHaveBeenCalledTimes(calls.length + 2); - calls.forEach((call) => { - expect(mockExecSync).toHaveBeenCalledWith(call, { - stdio: "ignore", - }); - }); - mockExecSync.mockRestore(); - }); - }); -}); diff --git a/packages/create-turbo/__tests__/index.test.ts b/packages/create-turbo/__tests__/index.test.ts deleted file mode 100644 index 641b193..0000000 --- a/packages/create-turbo/__tests__/index.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -import path from "path"; -import chalk from "chalk"; -import childProcess from "child_process"; -import { setupTestFixtures, spyConsole } from "@turbo/test-utils"; -import { create } from "../src/commands/create"; -import type { CreateCommandArgument } from "../src/commands/create/types"; -import { turboGradient } from "../src/logger"; -import type { PackageManager } from "@turbo/workspaces"; - -// imports for mocks -import * as createProject from "../src/commands/create/createProject"; -import * as turboWorkspaces from "@turbo/workspaces"; -import { getWorkspaceDetailsMockReturnValue } from "./test-utils"; - -jest.mock("@turbo/workspaces", () => ({ - __esModule: true, - ...jest.requireActual("@turbo/workspaces"), -})); - -describe("create-turbo", () => { - const { useFixture } = setupTestFixtures({ - directory: path.join(__dirname, "../"), - }); - - const mockConsole = spyConsole(); - - test.each<{ packageManager: PackageManager }>([ - { packageManager: "yarn" }, - { packageManager: "npm" }, - { packageManager: "pnpm" }, - ])( - "outputs expected console messages when using $packageManager", - async ({ packageManager }) => { - const { root } = useFixture({ fixture: `create-turbo` }); - - const availableScripts = ["build", "test", "dev"]; - - const mockCreateProject = jest - .spyOn(createProject, "createProject") - .mockResolvedValue({ - cdPath: "", - hasPackageJson: true, - availableScripts, - }); - - const mockGetWorkspaceDetails = jest - .spyOn(turboWorkspaces, "getWorkspaceDetails") - .mockResolvedValue( - getWorkspaceDetailsMockReturnValue({ - root, - packageManager, - }) - ); - - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockImplementation(() => { - return "success"; - }); - - await create( - root as CreateCommandArgument, - packageManager as CreateCommandArgument, - { - skipInstall: true, - example: "default", - } - ); - - const expected = `${chalk.bold( - turboGradient(">>> Success!") - )} Created a new Turborepo at "${path.relative(process.cwd(), root)}".`; - - expect(mockConsole.log).toHaveBeenCalledWith(expected); - expect(mockConsole.log).toHaveBeenCalledWith( - "Inside that directory, you can run several commands:" - ); - - availableScripts.forEach((script) => { - expect(mockConsole.log).toHaveBeenCalledWith( - chalk.cyan(` ${packageManager} run ${script}`) - ); - }); - - mockCreateProject.mockRestore(); - mockGetWorkspaceDetails.mockRestore(); - mockExecSync.mockRestore(); - } - ); -}); diff --git a/packages/create-turbo/__tests__/isFolderEmpty.test.ts b/packages/create-turbo/__tests__/isFolderEmpty.test.ts deleted file mode 100644 index 66b2310..0000000 --- a/packages/create-turbo/__tests__/isFolderEmpty.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import fs from "fs-extra"; -import path from "path"; -import { isFolderEmpty } from "../src/utils/isFolderEmpty"; -import { setupTestFixtures } from "@turbo/test-utils"; - -describe("isFolderEmpty", () => { - const { useFixture } = setupTestFixtures({ - directory: path.join(__dirname, "../"), - }); - - it("correctly identifies an empty directory", async () => { - const { root } = useFixture({ fixture: `is-folder-empty` }); - const result = isFolderEmpty(root); - expect(result.isEmpty).toEqual(true); - expect(result.conflicts).toEqual([]); - }); - - it("correctly identifies a directory with non-conflicting files", async () => { - const { root } = useFixture({ fixture: `is-folder-empty` }); - fs.writeFileSync(path.join(root, "LICENSE"), "MIT"); - const result = isFolderEmpty(root); - expect(result.isEmpty).toEqual(true); - expect(result.conflicts).toEqual([]); - }); - - it("correctly identifies a directory non-conflicting files (intelliJ)", async () => { - const { root } = useFixture({ fixture: `is-folder-empty` }); - fs.writeFileSync(path.join(root, "intellij-idea-config.iml"), "{}"); - const result = isFolderEmpty(root); - expect(result.isEmpty).toEqual(true); - expect(result.conflicts).toEqual([]); - }); - - it("correctly identifies a directory conflicting files", async () => { - const { root } = useFixture({ fixture: `is-folder-empty` }); - fs.writeFileSync(path.join(root, "README.md"), "my cool project"); - const result = isFolderEmpty(root); - expect(result.isEmpty).toEqual(false); - expect(result.conflicts).toEqual(["README.md"]); - }); -}); diff --git a/packages/create-turbo/__tests__/isWritable.test.ts b/packages/create-turbo/__tests__/isWritable.test.ts deleted file mode 100644 index b06670b..0000000 --- a/packages/create-turbo/__tests__/isWritable.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import path from "path"; -import { isWriteable } from "../src/utils/isWriteable"; -import { setupTestFixtures } from "@turbo/test-utils"; -import fs from "fs-extra"; - -describe("isWriteable", () => { - const { useFixture } = setupTestFixtures({ - directory: path.join(__dirname, "../"), - }); - - it("correctly identifies a writeable directory", async () => { - const { root } = useFixture({ fixture: `is-writeable` }); - const result = await isWriteable(root); - expect(result).toEqual(true); - }); - - it("correctly identifies a non-writeable directory", async () => { - const { root } = useFixture({ fixture: `is-writeable` }); - const result = await isWriteable(path.join(root, "does-not-exist")); - expect(result).toEqual(false); - }); - - it("returns false on unexpected failure", async () => { - const { root } = useFixture({ fixture: `is-writeable` }); - const mockFsAccess = jest - .spyOn(fs, "access") - .mockRejectedValue(new Error("unknown error")); - - const result = await isWriteable(root); - expect(result).toEqual(false); - expect(mockFsAccess).toHaveBeenCalledWith(root, fs.constants.W_OK); - - mockFsAccess.mockRestore(); - }); -}); diff --git a/packages/create-turbo/__tests__/test-utils.ts b/packages/create-turbo/__tests__/test-utils.ts deleted file mode 100644 index fa6c204..0000000 --- a/packages/create-turbo/__tests__/test-utils.ts +++ /dev/null @@ -1,34 +0,0 @@ -import path from "path"; -import { PackageManager } from "@turbo/workspaces"; - -export function getWorkspaceDetailsMockReturnValue({ - root, - packageManager = "npm", -}: { - root: string; - packageManager: PackageManager; -}) { - return { - name: "mock-project", - packageManager, - paths: { - root, - packageJson: path.join(root, "package.json"), - lockfile: path.join(root, "yarn.lock"), - nodeModules: path.join(root, "node_modules"), - }, - workspaceData: { - globs: ["packages/*"], - workspaces: [ - { - name: "packages/mock-package", - paths: { - root: path.join(root, "packages/mock-package"), - packageJson: path.join(root, "packages/mock-package/package.json"), - nodeModules: path.join(root, "packages/mock-package/node_modules"), - }, - }, - ], - }, - }; -} diff --git a/packages/create-turbo/jest.config.js b/packages/create-turbo/jest.config.js deleted file mode 100644 index b738f4b..0000000 --- a/packages/create-turbo/jest.config.js +++ /dev/null @@ -1,11 +0,0 @@ -/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ -module.exports = { - preset: "ts-jest/presets/js-with-ts", - testEnvironment: "node", - testPathIgnorePatterns: ["/__fixtures__/", "/__tests__/test-utils.ts"], - coveragePathIgnorePatterns: ["/__fixtures__/", "/__tests__/test-utils.ts"], - transformIgnorePatterns: ["/node_modules/(?!(ansi-regex)/)"], - modulePathIgnorePatterns: ["/node_modules", "/dist"], - collectCoverage: true, - verbose: true, -}; diff --git a/packages/create-turbo/package.json b/packages/create-turbo/package.json deleted file mode 100644 index 9f723ba..0000000 --- a/packages/create-turbo/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "create-turbo", - "version": "1.9.4-canary.2", - "description": "Create a new Turborepo", - "homepage": "https://turbo.build/repo", - "license": "MPL-2.0", - "repository": { - "type": "git", - "url": "https://github.com/vercel/turbo", - "directory": "packages/create-turbo" - }, - "bugs": { - "url": "https://github.com/vercel/turbo/issues" - }, - "bin": { - "create-turbo": "dist/cli.js" - }, - "scripts": { - "build": "tsup", - "test": "jest", - "lint": "eslint src/**/*.ts", - "check-types": "tsc --noEmit" - }, - "dependencies": { - "async-retry": "^1.3.3", - "chalk": "2.4.2", - "commander": "^10.0.0", - "cross-spawn": "^7.0.3", - "execa": "5.1.1", - "fs-extra": "^10.1.0", - "got": "^11.8.5", - "gradient-string": "^2.0.0", - "inquirer": "^8.0.0", - "ora": "4.1.1", - "rimraf": "^3.0.2", - "semver": "^7.3.8", - "tar": "6.1.13", - "update-check": "^1.5.4" - }, - "devDependencies": { - "@turbo/workspaces": "workspace:*", - "@types/async-retry": "^1.4.5", - "@types/cross-spawn": "^6.0.2", - "@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/rimraf": "^3.0.2", - "@types/semver": "^7.3.9", - "@types/tar": "^6.1.4", - "eslint": "^7.23.0", - "jest": "^27.4.3", - "strip-ansi": "^6.0.1", - "ts-jest": "^27.1.1", - "@turbo/tsconfig": "workspace:*", - "tsup": "^5.10.3", - "@turbo/utils": "workspace:*", - "@turbo/test-utils": "workspace:*", - "typescript": "^4.5.5" - }, - "files": [ - "dist" - ] -} diff --git a/packages/create-turbo/src/cli.ts b/packages/create-turbo/src/cli.ts deleted file mode 100644 index 1290a13..0000000 --- a/packages/create-turbo/src/cli.ts +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env node - -import chalk from "chalk"; -import { Command } from "commander"; -import notifyUpdate from "./utils/notifyUpdate"; -import { turboGradient, error } from "./logger"; - -import { create } from "./commands"; -import cliPkg from "../package.json"; - -const createTurboCli = new Command(); - -// create -createTurboCli - .name(chalk.bold(turboGradient("create-turbo"))) - .description("Create a new Turborepo") - .usage(`${chalk.bold(" ")} [options]`) - .argument("[project-directory]") - .argument("[package-manager]") - .option( - "--skip-install", - "Do not run a package manager install after creating the project", - false - ) - .option( - "--skip-transforms", - "Do not run any code transformation after creating the project", - false - ) - .option( - "-e, --example [name]|[github-url]", - ` - An example to bootstrap the app with. You can use an example name - from the official Turborepo repo or a GitHub URL. The URL can use - any branch and/or subdirectory -` - ) - .option( - "-p, --example-path ", - ` - In a rare case, your GitHub URL might contain a branch name with - a slash (e.g. bug/fix-1) and the path to the example (e.g. foo/bar). - In this case, you must specify the path to the example separately: - --example-path foo/bar -` - ) - .version(cliPkg.version, "-v, --version", "output the current version") - .helpOption() - .action(create); - -createTurboCli - .parseAsync() - .then(notifyUpdate) - .catch(async (reason) => { - console.log(); - if (reason.command) { - error(`${chalk.bold(reason.command)} has failed.`); - } else { - error("Unexpected error. Please report it as a bug:"); - console.log(reason); - } - console.log(); - await notifyUpdate(); - process.exit(1); - }); diff --git a/packages/create-turbo/src/commands/create/createProject.ts b/packages/create-turbo/src/commands/create/createProject.ts deleted file mode 100644 index 0c1d2ac..0000000 --- a/packages/create-turbo/src/commands/create/createProject.ts +++ /dev/null @@ -1,192 +0,0 @@ -import retry from "async-retry"; -import chalk from "chalk"; -import fs from "fs-extra"; -import path from "path"; - -import { - downloadAndExtractExample, - downloadAndExtractRepo, - getRepoInfo, - existsInRepo, - hasRepo, - RepoInfo, -} from "../../utils/examples"; -import { isFolderEmpty } from "../../utils/isFolderEmpty"; -import { isWriteable } from "../../utils/isWriteable"; -import { turboLoader, error } from "../../logger"; -import { isDefaultExample } from "../../utils/isDefaultExample"; - -export class DownloadError extends Error {} - -export async function createProject({ - appPath, - example, - examplePath, -}: { - appPath: string; - example: string; - examplePath?: string; -}): Promise<{ - cdPath: string; - hasPackageJson: boolean; - availableScripts: Array; - repoInfo?: RepoInfo; -}> { - let repoInfo: RepoInfo | undefined; - let repoUrl: URL | undefined; - const defaultExample = isDefaultExample(example); - - try { - repoUrl = new URL(example); - } catch (err: any) { - if (err.code !== "ERR_INVALID_URL") { - error(err); - process.exit(1); - } - } - - if (repoUrl) { - if (repoUrl.origin !== "https://github.com") { - error( - `Invalid URL: ${chalk.red( - `"${example}"` - )}. Only GitHub repositories are supported. Please use a GitHub URL and try again.` - ); - process.exit(1); - } - - repoInfo = await getRepoInfo(repoUrl, examplePath); - - if (!repoInfo) { - error( - `Unable to fetch repository information from: ${chalk.red( - `"${example}"` - )}. Please fix the URL and try again.` - ); - process.exit(1); - } - - const found = await hasRepo(repoInfo); - - if (!found) { - error( - `Could not locate the repository for ${chalk.red( - `"${example}"` - )}. Please check that the repository exists and try again.` - ); - process.exit(1); - } - } else { - const found = await existsInRepo(example); - - if (!found) { - error( - `Could not locate an example named ${chalk.red( - `"${example}"` - )}. It could be due to the following:\n`, - `1. Your spelling of example ${chalk.red( - `"${example}"` - )} might be incorrect.\n`, - `2. You might not be connected to the internet or you are behind a proxy.` - ); - process.exit(1); - } - } - - const root = path.resolve(appPath); - - if (!(await isWriteable(path.dirname(root)))) { - error( - "The application path is not writable, please check folder permissions and try again." - ); - error("It is likely you do not have write permissions for this folder."); - process.exit(1); - } - - const appName = path.basename(root); - try { - await fs.mkdir(root, { recursive: true }); - } catch (err) { - error("Unable to create project directory"); - console.error(err); - process.exit(1); - } - const { isEmpty, conflicts } = isFolderEmpty(root); - if (!isEmpty) { - error( - `${chalk.dim(root)} has ${conflicts.length} conflicting ${ - conflicts.length === 1 ? "file" : "files" - } - please try a different location` - ); - process.exit(1); - } - - const originalDirectory = process.cwd(); - process.chdir(root); - - /** - * clone the example repository - */ - const loader = turboLoader("Downloading files..."); - try { - if (repoInfo) { - console.log( - `\nDownloading files from repo ${chalk.cyan( - example - )}. This might take a moment.` - ); - console.log(); - loader.start(); - await retry(() => downloadAndExtractRepo(root, repoInfo as RepoInfo), { - retries: 3, - }); - } else { - console.log( - `\nDownloading files${ - !defaultExample ? ` for example ${chalk.cyan(example)}` : "" - }. This might take a moment.` - ); - console.log(); - loader.start(); - await retry(() => downloadAndExtractExample(root, example), { - retries: 3, - }); - } - } catch (reason) { - function isErrorLike(err: unknown): err is { message: string } { - return ( - typeof err === "object" && - err !== null && - typeof (err as { message?: unknown }).message === "string" - ); - } - throw new DownloadError(isErrorLike(reason) ? reason.message : reason + ""); - } finally { - loader.stop(); - } - - const rootPackageJsonPath = path.join(root, "package.json"); - const hasPackageJson = fs.existsSync(rootPackageJsonPath); - const availableScripts = []; - - if (hasPackageJson) { - let packageJsonContent; - try { - packageJsonContent = fs.readJsonSync(rootPackageJsonPath); - } catch { - // ignore - } - - if (packageJsonContent) { - // read the scripts from the package.json - availableScripts.push(...Object.keys(packageJsonContent.scripts || {})); - } - } - - let cdPath: string = appPath; - if (path.join(originalDirectory, appName) === appPath) { - cdPath = appName; - } - - return { cdPath, hasPackageJson, availableScripts, repoInfo }; -} diff --git a/packages/create-turbo/src/commands/create/index.ts b/packages/create-turbo/src/commands/create/index.ts deleted file mode 100644 index 419328b..0000000 --- a/packages/create-turbo/src/commands/create/index.ts +++ /dev/null @@ -1,243 +0,0 @@ -import path from "path"; -import chalk from "chalk"; -import type { Project } from "@turbo/workspaces"; -import { - getWorkspaceDetails, - install, - getPackageManagerMeta, - ConvertError, -} from "@turbo/workspaces"; -import { getAvailablePackageManagers } from "@turbo/utils"; -import type { CreateCommandArgument, CreateCommandOptions } from "./types"; -import * as prompts from "./prompts"; -import { createProject } from "./createProject"; -import { tryGitCommit, tryGitInit } from "../../utils/git"; -import { isOnline } from "../../utils/isOnline"; -import { transforms } from "../../transforms"; -import { turboGradient, turboLoader, info, error, warn } from "../../logger"; -import { TransformError } from "../../transforms/errors"; - -function handleErrors(err: unknown) { - // handle errors from ../../transforms - if (err instanceof TransformError) { - error(chalk.bold(err.transform), chalk.red(err.message)); - if (err.fatal) { - process.exit(1); - } - // handle errors from @turbo/workspaces - } else if (err instanceof ConvertError && err.type !== "unknown") { - error(chalk.red(err.message)); - process.exit(1); - // handle unknown errors (no special handling, just re-throw to catch at root) - } else { - throw err; - } -} - -const SCRIPTS_TO_DISPLAY: Record = { - build: "Build", - dev: "Develop", - test: "Test", - lint: "Lint", -}; - -export async function create( - directory: CreateCommandArgument, - packageManager: CreateCommandArgument, - opts: CreateCommandOptions -) { - const { skipInstall, skipTransforms } = opts; - console.log(chalk.bold(turboGradient(`\n>>> TURBOREPO\n`))); - info(`Welcome to Turborepo! Let's get you set up with a new codebase.`); - console.log(); - - const [online, availablePackageManagers] = await Promise.all([ - isOnline(), - getAvailablePackageManagers(), - ]); - - if (!online) { - error( - "You appear to be offline. Please check your network connection and try again." - ); - process.exit(1); - } - const { root, projectName } = await prompts.directory({ directory }); - const relativeProjectDir = path.relative(process.cwd(), root); - const projectDirIsCurrentDir = relativeProjectDir === ""; - - // selected package manager can be undefined if the user chooses to skip transforms - const selectedPackageManagerDetails = await prompts.packageManager({ - packageManager, - skipTransforms, - }); - - if (packageManager && opts.skipTransforms) { - warn( - "--skip-transforms conflicts with . The package manager argument will be ignored." - ); - } - - const { example, examplePath } = opts; - const exampleName = example && example !== "default" ? example : "basic"; - const { hasPackageJson, availableScripts, repoInfo } = await createProject({ - appPath: root, - example: exampleName, - examplePath, - }); - - // create a new git repo after creating the project - tryGitInit(root, `feat(create-turbo): create ${exampleName}`); - - // read the project after creating it to get details about workspaces, package manager, etc. - let project: Project = {} as Project; - try { - project = await getWorkspaceDetails({ root }); - } catch (err) { - handleErrors(err); - } - - // run any required transforms - if (!skipTransforms) { - for (const transform of transforms) { - try { - const transformResult = await transform({ - example: { - repo: repoInfo, - name: exampleName, - }, - project, - prompts: { - projectName, - root, - packageManager: selectedPackageManagerDetails, - }, - opts, - }); - if (transformResult.result === "success") { - tryGitCommit( - `feat(create-turbo): apply ${transformResult.name} transform` - ); - } - } catch (err) { - handleErrors(err); - } - } - } - - // if the user opted out of transforms, the package manager will be the same as the source example - const projectPackageManager = - skipTransforms || !selectedPackageManagerDetails - ? { - name: project.packageManager, - version: availablePackageManagers[project.packageManager].version, - } - : selectedPackageManagerDetails; - - info("Created a new Turborepo with the following:"); - console.log(); - if (project.workspaceData.workspaces.length > 0) { - const workspacesForDisplay = project.workspaceData.workspaces - .map((w) => ({ - group: path.relative(root, w.paths.root).split(path.sep)?.[0] || "", - title: path.relative(root, w.paths.root), - description: w.description, - })) - .sort((a, b) => a.title.localeCompare(b.title)); - - let lastGroup: string | undefined; - workspacesForDisplay.forEach(({ group, title, description }, idx) => { - if (idx === 0 || group !== lastGroup) { - console.log(chalk.cyan(group)); - } - console.log( - ` - ${chalk.bold(title)}${description ? `: ${description}` : ""}` - ); - lastGroup = group; - }); - } else { - console.log(chalk.cyan("apps")); - console.log(` - ${chalk.bold(projectName)}`); - } - - // run install - console.log(); - if (hasPackageJson && !skipInstall) { - // in the case when the user opted out of transforms, but not install, we need to make sure the package manager is available - // before we attempt an install - if ( - opts.skipTransforms && - !availablePackageManagers[project.packageManager].available - ) { - warn( - `Unable to install dependencies - "${exampleName}" uses "${project.packageManager}" which could not be found.` - ); - warn( - `Try running without "--skip-transforms" to convert "${exampleName}" to a package manager that is available on your system.` - ); - console.log(); - } else if (projectPackageManager) { - console.log("Installing packages. This might take a couple of minutes."); - console.log(); - - const loader = turboLoader("Installing dependencies...").start(); - await install({ - project, - to: projectPackageManager, - options: { - interactive: false, - }, - }); - - tryGitCommit("feat(create-turbo): install dependencies"); - loader.stop(); - } - } - - if (projectDirIsCurrentDir) { - console.log( - `${chalk.bold( - turboGradient(">>> Success!") - )} Your new Turborepo is ready.` - ); - } else { - console.log( - `${chalk.bold( - turboGradient(">>> Success!") - )} Created a new Turborepo at "${relativeProjectDir}".` - ); - } - - // get the package manager details so we display the right commands to the user in log messages - const packageManagerMeta = getPackageManagerMeta(projectPackageManager); - if (packageManagerMeta && hasPackageJson) { - console.log( - `Inside ${ - projectDirIsCurrentDir ? "this" : "that" - } directory, you can run several commands:` - ); - console.log(); - availableScripts - .filter((script) => SCRIPTS_TO_DISPLAY[script]) - .forEach((script) => { - console.log( - chalk.cyan(` ${packageManagerMeta.command} run ${script}`) - ); - console.log(` ${SCRIPTS_TO_DISPLAY[script]} all apps and packages`); - console.log(); - }); - console.log(`Turborepo will cache locally by default. For an additional`); - console.log(`speed boost, enable Remote Caching with Vercel by`); - console.log(`entering the following command:`); - console.log(); - console.log(chalk.cyan(` ${packageManagerMeta.executable} turbo login`)); - console.log(); - console.log(`We suggest that you begin by typing:`); - console.log(); - if (!projectDirIsCurrentDir) { - console.log(` ${chalk.cyan("cd")} ${relativeProjectDir}`); - } - console.log(chalk.cyan(` ${packageManagerMeta.executable} turbo login`)); - console.log(); - } -} diff --git a/packages/create-turbo/src/commands/create/prompts.ts b/packages/create-turbo/src/commands/create/prompts.ts deleted file mode 100644 index a5ed7bf..0000000 --- a/packages/create-turbo/src/commands/create/prompts.ts +++ /dev/null @@ -1,124 +0,0 @@ -import path from "path"; -import fs from "fs-extra"; -import chalk from "chalk"; -import type { PackageManager } from "@turbo/workspaces"; -import type { CreateCommandArgument } from "./types"; -import { getAvailablePackageManagers } from "@turbo/utils"; -import { isFolderEmpty } from "../../utils/isFolderEmpty"; -import inquirer from "inquirer"; - -function validateDirectory(directory: string): { - valid: boolean; - root: string; - projectName: string; - error?: string; -} { - const root = path.resolve(directory); - const projectName = path.basename(root); - const exists = fs.existsSync(root); - - const stat = fs.lstatSync(root, { throwIfNoEntry: false }); - if (stat && !stat.isDirectory()) { - return { - valid: false, - root, - projectName, - error: `${chalk.dim( - projectName - )} is not a directory - please try a different location`, - }; - } - - if (exists) { - const { isEmpty, conflicts } = isFolderEmpty(root); - if (!isEmpty) { - return { - valid: false, - root, - projectName, - error: `${chalk.dim(projectName)} has ${conflicts.length} conflicting ${ - conflicts.length === 1 ? "file" : "files" - } - please try a different location`, - }; - } - } - - return { valid: true, root, projectName }; -} - -export async function directory({ - directory, -}: { - directory: CreateCommandArgument; -}) { - const projectDirectoryAnswer = await inquirer.prompt<{ - projectDirectory: string; - }>({ - type: "input", - name: "projectDirectory", - message: "Where would you like to create your turborepo?", - when: !directory, - default: "./my-turborepo", - validate: (directory: string) => { - const { valid, error } = validateDirectory(directory); - if (!valid && error) { - return error; - } - return true; - }, - filter: (directory: string) => directory.trim(), - }); - - const { projectDirectory: selectedProjectDirectory = directory as string } = - projectDirectoryAnswer; - - return validateDirectory(selectedProjectDirectory); -} - -export async function packageManager({ - packageManager, - skipTransforms, -}: { - packageManager: CreateCommandArgument; - skipTransforms?: boolean; -}) { - // if skip transforms is passed, we don't need to ask about the package manager (because that requires a transform) - if (skipTransforms) { - return undefined; - } - - const availablePackageManagers = await getAvailablePackageManagers(); - const packageManagerAnswer = await inquirer.prompt<{ - packageManagerInput?: PackageManager; - }>({ - name: "packageManagerInput", - type: "list", - message: "Which package manager do you want to use?", - when: - // prompt for package manager if it wasn't provided as an argument, or if it was - // provided, but isn't available (always allow npm) - !packageManager || - (packageManager as PackageManager) !== "npm" || - !Object.keys(availablePackageManagers).includes(packageManager), - choices: ["npm", "pnpm", "yarn"].map((p) => ({ - name: p, - value: p, - disabled: - // npm should always be available - p === "npm" || - availablePackageManagers?.[p as PackageManager]?.available - ? false - : `not installed`, - })), - }); - - const { - packageManagerInput: - selectedPackageManager = packageManager as PackageManager, - } = packageManagerAnswer; - - return { - name: selectedPackageManager, - version: availablePackageManagers[selectedPackageManager].version, - }; -} diff --git a/packages/create-turbo/src/commands/create/types.ts b/packages/create-turbo/src/commands/create/types.ts deleted file mode 100644 index 094c8d2..0000000 --- a/packages/create-turbo/src/commands/create/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -export type CreateCommandArgument = "string" | undefined; - -export interface CreateCommandOptions { - skipInstall?: boolean; - skipTransforms?: boolean; - example?: string; - examplePath?: string; -} diff --git a/packages/create-turbo/src/commands/index.ts b/packages/create-turbo/src/commands/index.ts deleted file mode 100644 index 7c5f96b..0000000 --- a/packages/create-turbo/src/commands/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { create } from "./create"; diff --git a/packages/create-turbo/src/logger.ts b/packages/create-turbo/src/logger.ts deleted file mode 100644 index ee6d584..0000000 --- a/packages/create-turbo/src/logger.ts +++ /dev/null @@ -1,32 +0,0 @@ -import chalk from "chalk"; -import ora from "ora"; -import gradient from "gradient-string"; - -const BLUE = "#0099F7"; -const RED = "#F11712"; -const YELLOW = "#FFFF00"; - -export const turboGradient = gradient(BLUE, RED); -export const turboBlue = chalk.hex(BLUE); -export const turboRed = chalk.hex(RED); -export const yellow = chalk.hex(YELLOW); - -export const turboLoader = (text: string) => - ora({ - text, - spinner: { - frames: [" ", turboBlue("> "), turboBlue(">> "), turboBlue(">>>")], - }, - }); - -export const info = (...args: any[]) => { - console.log(turboBlue.bold(">>>"), ...args); -}; - -export const error = (...args: any[]) => { - console.error(turboRed.bold(">>>"), ...args); -}; - -export const warn = (...args: any[]) => { - console.error(yellow.bold(">>>"), ...args); -}; diff --git a/packages/create-turbo/src/transforms/errors.ts b/packages/create-turbo/src/transforms/errors.ts deleted file mode 100644 index a5b8a7a..0000000 --- a/packages/create-turbo/src/transforms/errors.ts +++ /dev/null @@ -1,17 +0,0 @@ -export type TransformErrorOptions = { - transform?: string; - fatal?: boolean; -}; - -export class TransformError extends Error { - public transform: string; - public fatal: boolean; - - constructor(message: string, opts?: TransformErrorOptions) { - super(message); - this.name = "TransformError"; - this.transform = opts?.transform ?? "unknown"; - this.fatal = opts?.fatal ?? true; - Error.captureStackTrace(this, TransformError); - } -} diff --git a/packages/create-turbo/src/transforms/git-ignore.ts b/packages/create-turbo/src/transforms/git-ignore.ts deleted file mode 100644 index bb61ca7..0000000 --- a/packages/create-turbo/src/transforms/git-ignore.ts +++ /dev/null @@ -1,30 +0,0 @@ -import path from "path"; -import fs from "fs-extra"; -import { DEFAULT_IGNORE } from "../utils/git"; -import { TransformInput, TransformResult } from "./types"; -import { TransformError } from "./errors"; - -const meta = { - name: "git-ignore", -}; - -export async function transform(args: TransformInput): TransformResult { - const { prompts } = args; - const ignorePath = path.join(prompts.root, ".gitignore"); - try { - if (!fs.existsSync(ignorePath)) { - fs.writeFileSync(ignorePath, DEFAULT_IGNORE); - } else { - return { result: "not-applicable", ...meta }; - } - } catch (err) { - // existsSync cannot throw, so we don't need to narrow here and can - // assume this came from writeFileSync - throw new TransformError("Unable to write .gitignore", { - transform: meta.name, - fatal: false, - }); - } - - return { result: "success", ...meta }; -} diff --git a/packages/create-turbo/src/transforms/index.ts b/packages/create-turbo/src/transforms/index.ts deleted file mode 100644 index 1918ecc..0000000 --- a/packages/create-turbo/src/transforms/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { transform as packageManagerTransform } from "./package-manager"; -import { transform as officialStarter } from "./official-starter"; -import { transform as gitIgnoreTransform } from "./git-ignore"; -import type { TransformInput, TransformResult } from "./types"; - -/** - * In the future, we may want to support sourcing additional transforms from the templates themselves. - */ -export const transforms: Array<(args: TransformInput) => TransformResult> = [ - officialStarter, - gitIgnoreTransform, - packageManagerTransform, -]; diff --git a/packages/create-turbo/src/transforms/official-starter.ts b/packages/create-turbo/src/transforms/official-starter.ts deleted file mode 100644 index 1d71909..0000000 --- a/packages/create-turbo/src/transforms/official-starter.ts +++ /dev/null @@ -1,73 +0,0 @@ -import path from "path"; -import fs from "fs-extra"; -import semverPrerelease from "semver/functions/prerelease"; -import cliPkgJson from "../../package.json"; -import { isDefaultExample } from "../utils/isDefaultExample"; -import { TransformInput, TransformResult } from "./types"; -import { TransformError } from "./errors"; - -const meta = { - name: "official-starter", -}; - -// applied to "official starter" examples (those hosted within vercel/turbo/examples) -export async function transform(args: TransformInput): TransformResult { - const { prompts, example } = args; - - const defaultExample = isDefaultExample(example.name); - const isOfficialStarter = - !example.repo || - (example.repo?.username === "vercel" && example.repo?.name === "turbo"); - - if (!isOfficialStarter) { - return { result: "not-applicable", ...meta }; - } - - // paths - const rootPackageJsonPath = path.join(prompts.root, "package.json"); - const rootMetaJsonPath = path.join(prompts.root, "meta.json"); - const hasPackageJson = fs.existsSync(rootPackageJsonPath); - - // 1. remove meta file (used for generating the examples page on turbo.build) - try { - fs.rmSync(rootMetaJsonPath, { force: true }); - } catch (_err) {} - - if (hasPackageJson) { - let packageJsonContent; - try { - packageJsonContent = fs.readJsonSync(rootPackageJsonPath); - } catch { - throw new TransformError("Unable to read package.json", { - transform: meta.name, - fatal: false, - }); - } - - // if using the basic example, set the name to the project name (legacy behavior) - if (packageJsonContent) { - if (defaultExample) { - packageJsonContent.name = prompts.projectName; - } - - // if we're using a pre-release version of create-turbo, install turbo canary instead of latest - const shouldUsePreRelease = semverPrerelease(cliPkgJson.version) !== null; - if (shouldUsePreRelease && packageJsonContent?.devDependencies?.turbo) { - packageJsonContent.devDependencies.turbo = "canary"; - } - - try { - fs.writeJsonSync(rootPackageJsonPath, packageJsonContent, { - spaces: 2, - }); - } catch (err) { - throw new TransformError("Unable to write package.json", { - transform: meta.name, - fatal: false, - }); - } - } - } - - return { result: "success", ...meta }; -} diff --git a/packages/create-turbo/src/transforms/package-manager.ts b/packages/create-turbo/src/transforms/package-manager.ts deleted file mode 100644 index 9c0af24..0000000 --- a/packages/create-turbo/src/transforms/package-manager.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { convert } from "@turbo/workspaces"; -import { TransformInput, TransformResult } from "./types"; - -const meta = { - name: "package-manager", -}; - -export async function transform(args: TransformInput): TransformResult { - const { project, prompts } = args; - const { root, packageManager } = prompts; - - if (packageManager && project.packageManager !== packageManager.name) { - await convert({ - root, - to: packageManager.name, - options: { - // skip install after conversion- we will do it later - skipInstall: true, - }, - }); - } else { - return { result: "not-applicable", ...meta }; - } - - return { result: "success", ...meta }; -} diff --git a/packages/create-turbo/src/transforms/types.ts b/packages/create-turbo/src/transforms/types.ts deleted file mode 100644 index 6a8e141..0000000 --- a/packages/create-turbo/src/transforms/types.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { CreateCommandOptions } from "../commands/create/types"; -import { RepoInfo } from "../utils/examples"; -import type { Project, PackageManager } from "@turbo/workspaces"; - -export interface TransformInput { - example: { - repo: RepoInfo | undefined; - name: string; - }; - project: Project; - prompts: { - projectName: string; - root: string; - packageManager: - | { - name: PackageManager; - version: string | undefined; - } - | undefined; - }; - opts: CreateCommandOptions; -} - -export interface TransformResponse { - // errors should be thrown as instances of TransformError - result: "not-applicable" | "success"; - name: string; -} - -export type TransformResult = Promise; diff --git a/packages/create-turbo/src/utils/examples.ts b/packages/create-turbo/src/utils/examples.ts deleted file mode 100644 index b7c4812..0000000 --- a/packages/create-turbo/src/utils/examples.ts +++ /dev/null @@ -1,139 +0,0 @@ -import got from "got"; -import tar from "tar"; -import { Stream } from "stream"; -import { promisify } from "util"; -import { join } from "path"; -import { tmpdir } from "os"; -import { createWriteStream, promises as fs } from "fs"; - -const pipeline = promisify(Stream.pipeline); - -export type RepoInfo = { - username: string; - name: string; - branch: string; - filePath: string; -}; - -export async function isUrlOk(url: string): Promise { - try { - const res = await got.head(url); - return res.statusCode === 200; - } catch (err) { - return false; - } -} - -export async function getRepoInfo( - url: URL, - examplePath?: string -): Promise { - const [, username, name, tree, sourceBranch, ...file] = - url.pathname.split("/"); - const filePath = examplePath - ? examplePath.replace(/^\//, "") - : file.join("/"); - - if ( - // Support repos whose entire purpose is to be a Turborepo example, e.g. - // https://github.com/:username/:my-cool-turborepo-example-repo-name. - tree === undefined || - // Support GitHub URL that ends with a trailing slash, e.g. - // https://github.com/:username/:my-cool-turborepo-example-repo-name/ - // In this case "t" will be an empty string while the turbo part "_branch" will be undefined - (tree === "" && sourceBranch === undefined) - ) { - try { - const infoResponse = await got( - `https://api.github.com/repos/${username}/${name}` - ); - const info = JSON.parse(infoResponse.body); - return { username, name, branch: info["default_branch"], filePath }; - } catch (err) { - return; - } - } - - // If examplePath is available, the branch name takes the entire path - const branch = examplePath - ? `${sourceBranch}/${file.join("/")}`.replace( - new RegExp(`/${filePath}|/$`), - "" - ) - : sourceBranch; - - if (username && name && branch && tree === "tree") { - return { username, name, branch, filePath }; - } -} - -export function hasRepo({ - username, - name, - branch, - filePath, -}: RepoInfo): Promise { - const contentsUrl = `https://api.github.com/repos/${username}/${name}/contents`; - const packagePath = `${filePath ? `/${filePath}` : ""}/package.json`; - - return isUrlOk(contentsUrl + packagePath + `?ref=${branch}`); -} - -export function existsInRepo(nameOrUrl: string): Promise { - try { - const url = new URL(nameOrUrl); - return isUrlOk(url.href); - } catch { - return isUrlOk( - `https://api.github.com/repos/vercel/turbo/contents/examples/${encodeURIComponent( - nameOrUrl - )}` - ); - } -} - -async function downloadTar(url: string, name: string) { - const tempFile = join(tmpdir(), `${name}.temp-${Date.now()}`); - await pipeline(got.stream(url), createWriteStream(tempFile)); - return tempFile; -} - -export async function downloadAndExtractRepo( - root: string, - { username, name, branch, filePath }: RepoInfo -) { - const tempFile = await downloadTar( - `https://codeload.github.com/${username}/${name}/tar.gz/${branch}`, - `turbo-ct-example` - ); - - await tar.x({ - file: tempFile, - cwd: root, - strip: filePath ? filePath.split("/").length + 1 : 1, - filter: (p: string) => - p.startsWith( - `${name}-${branch.replace(/\//g, "-")}${ - filePath ? `/${filePath}/` : "/" - }` - ), - }); - - await fs.unlink(tempFile); -} - -export async function downloadAndExtractExample(root: string, name: string) { - const tempFile = await downloadTar( - `https://codeload.github.com/vercel/turbo/tar.gz/main`, - `turbo-ct-example` - ); - - await tar.x({ - file: tempFile, - cwd: root, - strip: 2 + name.split("/").length, - filter: (p: string) => p.includes(`turbo-main/examples/${name}/`), - }); - - await fs.unlink(tempFile); -} diff --git a/packages/create-turbo/src/utils/git.ts b/packages/create-turbo/src/utils/git.ts deleted file mode 100644 index 593e7ea..0000000 --- a/packages/create-turbo/src/utils/git.ts +++ /dev/null @@ -1,90 +0,0 @@ -import fs from "fs-extra"; -import { execSync } from "child_process"; -import path from "path"; -import rimraf from "rimraf"; - -export const DEFAULT_IGNORE = ` -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -node_modules -.pnp -.pnp.js - -# testing -coverage - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# turbo -.turbo - -# vercel -.vercel -`; - -export const GIT_REPO_COMMAND = "git rev-parse --is-inside-work-tree"; -export const HG_REPO_COMMAND = "hg --cwd . root"; - -export function isInGitRepository(): boolean { - try { - execSync(GIT_REPO_COMMAND, { stdio: "ignore" }); - return true; - } catch (_) {} - return false; -} - -export function isInMercurialRepository(): boolean { - try { - execSync(HG_REPO_COMMAND, { stdio: "ignore" }); - return true; - } catch (_) {} - return false; -} - -export function tryGitInit(root: string, message: string): boolean { - let didInit = false; - try { - execSync("git --version", { stdio: "ignore" }); - if (isInGitRepository() || isInMercurialRepository()) { - return false; - } - - execSync("git init", { stdio: "ignore" }); - didInit = true; - - execSync("git checkout -b main", { stdio: "ignore" }); - - execSync("git add -A", { stdio: "ignore" }); - execSync(`git commit -m "${message}"`, { - stdio: "ignore", - }); - return true; - } catch (err) { - if (didInit) { - try { - rimraf.sync(path.join(root, ".git")); - } catch (_) {} - } - return false; - } -} - -export function tryGitCommit(message: string): boolean { - try { - execSync("git add -A", { stdio: "ignore" }); - execSync(`git commit -m "${message}"`, { - stdio: "ignore", - }); - return true; - } catch (err) { - return false; - } -} diff --git a/packages/create-turbo/src/utils/isDefaultExample.ts b/packages/create-turbo/src/utils/isDefaultExample.ts deleted file mode 100644 index 9fb2ef2..0000000 --- a/packages/create-turbo/src/utils/isDefaultExample.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const DEFAULT_EXAMPLES = new Set(["basic", "default"]); - -export function isDefaultExample(example: string): boolean { - return DEFAULT_EXAMPLES.has(example); -} diff --git a/packages/create-turbo/src/utils/isFolderEmpty.ts b/packages/create-turbo/src/utils/isFolderEmpty.ts deleted file mode 100644 index 4de2d58..0000000 --- a/packages/create-turbo/src/utils/isFolderEmpty.ts +++ /dev/null @@ -1,37 +0,0 @@ -import fs from "fs-extra"; - -const VALID_FILES = [ - ".DS_Store", - ".git", - ".gitattributes", - ".gitignore", - ".gitlab-ci.yml", - ".hg", - ".hgcheck", - ".hgignore", - ".idea", - ".npmignore", - ".travis.yml", - "LICENSE", - "Thumbs.db", - "docs", - "mkdocs.yml", - "npm-debug.log", - "yarn-debug.log", - "yarn-error.log", - "yarnrc.yml", - ".yarn", -]; - -export function isFolderEmpty(root: string): { - isEmpty: boolean; - conflicts: Array; -} { - const conflicts = fs - .readdirSync(root) - .filter((file) => !VALID_FILES.includes(file)) - // Support IntelliJ IDEA-based editors - .filter((file) => !/\.iml$/.test(file)); - - return { isEmpty: conflicts.length === 0, conflicts }; -} diff --git a/packages/create-turbo/src/utils/isOnline.ts b/packages/create-turbo/src/utils/isOnline.ts deleted file mode 100644 index f02b2e6..0000000 --- a/packages/create-turbo/src/utils/isOnline.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { execSync } from "child_process"; -import dns from "dns"; -import url from "url"; - -function getProxy(): string | undefined { - if (process.env.https_proxy) { - return process.env.https_proxy; - } - - try { - const httpsProxy = execSync("npm config get https-proxy").toString().trim(); - return httpsProxy !== "null" ? httpsProxy : undefined; - } catch (e) { - return; - } -} - -export function isOnline(): Promise { - return new Promise((resolve) => { - dns.lookup("registry.yarnpkg.com", (registryErr) => { - if (!registryErr) { - return resolve(true); - } - - const proxy = getProxy(); - if (!proxy) { - return resolve(false); - } - - const { hostname } = url.parse(proxy); - if (!hostname) { - return resolve(false); - } - - dns.lookup(hostname, (proxyErr) => { - resolve(proxyErr == null); - }); - }); - }); -} diff --git a/packages/create-turbo/src/utils/isWriteable.ts b/packages/create-turbo/src/utils/isWriteable.ts deleted file mode 100644 index 132c42a..0000000 --- a/packages/create-turbo/src/utils/isWriteable.ts +++ /dev/null @@ -1,10 +0,0 @@ -import fs from "fs-extra"; - -export async function isWriteable(directory: string): Promise { - try { - await fs.access(directory, (fs.constants || fs).W_OK); - return true; - } catch (err) { - return false; - } -} diff --git a/packages/create-turbo/src/utils/notifyUpdate.ts b/packages/create-turbo/src/utils/notifyUpdate.ts deleted file mode 100644 index e1dadc0..0000000 --- a/packages/create-turbo/src/utils/notifyUpdate.ts +++ /dev/null @@ -1,22 +0,0 @@ -import chalk from "chalk"; -import checkForUpdate from "update-check"; - -import cliPkgJson from "../../package.json"; - -const update = checkForUpdate(cliPkgJson).catch(() => null); - -export default async function notifyUpdate(): Promise { - try { - const res = await update; - if (res?.latest) { - console.log(); - console.log( - chalk.yellow.bold("A new version of `create-turbo` is available!") - ); - console.log(); - } - process.exit(); - } catch (_e: any) { - // ignore error - } -} diff --git a/packages/create-turbo/tsconfig.json b/packages/create-turbo/tsconfig.json deleted file mode 100644 index abcb2c6..0000000 --- a/packages/create-turbo/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "@turbo/tsconfig/library.json", - "exclude": ["templates"], - "compilerOptions": { - "rootDir": "." - } -} diff --git a/packages/create-turbo/tsup.config.ts b/packages/create-turbo/tsup.config.ts deleted file mode 100644 index 18b0666..0000000 --- a/packages/create-turbo/tsup.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { defineConfig, Options } from "tsup"; - -export default defineConfig((options: Options) => ({ - entry: ["src/cli.ts"], - format: ["cjs"], - clean: true, - minify: true, - ...options, -})); diff --git a/packages/create-turbo/turbo.json b/packages/create-turbo/turbo.json deleted file mode 100644 index 6466b2d..0000000 --- a/packages/create-turbo/turbo.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "../../docs/public/schema.json", - "extends": ["//"], - "pipeline": { - "test": { - "dependsOn": ["build"] - }, - "build": { - "dependsOn": ["^build"] - } - } -} diff --git a/packages/eslint-config-turbo/LICENSE b/packages/eslint-config-turbo/LICENSE deleted file mode 100644 index fa0086a..0000000 --- a/packages/eslint-config-turbo/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. \ No newline at end of file diff --git a/packages/eslint-config-turbo/README.md b/packages/eslint-config-turbo/README.md deleted file mode 100644 index 834b887..0000000 --- a/packages/eslint-config-turbo/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# `eslint-config-turbo` - -Ease configuration for Turborepo - -## Installation - -1. You'll first need to install [ESLint](https://eslint.org/): - -```sh -npm install eslint --save-dev -``` - -2. Next, install `eslint-config-turbo`: - -```sh -npm install eslint-config-turbo --save-dev -``` - -## Usage - -Add `turbo` to the extends section of your eslint configuration file. You can omit the `eslint-config-` prefix: - -```json -{ - "extends": ["turbo"] -} -``` diff --git a/packages/eslint-config-turbo/index.js b/packages/eslint-config-turbo/index.js deleted file mode 100644 index 5d932b3..0000000 --- a/packages/eslint-config-turbo/index.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ["plugin:turbo/recommended"], -}; diff --git a/packages/eslint-config-turbo/package.json b/packages/eslint-config-turbo/package.json deleted file mode 100644 index 88717ca..0000000 --- a/packages/eslint-config-turbo/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "eslint-config-turbo", - "version": "1.9.4-canary.2", - "description": "ESLint config for Turborepo", - "repository": { - "type": "git", - "url": "https://github.com/vercel/turbo", - "directory": "packages/eslint-config-turbo" - }, - "bugs": { - "url": "https://github.com/vercel/turbo/issues" - }, - "keywords": [ - "turbo", - "eslint", - "turborepo", - "eslintconfig", - "eslint-config" - ], - "main": "index.js", - "author": "Vercel", - "dependencies": { - "eslint-plugin-turbo": "workspace:*" - }, - "peerDependencies": { - "eslint": ">6.6.0" - }, - "license": "MPL-2.0", - "devDependencies": { - "@types/eslint": "^8.4.5" - } -} diff --git a/packages/eslint-plugin-turbo/LICENSE b/packages/eslint-plugin-turbo/LICENSE deleted file mode 100644 index fa0086a..0000000 --- a/packages/eslint-plugin-turbo/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. \ No newline at end of file diff --git a/packages/eslint-plugin-turbo/README.md b/packages/eslint-plugin-turbo/README.md deleted file mode 100644 index 83627a1..0000000 --- a/packages/eslint-plugin-turbo/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# `eslint-plugin-turbo` - -Ease configuration for Turborepo - -## Installation - -1. You'll first need to install [ESLint](https://eslint.org/): - -```sh -npm install eslint --save-dev -``` - -2. Next, install `eslint-plugin-turbo`: - -```sh -npm install eslint-plugin-turbo --save-dev -``` - -## Usage - -Add `turbo` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix: - -```json -{ - "plugins": ["turbo"] -} -``` - -Then configure the rules you want to use under the rules section. - -```json -{ - "rules": { - "turbo/no-undeclared-env-vars": "error" - } -} -``` - -### Example - -```json -{ - "plugins": ["turbo"], - "rules": { - "turbo/no-undeclared-env-vars": [ - "error", - { - "allowList": ["^ENV_[A-Z]+$"] - } - ] - } -} -``` diff --git a/packages/eslint-plugin-turbo/__fixtures__/configs/single/turbo.json b/packages/eslint-plugin-turbo/__fixtures__/configs/single/turbo.json deleted file mode 100644 index 22b79b5..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/configs/single/turbo.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - // new style, global env dependency - "globalEnv": ["NEW_STYLE_GLOBAL_ENV_KEY", "$NEW_STYLE_GLOBAL_ENV_KEY"], - // old style, global env dependency (deprecated) - "globalDependencies": ["$GLOBAL_ENV_KEY"], - "pipeline": { - "test": { - "outputs": ["coverage/**"], - "dependsOn": ["^build"] - }, - "lint": { - "outputs": [] - }, - "dev": { - "cache": false - }, - "build": { - "outputs": ["dist/**", ".next/**", "!.next/.cache/**"], - // task level env var deps - "env": ["NEW_STYLE_ENV_KEY"], - // old task level env var deps (deprecated) - "dependsOn": ["^build", "$TASK_ENV_KEY", "$ANOTHER_ENV_KEY"] - } - } -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/index.js b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/index.js deleted file mode 100644 index 4de53f5..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function docs() { - if (process.env.ENV_1 === undefined) { - return "does not exist"; - } - return "exists"; -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/package.json b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/package.json deleted file mode 100644 index 82f9a44..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "docs", - "version": "1.0.0" -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/turbo.json b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/turbo.json deleted file mode 100644 index a3713ef..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/docs/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "pipeline": { - "build": { - "env": ["ENV_3"] - } - } -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/index.js b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/index.js deleted file mode 100644 index bfd3ab8..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function web() { - if (!process.env.ENV_2) { - return "bar"; - } - return "foo"; -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/package.json b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/package.json deleted file mode 100644 index d8a83ed..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "web", - "version": "1.0.0" -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/turbo.json b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/turbo.json deleted file mode 100644 index 0d1b80f..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/apps/web/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "pipeline": { - "build": { - "env": ["ENV_2"] - } - } -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/package.json b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/package.json deleted file mode 100644 index c6616a6..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "private": true, - "workspaces": [ - "apps/*", - "packages/*" - ], - "scripts": { - "build": "turbo run build" - }, - "devDependencies": { - "turbo": "latest" - }, - "packageManager": "yarn@1.22.19" -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/index.js b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/index.js deleted file mode 100644 index dee5e80..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function foo() { - if (!process.env.IS_SERVER) { - return "bar"; - } - return "foo"; -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/package.json b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/package.json deleted file mode 100644 index 7cb7cf1..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "ui", - "version": "1.0.0" -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/turbo.json b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/turbo.json deleted file mode 100644 index 8bff09e..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/packages/ui/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "pipeline": { - "build": { - "env": ["IS_SERVER"] - } - } -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/turbo.json b/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/turbo.json deleted file mode 100644 index cb4fb20..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace-configs/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "globalEnv": ["CI"], - "pipeline": { - "build": { - "env": ["ENV_1"] - } - } -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace/.eslintrc.js b/packages/eslint-plugin-turbo/__fixtures__/workspace/.eslintrc.js deleted file mode 100644 index 8dc66dc..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace/.eslintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - root: true, - extends: ["plugin:turbo/recommended"], -}; diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace/child/child.js b/packages/eslint-plugin-turbo/__fixtures__/workspace/child/child.js deleted file mode 100644 index 9e799a2..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace/child/child.js +++ /dev/null @@ -1,2 +0,0 @@ -process.env.NONEXISTENT; -process.env.CI; diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace/package-lock.json b/packages/eslint-plugin-turbo/__fixtures__/workspace/package-lock.json deleted file mode 100644 index 301f072..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace/package-lock.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "workspace", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "dependencies": { - "eslint-plugin-turbo": "../../" - } - }, - "../..": { - "version": "1.9.0", - "license": "MPL-2.0", - "devDependencies": { - "@turbo/test-utils": "workspace:*", - "@turbo/tsconfig": "workspace:*", - "@turbo/types": "workspace:*", - "@turbo/utils": "workspace:*", - "@types/eslint": "^8.4.5", - "@types/estree": "^1.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.12", - "jest": "^27.4.3", - "json5": "^2.2.1", - "ts-jest": "^27.1.1", - "tsup": "^6.2.0", - "typescript": "^4.7.4" - }, - "peerDependencies": { - "eslint": ">6.6.0" - } - }, - "node_modules/eslint-plugin-turbo": { - "resolved": "../..", - "link": true - } - }, - "dependencies": { - "eslint-plugin-turbo": { - "version": "file:../..", - "requires": { - "@turbo/test-utils": "workspace:*", - "@turbo/tsconfig": "workspace:*", - "@turbo/types": "workspace:*", - "@turbo/utils": "workspace:*", - "@types/eslint": "^8.4.5", - "@types/estree": "^1.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.12", - "jest": "^27.4.3", - "json5": "^2.2.1", - "ts-jest": "^27.1.1", - "tsup": "^6.2.0", - "typescript": "^4.7.4" - } - } - } -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace/package.json b/packages/eslint-plugin-turbo/__fixtures__/workspace/package.json deleted file mode 100644 index a1b2929..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "eslint-plugin-turbo": "../../" - } -} diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace/peer.js b/packages/eslint-plugin-turbo/__fixtures__/workspace/peer.js deleted file mode 100644 index 16c8bb0..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace/peer.js +++ /dev/null @@ -1 +0,0 @@ -process.env.CI; diff --git a/packages/eslint-plugin-turbo/__fixtures__/workspace/turbo.json b/packages/eslint-plugin-turbo/__fixtures__/workspace/turbo.json deleted file mode 100644 index 8079eb2..0000000 --- a/packages/eslint-plugin-turbo/__fixtures__/workspace/turbo.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "globalEnv": ["UNORDERED", "CI"], - "pipeline": { - "build": { - // A workspace's `build` task depends on that workspace's - // topological dependencies' and devDependencies' - // `build` tasks being completed first. The `^` symbol - // indicates an upstream dependency. - "dependsOn": ["^build"] - }, - "test": { - // A workspace's `test` task depends on that workspace's - // own `build` task being completed first. - "dependsOn": ["build"], - "outputs": [], - // A workspace's `test` task should only be rerun when - // either a `.tsx` or `.ts` file has changed. - "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"] - }, - "lint": { - // A workspace's `lint` task has no dependencies and - // can be run whenever. - "outputs": [] - }, - "deploy": { - // A workspace's `deploy` task depends on the `build`, - // `test`, and `lint` tasks of the same workspace - // being completed. - "dependsOn": ["build", "test", "lint"], - "outputs": [] - } - } -} diff --git a/packages/eslint-plugin-turbo/__tests__/cwd.test.ts b/packages/eslint-plugin-turbo/__tests__/cwd.test.ts deleted file mode 100644 index 15a2695..0000000 --- a/packages/eslint-plugin-turbo/__tests__/cwd.test.ts +++ /dev/null @@ -1,88 +0,0 @@ -import path from "path"; -import JSON5 from "json5"; -import { execSync } from "child_process"; -import { Schema } from "@turbo/types"; -import { setupTestFixtures } from "@turbo/test-utils"; - -describe("eslint settings check", () => { - const { useFixture } = setupTestFixtures({ - directory: path.join(__dirname, "../"), - }); - - it("does the right thing for peers", () => { - const { root: cwd } = useFixture({ fixture: "workspace" }); - execSync(`npm install`, { cwd }); - - const configString = execSync(`eslint --print-config peer.js`, { - cwd, - encoding: "utf8", - }); - const configJson = JSON5.parse(configString); - - expect(configJson.settings).toEqual({ - turbo: { envVars: ["CI", "UNORDERED"] }, - }); - }); - - it("does the right thing for child dirs", () => { - const { root } = useFixture({ fixture: "workspace" }); - execSync(`npm install`, { cwd: root }); - - const cwd = path.join(root, "child"); - const configString = execSync(`eslint --print-config child.js`, { - cwd, - encoding: "utf8", - }); - const configJson = JSON5.parse(configString); - - expect(configJson.settings).toEqual({ - turbo: { envVars: ["CI", "UNORDERED"] }, - }); - }); -}); - -describe("eslint cache is busted", () => { - const { useFixture } = setupTestFixtures({ - directory: path.join(__dirname, "../"), - }); - - it("catches a lint error after changing config", () => { - expect.assertions(2); - - // ensure that we populate the cache with a failure. - const { root, readJson, write } = useFixture({ fixture: "workspace" }); - execSync(`npm install`, { cwd: root }); - - const cwd = path.join(root, "child"); - try { - execSync(`eslint --format=json child.js`, { cwd, encoding: "utf8" }); - } catch (error: any) { - const outputJson = JSON5.parse(error.stdout); - expect(outputJson).toMatchObject([ - { - messages: [ - { - message: - "NONEXISTENT is not listed as a dependency in turbo.json", - }, - ], - }, - ]); - } - - // change the configuration - const turboJson = readJson("turbo.json"); - if (turboJson && "globalEnv" in turboJson) { - turboJson.globalEnv = ["CI", "NONEXISTENT"]; - write("turbo.json", JSON5.stringify(turboJson, null, 2)); - } - - // test that we invalidated the eslint cache - const output = execSync(`eslint --format=json child.js`, { - cwd, - encoding: "utf8", - }); - const outputJson = JSON5.parse(output); - expect(outputJson).toMatchObject([{ errorCount: 0 }]); - }); -}); diff --git a/packages/eslint-plugin-turbo/__tests__/lib/no-undeclared-env-vars.test.ts b/packages/eslint-plugin-turbo/__tests__/lib/no-undeclared-env-vars.test.ts deleted file mode 100644 index 5c753dd..0000000 --- a/packages/eslint-plugin-turbo/__tests__/lib/no-undeclared-env-vars.test.ts +++ /dev/null @@ -1,433 +0,0 @@ -import { RULES } from "../../lib/constants"; -import rule from "../../lib/rules/no-undeclared-env-vars"; -import { RuleTester } from "eslint"; -import path from "path"; - -const ruleTester = new RuleTester({ - parserOptions: { ecmaVersion: 2020 }, -}); - -ruleTester.run(RULES.noUndeclaredEnvVars, rule, { - valid: [ - { - code: ` - const { ENV_2 } = process.env; - `, - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/workspace-configs") }, - ], - filename: path.join( - __dirname, - "../../__fixtures__/workspace-configs/apps/web/index.js" - ), - }, - { - code: ` - const { ENV_1 } = process.env; - `, - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/workspace-configs") }, - ], - filename: path.join( - __dirname, - "../../__fixtures__/workspace-configs/apps/web/index.js" - ), - }, - { - code: ` - const { ENV_1 } = process.env; - `, - options: [{ cwd: "/some/random/path" }], - }, - { - code: ` - const { CI } = process.env; - `, - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/workspace-configs") }, - ], - filename: path.join( - __dirname, - "../../__fixtures__/workspace-configs/apps/web/index.js" - ), - }, - { - code: ` - const { TASK_ENV_KEY, ANOTHER_ENV_KEY } = process.env; - `, - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - { - code: ` - const { NEW_STYLE_ENV_KEY, TASK_ENV_KEY } = process.env; - `, - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - { - code: ` - const { NEW_STYLE_GLOBAL_ENV_KEY, TASK_ENV_KEY } = process.env; - `, - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - { - code: ` - const val = process.env["NEW_STYLE_GLOBAL_ENV_KEY"]; - `, - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - { - code: ` - const { TASK_ENV_KEY, ANOTHER_ENV_KEY } = process.env; - `, - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - { - code: ` - const x = process.env.GLOBAL_ENV_KEY; - const { TASK_ENV_KEY, GLOBAL_ENV_KEY: renamedX } = process.env; - `, - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - { - code: "var x = process.env.GLOBAL_ENV_KEY;", - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - { - code: "let x = process.env.TASK_ENV_KEY;", - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - { - code: "const x = process.env.ANOTHER_KEY_VALUE;", - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - allowList: ["^ANOTHER_KEY_[A-Z]+$"], - }, - ], - }, - { - code: ` - var x = process.env.ENV_VAR_ONE; - var y = process.env.ENV_VAR_TWO; - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - allowList: ["^ENV_VAR_[A-Z]+$"], - }, - ], - }, - { - code: ` - var x = process.env.ENV_VAR_ONE; - var y = process.env.ENV_VAR_TWO; - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - allowList: ["^ENV_VAR_O[A-Z]+$", "ENV_VAR_TWO"], - }, - ], - }, - { - code: ` - var globalOrTask = process.env.TASK_ENV_KEY || process.env.GLOBAL_ENV_KEY; - var oneOrTwo = process.env.ENV_VAR_ONE || process.env.ENV_VAR_TWO; - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - allowList: ["^ENV_VAR_[A-Z]+$"], - }, - ], - }, - { - code: ` - () => { return process.env.GLOBAL_ENV_KEY } - () => { return process.env.TASK_ENV_KEY } - () => { return process.env.ENV_VAR_ALLOWED } - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - allowList: ["^ENV_VAR_[A-Z]+$"], - }, - ], - }, - { - code: ` - var foo = process?.env.GLOBAL_ENV_KEY - var foo = process?.env.TASK_ENV_KEY - var foo = process?.env.ENV_VAR_ALLOWED - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - allowList: ["^ENV_VAR_[A-Z]+$"], - }, - ], - }, - { - code: ` - function test(arg1 = process.env.GLOBAL_ENV_KEY) {}; - function test(arg1 = process.env.TASK_ENV_KEY) {}; - function test(arg1 = process.env.ENV_VAR_ALLOWED) {}; - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - allowList: ["^ENV_VAR_[A-Z]+$"], - }, - ], - }, - { - code: ` - (arg1 = process.env.GLOBAL_ENV_KEY) => {} - (arg1 = process.env.TASK_ENV_KEY) => {} - (arg1 = process.env.ENV_VAR_ALLOWED) => {} - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - allowList: ["^ENV_VAR_[A-Z]+$"], - }, - ], - }, - { - code: "const getEnv = (key) => process.env[key];", - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - { - code: "function getEnv(key) { return process.env[key]; }", - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - { - code: "for (let x of ['ONE', 'TWO', 'THREE']) { console.log(process.env[x]); }", - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - }, - ], - - invalid: [ - { - code: ` - const { ENV_2 } = process.env; - `, - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/workspace-configs") }, - ], - filename: path.join( - __dirname, - "../../__fixtures__/workspace-configs/apps/docs/index.js" - ), - errors: [ - { - message: - "ENV_2 is not listed as a dependency in the root turbo.json or workspace (apps/docs) turbo.json", - }, - ], - }, - { - code: "let { X } = process.env;", - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - errors: [{ message: "X is not listed as a dependency in turbo.json" }], - }, - { - code: "const { X, Y, Z } = process.env;", - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - errors: [ - { message: "X is not listed as a dependency in turbo.json" }, - { message: "Y is not listed as a dependency in turbo.json" }, - { message: "Z is not listed as a dependency in turbo.json" }, - ], - }, - { - code: "const { X, Y: NewName, Z } = process.env;", - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - errors: [ - { message: "X is not listed as a dependency in turbo.json" }, - { message: "Y is not listed as a dependency in turbo.json" }, - { message: "Z is not listed as a dependency in turbo.json" }, - ], - }, - { - code: "var x = process.env.NOT_THERE;", - options: [ - { cwd: path.join(__dirname, "../../__fixtures__/configs/single") }, - ], - errors: [ - { - message: "NOT_THERE is not listed as a dependency in turbo.json", - }, - ], - }, - { - code: "var x = process.env.KEY;", - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - allowList: ["^ANOTHER_KEY_[A-Z]+$"], - }, - ], - errors: [{ message: "KEY is not listed as a dependency in turbo.json" }], - }, - { - code: ` - var globalOrTask = process.env.TASK_ENV_KEY_NEW || process.env.GLOBAL_ENV_KEY_NEW; - var oneOrTwo = process.env.ENV_VAR_ONE || process.env.ENV_VAR_TWO; - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - }, - ], - errors: [ - { - message: - "TASK_ENV_KEY_NEW is not listed as a dependency in turbo.json", - }, - { - message: - "GLOBAL_ENV_KEY_NEW is not listed as a dependency in turbo.json", - }, - { - message: "ENV_VAR_ONE is not listed as a dependency in turbo.json", - }, - { - message: "ENV_VAR_TWO is not listed as a dependency in turbo.json", - }, - ], - }, - { - code: ` - () => { return process.env.GLOBAL_ENV_KEY_NEW } - () => { return process.env.TASK_ENV_KEY_NEW } - () => { return process.env.ENV_VAR_NOT_ALLOWED } - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - }, - ], - errors: [ - { - message: - "GLOBAL_ENV_KEY_NEW is not listed as a dependency in turbo.json", - }, - { - message: - "TASK_ENV_KEY_NEW is not listed as a dependency in turbo.json", - }, - { - message: - "ENV_VAR_NOT_ALLOWED is not listed as a dependency in turbo.json", - }, - ], - }, - { - code: ` - var foo = process?.env.GLOBAL_ENV_KEY_NEW - var foo = process?.env.TASK_ENV_KEY_NEW - var foo = process?.env.ENV_VAR_NOT_ALLOWED - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - }, - ], - errors: [ - { - message: - "GLOBAL_ENV_KEY_NEW is not listed as a dependency in turbo.json", - }, - { - message: - "TASK_ENV_KEY_NEW is not listed as a dependency in turbo.json", - }, - { - message: - "ENV_VAR_NOT_ALLOWED is not listed as a dependency in turbo.json", - }, - ], - }, - { - code: ` - function test(arg1 = process.env.GLOBAL_ENV_KEY_NEW) {}; - function test(arg1 = process.env.TASK_ENV_KEY_NEW) {}; - function test(arg1 = process.env.ENV_VAR_NOT_ALLOWED) {}; - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - }, - ], - errors: [ - { - message: - "GLOBAL_ENV_KEY_NEW is not listed as a dependency in turbo.json", - }, - { - message: - "TASK_ENV_KEY_NEW is not listed as a dependency in turbo.json", - }, - { - message: - "ENV_VAR_NOT_ALLOWED is not listed as a dependency in turbo.json", - }, - ], - }, - { - code: ` - (arg1 = process.env.GLOBAL_ENV_KEY_NEW) => {} - (arg1 = process.env.TASK_ENV_KEY_NEW) => {} - (arg1 = process.env.ENV_VAR_NOT_ALLOWED) => {} - `, - options: [ - { - cwd: path.join(__dirname, "../../__fixtures__/configs/single"), - }, - ], - errors: [ - { - message: - "GLOBAL_ENV_KEY_NEW is not listed as a dependency in turbo.json", - }, - { - message: - "TASK_ENV_KEY_NEW is not listed as a dependency in turbo.json", - }, - { - message: - "ENV_VAR_NOT_ALLOWED is not listed as a dependency in turbo.json", - }, - ], - }, - ], -}); diff --git a/packages/eslint-plugin-turbo/docs/rules/no-undeclared-env-vars.md b/packages/eslint-plugin-turbo/docs/rules/no-undeclared-env-vars.md deleted file mode 100644 index 049d7af..0000000 --- a/packages/eslint-plugin-turbo/docs/rules/no-undeclared-env-vars.md +++ /dev/null @@ -1,74 +0,0 @@ -# Ensure all environment variables are correctly included in cache keys (`no-undeclared-env-vars`) - -Ensures that all detectable usage of environment variables are correctly included in cache keys. This ensures build outputs remain correctly cacheable across environments. - -## Rule Details - -This rule aims to prevent users from forgetting to include an environment variable in their `turbo.json` configuration. - -The following examples assume the following code: - -```js -const client = MyAPI({ token: process.env.MY_API_TOKEN }); -``` - -Examples of **incorrect** code for this rule: - -```json -{ - "pipeline": { - "build": { - "dependsOn": ["^build"], - "outputs": ["dist/**", ".next/**", "!.next/cache/**"] - }, - "lint": {}, - "dev": { - "cache": false - } - } -} -``` - -Examples of **correct** code for this rule: - -```json -{ - "globalEnv": ["MY_API_TOKEN"], - "pipeline": { - "build": { - "dependsOn": ["^build"], - "outputs": ["dist/**", ".next/**", "!.next/cache/**"] - }, - "lint": {}, - "dev": { - "cache": false - } - } -} -``` - -```json -{ - "pipeline": { - "build": { - "dependsOn": ["^build"], - "env": ["MY_API_TOKEN"], - "outputs": ["dist/**", ".next/**", "!.next/cache/**"] - }, - "lint": {}, - "dev": { - "cache": false - } - } -} -``` - -## Options - -| Option | Required | Default | Details | Example | -| ----------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| `allowList` | No | [] | An array of strings (or regular expressions) to exclude. NOTE: an env variable should only be excluded if it has no effect on build outputs | `["MY_API_TOKEN", "^MY_ENV_PREFIX_[A-Z]+$"]` | - -## Further Reading - -- [Altering Caching Based on Environment Variables](https://turbo.build/repo/docs/core-concepts/caching#altering-caching-based-on-environment-variables) diff --git a/packages/eslint-plugin-turbo/jest.config.js b/packages/eslint-plugin-turbo/jest.config.js deleted file mode 100644 index 102773e..0000000 --- a/packages/eslint-plugin-turbo/jest.config.js +++ /dev/null @@ -1,12 +0,0 @@ -/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ -module.exports = { - roots: [""], - transform: { - "^.+\\.tsx?$": "ts-jest", - }, - testPathIgnorePatterns: ["/__fixtures__/"], - coveragePathIgnorePatterns: ["/__fixtures__/"], - moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], - modulePathIgnorePatterns: ["/node_modules", "/dist"], - preset: "ts-jest", -}; diff --git a/packages/eslint-plugin-turbo/lib/configs/recommended.ts b/packages/eslint-plugin-turbo/lib/configs/recommended.ts deleted file mode 100644 index e247503..0000000 --- a/packages/eslint-plugin-turbo/lib/configs/recommended.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { RULES } from "../constants"; -import getEnvVarDependencies from "../utils/getEnvVarDependencies"; - -// Add the environment variables into the ESLint incremental cache key. -const envVars = getEnvVarDependencies({ - cwd: process.cwd(), -}); -const settings = { - turbo: { - envVars: envVars - ? Object.values(envVars) - .flatMap((s) => Array.from(s)) - .sort() - : [], - }, -}; - -const config = { - settings, - plugins: ["turbo"], - rules: { - [`turbo/${RULES.noUndeclaredEnvVars}`]: "error", - }, -}; - -export default config; diff --git a/packages/eslint-plugin-turbo/lib/constants.ts b/packages/eslint-plugin-turbo/lib/constants.ts deleted file mode 100644 index 5af2e6f..0000000 --- a/packages/eslint-plugin-turbo/lib/constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -const RULES = { - noUndeclaredEnvVars: `no-undeclared-env-vars`, -}; - -export { RULES }; diff --git a/packages/eslint-plugin-turbo/lib/index.ts b/packages/eslint-plugin-turbo/lib/index.ts deleted file mode 100644 index e7f113c..0000000 --- a/packages/eslint-plugin-turbo/lib/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { RULES } from "./constants"; - -// rules -import noUndeclaredEnvVars from "./rules/no-undeclared-env-vars"; - -// configs -import recommended from "./configs/recommended"; - -const rules = { - [RULES.noUndeclaredEnvVars]: noUndeclaredEnvVars, -}; - -const configs = { - recommended, -}; - -export { rules, configs }; diff --git a/packages/eslint-plugin-turbo/lib/rules/no-undeclared-env-vars.ts b/packages/eslint-plugin-turbo/lib/rules/no-undeclared-env-vars.ts deleted file mode 100644 index 372d21a..0000000 --- a/packages/eslint-plugin-turbo/lib/rules/no-undeclared-env-vars.ts +++ /dev/null @@ -1,187 +0,0 @@ -import type { Rule } from "eslint"; -import path from "path"; -import { Node, MemberExpression } from "estree"; -import { RULES } from "../constants"; -import getEnvVarDependencies from "../utils/getEnvVarDependencies"; - -const meta: Rule.RuleMetaData = { - type: "problem", - docs: { - description: - "Do not allow the use of `process.env` without including the env key in any turbo.json", - category: "Configuration Issues", - recommended: true, - url: `https://github.com/vercel/turbo/tree/main/packages/eslint-plugin-turbo/docs/rules/${RULES.noUndeclaredEnvVars}.md`, - }, - schema: [ - { - type: "object", - default: {}, - additionalProperties: false, - properties: { - // override cwd, primarily exposed for easier testing - cwd: { - require: false, - type: "string", - }, - allowList: { - default: [], - type: "array", - items: { - type: "string", - }, - }, - }, - }, - ], -}; - -/** - * Normalize the value of the cwd - * Extracted from eslint - * SPDX-License-Identifier: MIT - */ -function normalizeCwd( - cwd: string | undefined, - options: Array -): string | undefined { - if (options?.[0]?.cwd) { - return options[0].cwd; - } - - if (cwd) { - return cwd; - } - if (typeof process === "object") { - return process.cwd(); - } - - return undefined; -} - -function create(context: Rule.RuleContext): Rule.RuleListener { - const { options, getPhysicalFilename } = context; - const allowList: Array = options?.[0]?.allowList || []; - const regexAllowList: Array = []; - allowList.forEach((allowed) => { - try { - regexAllowList.push(new RegExp(allowed)); - } catch (err) { - // log the error, but just move on without this allowList entry - console.error(`Unable to convert "${allowed}" to regex`); - } - }); - - const cwd = normalizeCwd( - context.getCwd ? context.getCwd() : undefined, - options - ); - const filePath = getPhysicalFilename(); - const allTurboVars = getEnvVarDependencies({ - cwd, - }); - - // if allTurboVars is null, something went wrong reading from the turbo config - // (this is different from finding a config with no env vars present, which would - // return an empty set) - so there is no point continuing if we have nothing to check against - if (!allTurboVars) { - // return of {} bails early from a rule check - return {}; - } - - const globalTurboVars = allTurboVars["//"]; - const hasWorkspaceConfigs = Object.keys(allTurboVars).length > 1; - - // find any workspace configs that match the current file path - // find workspace config (if any) that match the current file path - const workspaceKey = Object.keys(allTurboVars).find( - (workspacePath) => filePath !== "//" && filePath.startsWith(workspacePath) - ); - - let workspaceTurboVars: Set | null = null; - if (workspaceKey) { - workspaceTurboVars = allTurboVars[workspaceKey]; - } - - const checkKey = (node: Node, envKey?: string) => { - if ( - envKey && - !globalTurboVars.has(envKey) && - !regexAllowList.some((regex) => regex.test(envKey)) - ) { - // if we have a workspace config, check that too - if (workspaceTurboVars && workspaceTurboVars.has(envKey)) { - return {}; - } else { - let message = `{{ envKey }} is not listed as a dependency in ${ - hasWorkspaceConfigs ? "root turbo.json" : "turbo.json" - }`; - if (workspaceKey && workspaceTurboVars) { - if (cwd) { - // if we have a cwd, we can provide a relative path to the workspace config - message = `{{ envKey }} is not listed as a dependency in the root turbo.json or workspace (${path.relative( - cwd, - workspaceKey - )}) turbo.json`; - } else { - message = `{{ envKey }} is not listed as a dependency in the root turbo.json or workspace turbo.json`; - } - } - - context.report({ - node, - message, - data: { envKey }, - }); - } - } - }; - - const isComputed = ( - node: MemberExpression & Rule.NodeParentExtension - ): boolean => { - if ("computed" in node.parent) { - return node.parent.computed; - } - - return false; - }; - - return { - MemberExpression(node) { - // we only care about complete process env declarations and non-computed keys - if ( - "name" in node.object && - "name" in node.property && - !isComputed(node) - ) { - const objectName = node.object.name; - const propertyName = node.property.name; - - // we're doing something with process.env - if (objectName === "process" && propertyName === "env") { - // destructuring from process.env - if ("id" in node.parent && node.parent.id?.type === "ObjectPattern") { - const values = node.parent.id.properties.values(); - Array.from(values).forEach((item) => { - if ("key" in item && "name" in item.key) { - checkKey(node.parent, item.key.name); - } - }); - } - - // accessing key on process.env - else if ( - "property" in node.parent && - "name" in node.parent.property - ) { - checkKey(node.parent, node.parent.property?.name); - } - } - } - }, - }; -} - -const rule = { create, meta }; -export default rule; diff --git a/packages/eslint-plugin-turbo/lib/utils/getEnvVarDependencies.ts b/packages/eslint-plugin-turbo/lib/utils/getEnvVarDependencies.ts deleted file mode 100644 index a57e5eb..0000000 --- a/packages/eslint-plugin-turbo/lib/utils/getEnvVarDependencies.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { getTurboConfigs } from "@turbo/utils"; - -function findDependsOnEnvVars({ - dependencies, -}: { - dependencies?: Array; -}) { - if (dependencies) { - return ( - dependencies - // filter for dep env vars - .filter((dep) => dep.startsWith("$")) - // remove leading $ - .map((envVar) => envVar.slice(1, envVar.length)) - ); - } - - return []; -} - -function getEnvVarDependencies({ - cwd, -}: { - cwd: string | undefined; -}): Record> | null { - const turboConfigs = getTurboConfigs(cwd); - - if (!turboConfigs.length) { - return null; - } - - const envVars: Record> = { - "//": new Set(), - }; - - turboConfigs.forEach((turboConfig) => { - const { config, workspacePath, isRootConfig } = turboConfig; - - const key = isRootConfig ? "//" : workspacePath; - if (!envVars[key]) { - envVars[key] = new Set(); - } - - // handle globals - if (!("extends" in config)) { - const { globalDependencies = [], globalEnv = [] } = config; - - const keys = [ - ...findDependsOnEnvVars({ - dependencies: globalDependencies, - }), - ...globalEnv, - ]; - keys.forEach((k) => envVars[key].add(k)); - } - - // handle pipelines - const { pipeline = {} } = config; - Object.values(pipeline).forEach(({ env, dependsOn }) => { - if (dependsOn) { - findDependsOnEnvVars({ dependencies: dependsOn }).forEach((k) => - envVars[key].add(k) - ); - } - - if (env) { - env.forEach((k) => envVars[key].add(k)); - } - }); - }); - - return envVars; -} - -export default getEnvVarDependencies; diff --git a/packages/eslint-plugin-turbo/package.json b/packages/eslint-plugin-turbo/package.json deleted file mode 100644 index d19eef2..0000000 --- a/packages/eslint-plugin-turbo/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "eslint-plugin-turbo", - "version": "1.9.4-canary.2", - "description": "ESLint plugin for Turborepo", - "keywords": [ - "turbo", - "eslint", - "turborepo", - "eslintplugin", - "eslint-plugin" - ], - "repository": { - "type": "git", - "url": "https://github.com/vercel/turbo", - "directory": "packages/eslint-plugin-turbo" - }, - "bugs": { - "url": "https://github.com/vercel/turbo/issues" - }, - "author": "Vercel", - "main": "./dist/index.js", - "files": [ - "dist/**" - ], - "scripts": { - "release": "pnpm build && pnpm publish", - "test": "jest", - "build": "tsup", - "check-types": "tsc --noEmit", - "lint": "eslint lib/**/*.ts" - }, - "devDependencies": { - "@types/eslint": "^8.4.5", - "@types/estree": "^1.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.12", - "jest": "^27.4.3", - "json5": "^2.2.1", - "ts-jest": "^27.1.1", - "@turbo/tsconfig": "workspace:*", - "tsup": "^6.2.0", - "@turbo/test-utils": "workspace:*", - "@turbo/types": "workspace:*", - "@turbo/utils": "workspace:*", - "typescript": "^4.7.4" - }, - "peerDependencies": { - "eslint": ">6.6.0" - }, - "license": "MPL-2.0" -} diff --git a/packages/eslint-plugin-turbo/tsconfig.json b/packages/eslint-plugin-turbo/tsconfig.json deleted file mode 100644 index 0620a3c..0000000 --- a/packages/eslint-plugin-turbo/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "@turbo/tsconfig/library.json", - "compilerOptions": { - "rootDir": "." - } -} diff --git a/packages/eslint-plugin-turbo/tsup.config.ts b/packages/eslint-plugin-turbo/tsup.config.ts deleted file mode 100644 index bbda8cb..0000000 --- a/packages/eslint-plugin-turbo/tsup.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig, Options } from "tsup"; - -export default defineConfig((options: Options) => ({ - entry: ["lib/index.ts"], - clean: true, - minify: true, - ...options, -})); diff --git a/packages/eslint-plugin-turbo/turbo.json b/packages/eslint-plugin-turbo/turbo.json deleted file mode 100644 index f86a4db..0000000 --- a/packages/eslint-plugin-turbo/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "$schema": "../../docs/public/schema.json", - "extends": ["//"], - "pipeline": { - "test": { - "dependsOn": ["build"] - } - } -} diff --git a/packages/node-module-trace/package.json b/packages/node-module-trace/package.json deleted file mode 100644 index 0494edc..0000000 --- a/packages/node-module-trace/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "@vercel/experimental-nft", - "version": "0.0.5-alpha.0", - "description": "Node.js module trace", - "license": "MPL-2.0", - "alias": "node-file-trace", - "publishConfig": { - "access": "public" - } -} diff --git a/packages/tsconfig/README.md b/packages/tsconfig/README.md deleted file mode 100644 index c78d9de..0000000 --- a/packages/tsconfig/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `tsconfig` - -Collection of internal tsconfigs shared between [turborepo/packages/](https://github.com/vercel/turbo/tree/main/packages) diff --git a/packages/tsconfig/base.json b/packages/tsconfig/base.json deleted file mode 100644 index aab01c7..0000000 --- a/packages/tsconfig/base.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Default", - "compilerOptions": { - "composite": false, - "declaration": true, - "declarationMap": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "inlineSources": false, - "isolatedModules": true, - "moduleResolution": "node", - "noUnusedLocals": false, - "noUnusedParameters": false, - "preserveWatchOutput": true, - "skipLibCheck": true, - "strict": true - }, - "exclude": ["node_modules", "dist"] -} diff --git a/packages/tsconfig/library.json b/packages/tsconfig/library.json deleted file mode 100644 index 66db367..0000000 --- a/packages/tsconfig/library.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./base.json", - "display": "TS Library", - "compilerOptions": { - "lib": ["ES2019"], - "target": "ES2019", - "skipLibCheck": true, - "resolveJsonModule": true, - "outDir": "dist", - "allowJs": false - } -} diff --git a/packages/tsconfig/package.json b/packages/tsconfig/package.json deleted file mode 100644 index 913e344..0000000 --- a/packages/tsconfig/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "@turbo/tsconfig", - "version": "0.0.0", - "private": true -} diff --git a/packages/turbo-codemod/LICENSE b/packages/turbo-codemod/LICENSE deleted file mode 100644 index fa0086a..0000000 --- a/packages/turbo-codemod/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. \ No newline at end of file diff --git a/packages/turbo-codemod/README.md b/packages/turbo-codemod/README.md deleted file mode 100644 index 5545561..0000000 --- a/packages/turbo-codemod/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Turborepo Codemods - -Turborepo provides Codemod transformations to help upgrade your Turborepo codebase. - -Codemods are transformations that run on your codebase programmatically. This allows for a large amount of changes to be applied without having to manually go through every file. - -## Commands - -### `migrate` - -Updates your Turborepo codebase to the specified version of Turborepo (defaults to the latest), running any required codemods, and installing the new version of Turborepo. - -``` -Usage: @turbo/codemod migrate|update [options] [path] - -Migrate a project to the latest version of Turborepo - -Arguments: - path Directory where the transforms should be applied - -Options: - --from Specify the version to migrate from (default: current version) - --to Specify the version to migrate to (default: latest) - --install Install new version of turbo after migration (default: true) - --force Bypass Git safety checks and forcibly run codemods (default: false) - --dry Dry run (no changes are made to files) (default: false) - --print Print transformed files to your terminal (default: false) - -h, --help display help for command -``` - -### `transform` (default) - -Runs a single codemod on your codebase. This is the default command, and can be omitted. - -``` -Usage: @turbo/codemod transform [options] [transform] [path] - @turbo/codemod [options] [transform] [path] - -Apply a single code transformation to a project - -Arguments: - transform The transformer to run - path Directory where the transforms should be applied - -Options: - --force Bypass Git safety checks and forcibly run codemods (default: false) - --list List all available transforms (default: false) - --dry Dry run (no changes are made to files) (default: false) - --print Print transformed files to your terminal (default: false) - -h, --help display help for command -``` - -## Developing - -To add a new transformer, run `pnpm add-transformer`, or [view the complete guide](./src/transforms/README.md). diff --git a/packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/has-package-manager/package.json b/packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/has-package-manager/package.json deleted file mode 100644 index d6edac5..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/has-package-manager/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "has-package-manager", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/no-package-manager/package.json b/packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/no-package-manager/package.json deleted file mode 100644 index 2e28fe4..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/no-package-manager/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "no-package-manager", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {} -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/wrong-package-manager/package.json b/packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/wrong-package-manager/package.json deleted file mode 100644 index f58aca2..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/add-package-manager/wrong-package-manager/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "has-package-manager", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "turbo@1.7.0" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/both-configs/package.json b/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/both-configs/package.json deleted file mode 100644 index c4606fa..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/both-configs/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "both-configs", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3", - "turbo": { - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "package-only": { - "cache": false, - "persistent": true - }, - "build": { - "outputs": [ - ".next/**", - "!.next/cache/**" - ] - }, - "lint": { - "outputs": [] - }, - "dev": { - "cache": false - } - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/both-configs/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/both-configs/turbo.json deleted file mode 100644 index e6eb652..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/both-configs/turbo.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "turbo-only": { - "cache": false, - "persistent": true - }, - "build": { - "outputs": [".next/**", "!.next/cache/**"] - }, - "lint": { - "outputs": [] - }, - "dev": { - "cache": false - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-package-json-config/package.json b/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-package-json-config/package.json deleted file mode 100644 index b965b7d..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-package-json-config/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "no-turbo-json-config", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-package-json-file/a-random-file.txt b/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-package-json-file/a-random-file.txt deleted file mode 100644 index 7488fec..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-package-json-file/a-random-file.txt +++ /dev/null @@ -1 +0,0 @@ -Nothing exists here diff --git a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-turbo-json-config/package.json b/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-turbo-json-config/package.json deleted file mode 100644 index 7754c7d..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/no-turbo-json-config/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "no-turbo-json-config", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3", - "turbo": { - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "build": { - "outputs": [ - ".next/**", - "!.next/cache/**" - ] - }, - "lint": { - "outputs": [] - }, - "dev": { - "cache": false - } - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/turbo-json-config/package.json b/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/turbo-json-config/package.json deleted file mode 100644 index a48d0ec..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/turbo-json-config/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "both-configs", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/turbo-json-config/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/turbo-json-config/turbo.json deleted file mode 100644 index e6eb652..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/create-turbo-config/turbo-json-config/turbo.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "turbo-only": { - "cache": false, - "persistent": true - }, - "build": { - "outputs": [".next/**", "!.next/cache/**"] - }, - "lint": { - "outputs": [] - }, - "dev": { - "cache": false - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-deps/package.json b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-deps/package.json deleted file mode 100644 index b632eef..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-deps/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "no-turbo", - "version": "0.0.0" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-package/README.md b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-package/README.md deleted file mode 100644 index 64355e7..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-package/README.md +++ /dev/null @@ -1 +0,0 @@ -Nothing here diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-turbo/package.json b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-turbo/package.json deleted file mode 100644 index 524df50..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/no-turbo/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "no-turbo", - "version": "0.0.0", - "dependencies": {}, - "devDependencies": {} -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/normal-workspaces-dev-install/package.json b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/normal-workspaces-dev-install/package.json deleted file mode 100644 index f5b2368..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/normal-workspaces-dev-install/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "normal-workspaces", - "version": "0.0.0", - "workspaces": [ - "apps/*", - "packages/*" - ], - "dependencies": {}, - "devDependencies": { - "turbo": "1.0.0" - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/normal-workspaces/package.json b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/normal-workspaces/package.json deleted file mode 100644 index 6344a38..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/normal-workspaces/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "normal-workspaces", - "version": "0.0.0", - "workspaces": [ - "apps/*", - "packages/*" - ], - "dependencies": { - "turbo": "1.0.0" - }, - "devDependencies": {} -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces-dev-install/package.json b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces-dev-install/package.json deleted file mode 100644 index 5c12f28..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces-dev-install/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "pnpm-workspaces", - "version": "0.0.0", - "dependencies": {}, - "devDependencies": { - "turbo": "1.0.0" - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces-dev-install/pnpm-workspace.yaml b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces-dev-install/pnpm-workspace.yaml deleted file mode 100644 index 3ff5faa..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces-dev-install/pnpm-workspace.yaml +++ /dev/null @@ -1,3 +0,0 @@ -packages: - - "apps/*" - - "packages/*" diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces/package.json b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces/package.json deleted file mode 100644 index fedeb8d..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "pnpm-workspaces", - "version": "0.0.0", - "dependencies": { - "turbo": "1.0.0" - }, - "devDependencies": {} -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces/pnpm-workspace.yaml b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces/pnpm-workspace.yaml deleted file mode 100644 index 3ff5faa..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/pnpm-workspaces/pnpm-workspace.yaml +++ /dev/null @@ -1,3 +0,0 @@ -packages: - - "apps/*" - - "packages/*" diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/single-package-dev-install/package.json b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/single-package-dev-install/package.json deleted file mode 100644 index 38bd995..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/single-package-dev-install/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "single-package-dev-install", - "version": "0.0.0", - "dependencies": {}, - "devDependencies": { - "turbo": "1.0.0" - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/single-package/package.json b/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/single-package/package.json deleted file mode 100644 index 0fd3453..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/get-turbo-upgrade-command/single-package/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "single-package", - "version": "0.0.0", - "dependencies": { - "turbo": "1.0.0" - }, - "devDependencies": {} -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/env-dependencies/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/env-dependencies/turbo.json deleted file mode 100644 index bb3e248..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/env-dependencies/turbo.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "globalDependencies": ["$NEXT_PUBLIC_API_KEY", "$STRIPE_API_KEY", ".env"], - "pipeline": { - "build": { - "outputs": [".next/**", "!.next/cache/**"], - "dependsOn": ["^build", "$PROD_API_KEY"] - }, - "lint": { - "outputs": [], - "dependsOn": ["$IS_CI"] - }, - "test": { - "outputs": [], - "dependsOn": ["$IS_CI", "test"] - }, - "dev": { - "cache": false - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/migrated-env-dependencies/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/migrated-env-dependencies/turbo.json deleted file mode 100644 index 9217af6..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/migrated-env-dependencies/turbo.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "globalDependencies": [], - "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": [] - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/no-turbo-json/package.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/no-turbo-json/package.json deleted file mode 100644 index 83443be..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/no-turbo-json/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "no-turbo-json", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/old-config/package.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/old-config/package.json deleted file mode 100644 index 6774d3c..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/old-config/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "migrate-env-var-dependencies-old-config", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3", - "turbo": { - "pipeline": { - "build-one": { - "outputs": [ - "foo" - ] - }, - "build-two": { - "outputs": [] - }, - "build-three": {} - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/old-config/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/old-config/turbo.json deleted file mode 100644 index b0f6150..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/old-config/turbo.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "build-one": { - "outputs": ["foo"] - }, - "build-two": { - "outputs": [] - }, - "build-three": {} - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/index.js b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/index.js deleted file mode 100644 index 4de53f5..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function docs() { - if (process.env.ENV_1 === undefined) { - return "does not exist"; - } - return "exists"; -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/package.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/package.json deleted file mode 100644 index 82f9a44..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "docs", - "version": "1.0.0" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/turbo.json deleted file mode 100644 index a3713ef..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/docs/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "pipeline": { - "build": { - "env": ["ENV_3"] - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/index.js b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/index.js deleted file mode 100644 index bfd3ab8..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function web() { - if (!process.env.ENV_2) { - return "bar"; - } - return "foo"; -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/package.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/package.json deleted file mode 100644 index d8a83ed..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "web", - "version": "1.0.0" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/turbo.json deleted file mode 100644 index dd69c31..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/apps/web/turbo.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "pipeline": { - "build": { - // old - "dependsOn": ["build", "$ENV_2"], - // new - "env": ["ENV_1"] - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/package.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/package.json deleted file mode 100644 index c6616a6..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "private": true, - "workspaces": [ - "apps/*", - "packages/*" - ], - "scripts": { - "build": "turbo run build" - }, - "devDependencies": { - "turbo": "latest" - }, - "packageManager": "yarn@1.22.19" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/index.js b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/index.js deleted file mode 100644 index dee5e80..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function foo() { - if (!process.env.IS_SERVER) { - return "bar"; - } - return "foo"; -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/package.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/package.json deleted file mode 100644 index 7cb7cf1..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "ui", - "version": "1.0.0" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/turbo.json deleted file mode 100644 index 6ce7b30..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/packages/ui/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "pipeline": { - "build": { - "dependsOn": ["$IS_SERVER"] - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/turbo.json deleted file mode 100644 index 718e461..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate-env-var-dependencies/workspace-configs/turbo.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "globalDependencies": ["$NEXT_PUBLIC_API_KEY", "$STRIPE_API_KEY", ".env"], - "pipeline": { - "build": { - "outputs": [".next/**", "!.next/cache/**"], - "dependsOn": ["^build", "$PROD_API_KEY"] - }, - "lint": { - "outputs": [], - "dependsOn": ["$IS_TEST"] - }, - "test": { - "outputs": [], - "dependsOn": ["$IS_CI", "test"] - }, - "dev": { - "cache": false - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate/no-repo/README.md b/packages/turbo-codemod/__tests__/__fixtures__/migrate/no-repo/README.md deleted file mode 100644 index 64355e7..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate/no-repo/README.md +++ /dev/null @@ -1 +0,0 @@ -Nothing here diff --git a/packages/turbo-codemod/__tests__/__fixtures__/migrate/old-turbo/package.json b/packages/turbo-codemod/__tests__/__fixtures__/migrate/old-turbo/package.json deleted file mode 100644 index 62959b8..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/migrate/old-turbo/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "no-turbo-json", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": { - "turbo": "1.0.0" - }, - "turbo": { - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "build": { - "outputs": [ - ".next/**", - "!.next/cache/**" - ] - }, - "lint": { - "outputs": [] - }, - "test": {}, - "dev": { - "cache": false - } - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/invalid-outputs/package.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/invalid-outputs/package.json deleted file mode 100644 index 6b50aac..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/invalid-outputs/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "invalid-outputs", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/invalid-outputs/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/invalid-outputs/turbo.json deleted file mode 100644 index 33c2b93..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/invalid-outputs/turbo.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "build-one": { - "outputs": ["foo"] - }, - "build-two": { - "outputs": [] - }, - "build-three": {}, - "garbage-in-numeric-0": { - "outputs": 0 - }, - "garbage-in-numeric": { - "outputs": 42 - }, - "garbage-in-string": { - "outputs": "string" - }, - "garbage-in-empty-string": { - "outputs": "" - }, - "garbage-in-null": { - "outputs": null - }, - "garbage-in-false": { - "outputs": false - }, - "garbage-in-true": { - "outputs": true - }, - "garbage-in-object": { - "outputs": {} - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-outputs/package.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-outputs/package.json deleted file mode 100644 index 4e17dc1..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-outputs/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "no-outputs", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-outputs/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-outputs/turbo.json deleted file mode 100644 index f5d57fc..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-outputs/turbo.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "build-one": { - "dependsOn": ["build-two"] - }, - "build-two": { - "cache": false - }, - "build-three": { - "persistent": true - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-pipeline/package.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-pipeline/package.json deleted file mode 100644 index 6e20fc8..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-pipeline/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "no-pipeline", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-pipeline/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-pipeline/turbo.json deleted file mode 100644 index 0e2d6fd..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-pipeline/turbo.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "globalDependencies": ["$NEXT_PUBLIC_API_KEY", "$STRIPE_API_KEY", ".env"], - "pipeline": {} -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-turbo-json/package.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-turbo-json/package.json deleted file mode 100644 index cd98334..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/no-turbo-json/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "set-default-outputs-no-turbo-json", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-config/package.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-config/package.json deleted file mode 100644 index 4c816c2..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-config/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "set-default-outputs-old-config", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3", - "turbo": { - "pipeline": { - "build-one": { - "outputs": [ - "foo" - ] - }, - "build-two": { - "outputs": [] - }, - "build-three": {} - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-config/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-config/turbo.json deleted file mode 100644 index b0f6150..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-config/turbo.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "build-one": { - "outputs": ["foo"] - }, - "build-two": { - "outputs": [] - }, - "build-three": {} - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-outputs/package.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-outputs/package.json deleted file mode 100644 index e4220ba..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-outputs/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "old-outputs", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": {}, - "packageManager": "npm@1.2.3" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-outputs/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-outputs/turbo.json deleted file mode 100644 index b0f6150..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/old-outputs/turbo.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "build-one": { - "outputs": ["foo"] - }, - "build-two": { - "outputs": [] - }, - "build-three": {} - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/index.js b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/index.js deleted file mode 100644 index 4de53f5..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function docs() { - if (process.env.ENV_1 === undefined) { - return "does not exist"; - } - return "exists"; -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/package.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/package.json deleted file mode 100644 index 82f9a44..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "docs", - "version": "1.0.0" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/turbo.json deleted file mode 100644 index e60cdb7..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/docs/turbo.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "pipeline": { - "build": {} - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/index.js b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/index.js deleted file mode 100644 index bfd3ab8..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function web() { - if (!process.env.ENV_2) { - return "bar"; - } - return "foo"; -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/package.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/package.json deleted file mode 100644 index d8a83ed..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "web", - "version": "1.0.0" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/turbo.json deleted file mode 100644 index b239cbf..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/apps/web/turbo.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "pipeline": { - "build": { - // old - "outputs": [] - } - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/package.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/package.json deleted file mode 100644 index c6616a6..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "private": true, - "workspaces": [ - "apps/*", - "packages/*" - ], - "scripts": { - "build": "turbo run build" - }, - "devDependencies": { - "turbo": "latest" - }, - "packageManager": "yarn@1.22.19" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/index.js b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/index.js deleted file mode 100644 index dee5e80..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function foo() { - if (!process.env.IS_SERVER) { - return "bar"; - } - return "foo"; -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/package.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/package.json deleted file mode 100644 index 7cb7cf1..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "ui", - "version": "1.0.0" -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/turbo.json deleted file mode 100644 index fe51119..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/packages/ui/turbo.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "extends": ["//"], - "pipeline": { - "build-three": {} - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/turbo.json b/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/turbo.json deleted file mode 100644 index b0f6150..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/set-default-outputs/workspace-configs/turbo.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "build-one": { - "outputs": ["foo"] - }, - "build-two": { - "outputs": [] - }, - "build-three": {} - } -} diff --git a/packages/turbo-codemod/__tests__/__fixtures__/transform/basic/package.json b/packages/turbo-codemod/__tests__/__fixtures__/transform/basic/package.json deleted file mode 100644 index 651edb6..0000000 --- a/packages/turbo-codemod/__tests__/__fixtures__/transform/basic/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "transform-basic", - "version": "1.0.0", - "dependencies": {}, - "devDependencies": { - "turbo": "1.0.0" - } -} diff --git a/packages/turbo-codemod/__tests__/add-package-manager.test.ts b/packages/turbo-codemod/__tests__/add-package-manager.test.ts deleted file mode 100644 index 5bde7e0..0000000 --- a/packages/turbo-codemod/__tests__/add-package-manager.test.ts +++ /dev/null @@ -1,504 +0,0 @@ -import { transformer } from "../src/transforms/add-package-manager"; -import { setupTestFixtures } from "@turbo/test-utils"; -import fs from "fs-extra"; -import * as getPackageManager from "../src/utils/getPackageManager"; -import * as getPackageManagerVersion from "../src/utils/getPackageManagerVersion"; - -describe("add-package-manager", () => { - const { useFixture } = setupTestFixtures({ - directory: __dirname, - test: "add-package-manager", - }); - test("no package manager - basic", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-package-manager" }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // mock out workspace and version detection so we're not dependent on our actual repo - const mockGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - - const mockGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager); - - // package manager should not exist - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - expect(mockGetPackageManager).toHaveBeenCalledWith({ directory: root }); - expect(mockGetPackageManagerVersion).toHaveBeenCalledWith( - packageManager, - root - ); - - // package manager should now exist - expect(JSON.parse(read("package.json") || "{}").packageManager).toBe( - `${packageManager}@${packageManagerVersion}` - ); - // result should be correct - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "modified", - "additions": 1, - "deletions": 0, - }, - } - `); - - mockGetPackageManagerVersion.mockRestore(); - mockGetPackageManager.mockRestore(); - }); - - test("no package manager - repeat run", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-package-manager" }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // mock out workspace and version detection so we're not dependent on our actual repo - const mockGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - - const mockGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager); - - // package manager should not exist - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - expect(mockGetPackageManager).toHaveBeenCalledWith({ directory: root }); - expect(mockGetPackageManagerVersion).toHaveBeenCalled(); - expect(mockGetPackageManagerVersion).toHaveBeenCalledWith( - packageManager, - root - ); - - // package manager should now exist - expect(JSON.parse(read("package.json") || "{}").packageManager).toBe( - `${packageManager}@${packageManagerVersion}` - ); - // result should be correct - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "modified", - "additions": 1, - "deletions": 0, - }, - } - `); - - // run the transformer again to ensure nothing changes on a second run - const repeatResult = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - expect(repeatResult.fatalError).toBeUndefined(); - expect(repeatResult.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - } - `); - - mockGetPackageManagerVersion.mockRestore(); - mockGetPackageManager.mockRestore(); - }); - - test("no package manager - dry", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-package-manager" }); - - const packageManager = "npm"; - const packageManagerVersion = "1.2.3"; - - // mock out workspace and version detection so we're not dependent on our actual repo - const mockGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager); - - // package manager should not exist - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: true, print: false }, - }); - - expect(mockGetPackageManager).toHaveBeenCalledWith({ directory: root }); - expect(mockGetPackageManagerVersion).toHaveBeenCalledWith( - packageManager, - root - ); - - // package manager should not exist - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - // result should be correct - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "skipped", - "additions": 1, - "deletions": 0, - }, - } - `); - - mockGetPackageManagerVersion.mockRestore(); - }); - - test("no package manager - print", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-package-manager" }); - - const packageManager = "yarn"; - const packageManagerVersion = "1.2.3"; - - // mock out workspace and version detection so we're not dependent on our actual repo - const mockGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - - const mockGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager); - - // package manager should not exist - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: true }, - }); - - expect(mockGetPackageManager).toHaveBeenCalledWith({ directory: root }); - expect(mockGetPackageManagerVersion).toHaveBeenCalledWith( - packageManager, - root - ); - // package manager should now exist - expect(JSON.parse(read("package.json") || "{}").packageManager).toBe( - `${packageManager}@${packageManagerVersion}` - ); - // result should be correct - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "modified", - "additions": 1, - "deletions": 0, - }, - } - `); - - mockGetPackageManagerVersion.mockRestore(); - }); - - test("no package manager - dry & print", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-package-manager" }); - - const packageManager = "npm"; - const packageManagerVersion = "1.2.3"; - - // mock out workspace and version detection so we're not dependent on our actual repo - const mockGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - - const mockGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager); - - // package manager should not exist - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: true, print: true }, - }); - - expect(mockGetPackageManager).toHaveBeenCalledWith({ directory: root }); - expect(mockGetPackageManagerVersion).toHaveBeenCalledWith( - packageManager, - root - ); - - // package manager should not exist - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - // result should be correct - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "skipped", - "additions": 1, - "deletions": 0, - }, - } - `); - - mockGetPackageManagerVersion.mockRestore(); - mockGetPackageManager.mockRestore(); - }); - - test("package manager already exists", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "has-package-manager" }); - const packageManager = "npm"; - const packageManagerVersion = "1.2.3"; - - // mock out workspace and version detection so we're not dependent on our actual repo - const mockGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - - const mockGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager); - - // package manager should exist - expect(JSON.parse(read("package.json") || "{}").packageManager).toBe( - `${packageManager}@${packageManagerVersion}` - ); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - expect(mockGetPackageManager).toHaveBeenCalledWith({ directory: root }); - expect(mockGetPackageManagerVersion).toHaveBeenCalledWith( - packageManager, - root - ); - - // package manager should still exist - expect(JSON.parse(read("package.json") || "{}").packageManager).toBe( - `${packageManager}@${packageManagerVersion}` - ); - // result should be correct - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - } - `); - - mockGetPackageManagerVersion.mockRestore(); - mockGetPackageManager.mockRestore(); - }); - - test("package manager exists but is wrong", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "wrong-package-manager" }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // mock out workspace and version detection so we're not dependent on our actual repo - const mockGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - - const mockGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager); - - // package manager should exist - expect(JSON.parse(read("package.json") || "{}").packageManager).toBe( - "turbo@1.7.0" - ); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - expect(mockGetPackageManager).toHaveBeenCalledWith({ directory: root }); - expect(mockGetPackageManagerVersion).toHaveBeenCalledWith( - packageManager, - root - ); - - // package manager should still exist - expect(JSON.parse(read("package.json") || "{}").packageManager).toBe( - `${packageManager}@${packageManagerVersion}` - ); - // result should be correct - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "modified", - "additions": 1, - "deletions": 1, - }, - } - `); - - mockGetPackageManagerVersion.mockRestore(); - mockGetPackageManager.mockRestore(); - }); - - test("errors when unable to determine workspace manager", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-package-manager" }); - - const mockGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(undefined); - - // package manager should not exist - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - expect(mockGetPackageManager).toHaveBeenCalledTimes(1); - expect(mockGetPackageManager).toHaveBeenCalledWith({ directory: root }); - - // result should be correct - // result should be correct - expect(result.fatalError?.message).toMatch( - /Unable to determine package manager for .*?/ - ); - - mockGetPackageManager.mockRestore(); - }); - - test("errors when unable to determine package manager", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-package-manager" }); - - const mockGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockImplementation(() => { - throw new Error("package manager not supported"); - }); - - // package manager should not exist - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - expect(mockGetPackageManagerVersion).toHaveBeenCalledTimes(1); - - // result should be correct - expect(result.fatalError?.message).toMatch( - /Unable to determine package manager version for .*?/ - ); - - mockGetPackageManagerVersion.mockRestore(); - }); - - test("errors when unable to write json", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-package-manager" }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // mock out workspace and version detection so we're not dependent on our actual repo - const mockGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - - const mockGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager); - - const mockWriteJsonSync = jest - .spyOn(fs, "writeJsonSync") - .mockImplementation(() => { - throw new Error("could not write file"); - }); - - // package manager should not exist - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - expect(mockGetPackageManager).toHaveBeenCalledWith({ directory: root }); - expect(mockGetPackageManagerVersion).toHaveBeenCalledWith( - packageManager, - root - ); - - // package manager should still not exist (we couldn't write it) - expect( - JSON.parse(read("package.json") || "{}").packageManager - ).toBeUndefined(); - - // result should be correct - expect(result.fatalError?.message).toMatch( - "Encountered an error while transforming files" - ); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "error", - "additions": 1, - "deletions": 0, - "error": [Error: could not write file], - }, - } - `); - - mockWriteJsonSync.mockRestore(); - mockGetPackageManagerVersion.mockRestore(); - mockGetPackageManager.mockRestore(); - }); -}); diff --git a/packages/turbo-codemod/__tests__/create-turbo-config.test.ts b/packages/turbo-codemod/__tests__/create-turbo-config.test.ts deleted file mode 100644 index 8938c78..0000000 --- a/packages/turbo-codemod/__tests__/create-turbo-config.test.ts +++ /dev/null @@ -1,416 +0,0 @@ -import { transformer } from "../src/transforms/create-turbo-config"; -import { setupTestFixtures } from "@turbo/test-utils"; -import fs from "fs-extra"; - -describe("create-turbo-config", () => { - const { useFixture } = setupTestFixtures({ - directory: __dirname, - test: "create-turbo-config", - }); - - test("package.json config exists but no turbo.json config - basic", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-turbo-json-config" }); - - // turbo.json should not exist - expect(read("turbo.json")).toBeUndefined(); - - // get config from package.json for comparison later - const turboConfig = JSON.parse(read("package.json") || "{}").turbo; - expect(turboConfig).toBeDefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - // turbo.json should now exist (and match the package.json config) - expect(JSON.parse(read("turbo.json") || "{}")).toEqual(turboConfig); - - // result should be correct - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "modified", - "additions": 0, - "deletions": 1, - }, - "turbo.json": Object { - "action": "modified", - "additions": 1, - "deletions": 0, - }, - } - `); - }); - - test("package.json config exists but no turbo.json config - repeat run", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-turbo-json-config" }); - - // turbo.json should not exist - expect(read("turbo.json")).toBeUndefined(); - - // get config from package.json for comparison later - const turboConfig = JSON.parse(read("package.json") || "{}").turbo; - expect(turboConfig).toBeDefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - // turbo.json should now exist (and match the package.json config) - expect(JSON.parse(read("turbo.json") || "{}")).toEqual(turboConfig); - - // result should be correct - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "modified", - "additions": 0, - "deletions": 1, - }, - "turbo.json": Object { - "action": "modified", - "additions": 1, - "deletions": 0, - }, - } - `); - - // run the transformer - const repeatResult = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - // result should be correct - expect(repeatResult.fatalError).toBeUndefined(); - expect(repeatResult.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - "turbo.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - } - `); - }); - - test("package.json config exists but no turbo.json config - dry", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-turbo-json-config" }); - - // turbo.json should not exist - expect(read("turbo.json")).toBeUndefined(); - - // get config from package.json for comparison later - const turboConfig = JSON.parse(read("package.json") || "{}").turbo; - expect(turboConfig).toBeDefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: true, print: false }, - }); - - // turbo.json still not exist (dry run) - expect(read("turbo.json")).toBeUndefined(); - - // result should be correct - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "skipped", - "additions": 0, - "deletions": 1, - }, - "turbo.json": Object { - "action": "skipped", - "additions": 1, - "deletions": 0, - }, - } - `); - }); - - test("package.json config exists but no turbo.json config - print", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-turbo-json-config" }); - - // turbo.json should not exist - expect(read("turbo.json")).toBeUndefined(); - - // get config from package.json for comparison later - const turboConfig = JSON.parse(read("package.json") || "{}").turbo; - expect(turboConfig).toBeDefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: true }, - }); - - // turbo.json should now exist (and match the package.json config) - expect(JSON.parse(read("turbo.json") || "{}")).toEqual(turboConfig); - - // result should be correct - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "modified", - "additions": 0, - "deletions": 1, - }, - "turbo.json": Object { - "action": "modified", - "additions": 1, - "deletions": 0, - }, - } - `); - }); - - test("package.json config exists but no turbo.json config - dry & print", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-turbo-json-config" }); - - // turbo.json should not exist - expect(read("turbo.json")).toBeUndefined(); - - // get config from package.json for comparison later - const turboConfig = JSON.parse(read("package.json") || "{}").turbo; - expect(turboConfig).toBeDefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: true, print: true }, - }); - - // turbo.json still not exist (dry run) - expect(read("turbo.json")).toBeUndefined(); - - // result should be correct - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "skipped", - "additions": 0, - "deletions": 1, - }, - "turbo.json": Object { - "action": "skipped", - "additions": 1, - "deletions": 0, - }, - } - `); - }); - - test("no package.json config or turbo.json file exists", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-package-json-config" }); - - // turbo.json should not exist - expect(read("turbo.json")).toBeUndefined(); - - // get config from package.json for comparison later - const packageJsonConfig = JSON.parse(read("package.json") || "{}"); - const turboConfig = packageJsonConfig.turbo; - expect(turboConfig).toBeUndefined(); - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - // turbo.json should still not exist - expect(read("turbo.json")).toBeUndefined(); - - // make sure we didn't change the package.json - expect(JSON.parse(read("package.json") || "{}")).toEqual(packageJsonConfig); - - // result should be correct - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - "turbo.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - } - `); - }); - - test("no package.json file exists", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-package-json-file" }); - - // turbo.json should not exist - expect(read("turbo.json")).toBeUndefined(); - - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - // turbo.json should still not exist - expect(read("turbo.json")).toBeUndefined(); - - // result should be correct - expect(result.fatalError?.message).toMatch( - /No package\.json found at .*?\. Is the path correct\?/ - ); - }); - - test("turbo.json file exists and no package.json config exists", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "turbo-json-config" }); - - // turbo.json should exist - expect(read("turbo.json")).toBeDefined(); - - // no config should exist in package.json - const packageJsonConfig = JSON.parse(read("package.json") || "{}"); - const turboConfig = packageJsonConfig.turbo; - expect(turboConfig).toBeUndefined(); - - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - // turbo.json should still exist - expect(read("turbo.json")).toBeDefined(); - - // make sure we didn't change the package.json - expect(JSON.parse(read("package.json") || "{}")).toEqual(packageJsonConfig); - - // result should be correct - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - "turbo.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - } - `); - }); - - test("turbo.json file exists and package.json config exists", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "both-configs" }); - - // turbo.json should exist - const turboJsonConfig = JSON.parse(read("turbo.json") || "{}"); - expect(turboJsonConfig.pipeline).toBeDefined(); - - // no config should exist in package.json - const packageJsonConfig = JSON.parse(read("package.json") || "{}"); - const turboConfig = JSON.parse(read("package.json") || "{}").turbo; - expect(turboConfig).toBeDefined(); - - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - // make sure we didn't change the package.json - expect(JSON.parse(read("package.json") || "{}")).toEqual(packageJsonConfig); - - // make sure we didn't change the turbo.json - expect(JSON.parse(read("turbo.json") || "{}")).toEqual(turboJsonConfig); - - // result should be correct - expect(result.fatalError?.message).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - "turbo.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - } - `); - }); - - test("errors when unable to write json", () => { - // load the fixture for the test - const { root, read } = useFixture({ fixture: "no-turbo-json-config" }); - - // turbo.json should not exist - expect(read("turbo.json")).toBeUndefined(); - - // get config from package.json for comparison later - const turboConfig = JSON.parse(read("package.json") || "{}").turbo; - expect(turboConfig).toBeDefined(); - - const mockWriteJsonSync = jest - .spyOn(fs, "writeJsonSync") - .mockImplementation(() => { - throw new Error("could not write file"); - }); - - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - // turbo.json should still not exist (error writing) - expect(read("turbo.json")).toBeUndefined(); - - // result should be correct - expect(result.fatalError).toBeDefined(); - expect(result.fatalError?.message).toMatch( - "Encountered an error while transforming files" - ); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "package.json": Object { - "action": "error", - "additions": 0, - "deletions": 1, - "error": [Error: could not write file], - }, - "turbo.json": Object { - "action": "error", - "additions": 1, - "deletions": 0, - "error": [Error: could not write file], - }, - } - `); - - mockWriteJsonSync.mockRestore(); - }); -}); diff --git a/packages/turbo-codemod/__tests__/get-turbo-upgrade-command.test.ts b/packages/turbo-codemod/__tests__/get-turbo-upgrade-command.test.ts deleted file mode 100644 index 1015589..0000000 --- a/packages/turbo-codemod/__tests__/get-turbo-upgrade-command.test.ts +++ /dev/null @@ -1,576 +0,0 @@ -import { setupTestFixtures } from "@turbo/test-utils"; -import getTurboUpgradeCommand from "../src/commands/migrate/steps/getTurboUpgradeCommand"; -import * as utils from "../src/commands/migrate/utils"; -import * as getPackageManager from "../src/utils/getPackageManager"; -import * as getPackageManagerVersion from "../src/utils/getPackageManagerVersion"; - -const LOCAL_INSTALL_COMMANDS = [ - // npm - workspaces - [ - "latest", - "npm", - "7.0.0", - "normal-workspaces-dev-install", - "npm install turbo@latest --save-dev", - ], - [ - "1.6.3", - "npm", - "7.0.0", - "normal-workspaces-dev-install", - "npm install turbo@1.6.3 --save-dev", - ], - [ - "canary", - "npm", - "7.0.0", - "normal-workspaces-dev-install", - "npm install turbo@canary --save-dev", - ], - ["latest", "npm", "7.0.0", "normal-workspaces", "npm install turbo@latest"], - // npm - single package - [ - "latest", - "npm", - "7.0.0", - "single-package-dev-install", - "npm install turbo@latest --save-dev", - ], - ["latest", "npm", "7.0.0", "single-package", "npm install turbo@latest"], - // pnpm - workspaces - [ - "latest", - "pnpm", - "7.0.0", - "pnpm-workspaces-dev-install", - "pnpm install turbo@latest --save-dev -w", - ], - [ - "1.6.3", - "pnpm", - "7.0.0", - "pnpm-workspaces-dev-install", - "pnpm install turbo@1.6.3 --save-dev -w", - ], - [ - "canary", - "pnpm", - "7.0.0", - "pnpm-workspaces-dev-install", - "pnpm install turbo@canary --save-dev -w", - ], - [ - "latest", - "pnpm", - "7.0.0", - "pnpm-workspaces", - "pnpm install turbo@latest -w", - ], - // pnpm - single package - [ - "latest", - "pnpm", - "7.0.0", - "single-package-dev-install", - "pnpm install turbo@latest --save-dev", - ], - ["latest", "pnpm", "7.0.0", "single-package", "pnpm install turbo@latest"], - // yarn 1.x - workspaces - [ - "latest", - "yarn", - "1.22.19", - "normal-workspaces-dev-install", - "yarn add turbo@latest --dev -W", - ], - [ - "latest", - "yarn", - "1.22.19", - "normal-workspaces", - "yarn add turbo@latest -W", - ], - [ - "1.6.3", - "yarn", - "1.22.19", - "normal-workspaces-dev-install", - "yarn add turbo@1.6.3 --dev -W", - ], - [ - "canary", - "yarn", - "1.22.19", - "normal-workspaces-dev-install", - "yarn add turbo@canary --dev -W", - ], - // yarn 1.x - single package - [ - "latest", - "yarn", - "1.22.19", - "single-package-dev-install", - "yarn add turbo@latest --dev", - ], - ["latest", "yarn", "1.22.19", "single-package", "yarn add turbo@latest"], - // yarn 2.x - workspaces - [ - "latest", - "yarn", - "2.3.4", - "normal-workspaces-dev-install", - "yarn add turbo@latest --dev", - ], - ["latest", "yarn", "2.3.4", "normal-workspaces", "yarn add turbo@latest"], - [ - "1.6.3", - "yarn", - "2.3.4", - "normal-workspaces-dev-install", - "yarn add turbo@1.6.3 --dev", - ], - [ - "canary", - "yarn", - "2.3.4", - "normal-workspaces-dev-install", - "yarn add turbo@canary --dev", - ], - // yarn 2.x - single package - [ - "latest", - "yarn", - "2.3.4", - "single-package-dev-install", - "yarn add turbo@latest --dev", - ], - ["latest", "yarn", "2.3.4", "single-package", "yarn add turbo@latest"], - // yarn 3.x - workspaces - [ - "latest", - "yarn", - "3.3.4", - "normal-workspaces-dev-install", - "yarn add turbo@latest --dev", - ], - ["latest", "yarn", "3.3.4", "normal-workspaces", "yarn add turbo@latest"], - [ - "1.6.3", - "yarn", - "3.3.4", - "normal-workspaces-dev-install", - "yarn add turbo@1.6.3 --dev", - ], - [ - "canary", - "yarn", - "3.3.4", - "normal-workspaces-dev-install", - "yarn add turbo@canary --dev", - ], - // yarn 3.x - single package - [ - "latest", - "yarn", - "3.3.4", - "single-package-dev-install", - "yarn add turbo@latest --dev", - ], - ["latest", "yarn", "3.3.4", "single-package", "yarn add turbo@latest"], -]; - -const GLOBAL_INSTALL_COMMANDS = [ - // npm - [ - "latest", - "npm", - "7.0.0", - "normal-workspaces-dev-install", - "npm install turbo@latest --global", - ], - [ - "1.6.3", - "npm", - "7.0.0", - "normal-workspaces-dev-install", - "npm install turbo@1.6.3 --global", - ], - [ - "latest", - "npm", - "7.0.0", - "normal-workspaces", - "npm install turbo@latest --global", - ], - [ - "latest", - "npm", - "7.0.0", - "single-package", - "npm install turbo@latest --global", - ], - [ - "latest", - "npm", - "7.0.0", - "single-package-dev-install", - "npm install turbo@latest --global", - ], - // pnpm - [ - "latest", - "pnpm", - "7.0.0", - "pnpm-workspaces-dev-install", - "pnpm install turbo@latest --global", - ], - [ - "1.6.3", - "pnpm", - "7.0.0", - "pnpm-workspaces-dev-install", - "pnpm install turbo@1.6.3 --global", - ], - [ - "latest", - "pnpm", - "7.0.0", - "pnpm-workspaces", - "pnpm install turbo@latest --global", - ], - [ - "latest", - "pnpm", - "7.0.0", - "single-package", - "pnpm install turbo@latest --global", - ], - [ - "latest", - "pnpm", - "7.0.0", - "single-package-dev-install", - "pnpm install turbo@latest --global", - ], - // yarn 1.x - [ - "latest", - "yarn", - "1.22.19", - "normal-workspaces-dev-install", - "yarn global add turbo@latest", - ], - [ - "latest", - "yarn", - "1.22.19", - "normal-workspaces", - "yarn global add turbo@latest", - ], - [ - "1.6.3", - "yarn", - "1.22.19", - "normal-workspaces-dev-install", - "yarn global add turbo@1.6.3", - ], - [ - "latest", - "yarn", - "1.22.19", - "single-package", - "yarn global add turbo@latest", - ], - [ - "latest", - "yarn", - "1.22.19", - "single-package-dev-install", - "yarn global add turbo@latest", - ], - // yarn 2.x - [ - "latest", - "yarn", - "2.3.4", - "normal-workspaces-dev-install", - "yarn global add turbo@latest", - ], - [ - "latest", - "yarn", - "2.3.4", - "normal-workspaces", - "yarn global add turbo@latest", - ], - [ - "1.6.3", - "yarn", - "2.3.4", - "normal-workspaces-dev-install", - "yarn global add turbo@1.6.3", - ], - ["latest", "yarn", "2.3.4", "single-package", "yarn global add turbo@latest"], - [ - "latest", - "yarn", - "2.3.4", - "single-package-dev-install", - "yarn global add turbo@latest", - ], - // yarn 3.x - [ - "latest", - "yarn", - "3.3.3", - "normal-workspaces-dev-install", - "yarn global add turbo@latest", - ], - [ - "latest", - "yarn", - "3.3.3", - "normal-workspaces", - "yarn global add turbo@latest", - ], - [ - "1.6.3", - "yarn", - "3.3.3", - "normal-workspaces-dev-install", - "yarn global add turbo@1.6.3", - ], - ["latest", "yarn", "3.3.4", "single-package", "yarn global add turbo@latest"], - [ - "latest", - "yarn", - "3.3.4", - "single-package-dev-install", - "yarn global add turbo@latest", - ], -]; - -describe("get-turbo-upgrade-command", () => { - const { useFixture } = setupTestFixtures({ - directory: __dirname, - test: "get-turbo-upgrade-command", - }); - - test.each(LOCAL_INSTALL_COMMANDS)( - "returns correct upgrade command for local install of turbo@%s using %s@%s (fixture: %s)", - ( - turboVersion, - packageManager, - packageManagerVersion, - fixture, - expectedUpgradeCommand - ) => { - const { root } = useFixture({ - fixture, - }); - - const mockedExec = jest - .spyOn(utils, "exec") - .mockImplementation((command: string) => { - // fail the check for the turbo, and package manager bins to force local - if (command.includes("bin")) { - return undefined; - } - }); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockedGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager as getPackageManager.PackageManager); - - // get the command - const upgradeCommand = getTurboUpgradeCommand({ - directory: root, - to: turboVersion === "latest" ? undefined : turboVersion, - }); - - expect(upgradeCommand).toEqual(expectedUpgradeCommand); - - mockedExec.mockRestore(); - mockedGetPackageManager.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - } - ); - - test.each(GLOBAL_INSTALL_COMMANDS)( - "returns correct upgrade command for global install of turbo@%s using %s@%s (fixture: %s)", - ( - turboVersion, - packageManager, - packageManagerVersion, - fixture, - expectedUpgradeCommand - ) => { - const { root } = useFixture({ - fixture, - }); - - const mockedExec = jest - .spyOn(utils, "exec") - .mockImplementation((command: string) => { - if (command === "turbo bin") { - return `/global/${packageManager}/bin/turbo`; - } - if (command.includes(packageManager)) { - return `/global/${packageManager}/bin`; - } - }); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockedGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager as getPackageManager.PackageManager); - - // get the command - const upgradeCommand = getTurboUpgradeCommand({ - directory: root, - to: turboVersion === "latest" ? undefined : turboVersion, - }); - - expect(upgradeCommand).toEqual(expectedUpgradeCommand); - - mockedExec.mockRestore(); - mockedGetPackageManager.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - } - ); - - test("fails gracefully if no package.json exists", () => { - const { root } = useFixture({ - fixture: "no-package", - }); - - const mockedExec = jest - .spyOn(utils, "exec") - .mockImplementation((command: string) => { - // fail the check for the turbo, and package manager bins to force local - if (command.includes("bin")) { - return undefined; - } - }); - - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue("8.0.0"); - const mockedGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue("pnpm" as getPackageManager.PackageManager); - - // get the command - const upgradeCommand = getTurboUpgradeCommand({ - directory: root, - }); - - expect(upgradeCommand).toEqual(undefined); - - mockedExec.mockRestore(); - mockedGetPackageManager.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - }); - - test("fails gracefully if turbo cannot be found in package.json", () => { - const { root } = useFixture({ - fixture: "no-turbo", - }); - - const mockedExec = jest - .spyOn(utils, "exec") - .mockImplementation((command: string) => { - // fail the check for the turbo, and package manager bins to force local - if (command.includes("bin")) { - return undefined; - } - }); - - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue("8.0.0"); - const mockedGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue("pnpm" as getPackageManager.PackageManager); - - // get the command - const upgradeCommand = getTurboUpgradeCommand({ - directory: root, - }); - - expect(upgradeCommand).toEqual(undefined); - - mockedExec.mockRestore(); - mockedGetPackageManager.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - }); - - test("fails gracefully if package.json has no deps or devDeps", () => { - const { root } = useFixture({ - fixture: "no-deps", - }); - - const mockedExec = jest - .spyOn(utils, "exec") - .mockImplementation((command: string) => { - // fail the check for the turbo, and package manager bins to force local - if (command.includes("bin")) { - return undefined; - } - }); - - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue("8.0.0"); - const mockedGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue("pnpm" as getPackageManager.PackageManager); - - // get the command - const upgradeCommand = getTurboUpgradeCommand({ - directory: root, - }); - - expect(upgradeCommand).toEqual(undefined); - - mockedExec.mockRestore(); - mockedGetPackageManager.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - }); - - test("fails gracefully if can't find packageManager", () => { - const { root } = useFixture({ - fixture: "no-deps", - }); - - const mockedExec = jest - .spyOn(utils, "exec") - .mockImplementation((command: string) => { - // fail the check for the turbo, and package manager bins to force local - if (command.includes("bin")) { - return undefined; - } - }); - - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue("8.0.0"); - const mockedGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue("pnpm" as getPackageManager.PackageManager); - - // get the command - const upgradeCommand = getTurboUpgradeCommand({ - directory: root, - }); - - expect(upgradeCommand).toEqual(undefined); - - mockedExec.mockRestore(); - mockedGetPackageManager.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - }); -}); diff --git a/packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts b/packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts deleted file mode 100644 index fbc5d8d..0000000 --- a/packages/turbo-codemod/__tests__/migrate-env-var-dependencies.test.ts +++ /dev/null @@ -1,758 +0,0 @@ -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' - ); - }); - }); -}); diff --git a/packages/turbo-codemod/__tests__/migrate.test.ts b/packages/turbo-codemod/__tests__/migrate.test.ts deleted file mode 100644 index 652ea41..0000000 --- a/packages/turbo-codemod/__tests__/migrate.test.ts +++ /dev/null @@ -1,761 +0,0 @@ -import { MigrateCommandArgument } from "../src/commands"; -import migrate from "../src/commands/migrate"; -import { setupTestFixtures, spyExit } from "@turbo/test-utils"; -import childProcess from "child_process"; -import * as checkGitStatus from "../src/utils/checkGitStatus"; -import * as getCurrentVersion from "../src/commands/migrate/steps/getCurrentVersion"; -import * as getLatestVersion from "../src/commands/migrate/steps/getLatestVersion"; -import * as getTurboUpgradeCommand from "../src/commands/migrate/steps/getTurboUpgradeCommand"; -import * as workspaceImplementation from "../src/utils/getPackageManager"; -import * as getPackageManagerVersion from "../src/utils/getPackageManagerVersion"; - -describe("migrate", () => { - const mockExit = spyExit(); - const { useFixture } = setupTestFixtures({ - directory: __dirname, - test: "migrate", - }); - - it("migrates from 1.0.0 to 1.7.0", async () => { - const { root, readJson } = useFixture({ - fixture: "old-turbo", - }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue("1.0.0"); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockResolvedValue("1.7.0"); - const mockedGetTurboUpgradeCommand = jest - .spyOn(getTurboUpgradeCommand, "default") - .mockReturnValue("pnpm install -g turbo@latest"); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockedGetWorkspaceImplementation = jest - .spyOn(workspaceImplementation, "default") - .mockReturnValue(packageManager); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: false, - }); - - expect(readJson("package.json")).toStrictEqual({ - dependencies: {}, - devDependencies: { - turbo: "1.0.0", - }, - name: "no-turbo-json", - packageManager: "pnpm@1.2.3", - version: "1.0.0", - }); - expect(readJson("turbo.json")).toStrictEqual({ - $schema: "https://turbo.build/schema.json", - pipeline: { - build: { - outputs: [".next/**", "!.next/cache/**"], - }, - dev: { - cache: false, - }, - lint: {}, - test: { - outputs: ["dist/**", "build/**"], - }, - }, - }); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - expect(mockedGetTurboUpgradeCommand).toHaveBeenCalled(); - expect(mockedGetPackageManagerVersion).toHaveBeenCalled(); - expect(mockedGetWorkspaceImplementation).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - mockedGetLatestVersion.mockRestore(); - mockedGetTurboUpgradeCommand.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - mockedGetWorkspaceImplementation.mockRestore(); - }); - - it("migrates from 1.0.0 to 1.2.0 (dry run)", async () => { - const { root, readJson } = useFixture({ - fixture: "old-turbo", - }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue("1.0.0"); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockResolvedValue("1.2.0"); - const mockedGetTurboUpgradeCommand = jest - .spyOn(getTurboUpgradeCommand, "default") - .mockReturnValue("pnpm install -g turbo@latest"); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockedGetWorkspaceImplementation = jest - .spyOn(workspaceImplementation, "default") - .mockReturnValue(packageManager); - - const packageJson = readJson("package.json"); - const turboJson = readJson("turbo.json"); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: true, - print: false, - install: true, - }); - - // make sure nothing changed - expect(readJson("package.json")).toStrictEqual(packageJson); - expect(readJson("turbo.json")).toStrictEqual(turboJson); - - // verify mocks were called - expect(mockedCheckGitStatus).not.toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - expect(mockedGetTurboUpgradeCommand).toHaveBeenCalled(); - expect(mockedGetPackageManagerVersion).toHaveBeenCalled(); - expect(mockedGetWorkspaceImplementation).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - mockedGetLatestVersion.mockRestore(); - mockedGetTurboUpgradeCommand.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - mockedGetWorkspaceImplementation.mockRestore(); - }); - - it("next version can be passed as an option", async () => { - const { root, readJson } = useFixture({ - fixture: "old-turbo", - }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue("1.0.0"); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockResolvedValue("1.7.0"); - const mockedGetTurboUpgradeCommand = jest - .spyOn(getTurboUpgradeCommand, "default") - .mockReturnValue("pnpm install -g turbo@latest"); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockedGetWorkspaceImplementation = jest - .spyOn(workspaceImplementation, "default") - .mockReturnValue(packageManager); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: false, - to: "1.7.0", - }); - - expect(readJson("package.json")).toStrictEqual({ - dependencies: {}, - devDependencies: { - turbo: "1.0.0", - }, - name: "no-turbo-json", - packageManager: "pnpm@1.2.3", - version: "1.0.0", - }); - expect(readJson("turbo.json")).toStrictEqual({ - $schema: "https://turbo.build/schema.json", - pipeline: { - build: { - outputs: [".next/**", "!.next/cache/**"], - }, - dev: { - cache: false, - }, - test: { - outputs: ["dist/**", "build/**"], - }, - lint: {}, - }, - }); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - expect(mockedGetTurboUpgradeCommand).toHaveBeenCalled(); - expect(mockedGetPackageManagerVersion).toHaveBeenCalled(); - expect(mockedGetWorkspaceImplementation).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - mockedGetLatestVersion.mockRestore(); - mockedGetTurboUpgradeCommand.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - mockedGetWorkspaceImplementation.mockRestore(); - }); - - it("current version can be passed as an option", async () => { - const { root, readJson } = useFixture({ - fixture: "old-turbo", - }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockResolvedValue("1.7.0"); - const mockedGetTurboUpgradeCommand = jest - .spyOn(getTurboUpgradeCommand, "default") - .mockReturnValue("pnpm install -g turbo@latest"); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - - const mockedGetWorkspaceImplementation = jest - .spyOn(workspaceImplementation, "default") - .mockReturnValue(packageManager); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: false, - from: "1.0.0", - }); - - expect(readJson("package.json")).toStrictEqual({ - dependencies: {}, - devDependencies: { - turbo: "1.0.0", - }, - name: "no-turbo-json", - packageManager: "pnpm@1.2.3", - version: "1.0.0", - }); - expect(readJson("turbo.json")).toStrictEqual({ - $schema: "https://turbo.build/schema.json", - pipeline: { - build: { - outputs: [".next/**", "!.next/cache/**"], - }, - dev: { - cache: false, - }, - lint: {}, - test: { - outputs: ["dist/**", "build/**"], - }, - }, - }); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - expect(mockedGetTurboUpgradeCommand).toHaveBeenCalled(); - expect(mockedGetPackageManagerVersion).toHaveBeenCalled(); - expect(mockedGetWorkspaceImplementation).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetLatestVersion.mockRestore(); - mockedGetTurboUpgradeCommand.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - mockedGetWorkspaceImplementation.mockRestore(); - }); - - it("exits if the current version is the same as the new version", async () => { - const { root } = useFixture({ - fixture: "old-turbo", - }); - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue("1.7.0"); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockResolvedValue("1.7.0"); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: false, - }); - - expect(mockExit.exit).toHaveBeenCalledWith(0); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - mockedGetLatestVersion.mockRestore(); - }); - - it("continues when migration doesn't require codemods", async () => { - const { root } = useFixture({ - fixture: "old-turbo", - }); - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue("1.3.0"); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockResolvedValue("1.3.1"); - const mockedGetTurboUpgradeCommand = jest - .spyOn(getTurboUpgradeCommand, "default") - .mockReturnValue("npm install turbo@1.3.1"); - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockReturnValue("installed"); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: true, - }); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - expect(mockedGetTurboUpgradeCommand).toHaveBeenCalled(); - expect(mockExecSync).toHaveBeenCalledWith("npm install turbo@1.3.1", { - cwd: root, - }); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - mockedGetLatestVersion.mockRestore(); - mockedGetTurboUpgradeCommand.mockRestore(); - mockExecSync.mockRestore(); - }); - - it("installs the correct turbo version", async () => { - const { root, readJson } = useFixture({ - fixture: "old-turbo", - }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue("1.0.0"); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockResolvedValue("1.7.0"); - const mockedGetTurboUpgradeCommand = jest - .spyOn(getTurboUpgradeCommand, "default") - .mockReturnValue("pnpm install -g turbo@1.7.0"); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockedGetWorkspaceImplementation = jest - .spyOn(workspaceImplementation, "default") - .mockReturnValue(packageManager); - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockReturnValue("installed"); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: true, - }); - - expect(readJson("package.json")).toStrictEqual({ - dependencies: {}, - devDependencies: { - turbo: "1.0.0", - }, - name: "no-turbo-json", - packageManager: "pnpm@1.2.3", - version: "1.0.0", - }); - expect(readJson("turbo.json")).toStrictEqual({ - $schema: "https://turbo.build/schema.json", - pipeline: { - build: { - outputs: [".next/**", "!.next/cache/**"], - }, - dev: { - cache: false, - }, - lint: {}, - test: { - outputs: ["dist/**", "build/**"], - }, - }, - }); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - expect(mockedGetTurboUpgradeCommand).toHaveBeenCalled(); - expect(mockedGetPackageManagerVersion).toHaveBeenCalled(); - expect(mockedGetWorkspaceImplementation).toHaveBeenCalled(); - expect(mockExecSync).toHaveBeenCalled(); - expect(mockExecSync).toHaveBeenCalledWith("pnpm install -g turbo@1.7.0", { - cwd: root, - }); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - mockedGetLatestVersion.mockRestore(); - mockedGetTurboUpgradeCommand.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - mockedGetWorkspaceImplementation.mockRestore(); - mockExecSync.mockRestore(); - }); - - it("fails gracefully when the correct upgrade command cannot be found", async () => { - const { root, readJson } = useFixture({ - fixture: "old-turbo", - }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue("1.0.0"); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockResolvedValue("1.7.0"); - const mockedGetTurboUpgradeCommand = jest - .spyOn(getTurboUpgradeCommand, "default") - .mockReturnValue(undefined); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockedGetWorkspaceImplementation = jest - .spyOn(workspaceImplementation, "default") - .mockReturnValue(packageManager); - const mockExecSync = jest - .spyOn(childProcess, "execSync") - .mockReturnValue("installed"); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: true, - }); - - expect(readJson("package.json")).toStrictEqual({ - dependencies: {}, - devDependencies: { - turbo: "1.0.0", - }, - name: "no-turbo-json", - packageManager: "pnpm@1.2.3", - version: "1.0.0", - }); - expect(readJson("turbo.json")).toStrictEqual({ - $schema: "https://turbo.build/schema.json", - pipeline: { - build: { - outputs: [".next/**", "!.next/cache/**"], - }, - dev: { - cache: false, - }, - lint: {}, - test: { - outputs: ["dist/**", "build/**"], - }, - }, - }); - - expect(mockExit.exit).toHaveBeenCalledWith(1); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - expect(mockedGetTurboUpgradeCommand).toHaveBeenCalled(); - expect(mockedGetPackageManagerVersion).toHaveBeenCalled(); - expect(mockedGetWorkspaceImplementation).toHaveBeenCalled(); - expect(mockExecSync).not.toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - mockedGetLatestVersion.mockRestore(); - mockedGetTurboUpgradeCommand.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - mockedGetWorkspaceImplementation.mockRestore(); - mockExecSync.mockRestore(); - }); - - it("exits if current version is not passed and cannot be inferred", async () => { - const { root } = useFixture({ - fixture: "old-turbo", - }); - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue(undefined); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: false, - }); - - expect(mockExit.exit).toHaveBeenCalledWith(1); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - }); - - it("exits if latest version is not passed and cannot be inferred", async () => { - const { root } = useFixture({ - fixture: "old-turbo", - }); - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue("1.5.0"); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockResolvedValue(undefined); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: false, - }); - - expect(mockExit.exit).toHaveBeenCalledWith(1); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - mockedGetLatestVersion.mockRestore(); - }); - - it("exits if latest version throws", async () => { - const { root } = useFixture({ - fixture: "old-turbo", - }); - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue("1.5.0"); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockRejectedValue(new Error("failed to fetch version")); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: false, - }); - - expect(mockExit.exit).toHaveBeenCalledWith(1); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - mockedGetLatestVersion.mockRestore(); - }); - - it("exits if any transforms encounter an error", async () => { - const { root } = useFixture({ - fixture: "old-turbo", - }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetCurrentVersion = jest - .spyOn(getCurrentVersion, "default") - .mockReturnValue("1.0.0"); - const mockedGetLatestVersion = jest - .spyOn(getLatestVersion, "default") - .mockResolvedValue("1.7.0"); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockedGetWorkspaceImplementation = jest - .spyOn(workspaceImplementation, "default") - .mockReturnValue(packageManager); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: true, - print: false, - install: true, - }); - - expect(mockExit.exit).toHaveBeenCalledWith(1); - - // verify mocks were called - expect(mockedCheckGitStatus).not.toHaveBeenCalled(); - expect(mockedGetCurrentVersion).toHaveBeenCalled(); - expect(mockedGetLatestVersion).toHaveBeenCalled(); - expect(mockedGetPackageManagerVersion).toHaveBeenCalled(); - expect(mockedGetWorkspaceImplementation).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetCurrentVersion.mockRestore(); - mockedGetLatestVersion.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - mockedGetWorkspaceImplementation.mockRestore(); - }); - - it("exits if invalid directory is passed", async () => { - const { root } = useFixture({ - fixture: "old-turbo", - }); - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - - await migrate("~/path/that/does/not/exist" as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: false, - }); - - expect(mockExit.exit).toHaveBeenCalledWith(1); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - }); - - it("exits if directory with no repo is passed", async () => { - const { root } = useFixture({ - fixture: "no-repo", - }); - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - - await migrate(root as MigrateCommandArgument, { - force: false, - dry: false, - print: false, - install: false, - }); - - expect(mockExit.exit).toHaveBeenCalledWith(1); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - }); -}); diff --git a/packages/turbo-codemod/__tests__/set-default-outputs.test.ts b/packages/turbo-codemod/__tests__/set-default-outputs.test.ts deleted file mode 100644 index 4a71fa7..0000000 --- a/packages/turbo-codemod/__tests__/set-default-outputs.test.ts +++ /dev/null @@ -1,391 +0,0 @@ -import { transformer } from "../src/transforms/set-default-outputs"; -import { setupTestFixtures } from "@turbo/test-utils"; - -describe("set-default-outputs", () => { - const { useFixture } = setupTestFixtures({ - directory: __dirname, - test: "set-default-outputs", - }); - it("migrates turbo.json outputs - basic", async () => { - // load the fixture for the test - const { root, read } = useFixture({ - fixture: "old-outputs", - }); - - // 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", - pipeline: { - "build-one": { - outputs: ["foo"], - }, - "build-two": {}, - "build-three": { - outputs: ["dist/**", "build/**"], - }, - }, - }); - - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "turbo.json": Object { - "action": "modified", - "additions": 2, - "deletions": 1, - }, - } - `); - }); - - it("migrates turbo.json outputs - 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", - pipeline: { - "build-one": { - outputs: ["foo"], - }, - "build-two": {}, - "build-three": { - outputs: ["dist/**", "build/**"], - }, - }, - }); - - expect(readJson("apps/docs/turbo.json") || "{}").toStrictEqual({ - $schema: "https://turbo.build/schema.json", - extends: ["//"], - pipeline: { - build: { - outputs: ["dist/**", "build/**"], - }, - }, - }); - - expect(readJson("apps/web/turbo.json") || "{}").toStrictEqual({ - $schema: "https://turbo.build/schema.json", - extends: ["//"], - pipeline: { - build: {}, - }, - }); - - expect(readJson("packages/ui/turbo.json") || "{}").toStrictEqual({ - $schema: "https://turbo.build/schema.json", - extends: ["//"], - pipeline: { - "build-three": { - outputs: ["dist/**", "build/**"], - }, - }, - }); - - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "apps/docs/turbo.json": Object { - "action": "modified", - "additions": 1, - "deletions": 1, - }, - "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": 2, - "deletions": 1, - }, - } - `); - }); - - it("migrates turbo.json outputs - dry", async () => { - // load the fixture for the test - const { root, read } = useFixture({ - fixture: "old-outputs", - }); - - 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": 2, - "deletions": 1, - }, - } - `); - }); - - it("migrates turbo.json outputs - print", async () => { - // load the fixture for the test - const { root, read } = useFixture({ - fixture: "old-outputs", - }); - - // 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", - pipeline: { - "build-one": { - outputs: ["foo"], - }, - "build-two": {}, - "build-three": { - outputs: ["dist/**", "build/**"], - }, - }, - }); - - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "turbo.json": Object { - "action": "modified", - "additions": 2, - "deletions": 1, - }, - } - `); - }); - - it("migrates turbo.json outputs - dry & print", async () => { - // load the fixture for the test - const { root, read } = useFixture({ - fixture: "old-outputs", - }); - - 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": 2, - "deletions": 1, - }, - } - `); - }); - - it("migrates turbo.json outputs - invalid", async () => { - // load the fixture for the test - const { root, read } = useFixture({ - fixture: "invalid-outputs", - }); - - // 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", - pipeline: { - "build-one": { - outputs: ["foo"], - }, - "build-two": {}, - "build-three": { - outputs: ["dist/**", "build/**"], - }, - "garbage-in-numeric-0": { - outputs: ["dist/**", "build/**"], - }, - "garbage-in-numeric": { - outputs: 42, - }, - "garbage-in-string": { - outputs: "string", - }, - "garbage-in-empty-string": { - outputs: ["dist/**", "build/**"], - }, - "garbage-in-null": { - outputs: ["dist/**", "build/**"], - }, - "garbage-in-false": { - outputs: ["dist/**", "build/**"], - }, - "garbage-in-true": { - outputs: true, - }, - "garbage-in-object": { - outputs: {}, - }, - }, - }); - - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "turbo.json": Object { - "action": "modified", - "additions": 6, - "deletions": 5, - }, - } - `); - }); - - it("migrates turbo.json outputs - config with no pipeline", async () => { - // load the fixture for the test - const { root, read } = useFixture({ - fixture: "no-pipeline", - }); - - // 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: ["$NEXT_PUBLIC_API_KEY", "$STRIPE_API_KEY", ".env"], - pipeline: {}, - }); - - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "turbo.json": Object { - "action": "unchanged", - "additions": 0, - "deletions": 0, - }, - } - `); - }); - - it("migrates turbo.json outputs - config with no outputs", async () => { - // load the fixture for the test - const { root, read } = useFixture({ - fixture: "no-outputs", - }); - - // 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", - pipeline: { - "build-one": { - dependsOn: ["build-two"], - outputs: ["dist/**", "build/**"], - }, - "build-two": { - cache: false, - }, - "build-three": { - persistent: true, - outputs: ["dist/**", "build/**"], - }, - }, - }); - - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(` - Object { - "turbo.json": Object { - "action": "modified", - "additions": 2, - "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' - ); - }); -}); diff --git a/packages/turbo-codemod/__tests__/transform.test.ts b/packages/turbo-codemod/__tests__/transform.test.ts deleted file mode 100644 index abd015d..0000000 --- a/packages/turbo-codemod/__tests__/transform.test.ts +++ /dev/null @@ -1,172 +0,0 @@ -import transform from "../src/commands/transform"; -import { MigrateCommandArgument } from "../src/commands"; -import { setupTestFixtures, spyExit } from "@turbo/test-utils"; -import * as checkGitStatus from "../src/utils/checkGitStatus"; -import * as getPackageManager from "../src/utils/getPackageManager"; -import * as getPackageManagerVersion from "../src/utils/getPackageManagerVersion"; - -describe("transform", () => { - const mockExit = spyExit(); - const { useFixture } = setupTestFixtures({ - directory: __dirname, - test: "transform", - }); - - it("runs the selected transform", async () => { - const { root, readJson } = useFixture({ - fixture: "basic", - }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockedGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager); - - await transform( - "add-package-manager" as MigrateCommandArgument, - root as MigrateCommandArgument, - { - list: false, - force: false, - dry: false, - print: false, - } - ); - - expect(readJson("package.json")).toStrictEqual({ - dependencies: {}, - devDependencies: { - turbo: "1.0.0", - }, - name: "transform-basic", - packageManager: "pnpm@1.2.3", - version: "1.0.0", - }); - - // verify mocks were called - expect(mockedCheckGitStatus).toHaveBeenCalled(); - expect(mockedGetPackageManagerVersion).toHaveBeenCalled(); - expect(mockedGetPackageManager).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - mockedGetPackageManager.mockRestore(); - }); - - it("runs the selected transform - dry & print", async () => { - const { root, readJson } = useFixture({ - fixture: "basic", - }); - - const packageManager = "pnpm"; - const packageManagerVersion = "1.2.3"; - - // setup mocks - const mockedCheckGitStatus = jest - .spyOn(checkGitStatus, "default") - .mockReturnValue(undefined); - const mockedGetPackageManagerVersion = jest - .spyOn(getPackageManagerVersion, "default") - .mockReturnValue(packageManagerVersion); - const mockedGetPackageManager = jest - .spyOn(getPackageManager, "default") - .mockReturnValue(packageManager); - - await transform( - "add-package-manager" as MigrateCommandArgument, - root as MigrateCommandArgument, - { - list: false, - force: false, - dry: true, - print: true, - } - ); - - expect(readJson("package.json")).toStrictEqual({ - dependencies: {}, - devDependencies: { - turbo: "1.0.0", - }, - name: "transform-basic", - version: "1.0.0", - }); - - // verify mocks were called - expect(mockedCheckGitStatus).not.toHaveBeenCalled(); - expect(mockedGetPackageManagerVersion).toHaveBeenCalled(); - expect(mockedGetPackageManager).toHaveBeenCalled(); - - // restore mocks - mockedCheckGitStatus.mockRestore(); - mockedGetPackageManagerVersion.mockRestore(); - mockedGetPackageManager.mockRestore(); - }); - - it("lists transforms", async () => { - const { root } = useFixture({ - fixture: "basic", - }); - - await transform( - "add-package-manager" as MigrateCommandArgument, - root as MigrateCommandArgument, - { - list: true, - force: false, - dry: false, - print: false, - } - ); - - expect(mockExit.exit).toHaveBeenCalledWith(0); - }); - - it("exits on invalid transform", async () => { - const { root } = useFixture({ - fixture: "basic", - }); - - await transform( - "not-a-real-option" as MigrateCommandArgument, - root as MigrateCommandArgument, - { - list: false, - force: false, - dry: false, - print: false, - } - ); - - expect(mockExit.exit).toHaveBeenCalledWith(1); - }); - - it("exits on invalid directory", async () => { - const { root } = useFixture({ - fixture: "basic", - }); - - await transform( - "add-package-manager" as MigrateCommandArgument, - "~/path/that/does/not/exist" as MigrateCommandArgument, - { - list: false, - force: false, - dry: false, - print: false, - } - ); - - expect(mockExit.exit).toHaveBeenCalledWith(1); - }); -}); diff --git a/packages/turbo-codemod/index.d.ts b/packages/turbo-codemod/index.d.ts deleted file mode 100644 index c3a4874..0000000 --- a/packages/turbo-codemod/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module "is-git-clean"; diff --git a/packages/turbo-codemod/jest.config.js b/packages/turbo-codemod/jest.config.js deleted file mode 100644 index 2c7542a..0000000 --- a/packages/turbo-codemod/jest.config.js +++ /dev/null @@ -1,18 +0,0 @@ -/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ -module.exports = { - preset: "ts-jest/presets/js-with-ts", - testEnvironment: "node", - transformIgnorePatterns: ["/node_modules/(?!(ansi-regex)/)"], - modulePathIgnorePatterns: ["/node_modules", "/dist"], - testPathIgnorePatterns: ["/__fixtures__/"], - coveragePathIgnorePatterns: ["/__fixtures__/"], - collectCoverage: true, - coverageThreshold: { - global: { - branches: 80, - functions: 89, - lines: 89, - statements: 89, - }, - }, -}; diff --git a/packages/turbo-codemod/package.json b/packages/turbo-codemod/package.json deleted file mode 100644 index d16bb05..0000000 --- a/packages/turbo-codemod/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "@turbo/codemod", - "version": "1.9.4-canary.2", - "description": "Provides Codemod transformations to help upgrade your Turborepo codebase when a feature is deprecated.", - "homepage": "https://turbo.build/repo", - "license": "MPL-2.0", - "repository": { - "type": "git", - "url": "https://github.com/vercel/turbo", - "directory": "packages/turbo-codemod" - }, - "bugs": { - "url": "https://github.com/vercel/turbo/issues" - }, - "bin": "dist/cli.js", - "scripts": { - "build": "tsup", - "test": "jest", - "lint": "eslint src/**/*.ts", - "check-types": "tsc --noEmit", - "add-transformer": "plop" - }, - "dependencies": { - "axios": "0.27.2", - "chalk": "2.4.2", - "commander": "^9.5.0", - "diff": "^5.1.0", - "find-up": "4.1.0", - "fs-extra": "^10.0.0", - "gradient-string": "^2.0.0", - "inquirer": "^8.2.4", - "inquirer-file-tree-selection-prompt": "^1.0.19", - "is-git-clean": "^1.1.0", - "ora": "4.1.1", - "semver": "^7.3.7", - "update-check": "^1.5.4" - }, - "devDependencies": { - "@types/chalk-animation": "^1.6.0", - "@types/diff": "^5.0.2", - "@types/fs-extra": "^9.0.13", - "@types/gradient-string": "^1.1.2", - "@types/inquirer": "^8.2.0", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.12", - "@types/semver": "^7.3.9", - "@types/uuid": "^9.0.0", - "deepmerge": "^4.2.2", - "eslint": "^7.23.0", - "jest": "^27.4.3", - "plop": "^3.1.1", - "semver": "^7.3.5", - "ts-jest": "^27.1.1", - "@turbo/tsconfig": "workspace:*", - "tsup": "^5.10.3", - "@turbo/test-utils": "workspace:*", - "@turbo/types": "workspace:*", - "@turbo/utils": "workspace:*", - "typescript": "^4.5.5" - }, - "files": [ - "dist" - ], - "publishConfig": { - "access": "public" - } -} diff --git a/packages/turbo-codemod/plopfile.js b/packages/turbo-codemod/plopfile.js deleted file mode 100644 index 9cc2dd7..0000000 --- a/packages/turbo-codemod/plopfile.js +++ /dev/null @@ -1,46 +0,0 @@ -const fs = require("fs-extra"); - -module.exports = function plopConfig(plop) { - // controller generator - plop.setGenerator("controller", { - description: "Add a new transformer", - prompts: [ - { - type: "input", - name: "name", - message: 'key for the transform (example: "create-turbo-config")', - }, - { - type: "input", - name: "description", - message: - 'description for the transform (example: "Create the `turbo.json` file from an existing "turbo" key in `package.json`")', - }, - { - type: "input", - name: "introducedIn", - message: - 'the semantic version of turbo where this change was introduced (example: "1.1.0")', - }, - ], - actions: [ - { - type: "add", - path: "src/transforms/{{name}}.ts", - templateFile: "templates/transformer.hbs", - }, - { - type: "add", - path: "__tests__/{{name}}.test.ts", - templateFile: "templates/transformer.test.hbs", - }, - function createFixturesDirectory(answers) { - process.chdir(plop.getPlopfilePath()); - const directory = `__tests__/__fixtures__/${answers.name}`; - fs.mkdirSync(`__tests__/__fixtures__/${answers.name}`); - - return `created empty ${directory} directory for fixtures`; - }, - ], - }); -}; diff --git a/packages/turbo-codemod/src/cli.ts b/packages/turbo-codemod/src/cli.ts deleted file mode 100644 index 451816f..0000000 --- a/packages/turbo-codemod/src/cli.ts +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env node - -import chalk from "chalk"; -import { Command } from "commander"; - -import { transform, migrate } from "./commands"; -import notifyUpdate from "./utils/notifyUpdate"; -import cliPkg from "../package.json"; - -const codemodCli = new Command(); - -codemodCli - .name("@turbo/codemod") - .description( - "Codemod transformations to help upgrade your Turborepo codebase when a feature is deprecated." - ) - .version(cliPkg.version, "-v, --version", "output the current version"); - -// migrate -codemodCli - .command("migrate") - .aliases(["update", "upgrade"]) - .description("Migrate a project to the latest version of Turborepo") - .argument("[path]", "Directory where the transforms should be applied") - .option( - "--from ", - "Specify the version to migrate from (default: current version)" - ) - .option( - "--to ", - "Specify the version to migrate to (default: latest)" - ) - .option("--install", "Install new version of turbo after migration", true) - .option( - "--force", - "Bypass Git safety checks and forcibly run codemods", - false - ) - .option("--dry", "Dry run (no changes are made to files)", false) - .option("--print", "Print transformed files to your terminal", false) - .action(migrate); - -// transform -codemodCli - .command("transform", { isDefault: true }) - .description("Apply a single code transformation to a project") - .argument("[transform]", "The transformer to run") - .argument("[path]", "Directory where the transforms should be applied") - .option( - "--force", - "Bypass Git safety checks and forcibly run codemods", - false - ) - .option("--list", "List all available transforms", false) - .option("--dry", "Dry run (no changes are made to files)", false) - .option("--print", "Print transformed files to your terminal", false) - .action(transform); - -codemodCli - .parseAsync() - .then(notifyUpdate) - .catch(async (reason) => { - console.log(); - if (reason.command) { - console.log(` ${chalk.cyan(reason.command)} has failed.`); - } else { - console.log(chalk.red("Unexpected error. Please report it as a bug:")); - console.log(reason); - } - console.log(); - await notifyUpdate(); - process.exit(1); - }); diff --git a/packages/turbo-codemod/src/commands/index.ts b/packages/turbo-codemod/src/commands/index.ts deleted file mode 100644 index a7aeee6..0000000 --- a/packages/turbo-codemod/src/commands/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -export { default as migrate } from "./migrate"; -export { default as transform } from "./transform"; - -export type { - TransformCommandArgument, - TransformCommandOptions, -} from "./transform/types"; -export type { - MigrateCommandArgument, - MigrateCommandOptions, -} from "./migrate/types"; diff --git a/packages/turbo-codemod/src/commands/migrate/index.ts b/packages/turbo-codemod/src/commands/migrate/index.ts deleted file mode 100644 index c4c6d02..0000000 --- a/packages/turbo-codemod/src/commands/migrate/index.ts +++ /dev/null @@ -1,215 +0,0 @@ -import chalk from "chalk"; -import os from "os"; -import inquirer from "inquirer"; -import { execSync } from "child_process"; - -import getCurrentVersion from "./steps/getCurrentVersion"; -import getLatestVersion from "./steps/getLatestVersion"; -import getCodemodsForMigration from "./steps/getTransformsForMigration"; -import checkGitStatus from "../../utils/checkGitStatus"; -import directoryInfo from "../../utils/directoryInfo"; -import getTurboUpgradeCommand from "./steps/getTurboUpgradeCommand"; -import Runner from "../../runner/Runner"; -import type { MigrateCommandArgument, MigrateCommandOptions } from "./types"; -import looksLikeRepo from "../../utils/looksLikeRepo"; - -function endMigration({ - message, - success, -}: { - message?: string; - success: boolean; -}) { - if (success) { - console.log(chalk.bold(chalk.green("Migration completed"))); - if (message) { - console.log(message); - } - return process.exit(0); - } - - console.log(chalk.bold(chalk.red("Migration failed"))); - if (message) { - console.log(message); - } - return process.exit(1); -} - -/** -Migration is done in 4 steps: - -- gather information - 1. find the version (x) of turbo to migrate from (if not specified) - 2. find the version (y) of turbo to migrate to (if not specified) - 3. determine which codemods need to be run to move from version x to version y - -- action - 4. execute the codemods (serially, and in order) - 5. update the turbo version (optionally) -**/ -export default async function migrate( - directory: MigrateCommandArgument, - options: MigrateCommandOptions -) { - // check git status - if (!options.dry) { - checkGitStatus({ directory, force: options.force }); - } - - const answers = await inquirer.prompt<{ - directoryInput?: string; - }>([ - { - type: "input", - name: "directoryInput", - message: "Where is the root of the repo to migrate?", - when: !directory, - default: ".", - validate: (directory: string) => { - const { exists, absolute } = directoryInfo({ directory }); - if (exists) { - return true; - } else { - return `Directory ${chalk.dim(`(${absolute})`)} does not exist`; - } - }, - filter: (directory: string) => directory.trim(), - }, - ]); - - const { directoryInput: selectedDirectory = directory as string } = answers; - const { exists, absolute: root } = directoryInfo({ - directory: selectedDirectory, - }); - if (!exists) { - return endMigration({ - success: false, - message: `Directory ${chalk.dim(`(${root})`)} does not exist`, - }); - } - - if (!looksLikeRepo({ directory: root })) { - return endMigration({ - success: false, - message: `Directory (${chalk.dim( - root - )}) does not appear to be a repository`, - }); - } - - // step 1 - const fromVersion = getCurrentVersion(selectedDirectory, options); - if (!fromVersion) { - return endMigration({ - success: false, - message: `Unable to infer the version of turbo being used by ${directory}`, - }); - } - - // step 2 - let toVersion = options.to; - try { - toVersion = await getLatestVersion(options); - } catch (err) { - let message = "UNKNOWN_ERROR"; - if (err instanceof Error) { - message = err.message; - } - return endMigration({ - success: false, - message, - }); - } - - if (!toVersion) { - return endMigration({ - success: false, - message: `Unable to fetch the latest version of turbo`, - }); - } - - if (fromVersion === toVersion) { - return endMigration({ - success: true, - message: `Nothing to do, current version (${chalk.bold( - fromVersion - )}) is the same as the requested version (${chalk.bold(toVersion)})`, - }); - } - - // step 3 - const codemods = getCodemodsForMigration({ fromVersion, toVersion }); - if (codemods.length === 0) { - console.log( - `No codemods required to migrate from ${fromVersion} to ${toVersion}`, - os.EOL - ); - } - - // step 4 - console.log( - `Upgrading turbo from ${chalk.bold(fromVersion)} to ${chalk.bold( - toVersion - )} (${ - codemods.length === 0 - ? "no codemods required" - : `${codemods.length} required codemod${ - codemods.length === 1 ? "" : "s" - }` - })`, - os.EOL - ); - const results = codemods.map((codemod, idx) => { - console.log( - `(${idx + 1}/${codemods.length}) ${chalk.bold( - `Running ${codemod.value}` - )}` - ); - - const result = codemod.transformer({ root: selectedDirectory, options }); - Runner.logResults(result); - return result; - }); - - const hasTransformError = results.some( - (result) => - result.fatalError || - Object.keys(result.changes).some((key) => result.changes[key].error) - ); - - if (hasTransformError) { - return endMigration({ - success: false, - message: `Could not complete migration due to codemod errors. Please fix the errors and try again.`, - }); - } - - // step 5 - const upgradeCommand = getTurboUpgradeCommand({ - directory: selectedDirectory, - to: options.to, - }); - - if (!upgradeCommand) { - return endMigration({ - success: false, - message: "Unable to determine upgrade command", - }); - } - - if (options.install) { - if (options.dry) { - console.log( - `Upgrading turbo with ${chalk.bold(upgradeCommand)} ${chalk.dim( - "(dry run)" - )}`, - os.EOL - ); - } else { - console.log(`Upgrading turbo with ${chalk.bold(upgradeCommand)}`, os.EOL); - execSync(upgradeCommand, { cwd: selectedDirectory }); - } - } else { - console.log(`Upgrade turbo with ${chalk.bold(upgradeCommand)}`, os.EOL); - } - - endMigration({ success: true }); -} diff --git a/packages/turbo-codemod/src/commands/migrate/steps/getCurrentVersion.ts b/packages/turbo-codemod/src/commands/migrate/steps/getCurrentVersion.ts deleted file mode 100644 index 3644f8b..0000000 --- a/packages/turbo-codemod/src/commands/migrate/steps/getCurrentVersion.ts +++ /dev/null @@ -1,45 +0,0 @@ -import path from "path"; -import { existsSync } from "fs-extra"; - -import getPackageManager from "../../../utils/getPackageManager"; -import { exec } from "../utils"; -import type { MigrateCommandOptions } from "../types"; - -function getCurrentVersion( - directory: string, - opts: MigrateCommandOptions -): string | undefined { - const { from } = opts; - if (from) { - return from; - } - - // try global first - const turboVersionFromGlobal = exec(`turbo --version`, { cwd: directory }); - - if (turboVersionFromGlobal) { - return turboVersionFromGlobal; - } - - // try to use the package manager to find the version - const packageManager = getPackageManager({ directory }); - if (packageManager) { - if (packageManager === "yarn") { - return exec(`yarn turbo --version`, { cwd: directory }); - } - if (packageManager === "pnpm") { - return exec(`pnpm turbo --version`, { cwd: directory }); - } else { - // this doesn't work for npm, so manually build the binary path - const turboBin = path.join(directory, "node_modules", ".bin", "turbo"); - if (existsSync(turboBin)) { - return exec(`${turboBin} --version`, { cwd: directory }); - } - } - } - - // unable to determine local version, - return undefined; -} - -export default getCurrentVersion; diff --git a/packages/turbo-codemod/src/commands/migrate/steps/getLatestVersion.ts b/packages/turbo-codemod/src/commands/migrate/steps/getLatestVersion.ts deleted file mode 100644 index a6ab7e6..0000000 --- a/packages/turbo-codemod/src/commands/migrate/steps/getLatestVersion.ts +++ /dev/null @@ -1,31 +0,0 @@ -import axios from "axios"; - -import type { MigrateCommandOptions } from "../types"; - -const REGISTRY = "https://registry.npmjs.org"; - -async function getPackageDetails({ packageName }: { packageName: string }) { - try { - const result = await axios.get(`${REGISTRY}/${packageName}`); - return result.data; - } catch (err) { - throw new Error(`Unable to fetch the latest version of ${packageName}`); - } -} - -export default async function getLatestVersion({ - to, -}: MigrateCommandOptions): Promise { - const packageDetails = await getPackageDetails({ packageName: "turbo" }); - const { "dist-tags": tags, versions } = packageDetails; - - if (to) { - if (tags[to] || versions[to]) { - return to; - } else { - throw new Error(`turbo@${to} does not exist`); - } - } - - return tags.latest as string; -} diff --git a/packages/turbo-codemod/src/commands/migrate/steps/getTransformsForMigration.ts b/packages/turbo-codemod/src/commands/migrate/steps/getTransformsForMigration.ts deleted file mode 100644 index 2224c06..0000000 --- a/packages/turbo-codemod/src/commands/migrate/steps/getTransformsForMigration.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { gt, lte } from "semver"; - -import loadTransformers from "../../../utils/loadTransformers"; -import type { Transformer } from "../../../types"; - -/** - Returns all transformers introduced after fromVersion, but before or equal to toVersion -**/ -function getTransformsForMigration({ - fromVersion, - toVersion, -}: { - fromVersion: string; - toVersion: string; -}): Array { - const transforms = loadTransformers(); - return transforms.filter((transformer) => { - return ( - gt(transformer.introducedIn, fromVersion) && - lte(transformer.introducedIn, toVersion) - ); - }); -} - -export default getTransformsForMigration; diff --git a/packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts b/packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts deleted file mode 100644 index 8fd5972..0000000 --- a/packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts +++ /dev/null @@ -1,182 +0,0 @@ -import os from "os"; -import path from "path"; -import fs from "fs-extra"; -import { gte } from "semver"; - -import { exec } from "../utils"; -import getPackageManager, { - PackageManager, -} from "../../../utils/getPackageManager"; -import getPackageManagerVersion from "../../../utils/getPackageManagerVersion"; - -type InstallType = "dependencies" | "devDependencies"; - -function getGlobalBinaryPaths(): Record { - return { - // we run these from a tmpdir to avoid corepack interference - yarn: exec(`yarn global bin`, { cwd: os.tmpdir() }), - npm: exec(`npm bin --global`, { cwd: os.tmpdir() }), - pnpm: exec(`pnpm bin --global`, { cwd: os.tmpdir() }), - }; -} - -function getGlobalUpgradeCommand( - packageManager: PackageManager, - to: string = "latest" -) { - switch (packageManager) { - case "yarn": - return `yarn global add turbo@${to}`; - case "npm": - return `npm install turbo@${to} --global`; - case "pnpm": - return `pnpm install turbo@${to} --global`; - } -} - -function getLocalUpgradeCommand({ - packageManager, - packageManagerVersion, - installType, - isUsingWorkspaces, - to = "latest", -}: { - packageManager: PackageManager; - packageManagerVersion: string; - installType: InstallType; - isUsingWorkspaces?: boolean; - to?: string; -}) { - const renderCommand = ( - command: Array - ): string => command.filter(Boolean).join(" "); - switch (packageManager) { - // yarn command differs depending on the version - case "yarn": - // yarn 2.x and 3.x (berry) - if (gte(packageManagerVersion, "2.0.0")) { - return renderCommand([ - "yarn", - "add", - `turbo@${to}`, - installType === "devDependencies" && "--dev", - ]); - // yarn 1.x - } else { - return renderCommand([ - "yarn", - "add", - `turbo@${to}`, - installType === "devDependencies" && "--dev", - isUsingWorkspaces && "-W", - ]); - } - case "npm": - return renderCommand([ - "npm", - "install", - `turbo@${to}`, - installType === "devDependencies" && "--save-dev", - ]); - case "pnpm": - return renderCommand([ - "pnpm", - "install", - `turbo@${to}`, - installType === "devDependencies" && "--save-dev", - isUsingWorkspaces && "-w", - ]); - } -} - -function getInstallType({ directory }: { directory: string }): { - installType?: InstallType; - isUsingWorkspaces?: boolean; -} { - // read package.json to make sure we have a reference to turbo - const packageJsonPath = path.join(directory, "package.json"); - const pnpmWorkspaceConfig = path.join(directory, "pnpm-workspace.yaml"); - const isPnpmWorkspaces = fs.existsSync(pnpmWorkspaceConfig); - - if (!fs.existsSync(packageJsonPath)) { - console.error(`Unable to find package.json at ${packageJsonPath}`); - return { installType: undefined, isUsingWorkspaces: undefined }; - } - - const packageJson = fs.readJsonSync(packageJsonPath); - const isDevDependency = - packageJson.devDependencies && "turbo" in packageJson.devDependencies; - const isDependency = - packageJson.dependencies && "turbo" in packageJson.dependencies; - let isUsingWorkspaces = "workspaces" in packageJson || isPnpmWorkspaces; - - if (isDependency || isDevDependency) { - return { - installType: isDependency ? "dependencies" : "devDependencies", - isUsingWorkspaces, - }; - } - - return { - installType: undefined, - isUsingWorkspaces, - }; -} - -/** - Finding the correct command to upgrade depends on two things: - 1. The package manager - 2. The install method (local or global) - - We try global first to let turbo handle the inference, then we try local. -**/ -export default function getTurboUpgradeCommand({ - directory, - to, -}: { - directory: string; - to?: string; -}) { - const turboBinaryPathFromGlobal = exec(`turbo bin`, { - cwd: directory, - stdio: "pipe", - }); - const packageManagerGlobalBinaryPaths = getGlobalBinaryPaths(); - - const globalPackageManager = Object.keys( - packageManagerGlobalBinaryPaths - ).find((packageManager) => { - const packageManagerBinPath = - packageManagerGlobalBinaryPaths[packageManager as PackageManager]; - if (packageManagerBinPath && turboBinaryPathFromGlobal) { - return turboBinaryPathFromGlobal.includes(packageManagerBinPath); - } - - return false; - }) as PackageManager; - - if (turboBinaryPathFromGlobal && globalPackageManager) { - // figure which package manager we need to upgrade - return getGlobalUpgradeCommand(globalPackageManager, to); - } else { - const packageManager = getPackageManager({ directory }); - // we didn't find a global install, so we'll try to find a local one - const { installType, isUsingWorkspaces } = getInstallType({ directory }); - if (packageManager && installType) { - const packageManagerVersion = getPackageManagerVersion( - packageManager, - directory - ); - - return getLocalUpgradeCommand({ - packageManager, - packageManagerVersion, - installType, - isUsingWorkspaces, - to, - }); - } - } - - return undefined; -} diff --git a/packages/turbo-codemod/src/commands/migrate/types.ts b/packages/turbo-codemod/src/commands/migrate/types.ts deleted file mode 100644 index ae90965..0000000 --- a/packages/turbo-codemod/src/commands/migrate/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { TransformerOptions } from "../../types"; - -export type MigrateCommandArgument = "string" | undefined; - -export interface MigrateCommandOptions extends TransformerOptions { - from?: string; - to?: string; - install: boolean; -} diff --git a/packages/turbo-codemod/src/commands/migrate/utils.ts b/packages/turbo-codemod/src/commands/migrate/utils.ts deleted file mode 100644 index 512d78b..0000000 --- a/packages/turbo-codemod/src/commands/migrate/utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { execSync, ExecSyncOptions } from "child_process"; - -function exec( - command: string, - opts: ExecSyncOptions, - fallback?: string -): string | undefined { - try { - const rawResult = execSync(command, opts); - return rawResult.toString("utf8").trim(); - } catch (err) { - return fallback || undefined; - } -} - -export { exec }; diff --git a/packages/turbo-codemod/src/commands/transform/index.ts b/packages/turbo-codemod/src/commands/transform/index.ts deleted file mode 100644 index e3b86aa..0000000 --- a/packages/turbo-codemod/src/commands/transform/index.ts +++ /dev/null @@ -1,101 +0,0 @@ -import chalk from "chalk"; -import inquirer from "inquirer"; - -import loadTransformers from "../../utils/loadTransformers"; -import checkGitStatus from "../../utils/checkGitStatus"; -import directoryInfo from "../../utils/directoryInfo"; -import type { - TransformCommandOptions, - TransformCommandArgument, -} from "./types"; -import { Runner } from "../../runner"; - -export default async function transform( - transform: TransformCommandArgument, - directory: TransformCommandArgument, - options: TransformCommandOptions -) { - const transforms = loadTransformers(); - if (options.list) { - console.log( - transforms - .map((transform) => `- ${chalk.cyan(transform.value)}`) - .join("\n") - ); - return process.exit(0); - } - - // check git status - if (!options.dry) { - checkGitStatus({ directory, force: options.force }); - } - - const answers = await inquirer.prompt<{ - directoryInput?: string; - transformerInput?: string; - }>([ - { - type: "input", - name: "directoryInput", - message: "Where is the root of the repo where the transform should run?", - when: !directory, - default: ".", - validate: (directory: string) => { - const { exists, absolute } = directoryInfo({ directory }); - if (exists) { - return true; - } else { - return `Directory ${chalk.dim(`(${absolute})`)} does not exist`; - } - }, - filter: (directory: string) => directory.trim(), - }, - { - type: "list", - name: "transformerInput", - message: "Which transform would you like to apply?", - when: !transform, - pageSize: transforms.length, - choices: transforms, - }, - ]); - - const { - directoryInput: selectedDirectory = directory as string, - transformerInput: selectedTransformer = transform as string, - } = answers; - const { exists, absolute: root } = directoryInfo({ - directory: selectedDirectory, - }); - if (!exists) { - console.error(`Directory ${chalk.dim(`(${root})`)} does not exist`); - return process.exit(1); - } - - const transformKeys = transforms.map((transform) => transform.value); - const transformData = transforms.find( - (transform) => transform.value === selectedTransformer - ); - - // validate transforms - if (!transformData) { - console.error( - `Invalid transform choice ${chalk.dim(`(${transform})`)}, pick one of:` - ); - console.error(transformKeys.map((key) => `- ${key}`).join("\n")); - return process.exit(1); - } - - // run the transform - const result = transformData.transformer({ - root, - options, - }); - - if (result.fatalError) { - // Runner already logs this, so we can just exit - return process.exit(1); - } - - Runner.logResults(result); -} diff --git a/packages/turbo-codemod/src/commands/transform/types.ts b/packages/turbo-codemod/src/commands/transform/types.ts deleted file mode 100644 index 9ac2db0..0000000 --- a/packages/turbo-codemod/src/commands/transform/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TransformerOptions } from "../../types"; - -export type TransformCommandArgument = "string" | undefined; - -export interface TransformCommandOptions extends TransformerOptions { - list: boolean; -} diff --git a/packages/turbo-codemod/src/runner/FileTransform.ts b/packages/turbo-codemod/src/runner/FileTransform.ts deleted file mode 100644 index 3b23f73..0000000 --- a/packages/turbo-codemod/src/runner/FileTransform.ts +++ /dev/null @@ -1,94 +0,0 @@ -import chalk from "chalk"; -import { diffLines, Change, diffJson } from "diff"; -import fs from "fs-extra"; -import os from "os"; -import path from "path"; - -import type { FileTransformArgs, LogFileArgs } from "./types"; - -export default class FileTransform { - filePath: string; - rootPath: string; - before: string | object; - after?: string | object; - error?: Error; - changes: Array = []; - - constructor(args: FileTransformArgs) { - this.filePath = args.filePath; - this.rootPath = args.rootPath; - this.after = args.after; - this.error = args.error; - - // load original file for comparison - if (args.before === undefined) { - try { - if (path.extname(args.filePath) === ".json") { - this.before = fs.readJsonSync(args.filePath); - } else { - this.before = fs.readFileSync(args.filePath); - } - } catch (err) { - this.before = ""; - } - } else if (args.before === null) { - this.before = ""; - } else { - this.before = args.before; - } - - // determine diff - if (args.after) { - if (typeof this.before === "object" || typeof args.after === "object") { - this.changes = diffJson(this.before, args.after); - } else { - this.changes = diffLines(this.before, args.after); - } - } else { - this.changes = []; - } - } - - fileName(): string { - return path.relative(this.rootPath, this.filePath); - } - - write(): void { - if (this.after) { - if (typeof this.after === "object") { - fs.writeJsonSync(this.filePath, this.after, { spaces: 2 }); - } else { - fs.writeFileSync(this.filePath, this.after); - } - } - } - - additions(): number { - return this.changes.filter((c) => c.added).length; - } - - deletions(): number { - return this.changes.filter((c) => c.removed).length; - } - - hasChanges(): boolean { - return this.additions() > 0 || this.deletions() > 0; - } - - log(args: LogFileArgs): void { - if (args.diff) { - this.changes.forEach((part) => { - if (part.added) { - process.stdout.write(chalk.green(part.value)); - } else if (part.removed) { - process.stdout.write(chalk.red(part.value)); - } else { - process.stdout.write(chalk.dim(part.value)); - } - }); - console.log(os.EOL); - } else { - console.log(this.after); - } - } -} diff --git a/packages/turbo-codemod/src/runner/Runner.ts b/packages/turbo-codemod/src/runner/Runner.ts deleted file mode 100644 index 8f8803d..0000000 --- a/packages/turbo-codemod/src/runner/Runner.ts +++ /dev/null @@ -1,132 +0,0 @@ -import chalk from "chalk"; - -import FileTransform from "./FileTransform"; -import Logger from "../utils/logger"; -import type { UtilityArgs } from "../types"; -import type { - FileResult, - ModifyFileArgs, - AbortTransformArgs, - TransformerResults, -} from "./types"; - -class Runner { - transform: string; - rootPath: string; - dry: boolean; - print: boolean; - modifications: Record = {}; - logger: Logger; - - constructor(options: UtilityArgs) { - this.transform = options.transformer; - this.rootPath = options.rootPath; - this.dry = options.dry; - this.print = options.print; - this.logger = new Logger(options); - } - - abortTransform(args: AbortTransformArgs): TransformerResults { - this.logger.error(args.reason); - return { - fatalError: new Error(args.reason), - changes: args.changes || {}, - }; - } - - // add a file to be transformed - modifyFile(args: ModifyFileArgs): void { - this.modifications[args.filePath] = new FileTransform({ - rootPath: this.rootPath, - ...args, - }); - } - - // execute all transforms and track results for reporting - finish(): TransformerResults { - const results: TransformerResults = { changes: {} }; - // perform all actions and track results - Object.keys(this.modifications).forEach((filePath) => { - const mod = this.modifications[filePath]; - const result: FileResult = { - action: "unchanged", - additions: mod.additions(), - deletions: mod.deletions(), - }; - - if (mod.hasChanges()) { - if (this.dry) { - result.action = "skipped"; - this.logger.skipped(chalk.dim(mod.fileName())); - } else { - try { - mod.write(); - result.action = "modified"; - this.logger.modified(chalk.bold(mod.fileName())); - } catch (err) { - let message = "Unknown error"; - if (err instanceof Error) { - message = err.message; - } - result.error = new Error(message); - result.action = "error"; - this.logger.error(mod.fileName(), message); - } - } - - if (this.print) { - mod.log({ diff: true }); - } - } else { - this.logger.unchanged(chalk.dim(mod.fileName())); - } - - results.changes[mod.fileName()] = result; - }); - - const encounteredError = Object.keys(results.changes).some((fileName) => { - return results.changes[fileName].action === "error"; - }); - - if (encounteredError) { - return this.abortTransform({ - reason: "Encountered an error while transforming files", - changes: results.changes, - }); - } - - return results; - } - - static logResults(results: TransformerResults): void { - const changedFiles = Object.keys(results.changes); - console.log(); - if (changedFiles.length > 0) { - console.log(chalk.bold(`Results:`)); - const table: Record< - string, - { - action: FileResult["action"]; - additions: FileResult["additions"]; - deletions: FileResult["deletions"]; - error?: string; - } - > = {}; - - changedFiles.forEach((fileName) => { - const fileChanges = results.changes[fileName]; - table[fileName] = { - action: fileChanges.action, - additions: fileChanges.additions, - deletions: fileChanges.deletions, - error: fileChanges.error?.message || "None", - }; - }); - - console.table(table); - console.log(); - } - } -} - -export default Runner; diff --git a/packages/turbo-codemod/src/runner/index.ts b/packages/turbo-codemod/src/runner/index.ts deleted file mode 100644 index 2aa323d..0000000 --- a/packages/turbo-codemod/src/runner/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as Runner } from "./Runner"; - -export type { TransformerResults, FileDiffer, FileWriter } from "./types"; diff --git a/packages/turbo-codemod/src/runner/types.ts b/packages/turbo-codemod/src/runner/types.ts deleted file mode 100644 index e7c37d4..0000000 --- a/packages/turbo-codemod/src/runner/types.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Change } from "diff"; - -export interface FileResult { - action: "skipped" | "modified" | "unchanged" | "error"; - error?: Error; - additions: number; - deletions: number; -} - -export interface FileTransformArgs extends ModifyFileArgs { - rootPath: string; -} - -export interface ModifyFileArgs { - filePath: string; - before?: string | object; - after?: string | object; - error?: Error; -} - -export interface AbortTransformArgs { - reason: string; - changes?: Record; -} - -export interface LogFileArgs { - diff?: boolean; -} - -export type FileWriter = (filePath: string, contents: string | object) => void; - -export type FileDiffer = ( - before: string | object, - after: string | object -) => Array; - -export interface TransformerResults { - fatalError?: Error; - changes: Record; -} diff --git a/packages/turbo-codemod/src/transforms/README.md b/packages/turbo-codemod/src/transforms/README.md deleted file mode 100644 index 8e4430f..0000000 --- a/packages/turbo-codemod/src/transforms/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# `@turbo/codemod` Transformers - -## Adding new transformers - -Add new transformers using the [plopjs](https://github.com/plopjs/plop) template by running: - -```bash -pnpm add-transformer -``` - -New Transformers will be automatically surfaced to the `transform` CLI command and used by the `migrate` CLI command when appropriate. - -## How it works - -Transformers are loaded automatically from the `src/transforms/` directory via the [`loadTransforms`](../utils/loadTransformers.ts) function. - -All new transformers must contain a default export that matches the [`Transformer`](../types.ts) type: - -```ts -export type Transformer = { - name: string; - value: string; - introducedIn: string; - transformer: (args: TransformerArgs) => TransformerResults; -}; -``` - -## Writing a Transform - -Transforms are ran using the [TransformRunner](../runner/Runner.ts). This class is designed to make writing transforms as simple as possible by abstracting away all of the boilerplate that determines what should be logged, saved, or output as a result. - -To use the TransformRunner: - -1. Transform each file in memory (do not write it back to disk `TransformRunner` takes care of this depending on the options passed in by the user), and pass to `TransformRunner.modifyFile` method. -2. If the transform encounters an unrecoverable error, pass it to the `TransformRunner.abortTransform` method. -3. When all files have been modified and passed to `TransformRunner.modifyFile`, call `TransformRunner.finish` method to write the files to disk (when not running in `dry` mode) and log the results. diff --git a/packages/turbo-codemod/src/transforms/add-package-manager.ts b/packages/turbo-codemod/src/transforms/add-package-manager.ts deleted file mode 100644 index bd6581f..0000000 --- a/packages/turbo-codemod/src/transforms/add-package-manager.ts +++ /dev/null @@ -1,75 +0,0 @@ -import path from "path"; -import fs from "fs-extra"; - -import getPackageManager from "../utils/getPackageManager"; -import getPackageManagerVersion from "../utils/getPackageManagerVersion"; -import getTransformerHelpers from "../utils/getTransformerHelpers"; -import { TransformerResults } from "../runner"; -import type { TransformerArgs } from "../types"; - -// transformer details -const TRANSFORMER = "add-package-manager"; -const DESCRIPTION = "Set the `packageManager` key in root `package.json` file"; -const INTRODUCED_IN = "1.1.0"; - -export function transformer({ - root, - options, -}: TransformerArgs): TransformerResults { - const { log, runner } = getTransformerHelpers({ - transformer: TRANSFORMER, - rootPath: root, - options, - }); - - log.info(`Set "packageManager" key in root "package.json" file...`); - const packageManager = getPackageManager({ directory: root }); - if (!packageManager) { - return runner.abortTransform({ - reason: `Unable to determine package manager for ${root}`, - }); - } - - // handle workspaces... - let version = null; - try { - version = getPackageManagerVersion(packageManager, root); - } catch (err) { - return runner.abortTransform({ - reason: `Unable to determine package manager version for ${root}`, - }); - } - const pkgManagerString = `${packageManager}@${version}`; - const rootPackageJsonPath = path.join(root, "package.json"); - const rootPackageJson = fs.readJsonSync(rootPackageJsonPath); - const allWorkspaces = [ - { - name: "package.json", - path: root, - packageJson: { - ...rootPackageJson, - packageJsonPath: rootPackageJsonPath, - }, - }, - ]; - - for (const workspace of allWorkspaces) { - const { packageJsonPath, ...pkgJson } = workspace.packageJson; - const newJson = { ...pkgJson, packageManager: pkgManagerString }; - runner.modifyFile({ - filePath: packageJsonPath, - after: newJson, - }); - } - - return runner.finish(); -} - -const transformerMeta = { - name: `${TRANSFORMER}: ${DESCRIPTION}`, - value: TRANSFORMER, - introducedIn: INTRODUCED_IN, - transformer, -}; - -export default transformerMeta; diff --git a/packages/turbo-codemod/src/transforms/create-turbo-config.ts b/packages/turbo-codemod/src/transforms/create-turbo-config.ts deleted file mode 100644 index 0e8549a..0000000 --- a/packages/turbo-codemod/src/transforms/create-turbo-config.ts +++ /dev/null @@ -1,70 +0,0 @@ -import fs from "fs-extra"; -import path from "path"; - -import { TransformerResults } from "../runner"; -import getTransformerHelpers from "../utils/getTransformerHelpers"; -import type { TransformerArgs } from "../types"; - -// transformer details -const TRANSFORMER = "create-turbo-config"; -const DESCRIPTION = - 'Create the `turbo.json` file from an existing "turbo" key in `package.json`'; -const INTRODUCED_IN = "1.1.0"; - -export function transformer({ - root, - options, -}: TransformerArgs): TransformerResults { - const { log, runner } = getTransformerHelpers({ - transformer: TRANSFORMER, - rootPath: root, - options, - }); - - log.info(`Migrating "package.json" "turbo" key to "turbo.json" file...`); - const turboConfigPath = path.join(root, "turbo.json"); - const rootPackageJsonPath = path.join(root, "package.json"); - if (!fs.existsSync(rootPackageJsonPath)) { - return runner.abortTransform({ - reason: `No package.json found at ${root}. Is the path correct?`, - }); - } - - // read files - const rootPackageJson = fs.readJsonSync(rootPackageJsonPath); - let rootTurboJson = null; - try { - rootTurboJson = fs.readJSONSync(turboConfigPath); - } catch (err) { - rootTurboJson = null; - } - - // modify files - let transformedPackageJson = rootPackageJson; - let transformedTurboConfig = rootTurboJson; - if (!rootTurboJson && rootPackageJson["turbo"]) { - const { turbo: turboConfig, ...remainingPkgJson } = rootPackageJson; - transformedTurboConfig = turboConfig; - transformedPackageJson = remainingPkgJson; - } - - runner.modifyFile({ - filePath: turboConfigPath, - after: transformedTurboConfig, - }); - runner.modifyFile({ - filePath: rootPackageJsonPath, - after: transformedPackageJson, - }); - - return runner.finish(); -} - -const transformerMeta = { - name: `${TRANSFORMER}: ${DESCRIPTION}`, - value: TRANSFORMER, - introducedIn: INTRODUCED_IN, - transformer, -}; - -export default transformerMeta; diff --git a/packages/turbo-codemod/src/transforms/migrate-env-var-dependencies.ts b/packages/turbo-codemod/src/transforms/migrate-env-var-dependencies.ts deleted file mode 100644 index ef3a34c..0000000 --- a/packages/turbo-codemod/src/transforms/migrate-env-var-dependencies.ts +++ /dev/null @@ -1,181 +0,0 @@ -import fs from "fs-extra"; -import path from "path"; -import { getTurboConfigs } from "@turbo/utils"; -import type { Schema, Pipeline } from "@turbo/types"; - -import getTransformerHelpers from "../utils/getTransformerHelpers"; -import { TransformerResults } from "../runner"; -import type { TransformerArgs } from "../types"; - -// transformer details -const TRANSFORMER = "migrate-env-var-dependencies"; -const DESCRIPTION = - 'Migrate environment variable dependencies from "dependsOn" to "env" in `turbo.json`'; -const INTRODUCED_IN = "1.5.0"; - -export function hasLegacyEnvVarDependencies(config: Schema) { - const dependsOn = [ - "extends" in config ? [] : config.globalDependencies, - Object.values(config.pipeline).flatMap( - (pipeline) => pipeline.dependsOn ?? [] - ), - ].flat(); - const envVars = dependsOn.filter((dep) => dep?.startsWith("$")); - return { hasKeys: !!envVars.length, envVars }; -} - -export function migrateDependencies({ - env, - deps, -}: { - env?: string[]; - deps?: string[]; -}) { - const envDeps: Set = new Set(env); - const otherDeps: string[] = []; - deps?.forEach((dep) => { - if (dep.startsWith("$")) { - envDeps.add(dep.slice(1)); - } else { - otherDeps.push(dep); - } - }); - if (envDeps.size) { - return { - deps: otherDeps, - env: Array.from(envDeps), - }; - } else { - return { env, deps }; - } -} - -export function migratePipeline(pipeline: Pipeline) { - const { deps: dependsOn, env } = migrateDependencies({ - env: pipeline.env, - deps: pipeline.dependsOn, - }); - const migratedPipeline = { ...pipeline }; - if (dependsOn) { - migratedPipeline.dependsOn = dependsOn; - } else { - delete migratedPipeline.dependsOn; - } - if (env && env.length) { - migratedPipeline.env = env; - } else { - delete migratedPipeline.env; - } - - return migratedPipeline; -} - -export function migrateGlobal(config: Schema) { - if ("extends" in config) { - return config; - } - - const { deps: globalDependencies, env } = migrateDependencies({ - env: config.globalEnv, - deps: config.globalDependencies, - }); - const migratedConfig = { ...config }; - if (globalDependencies && globalDependencies.length) { - migratedConfig.globalDependencies = globalDependencies; - } else { - delete migratedConfig.globalDependencies; - } - if (env && env.length) { - migratedConfig.globalEnv = env; - } else { - delete migratedConfig.globalEnv; - } - return migratedConfig; -} - -export function migrateConfig(config: Schema) { - let migratedConfig = migrateGlobal(config); - Object.keys(config.pipeline).forEach((pipelineKey) => { - config.pipeline; - if (migratedConfig.pipeline && config.pipeline[pipelineKey]) { - const pipeline = migratedConfig.pipeline[pipelineKey]; - migratedConfig.pipeline[pipelineKey] = { - ...pipeline, - ...migratePipeline(pipeline), - }; - } - }); - return migratedConfig; -} - -export function transformer({ - root, - options, -}: TransformerArgs): TransformerResults { - const { log, runner } = getTransformerHelpers({ - transformer: TRANSFORMER, - rootPath: root, - options, - }); - - log.info( - `Migrating environment variable dependencies from "globalDependencies" and "dependsOn" to "env" in "turbo.json"...` - ); - - // validate we don't have a package.json config - const packageJsonPath = path.join(root, "package.json"); - let packageJSON = {}; - try { - packageJSON = fs.readJSONSync(packageJsonPath); - } catch (e) { - // readJSONSync probably failed because the file doesn't exist - } - - if ("turbo" in packageJSON) { - return runner.abortTransform({ - reason: - '"turbo" key detected in package.json. Run `npx @turbo/codemod transform create-turbo-config` first', - }); - } - - // validate we have a root config - const turboConfigPath = path.join(root, "turbo.json"); - if (!fs.existsSync(turboConfigPath)) { - return runner.abortTransform({ - reason: `No turbo.json found at ${root}. Is the path correct?`, - }); - } - - let turboJson: Schema = fs.readJsonSync(turboConfigPath); - if (hasLegacyEnvVarDependencies(turboJson).hasKeys) { - turboJson = migrateConfig(turboJson); - } - - runner.modifyFile({ - filePath: turboConfigPath, - after: turboJson, - }); - - // find and migrate any workspace configs - const workspaceConfigs = getTurboConfigs(root); - workspaceConfigs.forEach((workspaceConfig) => { - const { config, turboConfigPath } = workspaceConfig; - if (hasLegacyEnvVarDependencies(config).hasKeys) { - runner.modifyFile({ - filePath: turboConfigPath, - after: migrateConfig(config), - }); - } - }); - - return runner.finish(); -} - -const transformerMeta = { - name: `${TRANSFORMER}: ${DESCRIPTION}`, - value: TRANSFORMER, - introducedIn: INTRODUCED_IN, - transformer, -}; - -export default transformerMeta; diff --git a/packages/turbo-codemod/src/transforms/set-default-outputs.ts b/packages/turbo-codemod/src/transforms/set-default-outputs.ts deleted file mode 100644 index 44f7fd1..0000000 --- a/packages/turbo-codemod/src/transforms/set-default-outputs.ts +++ /dev/null @@ -1,97 +0,0 @@ -import path from "path"; -import fs from "fs-extra"; -import { getTurboConfigs } from "@turbo/utils"; -import type { Schema as TurboJsonSchema } from "@turbo/types"; - -import type { TransformerArgs } from "../types"; -import getTransformerHelpers from "../utils/getTransformerHelpers"; -import { TransformerResults } from "../runner"; - -const DEFAULT_OUTPUTS = ["dist/**", "build/**"]; - -// transformer details -const TRANSFORMER = "set-default-outputs"; -const DESCRIPTION = - 'Add the "outputs" key with defaults where it is missing in `turbo.json`'; -const INTRODUCED_IN = "1.7.0"; - -function migrateConfig(config: TurboJsonSchema) { - for (const [_, taskDef] of Object.entries(config.pipeline)) { - if (taskDef.cache !== false) { - if (!taskDef.outputs) { - taskDef.outputs = DEFAULT_OUTPUTS; - } else if ( - Array.isArray(taskDef.outputs) && - taskDef.outputs.length === 0 - ) { - delete taskDef.outputs; - } - } - } - - return config; -} - -export function transformer({ - root, - options, -}: TransformerArgs): TransformerResults { - const { log, runner } = getTransformerHelpers({ - transformer: TRANSFORMER, - rootPath: root, - options, - }); - - // If `turbo` key is detected in package.json, require user to run the other codemod first. - const packageJsonPath = path.join(root, "package.json"); - // package.json should always exist, but if it doesn't, it would be a silly place to blow up this codemod - let packageJSON = {}; - - try { - packageJSON = fs.readJSONSync(packageJsonPath); - } catch (e) { - // readJSONSync probably failed because the file doesn't exist - } - - if ("turbo" in packageJSON) { - return runner.abortTransform({ - reason: - '"turbo" key detected in package.json. Run `npx @turbo/codemod transform create-turbo-config` first', - }); - } - - log.info(`Adding default \`outputs\` key into tasks if it doesn't exist`); - const turboConfigPath = path.join(root, "turbo.json"); - if (!fs.existsSync(turboConfigPath)) { - return runner.abortTransform({ - reason: `No turbo.json found at ${root}. Is the path correct?`, - }); - } - - const turboJson: TurboJsonSchema = fs.readJsonSync(turboConfigPath); - runner.modifyFile({ - filePath: turboConfigPath, - after: migrateConfig(turboJson), - }); - - // find and migrate any workspace configs - const workspaceConfigs = getTurboConfigs(root); - workspaceConfigs.forEach((workspaceConfig) => { - const { config, turboConfigPath } = workspaceConfig; - runner.modifyFile({ - filePath: turboConfigPath, - after: migrateConfig(config), - }); - }); - - return runner.finish(); -} - -const transformerMeta = { - name: `${TRANSFORMER}: ${DESCRIPTION}`, - value: TRANSFORMER, - introducedIn: INTRODUCED_IN, - transformer, -}; - -export default transformerMeta; diff --git a/packages/turbo-codemod/src/types.ts b/packages/turbo-codemod/src/types.ts deleted file mode 100644 index d5c13c3..0000000 --- a/packages/turbo-codemod/src/types.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { TransformerResults } from "./runner"; - -export type Transformer = { - name: string; - value: string; - introducedIn: string; - transformer: (args: TransformerArgs) => TransformerResults; -}; - -export type TransformerOptions = { - force: boolean; - dry: boolean; - print: boolean; -}; - -export type TransformerArgs = { - root: string; - options: TransformerOptions; -}; - -export interface UtilityArgs extends TransformerOptions { - transformer: string; - rootPath: string; -} diff --git a/packages/turbo-codemod/src/utils/checkGitStatus.ts b/packages/turbo-codemod/src/utils/checkGitStatus.ts deleted file mode 100644 index 68d39ae..0000000 --- a/packages/turbo-codemod/src/utils/checkGitStatus.ts +++ /dev/null @@ -1,40 +0,0 @@ -import chalk from "chalk"; -import isGitClean from "is-git-clean"; - -export default function checkGitStatus({ - directory, - force, -}: { - directory?: string; - force: boolean; -}) { - let clean = false; - let errorMessage = "Unable to determine if git directory is clean"; - try { - clean = isGitClean.sync(directory || process.cwd()); - errorMessage = "Git directory is not clean"; - } catch (err: any) { - if (err && err.stderr && err.stderr.indexOf("not a git repository") >= 0) { - clean = true; - } - } - - if (!clean) { - if (force) { - console.log( - `${chalk.yellow("WARNING")}: ${errorMessage}. Forcibly continuing...` - ); - } else { - console.log("Thank you for using @turbo/codemod!"); - console.log( - chalk.yellow( - "\nBut before we continue, please stash or commit your git changes." - ) - ); - console.log( - "\nYou may use the --force flag to override this safety check." - ); - process.exit(1); - } - } -} diff --git a/packages/turbo-codemod/src/utils/directoryInfo.ts b/packages/turbo-codemod/src/utils/directoryInfo.ts deleted file mode 100644 index 7cb3594..0000000 --- a/packages/turbo-codemod/src/utils/directoryInfo.ts +++ /dev/null @@ -1,10 +0,0 @@ -import path from "path"; -import fs from "fs"; - -export default function directoryInfo({ directory }: { directory: string }) { - const dir = path.isAbsolute(directory) - ? directory - : path.join(process.cwd(), directory); - - return { exists: fs.existsSync(dir), absolute: dir }; -} diff --git a/packages/turbo-codemod/src/utils/getPackageManager.ts b/packages/turbo-codemod/src/utils/getPackageManager.ts deleted file mode 100644 index 1df0acc..0000000 --- a/packages/turbo-codemod/src/utils/getPackageManager.ts +++ /dev/null @@ -1,42 +0,0 @@ -import findUp from "find-up"; -import path from "path"; - -export type PackageManager = "yarn" | "pnpm" | "npm"; - -const cache: { [cwd: string]: PackageManager } = {}; - -export default function getPackageManager({ - directory, -}: { directory?: string } = {}): PackageManager | undefined { - const cwd = directory || process.cwd(); - if (cache[cwd]) { - return cache[cwd]; - } - - const lockFile = findUp.sync( - ["yarn.lock", "pnpm-lock.yaml", "package-lock.json"], - { - cwd, - } - ); - - if (!lockFile) { - return; - } - - switch (path.basename(lockFile)) { - case "yarn.lock": - cache[cwd] = "yarn"; - break; - - case "pnpm-lock.yaml": - cache[cwd] = "pnpm"; - break; - - case "package-lock.json": - cache[cwd] = "npm"; - break; - } - - return cache[cwd]; -} diff --git a/packages/turbo-codemod/src/utils/getPackageManagerVersion.ts b/packages/turbo-codemod/src/utils/getPackageManagerVersion.ts deleted file mode 100644 index 54a572a..0000000 --- a/packages/turbo-codemod/src/utils/getPackageManagerVersion.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { execSync } from "child_process"; -import type { PackageManager } from "./getPackageManager"; - -export default function getPackageManagerVersion( - packageManager: PackageManager, - root: string -): string { - switch (packageManager) { - case "yarn": - return execSync("yarn --version", { cwd: root }).toString().trim(); - case "pnpm": - return execSync("pnpm --version", { cwd: root }).toString().trim(); - case "npm": - return execSync("npm --version", { cwd: root }).toString().trim(); - } -} diff --git a/packages/turbo-codemod/src/utils/getTransformerHelpers.ts b/packages/turbo-codemod/src/utils/getTransformerHelpers.ts deleted file mode 100644 index e37da6e..0000000 --- a/packages/turbo-codemod/src/utils/getTransformerHelpers.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { TransformerOptions } from "../types"; -import { Runner } from "../runner"; -import Logger from "./logger"; - -export default function getTransformerHelpers({ - transformer, - rootPath, - options, -}: { - transformer: string; - rootPath: string; - options: TransformerOptions; -}) { - const utilArgs = { - transformer, - rootPath, - ...options, - }; - const log = new Logger(utilArgs); - const runner = new Runner(utilArgs); - - return { log, runner }; -} diff --git a/packages/turbo-codemod/src/utils/loadTransformers.ts b/packages/turbo-codemod/src/utils/loadTransformers.ts deleted file mode 100644 index 9ba5ca1..0000000 --- a/packages/turbo-codemod/src/utils/loadTransformers.ts +++ /dev/null @@ -1,27 +0,0 @@ -import path from "path"; -import fs from "fs-extra"; -import type { Transformer } from "../types"; - -// transforms/ is a sibling when built in in dist/ -export const transformerDirectory = - process.env.NODE_ENV === "test" - ? path.join(__dirname, "../transforms") - : path.join(__dirname, "./transforms"); - -export default function loadTransformers(): Array { - const transformerFiles = fs.readdirSync(transformerDirectory); - return transformerFiles - .map((transformerFilename) => { - const transformerPath = path.join( - transformerDirectory, - transformerFilename - ); - try { - return require(transformerPath).default; - } catch (e) { - // we ignore this error because it's likely that the file is not a transformer (README, etc) - return undefined; - } - }) - .filter(Boolean); -} diff --git a/packages/turbo-codemod/src/utils/logger.ts b/packages/turbo-codemod/src/utils/logger.ts deleted file mode 100644 index 123a836..0000000 --- a/packages/turbo-codemod/src/utils/logger.ts +++ /dev/null @@ -1,47 +0,0 @@ -import chalk from "chalk"; -import { UtilityArgs } from "../types"; - -export default class Logger { - transform: string; - dry: boolean; - - constructor(args: UtilityArgs) { - this.transform = args.transformer; - this.dry = args.dry; - } - modified(...args: any[]) { - console.log( - chalk.green(` MODIFIED `), - ...args, - this.dry ? chalk.dim(`(dry run)`) : "" - ); - } - unchanged(...args: any[]) { - console.log( - chalk.gray(` UNCHANGED `), - ...args, - this.dry ? chalk.dim(`(dry run)`) : "" - ); - } - skipped(...args: any[]) { - console.log( - chalk.yellow(` SKIPPED `), - ...args, - this.dry ? chalk.dim(`(dry run)`) : "" - ); - } - error(...args: any[]) { - console.log( - chalk.red(` ERROR `), - ...args, - this.dry ? chalk.dim(`(dry run)`) : "" - ); - } - info(...args: any[]) { - console.log( - chalk.bold(` INFO `), - ...args, - this.dry ? chalk.dim(`(dry run)`) : "" - ); - } -} diff --git a/packages/turbo-codemod/src/utils/looksLikeRepo.ts b/packages/turbo-codemod/src/utils/looksLikeRepo.ts deleted file mode 100644 index 77f0e5c..0000000 --- a/packages/turbo-codemod/src/utils/looksLikeRepo.ts +++ /dev/null @@ -1,12 +0,0 @@ -import path from "path"; -import { existsSync } from "fs-extra"; - -const HINTS = ["package.json", "turbo.json", ".git"]; - -export default function looksLikeRepo({ - directory, -}: { - directory: string; -}): boolean { - return HINTS.some((hint) => existsSync(path.join(directory, hint))); -} diff --git a/packages/turbo-codemod/src/utils/notifyUpdate.ts b/packages/turbo-codemod/src/utils/notifyUpdate.ts deleted file mode 100644 index 634ffd8..0000000 --- a/packages/turbo-codemod/src/utils/notifyUpdate.ts +++ /dev/null @@ -1,35 +0,0 @@ -import chalk from "chalk"; -import checkForUpdate from "update-check"; - -import cliPkgJson from "../../package.json"; -import getWorkspaceImplementation from "./getPackageManager"; - -const update = checkForUpdate(cliPkgJson).catch(() => null); - -export default async function notifyUpdate(): Promise { - try { - const res = await update; - if (res?.latest) { - const ws = getWorkspaceImplementation(); - - console.log(); - console.log( - chalk.yellow.bold("A new version of `@turbo/codemod` is available!") - ); - console.log( - "You can update by running: " + - chalk.cyan( - ws === "yarn" - ? "yarn global add @turbo/codemod" - : ws === "pnpm" - ? "pnpm i -g @turbo/codemod" - : "npm i -g @turbo/codemod" - ) - ); - console.log(); - } - process.exit(); - } catch (_e: any) { - // ignore error - } -} diff --git a/packages/turbo-codemod/templates/transformer.hbs b/packages/turbo-codemod/templates/transformer.hbs deleted file mode 100644 index 593490a..0000000 --- a/packages/turbo-codemod/templates/transformer.hbs +++ /dev/null @@ -1,45 +0,0 @@ -import { TransformerArgs } from "../types"; -import { TransformerResults } from "../runner"; -import getTransformerHelpers from "../utils/getTransformerHelpers"; - -// transformer details -const TRANSFORMER = "{{ name }}"; -const DESCRIPTION = "{{ description }}"; -const INTRODUCED_IN = "{{ introducedIn }}"; - -export function transformer({ - root, - options, -}: TransformerArgs): TransformerResults { - const { log, runner } = getTransformerHelpers({ - transformer: TRANSFORMER, - rootPath: root, - options, - }); - - log.info("Short description about {{ name }}") - - /* - Make changes to required files, and track each modified file with: - - runner.modifyFile({ - filePath: packageJsonPath, // absolute path to file - after: transformedFile, // file after modifications have been made - }); - - This automatically handles all cases of print / dry etc. - */ - - return runner.finish(); -} - -const transformerMeta = { - name: `${TRANSFORMER}: ${DESCRIPTION}`, - value: TRANSFORMER, - introducedIn: INTRODUCED_IN, - transformer, -}; - -export default transformerMeta; - - diff --git a/packages/turbo-codemod/templates/transformer.test.hbs b/packages/turbo-codemod/templates/transformer.test.hbs deleted file mode 100644 index c63a9df..0000000 --- a/packages/turbo-codemod/templates/transformer.test.hbs +++ /dev/null @@ -1,25 +0,0 @@ -import { transformer } from "../src/transforms/{{ name }}"; -import { setupTestFixtures } from "./test-utils"; - -describe("{{ name }}", () => { - - const { useFixture } = setupTestFixtures({ test: "{{ name }}" }); - - test("basic", () => { - // load the fixture for the test - const { root, read, readJson } = useFixture({ - fixture: "specific-fixture", - }); - - // run the transformer - const result = transformer({ - root, - options: { force: false, dry: false, print: false }, - }); - - // result should be correct - expect(result.fatalError).toBeUndefined(); - expect(result.changes).toMatchInlineSnapshot(); - }); -}); - diff --git a/packages/turbo-codemod/tsconfig.json b/packages/turbo-codemod/tsconfig.json deleted file mode 100644 index 0620a3c..0000000 --- a/packages/turbo-codemod/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "@turbo/tsconfig/library.json", - "compilerOptions": { - "rootDir": "." - } -} diff --git a/packages/turbo-codemod/tsup.config.ts b/packages/turbo-codemod/tsup.config.ts deleted file mode 100644 index 8e92107..0000000 --- a/packages/turbo-codemod/tsup.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { defineConfig, Options } from "tsup"; - -export default defineConfig((options: Options) => ({ - entry: ["src/cli.ts", "src/transforms/*.ts"], - format: ["cjs"], - clean: true, - minify: true, - ...options, -})); diff --git a/packages/turbo-ignore/README.md b/packages/turbo-ignore/README.md deleted file mode 100644 index 866c0e7..0000000 --- a/packages/turbo-ignore/README.md +++ /dev/null @@ -1,99 +0,0 @@ -# `turbo-ignore` - -To get started, use the following command as your [Ignored Build Step](https://vercel.com/docs/concepts/projects/overview#ignored-build-step): - -```sh -$ npx turbo-ignore -``` - -This uses `turbo` to automatically determine if the current app has new changes that need to be deployed. - -## Usage - -Use `npx turbo-ignore --help` to see list of options: - -```sh -turbo-ignore - -Automatically ignore builds that have no changes - -Usage: - $ npx turbo-ignore [] [flags...] - -If is not provided, it will be inferred from the "name" -field of the "package.json" located at the current working directory. - -Flags: - --fallback= On Vercel, if no previously deployed SHA is available to compare against, - fallback to comparing against the provided ref [default: None] - --help, -h Show this help message - --version, -v Show the version of this script - ---- - -turbo-ignore will also check for special commit messages to indicate if a build should be skipped or not. - -Skip turbo-ignore check and automatically ignore: - - [skip ci] - - [ci skip] - - [no ci] - - [skip vercel] - - [vercel skip] - - [vercel skip ] - -Skip turbo-ignore check and automatically deploy: - - [vercel deploy] - - [vercel build] - - [vercel deploy ] - - [vercel build ] -``` - -### Examples - -```sh -npx turbo-ignore -``` - -> Only build if there are changes to the workspace in the current working directory, or any of it's dependencies. On Vercel, compare against the last successful deployment for the current branch. When not on Vercel, compare against the parent commit (`HEAD^`). - ---- - -```sh -npx turbo-ignore docs -``` - -> Only build if there are changes to the `docs` workspace, or any of its dependencies. On Vercel, compare against the last successful deployment for the current branch. When not on Vercel compare against the parent commit (`HEAD^`). - ---- - -```sh -npx turbo-ignore --fallback=HEAD~10 -``` - -> Only build if there are changes to the workspace in the current working directory, or any of it's dependencies. On Vercel, compare against the last successful deployment for the current branch. If this does not exist (first deploy of the branch), compare against the previous 10 commits. When not on Vercel, always compare against the parent commit (`HEAD^`). - ---- - -```sh -npx turbo-ignore --fallback=HEAD^ -``` - -> Only build if there are changes to the workspace in the current working directory, or any of it's dependencies. On Vercel, compare against the last successful deployment for the current branch. If this does not exist (first deploy of the branch), compare against the parent commit (`HEAD^`). When not on Vercel, always compare against the parent commit (`HEAD^`). - -## How it Works - -`turbo-ignore` determines if a build should continue by analyzing the package dependency graph of the given workspace. - -The _given workspace_ is determined by reading the "name" field in the "package.json" file located at the current working directory, or by passing in a workspace name as the first argument to `turbo-ignore`. - -Next, it uses `turbo run build --dry` to determine if the given workspace, _or any dependencies of the workspace_, have changed since the previous commit. - -**NOTE:** `turbo` determines dependencies from reading the dependency graph of the given workspace. This means a workspace **must** be listed as a `dependency` (or `devDependency`) in the given workspaces `package.json` for `turbo` to recognize it. - -When deploying on [Vercel](https://vercel.com), `turbo-ignore` can make a more accurate decision by comparing between the current commit, and the last successfully deployed commit for the current branch. - -**NOTE:** By default on Vercel, `turbo-ignore` will always deploy the first commit of a new branch. This behavior can be changed by providing the `ref` to compare against to the `--fallback` flag. See the [Examples](#Examples) section for more details. - ---- - -For more information about Turborepo, visit [turbo.build](https://turbo.build) and follow us on Twitter ([@turborepo](https://twitter.com/turborepo))! diff --git a/packages/turbo-ignore/__fixtures__/app/package.json b/packages/turbo-ignore/__fixtures__/app/package.json deleted file mode 100644 index 17d7c56..0000000 --- a/packages/turbo-ignore/__fixtures__/app/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "test-app", - "private": true, - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "vercel" -} diff --git a/packages/turbo-ignore/__fixtures__/invalid-app/package.json b/packages/turbo-ignore/__fixtures__/invalid-app/package.json deleted file mode 100644 index ee2f59b..0000000 --- a/packages/turbo-ignore/__fixtures__/invalid-app/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "private": true, - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "vercel" -} diff --git a/packages/turbo-ignore/__fixtures__/no-app/index.js b/packages/turbo-ignore/__fixtures__/no-app/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/turbo-ignore/__tests__/args.test.ts b/packages/turbo-ignore/__tests__/args.test.ts deleted file mode 100644 index f546247..0000000 --- a/packages/turbo-ignore/__tests__/args.test.ts +++ /dev/null @@ -1,109 +0,0 @@ -import parseArgs, { help } from "../src/args"; -import pkg from "../package.json"; -import { spyConsole, spyExit } from "@turbo/test-utils"; - -describe("parseArgs()", () => { - const mockConsole = spyConsole(); - const mockExit = spyExit(); - - it("does not throw with no args", async () => { - const result = parseArgs({ argv: [] }); - expect(result.workspace).toBe(undefined); - expect(result.fallback).toBe(undefined); - expect(result.task).toBe(undefined); - }); - - it("outputs help text (--help)", async () => { - parseArgs({ argv: ["--help"] }); - expect(mockExit.exit).toHaveBeenCalledWith(0); - expect(mockConsole.log).toHaveBeenCalledWith(help); - }); - - it("outputs help text (-h)", async () => { - parseArgs({ argv: ["-h"] }); - expect(mockExit.exit).toHaveBeenCalledWith(0); - expect(mockConsole.log).toHaveBeenCalledWith(help); - }); - - it("outputs version text (--version)", async () => { - parseArgs({ argv: ["--version"] }); - expect(mockExit.exit).toHaveBeenCalledWith(0); - expect(mockConsole.log).toHaveBeenCalledWith(pkg.version); - }); - - it("outputs version text (-v)", async () => { - parseArgs({ argv: ["-v"] }); - expect(mockExit.exit).toHaveBeenCalledWith(0); - expect(mockConsole.log).toHaveBeenCalledWith(pkg.version); - }); - - it("correctly finds workspace", async () => { - const result = parseArgs({ argv: ["this-workspace"] }); - expect(result.workspace).toBe("this-workspace"); - expect(result.fallback).toBe(undefined); - expect(result.task).toBe(undefined); - expect(mockExit.exit).toHaveBeenCalledTimes(0); - }); - - it("correctly finds fallback", async () => { - const result = parseArgs({ argv: ["--fallback=HEAD^"] }); - expect(result.workspace).toBe(undefined); - expect(result.fallback).toBe("HEAD^"); - expect(result.task).toBe(undefined); - expect(mockExit.exit).toHaveBeenCalledTimes(0); - }); - - it("correctly finds task", async () => { - const result = parseArgs({ argv: ["--task=some-workspace#build"] }); - expect(result.workspace).toBe(undefined); - expect(result.fallback).toBe(undefined); - expect(result.task).toBe("some-workspace#build"); - expect(mockExit.exit).toHaveBeenCalledTimes(0); - }); - - it("uses default fallback if incorrectly specified", async () => { - const result = parseArgs({ argv: ["--fallback"] }); - expect(result.workspace).toBe(undefined); - expect(result.fallback).toBe(undefined); - expect(result.task).toBe(undefined); - expect(mockExit.exit).toHaveBeenCalledTimes(0); - }); - - it("uses default fallback if empty string", async () => { - const result = parseArgs({ argv: ["--fallback="] }); - expect(result.workspace).toBe(undefined); - expect(result.fallback).toBe(undefined); - expect(result.task).toBe(undefined); - expect(mockExit.exit).toHaveBeenCalledTimes(0); - }); - - it("uses default task if incorrectly specified", async () => { - const result = parseArgs({ argv: ["--task"] }); - expect(result.workspace).toBe(undefined); - expect(result.fallback).toBe(undefined); - expect(result.task).toBe(undefined); - expect(mockExit.exit).toHaveBeenCalledTimes(0); - }); - - it("uses default task if empty string", async () => { - const result = parseArgs({ argv: ["--task="] }); - expect(result.workspace).toBe(undefined); - expect(result.fallback).toBe(undefined); - expect(result.task).toBe(undefined); - expect(mockExit.exit).toHaveBeenCalledTimes(0); - }); - - it("correctly finds fallback and workspace", async () => { - const result = parseArgs({ - argv: [ - "this-workspace", - "--fallback=HEAD~10", - "--task=some-workspace#build", - ], - }); - expect(result.workspace).toBe("this-workspace"); - expect(result.fallback).toBe("HEAD~10"); - expect(result.task).toBe("some-workspace#build"); - expect(mockExit.exit).toHaveBeenCalledTimes(0); - }); -}); diff --git a/packages/turbo-ignore/__tests__/checkCommit.test.ts b/packages/turbo-ignore/__tests__/checkCommit.test.ts deleted file mode 100644 index e7e4a5f..0000000 --- a/packages/turbo-ignore/__tests__/checkCommit.test.ts +++ /dev/null @@ -1,229 +0,0 @@ -import child_process from "child_process"; -import { checkCommit } from "../src/checkCommit"; -import { mockEnv } from "@turbo/test-utils"; - -describe("checkCommit()", () => { - describe("on Vercel", () => { - mockEnv(); - - describe("for all workspaces", () => { - it("results in continue when no special commit messages are found", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = "fixing a test"; - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "continue", - scope: "global", - reason: "No deploy or skip string found in commit message.", - }); - }); - - it("results in conflict when deploy and skip commit messages are found", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = - "deploying [vercel deploy] and skipping [vercel skip]"; - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "conflict", - scope: "global", - reason: - "Conflicting commit messages found: [vercel deploy] and [vercel skip]", - }); - }); - - it("results in deploy when deploy commit message is found", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = "deploying [vercel deploy]"; - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "deploy", - scope: "global", - reason: "Found commit message: [vercel deploy]", - }); - }); - - it("results in skip when skip commit message is found", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = "skip deployment [vercel skip]"; - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "skip", - scope: "global", - reason: "Found commit message: [vercel skip]", - }); - }); - }); - - describe("for specific workspaces", () => { - it("results in continue when no special commit messages are found", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = - "fixing a test in test-workspace"; - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "continue", - scope: "global", - reason: "No deploy or skip string found in commit message.", - }); - }); - - it("results in conflict when deploy and skip commit messages are found", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = - "deploying [vercel deploy test-workspace] and skipping [vercel skip test-workspace]"; - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "conflict", - scope: "workspace", - reason: - "Conflicting commit messages found: [vercel deploy test-workspace] and [vercel skip test-workspace]", - }); - }); - - it("results in deploy when deploy commit message is found", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = - "deploying [vercel deploy test-workspace]"; - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "deploy", - scope: "workspace", - reason: "Found commit message: [vercel deploy test-workspace]", - }); - }); - - it("results in skip when skip commit message is found", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = - "skip deployment [vercel skip test-workspace]"; - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "skip", - scope: "workspace", - reason: "Found commit message: [vercel skip test-workspace]", - }); - }); - }); - }); - describe("Not on Vercel", () => { - describe("for all workspaces", () => { - it("results in continue when no special commit messages are found", async () => { - const commitBody = "fixing a test"; - const mockExecSync = jest - .spyOn(child_process, "execSync") - .mockImplementation((_) => commitBody); - - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "continue", - scope: "global", - reason: "No deploy or skip string found in commit message.", - }); - expect(mockExecSync).toHaveBeenCalledWith("git show -s --format=%B"); - mockExecSync.mockRestore(); - }); - - it("results in conflict when deploy and skip commit messages are found", async () => { - const commitBody = - "deploying [vercel deploy] and skipping [vercel skip]"; - const mockExecSync = jest - .spyOn(child_process, "execSync") - .mockImplementation((_) => commitBody); - - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "conflict", - scope: "global", - reason: - "Conflicting commit messages found: [vercel deploy] and [vercel skip]", - }); - expect(mockExecSync).toHaveBeenCalledWith("git show -s --format=%B"); - mockExecSync.mockRestore(); - }); - - it("results in deploy when deploy commit message is found", async () => { - const commitBody = "deploying [vercel deploy]"; - const mockExecSync = jest - .spyOn(child_process, "execSync") - .mockImplementation((_) => commitBody); - - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "deploy", - scope: "global", - reason: "Found commit message: [vercel deploy]", - }); - expect(mockExecSync).toHaveBeenCalledWith("git show -s --format=%B"); - mockExecSync.mockRestore(); - }); - - it("results in skip when skip commit message is found", async () => { - const commitBody = "skip deployment [vercel skip]"; - const mockExecSync = jest - .spyOn(child_process, "execSync") - .mockImplementation((_) => commitBody); - - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "skip", - scope: "global", - reason: "Found commit message: [vercel skip]", - }); - expect(mockExecSync).toHaveBeenCalledWith("git show -s --format=%B"); - mockExecSync.mockRestore(); - }); - }); - - describe("for specific workspaces", () => { - it("results in continue when no special commit messages are found", async () => { - const commitBody = "fixing a test in test-workspace"; - const mockExecSync = jest - .spyOn(child_process, "execSync") - .mockImplementation((_) => commitBody); - - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "continue", - scope: "global", - reason: "No deploy or skip string found in commit message.", - }); - expect(mockExecSync).toHaveBeenCalledWith("git show -s --format=%B"); - mockExecSync.mockRestore(); - }); - - it("results in conflict when deploy and skip commit messages are found", async () => { - const commitBody = - "deploying [vercel deploy test-workspace] and skipping [vercel skip test-workspace]"; - const mockExecSync = jest - .spyOn(child_process, "execSync") - .mockImplementation((_) => commitBody); - - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "conflict", - scope: "workspace", - reason: - "Conflicting commit messages found: [vercel deploy test-workspace] and [vercel skip test-workspace]", - }); - expect(mockExecSync).toHaveBeenCalledWith("git show -s --format=%B"); - mockExecSync.mockRestore(); - }); - - it("results in deploy when deploy commit message is found", async () => { - const commitBody = "deploying [vercel deploy test-workspace]"; - const mockExecSync = jest - .spyOn(child_process, "execSync") - .mockImplementation((_) => commitBody); - - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "deploy", - scope: "workspace", - reason: "Found commit message: [vercel deploy test-workspace]", - }); - expect(mockExecSync).toHaveBeenCalledWith("git show -s --format=%B"); - mockExecSync.mockRestore(); - }); - - it("results in skip when skip commit message is found", async () => { - const commitBody = "skip deployment [vercel skip test-workspace]"; - const mockExecSync = jest - .spyOn(child_process, "execSync") - .mockImplementation((_) => commitBody); - - expect(checkCommit({ workspace: "test-workspace" })).toEqual({ - result: "skip", - scope: "workspace", - reason: "Found commit message: [vercel skip test-workspace]", - }); - expect(mockExecSync).toHaveBeenCalledWith("git show -s --format=%B"); - mockExecSync.mockRestore(); - }); - }); - }); -}); diff --git a/packages/turbo-ignore/__tests__/errors.test.ts b/packages/turbo-ignore/__tests__/errors.test.ts deleted file mode 100644 index 18f26bd..0000000 --- a/packages/turbo-ignore/__tests__/errors.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { shouldWarn, NON_FATAL_ERRORS } from "../src/errors"; - -describe("shouldWarn()", () => { - it("it detects errors when packageManager is missing", async () => { - const result = shouldWarn({ - err: `run failed: We did not detect an in-use package manager for your project. Please set the "packageManager" property in your root package.json (https://nodejs.org/api/packages.html#packagemanager) or run \`npx @turbo/codemod add-package-manager\` in the root of your monorepo.`, - }); - expect(result.code).toBe("NO_PACKAGE_MANAGER"); - expect(result.level).toBe("warn"); - expect(result.message).toBe(NON_FATAL_ERRORS.NO_PACKAGE_MANAGER.message); - }); - - it("it detects errors when yarn lockfile is missing", async () => { - const result = shouldWarn({ - err: `* reading yarn.lock: open /test/../yarn.lock: no such file or directory`, - }); - expect(result.code).toBe("MISSING_LOCKFILE"); - expect(result.level).toBe("warn"); - expect(result.message).toBe(NON_FATAL_ERRORS.MISSING_LOCKFILE.message); - }); - - it("it detects errors when pnpm lockfile is missing", async () => { - const result = shouldWarn({ - err: `* reading pnpm-lock.yaml: open /test/../pnpm-lock.yaml: no such file or directory`, - }); - expect(result.code).toBe("MISSING_LOCKFILE"); - expect(result.level).toBe("warn"); - expect(result.message).toBe(NON_FATAL_ERRORS.MISSING_LOCKFILE.message); - }); - - it("it detects errors when npm lockfile is missing", async () => { - const result = shouldWarn({ - err: `* reading package-lock.json: open /test/../package-lock.json: no such file or directory`, - }); - expect(result.code).toBe("MISSING_LOCKFILE"); - expect(result.level).toBe("warn"); - expect(result.message).toBe(NON_FATAL_ERRORS.MISSING_LOCKFILE.message); - }); - - it("it returns unknown errors", async () => { - const result = shouldWarn({ err: `something bad happened` }); - expect(result.code).toBe("UNKNOWN_ERROR"); - expect(result.level).toBe("error"); - expect(result.message).toBe(`something bad happened`); - }); -}); diff --git a/packages/turbo-ignore/__tests__/getComparison.test.ts b/packages/turbo-ignore/__tests__/getComparison.test.ts deleted file mode 100644 index b5c74c7..0000000 --- a/packages/turbo-ignore/__tests__/getComparison.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { getComparison } from "../src/getComparison"; -import { spyConsole, mockEnv } from "@turbo/test-utils"; - -describe("getComparison()", () => { - mockEnv(); - const mockConsole = spyConsole(); - it("uses headRelative comparison when not running Vercel CI", async () => { - expect(getComparison({ workspace: "test-workspace" })) - .toMatchInlineSnapshot(` - Object { - "ref": "HEAD^", - "type": "headRelative", - } - `); - }); - - it("returns null when running in Vercel CI with no VERCEL_GIT_PREVIOUS_SHA", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_REF = "my-branch"; - expect(getComparison({ workspace: "test-workspace" })).toBeNull(); - expect(mockConsole.log).toHaveBeenCalledWith( - "≫ ", - 'No previous deployments found for "test-workspace" on branch "my-branch".' - ); - }); - - it("uses custom fallback when running in Vercel CI with no VERCEL_GIT_PREVIOUS_SHA", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_REF = "my-branch"; - expect(getComparison({ workspace: "test-workspace", fallback: "HEAD^2" })) - .toMatchInlineSnapshot(` - Object { - "ref": "HEAD^2", - "type": "customFallback", - } - `); - expect(mockConsole.log).toHaveBeenNthCalledWith( - 1, - "≫ ", - 'No previous deployments found for "test-workspace" on branch "my-branch".' - ); - expect(mockConsole.log).toHaveBeenNthCalledWith( - 2, - "≫ ", - "Falling back to ref HEAD^2" - ); - }); - - it("uses previousDeploy when running in Vercel CI with VERCEL_GIT_PREVIOUS_SHA", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_PREVIOUS_SHA = "mygitsha"; - process.env.VERCEL_GIT_COMMIT_REF = "my-branch"; - expect(getComparison({ workspace: "test-workspace" })) - .toMatchInlineSnapshot(` - Object { - "ref": "mygitsha", - "type": "previousDeploy", - } - `); - }); -}); diff --git a/packages/turbo-ignore/__tests__/getTask.test.ts b/packages/turbo-ignore/__tests__/getTask.test.ts deleted file mode 100644 index a184893..0000000 --- a/packages/turbo-ignore/__tests__/getTask.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { getTask } from "../src/getTask"; -import { spyConsole, validateLogs } from "@turbo/test-utils"; - -describe("getWorkspace()", () => { - const mockConsole = spyConsole(); - it("getTask defaults to build", async () => { - expect(getTask({})).toEqual("build"); - validateLogs( - ['Using "build" as the task as it was unspecified'], - mockConsole.log, - { prefix: "≫ " } - ); - }); - - it("getTask returns a quoted task if user-supplied", async () => { - expect( - getTask({ - task: "workspace#task", - }) - ).toEqual(`"workspace#task"`); - validateLogs( - ['Using "workspace#task" as the task from the arguments'], - mockConsole.log, - { prefix: "≫ " } - ); - }); -}); diff --git a/packages/turbo-ignore/__tests__/getWorkspace.test.ts b/packages/turbo-ignore/__tests__/getWorkspace.test.ts deleted file mode 100644 index 6d97fe2..0000000 --- a/packages/turbo-ignore/__tests__/getWorkspace.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { getWorkspace } from "../src/getWorkspace"; -import { spyConsole, validateLogs } from "@turbo/test-utils"; - -describe("getWorkspace()", () => { - const mockConsole = spyConsole(); - it("getWorkspace returns workspace from arg", async () => { - expect( - getWorkspace({ - workspace: "test-workspace", - }) - ).toEqual("test-workspace"); - validateLogs( - ['Using "test-workspace" as workspace from arguments'], - mockConsole.log, - { prefix: "≫ " } - ); - }); - - it("getWorkspace returns workspace from package.json", async () => { - expect( - getWorkspace({ - directory: "./__fixtures__/app", - }) - ).toEqual("test-app"); - expect(mockConsole.log).toHaveBeenCalledWith( - "≫ ", - 'Inferred "test-app" as workspace from "package.json"' - ); - }); - - it("getWorkspace used current directory if not specified", async () => { - expect(getWorkspace({})).toEqual("turbo-ignore"); - expect(mockConsole.log).toHaveBeenCalledWith( - "≫ ", - 'Inferred "turbo-ignore" as workspace from "package.json"' - ); - }); - - it("getWorkspace returns null when no arg is provided and package.json is missing name field", async () => { - expect( - getWorkspace({ - directory: "./__fixtures__/invalid-app", - }) - ).toEqual(null); - expect(mockConsole.error).toHaveBeenCalledWith( - "≫ ", - '"__fixtures__/invalid-app/package.json" is missing the "name" field (required).' - ); - }); - - it("getWorkspace returns null when no arg is provided and package.json can be found", async () => { - expect( - getWorkspace({ - directory: "./__fixtures__/no-app", - }) - ).toEqual(null); - expect(mockConsole.error).toHaveBeenCalledWith( - "≫ ", - '"__fixtures__/no-app/package.json" could not be found. turbo-ignore inferencing failed' - ); - }); -}); diff --git a/packages/turbo-ignore/__tests__/ignore.test.ts b/packages/turbo-ignore/__tests__/ignore.test.ts deleted file mode 100644 index 37908c5..0000000 --- a/packages/turbo-ignore/__tests__/ignore.test.ts +++ /dev/null @@ -1,578 +0,0 @@ -import child_process, { ChildProcess, ExecException } from "child_process"; -import turboIgnore from "../src/ignore"; -import { - spyConsole, - spyExit, - SpyExit, - mockEnv, - validateLogs, -} from "@turbo/test-utils"; - -function expectBuild(mockExit: SpyExit) { - expect(mockExit.exit).toHaveBeenCalledWith(1); -} - -function expectIgnore(mockExit: SpyExit) { - expect(mockExit.exit).toHaveBeenCalledWith(0); -} - -describe("turboIgnore()", () => { - mockEnv(); - const mockExit = spyExit(); - const mockConsole = spyConsole(); - - it("throws error and allows build when exec fails", async () => { - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback( - "error" as unknown as ExecException, - "stdout", - "stderr" - ) as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - - turboIgnore({ - args: { workspace: "test-workspace" }, - }); - - expect(mockExec).toHaveBeenCalledWith( - "npx turbo run build --filter=test-workspace...[HEAD^] --dry=json", - expect.anything(), - expect.anything() - ); - - validateLogs(["UNKNOWN_ERROR: error"], mockConsole.error, { - prefix: "≫ ", - }); - - expectBuild(mockExit); - mockExec.mockRestore(); - }); - - it("throws pretty error and allows build when exec fails", async () => { - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback( - { - message: - "run failed: We did not detect an in-use package manager for your project", - } as unknown as ExecException, - "stdout", - "stderr" - ) as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - - turboIgnore({ - args: { workspace: "test-workspace" }, - }); - - expect(mockExec).toHaveBeenCalledWith( - "npx turbo run build --filter=test-workspace...[HEAD^] --dry=json", - expect.anything(), - expect.anything() - ); - - validateLogs( - [ - `turbo-ignore could not complete - no package manager detected, please commit a lockfile, or set "packageManager" in your root "package.json"`, - ], - mockConsole.warn, - { prefix: "≫ " } - ); - - expectBuild(mockExit); - mockExec.mockRestore(); - }); - - it("throws pretty error and allows build when can't find previous sha", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_PREVIOUS_SHA = "too-far-back"; - process.env.VERCEL_GIT_COMMIT_REF = "my-branch"; - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback( - { - message: - " ERROR run failed: failed to resolve packages to run: commit too-far-back does not exist", - } as unknown as ExecException, - "stdout", - "stderr" - ) as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - - turboIgnore({ - args: { workspace: "test-workspace" }, - }); - - expect(mockExec).toHaveBeenCalledWith( - "npx turbo run build --filter=test-workspace...[too-far-back] --dry=json", - expect.anything(), - expect.anything() - ); - - validateLogs( - [ - `turbo-ignore could not complete - commit does not exist or is unreachable`, - ], - mockConsole.warn, - { prefix: "≫ " } - ); - - expectBuild(mockExit); - mockExec.mockRestore(); - }); - - it("throws pretty error and allows build when fallback fails", async () => { - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback( - { - message: - "ERROR run failed: failed to resolve packages to run: commit HEAD^ does not exist", - } as unknown as ExecException, - "stdout", - "stderr" - ) as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - - turboIgnore({ - args: { workspace: "test-workspace", fallback: "HEAD^" }, - }); - - expect(mockExec).toHaveBeenCalledWith( - "npx turbo run build --filter=test-workspace...[HEAD^] --dry=json", - expect.anything(), - expect.anything() - ); - - validateLogs( - [ - `turbo-ignore could not complete - parent commit does not exist or is unreachable`, - ], - mockConsole.warn, - { prefix: "≫ " } - ); - - expectBuild(mockExit); - mockExec.mockRestore(); - }); - - it("skips checks and allows build when no workspace can be found", async () => { - turboIgnore({ - args: { - directory: "__fixtures__/no-app", - }, - }); - validateLogs( - [ - () => [ - "≫ ", - expect.stringContaining( - " could not be found. turbo-ignore inferencing failed" - ), - ], - ], - mockConsole.error, - { prefix: "≫ " } - ); - expectBuild(mockExit); - }); - - it("skips checks and allows build when a workspace with no name is found", async () => { - turboIgnore({ - args: { - directory: "__fixtures__/invalid-app", - }, - }); - validateLogs( - [ - () => [ - "≫ ", - expect.stringContaining(' is missing the "name" field (required).'), - ], - ], - mockConsole.error, - { prefix: "≫ " } - ); - expectBuild(mockExit); - }); - - it("skips checks and allows build when no monorepo root can be found", async () => { - turboIgnore({ - args: { directory: "/" }, - }); - expectBuild(mockExit); - expect(mockConsole.error).toHaveBeenLastCalledWith( - "≫ ", - "Monorepo root not found. turbo-ignore inferencing failed" - ); - }); - - it("skips checks and allows build when TURBO_FORCE is set", async () => { - process.env.TURBO_FORCE = "true"; - turboIgnore({ - args: { workspace: "test-workspace" }, - }); - expect(mockConsole.log).toHaveBeenNthCalledWith( - 2, - "≫ ", - "`TURBO_FORCE` detected" - ); - expectBuild(mockExit); - }); - - it("allows build when no comparison is returned", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_PREVIOUS_SHA = ""; - process.env.VERCEL_GIT_COMMIT_REF = "my-branch"; - turboIgnore({ - args: { - workspace: "test-app", - directory: "__fixtures__/app", - }, - }); - expect(mockConsole.log).toHaveBeenNthCalledWith( - 4, - "≫ ", - 'No previous deployments found for "test-app" on branch "my-branch".' - ); - expectBuild(mockExit); - }); - - it("skips build for `previousDeploy` comparison with no changes", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_PREVIOUS_SHA = "last-deployed-sha"; - process.env.VERCEL_GIT_COMMIT_REF = "my-branch"; - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback( - null, - '{"packages":[],"tasks":[]}', - "stderr" - ) as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - turboIgnore({ - args: { - directory: "__fixtures__/app", - }, - }); - validateLogs( - [ - "Using Turborepo to determine if this project is affected by the commit...\n", - 'Inferred "test-app" as workspace from "package.json"', - 'Using "build" as the task as it was unspecified', - `Found previous deployment ("last-deployed-sha") for \"test-app\" on branch \"my-branch\"`, - "Analyzing results of `npx turbo run build --filter=test-app...[last-deployed-sha] --dry=json`", - "This project and its dependencies are not affected", - () => expect.stringContaining("⏭ Ignoring the change"), - ], - mockConsole.log, - { prefix: "≫ " } - ); - - expectIgnore(mockExit); - mockExec.mockRestore(); - }); - - it("allows build for `previousDeploy` comparison with changes", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_PREVIOUS_SHA = "last-deployed-sha"; - process.env.VERCEL_GIT_COMMIT_REF = "my-branch"; - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback( - null, - '{"packages":["test-app"],"tasks":[]}', - "stderr" - ) as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - turboIgnore({ - args: { - task: "workspace#build", - directory: "__fixtures__/app", - }, - }); - validateLogs( - [ - "Using Turborepo to determine if this project is affected by the commit...\n", - 'Inferred "test-app" as workspace from "package.json"', - 'Using "workspace#build" as the task from the arguments', - 'Found previous deployment ("last-deployed-sha") for "test-app" on branch "my-branch"', - 'Analyzing results of `npx turbo run "workspace#build" --filter=test-app...[last-deployed-sha] --dry=json`', - 'This commit affects "test-app"', - () => expect.stringContaining("✓ Proceeding with deployment"), - ], - mockConsole.log, - { prefix: "≫ " } - ); - - expectBuild(mockExit); - mockExec.mockRestore(); - }); - - it("allows build for `previousDeploy` comparison with single dependency change", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_PREVIOUS_SHA = "last-deployed-sha"; - process.env.VERCEL_GIT_COMMIT_REF = "my-branch"; - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback( - null, - '{"packages":["test-app", "ui"],"tasks":[]}', - "stderr" - ) as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - turboIgnore({ - args: { - directory: "__fixtures__/app", - }, - }); - validateLogs( - [ - "Using Turborepo to determine if this project is affected by the commit...\n", - 'Inferred "test-app" as workspace from "package.json"', - 'Using "build" as the task as it was unspecified', - 'Found previous deployment ("last-deployed-sha") for "test-app" on branch "my-branch"', - "Analyzing results of `npx turbo run build --filter=test-app...[last-deployed-sha] --dry=json`", - 'This commit affects "test-app" and 1 dependency (ui)', - () => expect.stringContaining("✓ Proceeding with deployment"), - ], - mockConsole.log, - { prefix: "≫ " } - ); - - expectBuild(mockExit); - mockExec.mockRestore(); - }); - - it("allows build for `previousDeploy` comparison with multiple dependency changes", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_PREVIOUS_SHA = "last-deployed-sha"; - process.env.VERCEL_GIT_COMMIT_REF = "my-branch"; - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback( - null, - '{"packages":["test-app", "ui", "tsconfig"],"tasks":[]}', - "stderr" - ) as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - turboIgnore({ - args: { - directory: "__fixtures__/app", - }, - }); - validateLogs( - [ - "Using Turborepo to determine if this project is affected by the commit...\n", - 'Inferred "test-app" as workspace from "package.json"', - 'Using "build" as the task as it was unspecified', - 'Found previous deployment ("last-deployed-sha") for "test-app" on branch "my-branch"', - "Analyzing results of `npx turbo run build --filter=test-app...[last-deployed-sha] --dry=json`", - 'This commit affects "test-app" and 2 dependencies (ui, tsconfig)', - () => expect.stringContaining("✓ Proceeding with deployment"), - ], - mockConsole.log, - { prefix: "≫ " } - ); - - expectBuild(mockExit); - mockExec.mockRestore(); - }); - - it("throws error and allows build when json cannot be parsed", async () => { - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback(null, "stdout", "stderr") as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - - turboIgnore({ - args: { - directory: "__fixtures__/app", - }, - }); - - expect(mockExec).toHaveBeenCalledWith( - "npx turbo run build --filter=test-app...[HEAD^] --dry=json", - expect.anything(), - expect.anything() - ); - validateLogs( - [ - "Failed to parse JSON output from `npx turbo run build --filter=test-app...[HEAD^] --dry=json`.", - ], - mockConsole.error, - { prefix: "≫ " } - ); - - expectBuild(mockExit); - mockExec.mockRestore(); - }); - - it("throws error and allows build when stdout is null", async () => { - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback( - null, - null as unknown as string, - "stderr" - ) as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - - turboIgnore({ - args: { - directory: "__fixtures__/app", - }, - }); - - expect(mockExec).toHaveBeenCalledWith( - "npx turbo run build --filter=test-app...[HEAD^] --dry=json", - expect.anything(), - expect.anything() - ); - validateLogs( - [ - "Failed to parse JSON output from `npx turbo run build --filter=test-app...[HEAD^] --dry=json`.", - ], - mockConsole.error, - { prefix: "≫ " } - ); - - expectBuild(mockExit); - mockExec.mockRestore(); - }); - - it("skips when commit message contains a skip string", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = "[vercel skip]"; - - turboIgnore({ - args: { - directory: "__fixtures__/app", - }, - }); - - validateLogs( - [ - "Using Turborepo to determine if this project is affected by the commit...\n", - 'Inferred "test-app" as workspace from "package.json"', - 'Using "build" as the task as it was unspecified', - "Found commit message: [vercel skip]", - () => expect.stringContaining("⏭ Ignoring the change"), - ], - mockConsole.log, - { prefix: "≫ " } - ); - - expectIgnore(mockExit); - }); - - it("deploys when commit message contains a deploy string", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = "[vercel deploy]"; - - turboIgnore({ - args: { - directory: "__fixtures__/app", - }, - }); - - validateLogs( - [ - "Using Turborepo to determine if this project is affected by the commit...\n", - 'Inferred "test-app" as workspace from "package.json"', - 'Using "build" as the task as it was unspecified', - "Found commit message: [vercel deploy]", - () => expect.stringContaining("✓ Proceeding with deployment"), - ], - mockConsole.log, - { prefix: "≫ " } - ); - - expectBuild(mockExit); - }); - - it("runs full turbo-ignore check when commit message contains a conflicting string", async () => { - process.env.VERCEL = "1"; - process.env.VERCEL_GIT_COMMIT_MESSAGE = "[vercel deploy] [vercel skip]"; - process.env.VERCEL_GIT_PREVIOUS_SHA = "last-deployed-sha"; - process.env.VERCEL_GIT_COMMIT_REF = "my-branch"; - - const mockExec = jest - .spyOn(child_process, "exec") - .mockImplementation((command, options, callback) => { - if (callback) { - return callback( - null, - '{"packages":[],"tasks":[]}', - "stderr" - ) as unknown as ChildProcess; - } - return {} as unknown as ChildProcess; - }); - - turboIgnore({ - args: { - directory: "__fixtures__/app", - }, - }); - - validateLogs( - [ - "Using Turborepo to determine if this project is affected by the commit...\n", - 'Inferred "test-app" as workspace from "package.json"', - 'Using "build" as the task as it was unspecified', - "Conflicting commit messages found: [vercel deploy] and [vercel skip]", - `Found previous deployment ("last-deployed-sha") for \"test-app\" on branch \"my-branch\"`, - "Analyzing results of `npx turbo run build --filter=test-app...[last-deployed-sha] --dry=json`", - "This project and its dependencies are not affected", - () => expect.stringContaining("⏭ Ignoring the change"), - ], - mockConsole.log, - { prefix: "≫ " } - ); - - expectIgnore(mockExit); - mockExec.mockRestore(); - }); -}); diff --git a/packages/turbo-ignore/jest.config.js b/packages/turbo-ignore/jest.config.js deleted file mode 100644 index 52ddbbc..0000000 --- a/packages/turbo-ignore/jest.config.js +++ /dev/null @@ -1,18 +0,0 @@ -/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ -module.exports = { - preset: "ts-jest/presets/js-with-ts", - testEnvironment: "node", - testPathIgnorePatterns: ["/__fixtures__/"], - coveragePathIgnorePatterns: ["/__fixtures__/"], - collectCoverage: true, - coverageThreshold: { - global: { - branches: 100, - functions: 100, - lines: 100, - statements: 100, - }, - }, - modulePathIgnorePatterns: ["/node_modules", "/dist"], - transformIgnorePatterns: ["/node_modules/(?!(ansi-regex)/)"], -}; diff --git a/packages/turbo-ignore/package.json b/packages/turbo-ignore/package.json deleted file mode 100644 index 0fae072..0000000 --- a/packages/turbo-ignore/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "turbo-ignore", - "version": "1.9.4-canary.2", - "description": "", - "homepage": "https://turbo.build/repo", - "keywords": [], - "author": "Jared Palmer", - "license": "MPL-2.0", - "repository": { - "type": "git", - "url": "https://github.com/vercel/turbo", - "directory": "packages/turbo-ignore" - }, - "bugs": { - "url": "https://github.com/vercel/turbo/issues" - }, - "files": [ - "dist" - ], - "main": "dist/index.js", - "bin": "dist/index.js", - "scripts": { - "build": "tsup", - "test": "jest", - "lint": "eslint src/**/*.ts", - "check-types": "tsc --noEmit" - }, - "devDependencies": { - "@types/jest": "^27.4.0", - "@types/node": "^16.11.12", - "eslint": "^8.20.0", - "jest": "^27.4.3", - "ts-jest": "^27.1.1", - "@turbo/tsconfig": "workspace:*", - "tsup": "^5.12.1", - "@turbo/test-utils": "workspace:^0.0.0", - "@turbo/utils": "workspace:*", - "typescript": "^4.7.4" - } -} diff --git a/packages/turbo-ignore/src/args.ts b/packages/turbo-ignore/src/args.ts deleted file mode 100644 index 8d6015c..0000000 --- a/packages/turbo-ignore/src/args.ts +++ /dev/null @@ -1,89 +0,0 @@ -import pkg from "../package.json"; -import { TurboIgnoreArgs } from "./types"; -import { - skipAllCommits, - forceAllCommits, - skipWorkspaceCommits, - forceWorkspaceCommits, -} from "./checkCommit"; - -export const help = ` -turbo-ignore - -Automatically ignore builds that have no changes - -Usage: - $ npx turbo-ignore [] [flags...] - -If is not provided, it will be inferred from the "name" -field of the "package.json" located at the current working directory. - -Flags: - --fallback= On Vercel, if no previously deployed SHA is available to compare against, - fallback to comparing against the provided ref - --help, -h Show this help message - --version, -v Show the version of this script - ---- - -turbo-ignore will also check for special commit messages to indicate if a build should be skipped or not. - -Skip turbo-ignore check and automatically ignore: -${[...skipAllCommits, ...skipWorkspaceCommits({ workspace: "" })] - .map((msg) => ` - ${msg}`) - .join("\n")} - -Skip turbo-ignore check and automatically deploy: -${[...forceAllCommits, ...forceWorkspaceCommits({ workspace: "" })] - .map((msg) => ` - ${msg}`) - .join("\n")} -`; - -// simple args parser because we don't want to pull in a dependency -// and we don't need many features -export default function parseArgs({ - argv, -}: { - argv: Array; -}): TurboIgnoreArgs { - const args: TurboIgnoreArgs = { directory: process.cwd() }; - - // find all flags - const flags = new Set( - argv - .filter((args) => args.startsWith("-")) - .map((flag) => flag.replace(/-/g, "")) - ); - - // handle help flag and exit - if (flags.has("help") || flags.has("h")) { - console.log(help); - process.exit(0); - } - // handle version flag and exit - if (flags.has("version") || flags.has("v")) { - console.log(pkg.version); - process.exit(0); - } - - // set workspace (if provided) - if (argv.length && !argv[0].startsWith("-")) { - args.workspace = argv[0]; - } - - // set task (if provided) - const taskArgSentinel = "--task="; - const taskArg = argv.find((arg) => arg.startsWith(taskArgSentinel)); - if (taskArg && taskArg.length > taskArgSentinel.length) { - args.task = taskArg.split("=")[1]; - } - - // set fallback (if provided) - const fallbackSentinel = "--fallback="; - const fallbackArg = argv.find((arg) => arg.startsWith(fallbackSentinel)); - if (fallbackArg && fallbackArg.length > fallbackSentinel.length) { - args.fallback = fallbackArg.split("=")[1]; - } - - return args; -} diff --git a/packages/turbo-ignore/src/checkCommit.ts b/packages/turbo-ignore/src/checkCommit.ts deleted file mode 100644 index af6108e..0000000 --- a/packages/turbo-ignore/src/checkCommit.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { execSync } from "child_process"; - -export const skipAllCommits = [ - `[skip ci]`, - `[ci skip]`, - `[no ci]`, - `[skip vercel]`, - `[vercel skip]`, -]; - -export const forceAllCommits = [`[vercel deploy]`, `[vercel build]`]; - -export function skipWorkspaceCommits({ workspace }: { workspace: string }) { - return [`[vercel skip ${workspace}]`]; -} - -export function forceWorkspaceCommits({ workspace }: { workspace: string }) { - return [`[vercel deploy ${workspace}]`, `[vercel build ${workspace}]`]; -} - -export function getCommitDetails() { - // if we're on Vercel, use the provided commit message - if (process.env.VERCEL === "1") { - if (process.env.VERCEL_GIT_COMMIT_MESSAGE) { - return process.env.VERCEL_GIT_COMMIT_MESSAGE; - } - } - return execSync("git show -s --format=%B").toString(); -} - -export function checkCommit({ workspace }: { workspace: string }): { - result: "skip" | "deploy" | "continue" | "conflict"; - scope: "global" | "workspace"; - reason: string; -} { - const commitMessage = getCommitDetails(); - const findInCommit = (commit: string) => commitMessage.includes(commit); - - // check workspace specific messages first - const forceWorkspaceDeploy = forceWorkspaceCommits({ workspace }).find( - findInCommit - ); - const forceWorkspaceSkip = skipWorkspaceCommits({ workspace }).find( - findInCommit - ); - - if (forceWorkspaceDeploy && forceWorkspaceSkip) { - return { - result: "conflict", - scope: "workspace", - reason: `Conflicting commit messages found: ${forceWorkspaceDeploy} and ${forceWorkspaceSkip}`, - }; - } - - if (forceWorkspaceDeploy) { - return { - result: "deploy", - scope: "workspace", - reason: `Found commit message: ${forceWorkspaceDeploy}`, - }; - } - - if (forceWorkspaceSkip) { - return { - result: "skip", - scope: "workspace", - reason: `Found commit message: ${forceWorkspaceSkip}`, - }; - } - - // check global messages last - const forceDeploy = forceAllCommits.find(findInCommit); - const forceSkip = skipAllCommits.find(findInCommit); - - if (forceDeploy && forceSkip) { - return { - result: "conflict", - scope: "global", - reason: `Conflicting commit messages found: ${forceDeploy} and ${forceSkip}`, - }; - } - - if (forceDeploy) { - return { - result: "deploy", - scope: "global", - reason: `Found commit message: ${forceDeploy}`, - }; - } - - if (forceSkip) { - return { - result: "skip", - scope: "global", - reason: `Found commit message: ${forceSkip}`, - }; - } - - return { - result: "continue", - scope: "global", - reason: `No deploy or skip string found in commit message.`, - }; -} diff --git a/packages/turbo-ignore/src/errors.ts b/packages/turbo-ignore/src/errors.ts deleted file mode 100644 index f600dfb..0000000 --- a/packages/turbo-ignore/src/errors.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { NonFatalErrorKey, NonFatalErrors } from "./types"; - -export const NON_FATAL_ERRORS: NonFatalErrors = { - MISSING_LOCKFILE: { - regex: - /reading (yarn.lock|package-lock.json|pnpm-lock.yaml):.*?no such file or directory/, - message: `turbo-ignore could not complete - no lockfile found, please commit one to your repository`, - }, - NO_PACKAGE_MANAGER: { - regex: - /run failed: We did not detect an in-use package manager for your project/, - message: `turbo-ignore could not complete - no package manager detected, please commit a lockfile, or set "packageManager" in your root "package.json"`, - }, - UNREACHABLE_PARENT: { - regex: /failed to resolve packages to run: commit HEAD\^ does not exist/, - message: `turbo-ignore could not complete - parent commit does not exist or is unreachable`, - }, - UNREACHABLE_COMMIT: { - regex: /commit \S+ does not exist/, - message: `turbo-ignore could not complete - commit does not exist or is unreachable`, - }, -}; - -export function shouldWarn({ err }: { err: string }): { - level: "warn" | "error"; - message: string; - code: NonFatalErrorKey | "UNKNOWN_ERROR"; -} { - const knownError = Object.keys(NON_FATAL_ERRORS).find((key) => { - const { regex } = NON_FATAL_ERRORS[key as NonFatalErrorKey]; - return regex.test(err); - }); - - if (knownError) { - return { - level: "warn", - message: NON_FATAL_ERRORS[knownError as NonFatalErrorKey].message, - code: knownError as NonFatalErrorKey, - }; - } - - return { level: "error", message: err, code: "UNKNOWN_ERROR" }; -} diff --git a/packages/turbo-ignore/src/getComparison.ts b/packages/turbo-ignore/src/getComparison.ts deleted file mode 100644 index a2ad61a..0000000 --- a/packages/turbo-ignore/src/getComparison.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { info } from "./logger"; -import { TurboIgnoreArgs } from "./types"; - -export interface GetComparisonArgs extends TurboIgnoreArgs { - // the workspace to check for changes - workspace: string; - // A ref/head to compare against if no previously deployed SHA is available - fallback?: string; -} - -export function getComparison(args: GetComparisonArgs): { - ref: string; - type: "previousDeploy" | "headRelative" | "customFallback"; -} | null { - const { fallback, workspace } = args; - if (process.env.VERCEL === "1") { - if (process.env.VERCEL_GIT_PREVIOUS_SHA) { - // use the commit SHA of the last successful deployment for this project / branch - info( - `Found previous deployment ("${process.env.VERCEL_GIT_PREVIOUS_SHA}") for "${workspace}" on branch "${process.env.VERCEL_GIT_COMMIT_REF}"` - ); - return { - ref: process.env.VERCEL_GIT_PREVIOUS_SHA, - type: "previousDeploy", - }; - } else { - info( - `No previous deployments found for "${workspace}" on branch "${process.env.VERCEL_GIT_COMMIT_REF}".` - ); - if (fallback) { - info(`Falling back to ref ${fallback}`); - return { ref: fallback, type: "customFallback" }; - } - - return null; - } - } - return { ref: "HEAD^", type: "headRelative" }; -} diff --git a/packages/turbo-ignore/src/getTask.ts b/packages/turbo-ignore/src/getTask.ts deleted file mode 100644 index 9e95e35..0000000 --- a/packages/turbo-ignore/src/getTask.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { info } from "./logger"; -import { TurboIgnoreArgs } from "./types"; - -export function getTask(args: TurboIgnoreArgs): string | null { - if (args.task) { - info(`Using "${args.task}" as the task from the arguments`); - return `"${args.task}"`; - } - - info('Using "build" as the task as it was unspecified'); - - return "build"; -} diff --git a/packages/turbo-ignore/src/getWorkspace.ts b/packages/turbo-ignore/src/getWorkspace.ts deleted file mode 100644 index e0b3167..0000000 --- a/packages/turbo-ignore/src/getWorkspace.ts +++ /dev/null @@ -1,37 +0,0 @@ -import fs from "fs"; -import path from "path"; -import { error, info } from "./logger"; -import { TurboIgnoreArgs } from "./types"; - -export function getWorkspace(args: TurboIgnoreArgs): string | null { - const { directory = process.cwd(), workspace } = args; - - // if the workspace is provided via args, use that - if (workspace) { - info(`Using "${workspace}" as workspace from arguments`); - return workspace; - } - - // otherwise, try and infer it from a package.json in the current directory - const packageJsonPath = path.join(directory, "package.json"); - try { - const raw = fs.readFileSync(packageJsonPath, "utf8"); - const packageJsonContent: Record & { name: string } = - JSON.parse(raw); - - if (!packageJsonContent.name) { - error(`"${packageJsonPath}" is missing the "name" field (required).`); - return null; - } - - info( - `Inferred "${packageJsonContent.name}" as workspace from "package.json"` - ); - return packageJsonContent.name; - } catch (e) { - error( - `"${packageJsonPath}" could not be found. turbo-ignore inferencing failed` - ); - return null; - } -} diff --git a/packages/turbo-ignore/src/ignore.ts b/packages/turbo-ignore/src/ignore.ts deleted file mode 100644 index a6f8f2e..0000000 --- a/packages/turbo-ignore/src/ignore.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { exec } from "child_process"; -import path from "path"; -import { getTurboRoot } from "@turbo/utils"; -import { getComparison } from "./getComparison"; -import { getTask } from "./getTask"; -import { getWorkspace } from "./getWorkspace"; -import { info, warn, error } from "./logger"; -import { shouldWarn } from "./errors"; -import { TurboIgnoreArgs } from "./types"; -import { checkCommit } from "./checkCommit"; - -function ignoreBuild() { - console.log("⏭ Ignoring the change"); - return process.exit(0); -} - -function continueBuild() { - console.log("✓ Proceeding with deployment"); - return process.exit(1); -} - -export default function turboIgnore({ args }: { args: TurboIgnoreArgs }) { - info( - `Using Turborepo to determine if this project is affected by the commit...\n` - ); - - // set default directory - args.directory = args.directory - ? path.resolve(args.directory) - : process.cwd(); - - // check for TURBO_FORCE and bail early if it's set - if (process.env.TURBO_FORCE === "true") { - info("`TURBO_FORCE` detected"); - return continueBuild(); - } - - // find the monorepo root - const root = getTurboRoot(args.directory); - if (!root) { - error("Monorepo root not found. turbo-ignore inferencing failed"); - return continueBuild(); - } - - // Find the workspace from the command-line args, or the package.json at the current directory - const workspace = getWorkspace(args); - if (!workspace) { - return continueBuild(); - } - - // Identify which task to execute from the command-line args - let task = getTask(args); - - // check the commit message - const parsedCommit = checkCommit({ workspace }); - if (parsedCommit.result === "skip") { - info(parsedCommit.reason); - return ignoreBuild(); - } - if (parsedCommit.result === "deploy") { - info(parsedCommit.reason); - return continueBuild(); - } - if (parsedCommit.result === "conflict") { - info(parsedCommit.reason); - } - - // Get the start of the comparison (previous deployment when available, or previous commit by default) - const comparison = getComparison({ workspace, fallback: args.fallback }); - if (!comparison) { - // This is either the first deploy of the project, or the first deploy for the branch, either way - build it. - return continueBuild(); - } - - // Build, and execute the command - const command = `npx turbo run ${task} --filter=${workspace}...[${comparison.ref}] --dry=json`; - info(`Analyzing results of \`${command}\``); - exec( - command, - { - cwd: root, - }, - (err, stdout) => { - if (err) { - const { level, code, message } = shouldWarn({ err: err.message }); - if (level === "warn") { - warn(message); - } else { - error(`${code}: ${err}`); - } - return continueBuild(); - } - - try { - const parsed = JSON.parse(stdout); - if (parsed == null) { - error(`Failed to parse JSON output from \`${command}\`.`); - return continueBuild(); - } - const { packages } = parsed; - if (packages && packages.length > 0) { - if (packages.length === 1) { - info(`This commit affects "${workspace}"`); - } else { - // subtract 1 because the first package is the workspace itself - info( - `This commit affects "${workspace}" and ${packages.length - 1} ${ - packages.length - 1 === 1 ? "dependency" : "dependencies" - } (${packages.slice(1).join(", ")})` - ); - } - - return continueBuild(); - } else { - info(`This project and its dependencies are not affected`); - return ignoreBuild(); - } - } catch (e) { - error(`Failed to parse JSON output from \`${command}\`.`); - error(e); - return continueBuild(); - } - } - ); -} diff --git a/packages/turbo-ignore/src/index.ts b/packages/turbo-ignore/src/index.ts deleted file mode 100644 index 0c34d3a..0000000 --- a/packages/turbo-ignore/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env node - -import turboIgnore from "./ignore"; -import parseArgs from "./args"; - -turboIgnore({ args: parseArgs({ argv: process.argv.slice(2) }) }); diff --git a/packages/turbo-ignore/src/logger.ts b/packages/turbo-ignore/src/logger.ts deleted file mode 100644 index a7903ac..0000000 --- a/packages/turbo-ignore/src/logger.ts +++ /dev/null @@ -1,16 +0,0 @@ -// ≫ -const TURBO_IGNORE_PREFIX = "\u226B "; - -function info(...args: any[]) { - console.log(TURBO_IGNORE_PREFIX, ...args); -} - -function error(...args: any[]) { - console.error(TURBO_IGNORE_PREFIX, ...args); -} - -function warn(...args: any[]) { - console.warn(TURBO_IGNORE_PREFIX, ...args); -} - -export { info, warn, error }; diff --git a/packages/turbo-ignore/src/types.ts b/packages/turbo-ignore/src/types.ts deleted file mode 100644 index 07fac3f..0000000 --- a/packages/turbo-ignore/src/types.ts +++ /dev/null @@ -1,23 +0,0 @@ -export type NonFatalErrorKey = - | "MISSING_LOCKFILE" - | "NO_PACKAGE_MANAGER" - | "UNREACHABLE_PARENT" - | "UNREACHABLE_COMMIT"; - -export interface NonFatalError { - regex: RegExp; - message: string; -} - -export type NonFatalErrors = Record; - -export interface TurboIgnoreArgs { - // the working directory to use when looking for a workspace - directory?: string; - // the workspace to check for changes - workspace?: string; - // the task to run, if not build - task?: string; - // A ref/head to compare against if no previously deployed SHA is available - fallback?: string; -} diff --git a/packages/turbo-ignore/tsconfig.json b/packages/turbo-ignore/tsconfig.json deleted file mode 100644 index 0620a3c..0000000 --- a/packages/turbo-ignore/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "@turbo/tsconfig/library.json", - "compilerOptions": { - "rootDir": "." - } -} diff --git a/packages/turbo-ignore/tsup.config.ts b/packages/turbo-ignore/tsup.config.ts deleted file mode 100644 index 4d9d9bf..0000000 --- a/packages/turbo-ignore/tsup.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { defineConfig, Options } from "tsup"; - -export default defineConfig((options: Options) => ({ - entry: ["src/index.ts"], - format: ["cjs"], - minify: true, - clean: true, - ...options, -})); diff --git a/packages/turbo-test-utils/README.md b/packages/turbo-test-utils/README.md deleted file mode 100644 index 60b6382..0000000 --- a/packages/turbo-test-utils/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `@turbo/test-utils` - -Internal package of generic testing utilities shared between [turborepo/packages/](https://github.com/vercel/turbo/tree/main/packages) diff --git a/packages/turbo-test-utils/package.json b/packages/turbo-test-utils/package.json deleted file mode 100644 index ff3f7f9..0000000 --- a/packages/turbo-test-utils/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "@turbo/test-utils", - "version": "0.0.0", - "private": true, - "description": "", - "homepage": "https://turbo.build/repo", - "keywords": [], - "author": "Vercel", - "main": "src/index.ts", - "license": "MPL-2.0", - "repository": { - "type": "git", - "url": "https://github.com/vercel/turbo", - "directory": "packages/turbo-test-utils" - }, - "bugs": { - "url": "https://github.com/vercel/turbo/issues" - }, - "scripts": { - "lint": "eslint src/**/*.ts", - "check-types": "tsc --noEmit" - }, - "devDependencies": { - "@types/fs-extra": "^9.0.13", - "@types/jest": "^27.4.0", - "@types/js-yaml": "^4.0.5", - "@types/node": "^16.11.12", - "@types/uuid": "^9.0.0", - "jest": "^27.4.3", - "ts-jest": "^27.1.1", - "@turbo/tsconfig": "workspace:*", - "typescript": "^4.7.4" - }, - "dependencies": { - "fs-extra": "^11.1.0", - "js-yaml": "^4.1.0", - "json5": "^2.2.3", - "uuid": "^9.0.0" - } -} diff --git a/packages/turbo-test-utils/src/index.ts b/packages/turbo-test-utils/src/index.ts deleted file mode 100644 index 07d0496..0000000 --- a/packages/turbo-test-utils/src/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export { default as setupTestFixtures } from "./useFixtures"; -export { default as validateLogs } from "./validateLogs"; -export { default as mockEnv } from "./mockEnv"; - -export { default as spyExit } from "./spyExit"; -export type { SpyExit } from "./spyExit"; - -export { default as spyConsole } from "./spyConsole"; -export type { SpyConsole } from "./spyConsole"; diff --git a/packages/turbo-test-utils/src/mockEnv.ts b/packages/turbo-test-utils/src/mockEnv.ts deleted file mode 100644 index 31909b0..0000000 --- a/packages/turbo-test-utils/src/mockEnv.ts +++ /dev/null @@ -1,12 +0,0 @@ -export default function mockEnv() { - const OLD_ENV = process.env; - - beforeEach(() => { - jest.resetModules(); - process.env = { ...OLD_ENV }; - }); - - afterAll(() => { - process.env = OLD_ENV; - }); -} diff --git a/packages/turbo-test-utils/src/spyConsole.ts b/packages/turbo-test-utils/src/spyConsole.ts deleted file mode 100644 index 61722a5..0000000 --- a/packages/turbo-test-utils/src/spyConsole.ts +++ /dev/null @@ -1,25 +0,0 @@ -export type SpyConsole = { log?: any; error?: any; warn?: any }; - -export default function spyConsole() { - let spy: SpyConsole = {}; - - beforeEach(() => { - spy.log = jest.spyOn(console, "log").mockImplementation(() => {}); - spy.error = jest.spyOn(console, "error").mockImplementation(() => {}); - spy.warn = jest.spyOn(console, "warn").mockImplementation(() => {}); - }); - - afterEach(() => { - spy.log.mockClear(); - spy.error.mockClear(); - spy.warn.mockClear(); - }); - - afterAll(() => { - spy.log.mockRestore(); - spy.error.mockRestore(); - spy.warn.mockRestore(); - }); - - return spy; -} diff --git a/packages/turbo-test-utils/src/spyExit.ts b/packages/turbo-test-utils/src/spyExit.ts deleted file mode 100644 index 1df9844..0000000 --- a/packages/turbo-test-utils/src/spyExit.ts +++ /dev/null @@ -1,21 +0,0 @@ -export type SpyExit = { exit?: any }; - -export default function spyExit() { - let spy: SpyExit = {}; - - beforeEach(() => { - spy.exit = jest - .spyOn(process, "exit") - .mockImplementation(() => undefined as never); - }); - - afterEach(() => { - spy.exit.mockClear(); - }); - - afterAll(() => { - spy.exit.mockRestore(); - }); - - return spy; -} diff --git a/packages/turbo-test-utils/src/useFixtures.ts b/packages/turbo-test-utils/src/useFixtures.ts deleted file mode 100644 index 2c47f5a..0000000 --- a/packages/turbo-test-utils/src/useFixtures.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { v4 as uuidv4 } from "uuid"; -import path from "path"; -import fs from "fs-extra"; -import yaml from "js-yaml"; -import JSON5 from "json5"; - -export default function setupTestFixtures({ - directory, - test = "", -}: { - directory: string; - test?: string; -}) { - const fixtures: Array = []; - const parentDirectory = path.join(directory, test ? test : "test-runs"); - - afterEach(() => { - fixtures.forEach((fixture) => { - fs.rmSync(fixture, { recursive: true, force: true }); - }); - }); - - afterAll(() => { - fs.rmSync(parentDirectory, { recursive: true, force: true }); - }); - - const useFixture = ({ fixture }: { fixture: string }) => { - const directoryName = uuidv4(); - const testDirectory = path.join(parentDirectory, directoryName); - if (!fs.existsSync(testDirectory)) { - fs.mkdirSync(testDirectory, { recursive: true }); - } - // keep track of it - fixtures.push(testDirectory); - - // copy fixture to test directory - const fixturePath = path.join(directory, "__fixtures__", test, fixture); - fs.copySync(fixturePath, testDirectory, { - recursive: true, - }); - - const getFilePath = (filename: string) => { - return path.isAbsolute(filename) - ? filename - : path.join(testDirectory, filename); - }; - - const readGenerator = (method: (filePath: string) => unknown) => { - return (filename: string) => { - try { - return method(getFilePath(filename)) as T; - } catch (e) { - return undefined; - } - }; - }; - - const write = ( - filename: string, - content: string | NodeJS.ArrayBufferView - ) => { - fs.writeFileSync(getFilePath(filename), content); - }; - - const exists = (filename: string): boolean => { - return fs.existsSync(getFilePath(filename)); - }; - - const read = readGenerator((filePath) => fs.readFileSync(filePath, "utf8")); - const readJson = readGenerator((filePath) => - JSON5.parse(fs.readFileSync(filePath, "utf8")) - ); - const readYaml = readGenerator((filePath) => - yaml.load(fs.readFileSync(filePath, "utf8")) - ); - - return { - root: testDirectory, - read, - readJson, - readYaml, - write, - exists, - directoryName, - }; - }; - - return { useFixture }; -} diff --git a/packages/turbo-test-utils/src/validateLogs.ts b/packages/turbo-test-utils/src/validateLogs.ts deleted file mode 100644 index b8e59ac..0000000 --- a/packages/turbo-test-utils/src/validateLogs.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { SpyConsole } from "./spyConsole"; - -export default function validateLogs( - logs: Array boolean | Array)>, - mockConsole: SpyConsole["log"] | SpyConsole["error"], - options: { prefix?: string } = {} -) { - logs.forEach((log, idx) => { - if (typeof log === "function") { - const expected = log(); - expect(mockConsole).toHaveBeenNthCalledWith( - idx + 1, - ...(Array.isArray(expected) ? expected : [expected]) - ); - } else { - if (options.prefix) { - expect(mockConsole).toHaveBeenNthCalledWith( - idx + 1, - options.prefix, - log - ); - } else { - expect(mockConsole).toHaveBeenNthCalledWith(idx + 1, log); - } - } - }); -} diff --git a/packages/turbo-test-utils/tsconfig.json b/packages/turbo-test-utils/tsconfig.json deleted file mode 100644 index 0620a3c..0000000 --- a/packages/turbo-test-utils/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "@turbo/tsconfig/library.json", - "compilerOptions": { - "rootDir": "." - } -} diff --git a/packages/turbo-tracing-next-plugin/README.md b/packages/turbo-tracing-next-plugin/README.md deleted file mode 100644 index dbd2609..0000000 --- a/packages/turbo-tracing-next-plugin/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# `@vercel/experimental-nft-next-plugin` - -## Installation - -- yarn add -D `@vercel/experimental-nft-next-plugin` -- npm install -D `@vercel/experimental-nft-next-plugin` -- pnpm install -D `@vercel/experimental-nft-next-plugin` - -## Usage - -```js -// next.config.js - -const { createNodeFileTrace } = require("@vercel/experimental-nft-next-plugin"); - -const withNodeFileTrace = createNodeFileTrace({ - // experimental nft options - log: { - all: true, - }, -}); - -module.exports = withNodeFileTrace({ - // next config -}); -``` - -### experimental nft options - -> **Note** -> -> The default options should work fine. - -- `cwd?: string`, default is `process.cwd()`, you can override it to specify another directory to run experimental nft. -- `contextDirectory?: string`, relative to cwd, default is `.`. It must be the directory where the `node_modules` directory is located. If you are in the monorepo, you should set it to the root directory of the monorepo. For yarn2+/npm workspaces, the default value will respect the `PROJECT_CWD` and `npm_config_local_prefix` environment variables injected by yarn/npm client. If the default value doesn't work, you can override it to specify the root directory of the monorepo. -- `path?: string`, additional path which will be appended into the `PATH` environment variable. -- `log?.all?: boolean`, default is `false`, whether to show all logs. -- `log?.level?: string`, default is `error`, the log level. -- `log?.detail?: boolean`, default is `false`, whether to expand the log details. diff --git a/packages/turbo-tracing-next-plugin/package.json b/packages/turbo-tracing-next-plugin/package.json deleted file mode 100644 index e2f0662..0000000 --- a/packages/turbo-tracing-next-plugin/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "@vercel/experimental-nft-next-plugin", - "version": "0.0.3-alpha.2", - "license": "MPL-2.0", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "files": [ - "dist/**/*" - ], - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@vercel/webpack-nft": "workspace:*" - }, - "peerDependencies": { - "next": ">= 12" - }, - "devDependencies": { - "next": "^13.0.6" - }, - "scripts": { - "lint": "eslint src/**/*.ts" - } -} diff --git a/packages/turbo-tracing-next-plugin/src/index.ts b/packages/turbo-tracing-next-plugin/src/index.ts deleted file mode 100644 index 0b75113..0000000 --- a/packages/turbo-tracing-next-plugin/src/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { - NodeModuleTracePlugin, - NodeModuleTracePluginOptions, -} from "@vercel/webpack-nft"; -import type { NextConfig } from "next"; - -export function createNodeFileTrace(options?: NodeModuleTracePluginOptions) { - return function withNodeFileTrace(config: NextConfig = {}) { - const createWebpackConfig = config.webpack; - config.outputFileTracing = false; - config.webpack = (webpackConfig, context) => { - const config = - createWebpackConfig?.(webpackConfig, context) ?? webpackConfig; - if (context.isServer && !context.dev) { - const plugin = new NodeModuleTracePlugin(options); - if (config.plugins) { - config.plugins.push(plugin); - } else { - config.plugins = [plugin]; - } - } - - return config; - }; - return config; - }; -} diff --git a/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.env.local.example b/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.env.local.example deleted file mode 100644 index 9dead41..0000000 --- a/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.env.local.example +++ /dev/null @@ -1 +0,0 @@ -MONGODB_URI= \ No newline at end of file diff --git a/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.gitignore b/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.gitignore deleted file mode 100644 index 1437c53..0000000 --- a/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env.local -.env.development.local -.env.test.local -.env.production.local - -# vercel -.vercel diff --git a/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/README.md b/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/README.md deleted file mode 100644 index 1f7110e..0000000 --- a/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# MongoDB and Mongoose with Next.js - -Copied from https://github.com/vercel/next.js/tree/canary/examples/with-mongodb. - -Run `pnpm run --filter @vercel/turbo-tracing-test-app build` to build this application. diff --git a/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/components/Form.js b/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/components/Form.js deleted file mode 100644 index b184d9c..0000000 --- a/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/components/Form.js +++ /dev/null @@ -1,202 +0,0 @@ -import { useState } from "react"; -import { useRouter } from "next/router"; -import { mutate } from "swr"; - -const Form = ({ formId, petForm, forNewPet = true }) => { - const router = useRouter(); - const contentType = "application/json"; - const [errors, setErrors] = useState({}); - const [message, setMessage] = useState(""); - - const [form, setForm] = useState({ - name: petForm.name, - owner_name: petForm.owner_name, - species: petForm.species, - age: petForm.age, - poddy_trained: petForm.poddy_trained, - diet: petForm.diet, - image_url: petForm.image_url, - likes: petForm.likes, - dislikes: petForm.dislikes, - }); - - /* The PUT method edits an existing entry in the mongodb database. */ - const putData = async (form) => { - const { id } = router.query; - - try { - const res = await fetch(`/api/pets/${id}`, { - method: "PUT", - headers: { - Accept: contentType, - "Content-Type": contentType, - }, - body: JSON.stringify(form), - }); - - // Throw error with status code in case Fetch API req failed - if (!res.ok) { - throw new Error(res.status); - } - - const { data } = await res.json(); - - mutate(`/api/pets/${id}`, data, false); // Update the local data without a revalidation - router.push("/"); - } catch (error) { - setMessage("Failed to update pet"); - } - }; - - /* The POST method adds a new entry in the mongodb database. */ - const postData = async (form) => { - try { - const res = await fetch("/api/pets", { - method: "POST", - headers: { - Accept: contentType, - "Content-Type": contentType, - }, - body: JSON.stringify(form), - }); - - // Throw error with status code in case Fetch API req failed - if (!res.ok) { - throw new Error(res.status); - } - - router.push("/"); - } catch (error) { - setMessage("Failed to add pet"); - } - }; - - const handleChange = (e) => { - const target = e.target; - const value = - target.name === "poddy_trained" ? target.checked : target.value; - const name = target.name; - - setForm({ - ...form, - [name]: value, - }); - }; - - const handleSubmit = (e) => { - e.preventDefault(); - const errs = formValidate(); - if (Object.keys(errs).length === 0) { - forNewPet ? postData(form) : putData(form); - } else { - setErrors({ errs }); - } - }; - - /* Makes sure pet info is filled for pet name, owner name, species, and image url*/ - const formValidate = () => { - let err = {}; - if (!form.name) err.name = "Name is required"; - if (!form.owner_name) err.owner_name = "Owner is required"; - if (!form.species) err.species = "Species is required"; - if (!form.image_url) err.image_url = "Image URL is required"; - return err; - }; - - return ( - <> -
- - - - - - - - - - - - - - - - -