aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts
diff options
context:
space:
mode:
author简律纯 <hsiangnianian@outlook.com>2023-04-28 01:36:44 +0800
committer简律纯 <hsiangnianian@outlook.com>2023-04-28 01:36:44 +0800
commitdd84b9d64fb98746a230cd24233ff50a562c39c9 (patch)
treeb583261ef00b3afe72ec4d6dacb31e57779a6faf /packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts
parent0b46fcd72ac34382387b2bcf9095233efbcc52f4 (diff)
downloadHydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.tar.gz
HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.zip
Diffstat (limited to 'packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts')
-rw-r--r--packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts182
1 files changed, 182 insertions, 0 deletions
diff --git a/packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts b/packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts
new file mode 100644
index 0000000..8fd5972
--- /dev/null
+++ b/packages/turbo-codemod/src/commands/migrate/steps/getTurboUpgradeCommand.ts
@@ -0,0 +1,182 @@
+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<PackageManager, string | undefined> {
+ 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 | boolean | undefined>
+ ): 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;
+}