From c3082c6a19337c1197dc8e5b4df48f2adf350667 Mon Sep 17 00:00:00 2001 From: Jacek Date: Sat, 26 Oct 2024 14:25:41 -0500 Subject: [PATCH 1/4] feat(upgrade): enhance error handling --- packages/upgrade/src/app.js | 7 +--- packages/upgrade/src/cli.js | 2 - packages/upgrade/src/components/Codemod.js | 2 +- .../upgrade/src/components/SDKWorkflow.js | 4 +- packages/upgrade/src/components/UpgradeSDK.js | 41 ++++++++++++++----- 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/packages/upgrade/src/app.js b/packages/upgrade/src/app.js index ee181f62fa1..10b9bff4427 100644 --- a/packages/upgrade/src/app.js +++ b/packages/upgrade/src/app.js @@ -63,12 +63,7 @@ export default function App(props) { // Handle the individual SDK upgrade if (!fromVersion && !toVersion && sdks[0] === 'nextjs') { - return ( - - ); + return ; } // We try to guess which SDK they are using diff --git a/packages/upgrade/src/cli.js b/packages/upgrade/src/cli.js index 78ad8769b33..da191342805 100644 --- a/packages/upgrade/src/cli.js +++ b/packages/upgrade/src/cli.js @@ -17,7 +17,6 @@ const cli = meow( --sdk Name of the SDK you're upgrading --dir Directory you'd like to scan for files --ignore Any files or directories you'd like to ignore - --packageManager The package manager you're using (npm, yarn, pnpm) --noWarnings Do not print warnings, only items that must be fixed --disableTelemetry Do not send anonymous usage telemetry @@ -34,7 +33,6 @@ const cli = meow( sdk: { type: 'string', choices: sdks.map(i => i.value) }, dir: { type: 'string' }, ignore: { type: 'string', isMultiple: true }, - packageManager: { type: 'string' }, yolo: { type: 'boolean' }, noWarnings: { type: 'boolean' }, disableTelemetry: { type: 'boolean' }, diff --git a/packages/upgrade/src/components/Codemod.js b/packages/upgrade/src/components/Codemod.js index 9350dd110ad..9498dd800f4 100644 --- a/packages/upgrade/src/components/Codemod.js +++ b/packages/upgrade/src/components/Codemod.js @@ -58,7 +58,7 @@ export function Codemod(props) { )} - {!result && !error && glob && codemod... ${transform}`} />} + {!result && !error && glob && } {result && ( <> diff --git a/packages/upgrade/src/components/SDKWorkflow.js b/packages/upgrade/src/components/SDKWorkflow.js index 4c734e18ca6..bf07c29f5c0 100644 --- a/packages/upgrade/src/components/SDKWorkflow.js +++ b/packages/upgrade/src/components/SDKWorkflow.js @@ -16,13 +16,12 @@ import { UpgradeSDK } from './UpgradeSDK.js'; * * @component * @param {Object} props - * @param {string} props.packageManager - The package manager to use for the upgrade, if needed. * @param {string} props.sdk - The SDK to be upgraded. * * @returns {JSX.Element} The rendered component. */ export function SDKWorkflow(props) { - const { packageManager, sdk } = props; + const { sdk } = props; const [done, setDone] = useState(false); const [runCodemod, setRunCodemod] = useState(false); @@ -59,7 +58,6 @@ export function SDKWorkflow(props) { <> {upgradeComplete ? ( diff --git a/packages/upgrade/src/components/UpgradeSDK.js b/packages/upgrade/src/components/UpgradeSDK.js index 1f52fffbb25..11d19055530 100644 --- a/packages/upgrade/src/components/UpgradeSDK.js +++ b/packages/upgrade/src/components/UpgradeSDK.js @@ -1,4 +1,4 @@ -import { Spinner, StatusMessage } from '@inkjs/ui'; +import { Select, Spinner, StatusMessage } from '@inkjs/ui'; import { execa } from 'execa'; import { existsSync } from 'fs'; import { Text } from 'ink'; @@ -11,13 +11,12 @@ function detectPackageManager() { return 'yarn'; } else if (existsSync('pnpm-lock.yaml')) { return 'pnpm'; - } else { - return 'npm'; } + return undefined; } function upgradeCommand(sdk, packageManager) { - switch (packageManager || detectPackageManager()) { + switch (packageManager) { case 'yarn': return `yarn add @clerk/${sdk}@latest`; case 'pnpm': @@ -33,20 +32,26 @@ function upgradeCommand(sdk, packageManager) { * @component * @param {Object} props * @param {Function} props.callback - The callback function to be called after the command execution. - * @param {string} props.packageManager - The package manager used in the project in case we cannot detect it automatically. * @param {string} props.sdk - The SDK for which the upgrade command is run. * @returns {JSX.Element} The rendered component. * * @example * */ -export function UpgradeSDK({ callback, packageManager, sdk }) { +export function UpgradeSDK({ callback, sdk }) { + const [command, setCommand] = useState(); const [error, setError] = useState(); + const [packageManager, setPackageManager] = useState(detectPackageManager()); const [result, setResult] = useState(); - const command = upgradeCommand(sdk, packageManager); - useEffect(() => { + if (!packageManager) return; + setCommand(previous => { + if (previous) return previous; + return upgradeCommand(sdk, packageManager); + }); + if (!command) return; + execa({ shell: true })`${command}` .then(res => { setResult(res); @@ -55,11 +60,27 @@ export function UpgradeSDK({ callback, packageManager, sdk }) { .catch(err => { setError(err); }); - }, [command]); + }, [command, packageManager, sdk]); return ( <> - {!result && !error && } + {packageManager ? null : ( + <> + + We could not detect the package manager used in your project. Please select the package manager you are + using + +