diff --git a/src/services/functions/build/build.rust.services.ts b/src/services/functions/build/build.rust.services.ts index 6bd5f31..8defbbf 100644 --- a/src/services/functions/build/build.rust.services.ts +++ b/src/services/functions/build/build.rust.services.ts @@ -26,6 +26,7 @@ import {checkRustVersion} from '../../../utils/env.utils'; import {formatTime} from '../../../utils/format.utils'; import {readPackageJson} from '../../../utils/pkg.utils'; import {detectPackageManager} from '../../../utils/pm.utils'; +import {isHeadless} from '../../../utils/process.utils'; import {readEmulatorConfigAndCreateDeployTargetDir} from '../../emulator/_fs.services'; import {prepareJunoPkgForSatellite, prepareJunoPkgForSputnik} from './build.metadata.services'; import {dispatchEmulatorTouchSatellite} from './touch.services'; @@ -52,7 +53,7 @@ export const buildRust = async ({ return; } - const {valid: validBindgen} = await checkIcpBindgen(); + const {valid: validBindgen} = await checkIcpBindgen({withGlobalFallback: isHeadless()}); if (!validBindgen) { return; diff --git a/src/utils/build.bindgen.utils.ts b/src/utils/build.bindgen.utils.ts index 8e3d343..f95cd48 100644 --- a/src/utils/build.bindgen.utils.ts +++ b/src/utils/build.bindgen.utils.ts @@ -1,36 +1,72 @@ import {isNullish} from '@dfinity/utils'; import {execute} from '@junobuild/cli-tools'; import {magenta} from 'kleur'; +import {type PackageManager} from '../types/pm'; import {checkToolInstalled} from './env.utils'; import {detectPackageManager} from './pm.utils'; import {confirmAndExit} from './prompt.utils'; -export const checkIcpBindgen = async (): Promise<{valid: boolean}> => { +export const checkIcpBindgen = async ({ + withGlobalFallback +}: { + withGlobalFallback: boolean; +}): Promise<{valid: boolean}> => { const pm = detectPackageManager(); - const command = pm === 'npm' || isNullish(pm) ? 'npx' : pm; + const {valid: localValid} = await checkLocalIcpBindgen({pm}); - const {valid} = await checkToolInstalled({ - command, - args: ['icp-bindgen', '--version', ...(command === 'npx' ? ['--no'] : [])] - }); + if (localValid === true) { + return {valid: true}; + } - if (valid === false) { - return {valid}; + if (withGlobalFallback) { + const {valid: globalValid} = await checkGlobalIcpBindgen(); + + if (globalValid === true) { + return {valid: true}; + } + + // Useful the day we require a specific version of the tool. + if (globalValid === false) { + return {valid: globalValid}; + } } - if (valid === 'error') { - await confirmAndExit( - `${magenta( - '@icp-sdk/bindgen' - )} is not available. This tool is required to generate API bindings. Would you like to install it now?` - ); - - await execute({ - command: pm ?? 'npm', - args: [pm === 'npm' ? 'i' : 'add', '@icp-sdk/bindgen', '-D'] - }); + // Useful the day we require a specific version of the tool. + if (localValid === false) { + return {valid: localValid}; } + await confirmAndExit( + `${magenta( + '@icp-sdk/bindgen' + )} is not available. This tool is required to generate API bindings. Would you like to install it now?` + ); + + await execute({ + command: pm ?? 'npm', + args: [pm === 'npm' ? 'i' : 'add', '@icp-sdk/bindgen', '-D'] + }); + return {valid: true}; }; + +const checkLocalIcpBindgen = async ({ + pm +}: { + pm: PackageManager | undefined; +}): Promise<{valid: boolean | 'error'}> => { + const command = pm === 'npm' || isNullish(pm) ? 'npx' : pm; + + return await checkToolInstalled({ + command, + args: ['icp-bindgen', '--version', ...(command === 'npx' ? ['--no'] : [])] + }); +}; + +const checkGlobalIcpBindgen = async (): Promise<{valid: boolean | 'error'}> => { + return await checkToolInstalled({ + command: 'icp-bindgen', + args: ['--version'] + }); +};