diff --git a/src/commands/init/init.ts b/src/commands/init/init.ts index f124884398e..cb0141ae6df 100644 --- a/src/commands/init/init.ts +++ b/src/commands/init/init.ts @@ -2,7 +2,7 @@ import { OptionValues } from 'commander' import inquirer from 'inquirer' import isEmpty from 'lodash/isEmpty.js' -import { chalk, exit, log } from '../../utils/command-helpers.js' +import { chalk, exit, log, netlifyCommand } from '../../utils/command-helpers.js' import getRepoData from '../../utils/get-repo-data.js' import { ensureNetlifyIgnore } from '../../utils/gitignore.js' import { configureRepo } from '../../utils/init/config.js' @@ -31,8 +31,8 @@ const logExistingAndExit = ({ siteInfo }: { siteInfo: SiteInfo }): never => { log(`Admin URL: ${chalk.cyan(siteInfo.admin_url)}`) log() log(`To disconnect this directory and create a new project (or link to another project ID)`) - log(`1. Run ${chalk.cyanBright.bold('netlify unlink')}`) - log(`2. Then run ${chalk.cyanBright.bold('netlify init')} again`) + log(`1. Run ${chalk.cyanBright.bold(`${netlifyCommand()} unlink`)}`) + log(`2. Then run ${chalk.cyanBright.bold(`${netlifyCommand()} init`)} again`) return exit() } @@ -78,7 +78,7 @@ const createNewSiteAndExit = async ({ } log() - log(`To deploy to this project, run ${chalk.cyanBright.bold('netlify deploy')}`) + log(`To deploy to this project, run ${chalk.cyanBright.bold(`${netlifyCommand()} deploy`)}`) return exit() } @@ -111,7 +111,7 @@ const logGitSetupInstructionsAndExit = (): never => { 7. Initialize your Netlify Site - ${chalk.cyanBright.bold('netlify init')} + ${chalk.cyanBright.bold(`${netlifyCommand()} init`)} `) return exit() } diff --git a/src/commands/link/link.ts b/src/commands/link/link.ts index 552ca3a27b6..a0d7619f6c6 100644 --- a/src/commands/link/link.ts +++ b/src/commands/link/link.ts @@ -6,7 +6,7 @@ import type { NetlifyAPI } from '@netlify/api' import { listSites } from '../../lib/api.js' import { startSpinner } from '../../lib/spinner.js' -import { chalk, logAndThrowError, exit, log, APIError } from '../../utils/command-helpers.js' +import { chalk, logAndThrowError, exit, log, APIError, netlifyCommand } from '../../utils/command-helpers.js' import getRepoData from '../../utils/get-repo-data.js' import { ensureNetlifyIgnore } from '../../utils/gitignore.js' import { track } from '../../utils/telemetry/index.js' @@ -23,7 +23,9 @@ const findSiteByRepoUrl = async (api: NetlifyAPI, repoUrl: string): Promise([ { @@ -142,8 +144,8 @@ const linkPrompt = async (command: BaseCommand, options: LinkOptionValues): Prom if (!matchingSites || matchingSites.length === 0) { return logAndThrowError(`No project names found containing '${searchTerm}'. -Run ${chalk.cyanBright('netlify link')} again to try a new search, -or run ${chalk.cyanBright('netlify sites:create')} to create a project.`) +Run ${chalk.cyanBright(`${netlifyCommand()} link`)} again to try a new search, +or run ${chalk.cyanBright(`npx ${netlifyCommand()} sites:create`)} to create a project.`) } if (matchingSites.length > 1) { @@ -183,7 +185,9 @@ or run ${chalk.cyanBright('netlify sites:create')} to create a project.`) if (!sites || sites.length === 0) { return logAndThrowError( - `You don't have any projects yet. Run ${chalk.cyanBright('netlify sites:create')} to create a project.`, + `You don't have any projects yet. Run ${chalk.cyanBright( + `${netlifyCommand()} sites:create`, + )} to create a project.`, ) } @@ -271,7 +275,7 @@ export const link = async (options: LinkOptionValues, command: BaseCommand) => { // Site id is incorrect if (siteId && isEmpty(siteInfo)) { log(`"${siteId}" was not found in your Netlify account.`) - log(`Please double check your project ID and which account you are logged into via \`netlify status\`.`) + log(`Please double check your project ID and which account you are logged into via \`${netlifyCommand()} status\`.`) return exit() } @@ -281,7 +285,7 @@ export const link = async (options: LinkOptionValues, command: BaseCommand) => { log(`Project already linked to "${initialSiteData.name}"`) log(`Admin url: ${initialSiteData.admin_url}`) log() - log(`To unlink this project, run: ${chalk.cyanBright('netlify unlink')}`) + log(`To unlink this project, run: ${chalk.cyanBright(`${netlifyCommand()} unlink`)}`) } else if (options.id) { try { // @ts-expect-error FIXME(serhalp): Mismatch between hardcoded `SiteInfo` and new generated Netlify API types. diff --git a/src/utils/command-helpers.ts b/src/utils/command-helpers.ts index 2129ffa4b8a..da919b60ebf 100644 --- a/src/utils/command-helpers.ts +++ b/src/utils/command-helpers.ts @@ -348,3 +348,27 @@ export const checkFileForLine = (filename: string, line: string) => { export const TABTAB_CONFIG_LINE = '[[ -f ~/.config/tabtab/__tabtab.zsh ]] && . ~/.config/tabtab/__tabtab.zsh || true' export const AUTOLOAD_COMPINIT = 'autoload -U compinit; compinit' + +function pkgFromUserAgent(userAgent: string | undefined): string | undefined { + if (!userAgent) return undefined + const pkgSpec = userAgent.split(' ')[0] + const [pkgManagerName] = pkgSpec.split('/') + return pkgManagerName +} + +export const netlifyCommand = () => { + const { npm_command, npm_config_user_agent, npm_lifecycle_event } = process.env + + // Captures both `npx netlify ...` and `npm exec netlify ...` + if (npm_lifecycle_event === 'npx') { + return `npx netlify` + } + + // Captures both `pnpx netlify ...` and `pnpm exec netlify ...` + if (pkgFromUserAgent(npm_config_user_agent) === 'pnpm' && npm_command === 'exec') { + return `pnpx netlify` + } + + // Default + return 'netlify' +}