Skip to content

Commit

Permalink
fix getPackageVersion and use it to discern use of dlx (#264)
Browse files Browse the repository at this point in the history
* fix getPackageVersion and use it to discern use of dlx

fix the getPackageVersion (currently not correctly parsing packages using pnpm)
and use it in the getVercelBuildChildProcess to decide if for yarn and pnpm
we should include the dlx option

resolves #250
resolves #262
  • Loading branch information
dario-piotrowicz authored May 22, 2023
1 parent 81bfcdb commit 97c8739
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 51 deletions.
17 changes: 17 additions & 0 deletions .changeset/tender-rats-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
'@cloudflare/next-on-pages': patch
---

fix getPackageVersion and use it to discern use of dlx

fix the `getPackageVersion` function so that it doesn't wrongly produce `N/A` (thus
improving the `-i|--info` results)

the when running `vercel build`, use the function to discern if `dlx` should be added
(for `yarn (berry)` and `pnpm` commands), ensuring that the vercel package is not
unnecessarily re-fetched/installed

> **Note**
> Currently the aforementioned check (and build command) runs `next-on-pages-vercel-cli`
> anyways that's a temporary solution, the changes here will also apply when we switch
> back to the proper vercel cli package
24 changes: 14 additions & 10 deletions src/buildApplication/buildVercelOutput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { join, resolve } from 'path';
import { cliLog } from '../cli';
import { validateDir, validateFile } from '../utils';
import type { PackageManager } from './packageManagerUtils';
import { getPackageVersion } from './packageManagerUtils';
import {
getCurrentPackageExecuter,
getCurrentPackageManager,
Expand Down Expand Up @@ -112,24 +113,27 @@ async function getVercelBuildChildProcess(
pkgMng: PackageManager
): Promise<ChildProcessWithoutNullStreams> {
const pkgMngCMD = getPackageManagerSpawnCommand(pkgMng);
if (pkgMng === 'yarn (berry)') {
const isYarnBerry = pkgMng === 'yarn (berry)';
const isPnpm = pkgMngCMD.startsWith('pnpm');
let useDlx = false;

if (isYarnBerry || isPnpm) {
const vercelPackageIsInstalled = await isVercelPackageInstalled(pkgMng);
if (!vercelPackageIsInstalled) {
return spawn(pkgMngCMD, ['dlx', 'next-on-pages-vercel-cli', 'build']);
}
useDlx = !vercelPackageIsInstalled;
}

return spawn(pkgMngCMD, ['next-on-pages-vercel-cli', 'build']);
return spawn(pkgMngCMD, [
...(useDlx ? ['dlx'] : []),
'next-on-pages-vercel-cli',
'build',
]);
}

async function isVercelPackageInstalled(
pkgMng: PackageManager
): Promise<boolean> {
const pkgMngCMD = getPackageManagerSpawnCommand(pkgMng);
const infoVercelExitCode = await new Promise(resolve =>
spawn(pkgMngCMD, ['info', 'vercel']).on('exit', resolve)
);
return infoVercelExitCode === 0;
const packageVersion = getPackageVersion(pkgMng, 'next-on-pages-vercel-cli');
return !!packageVersion;
}

/**
Expand Down
55 changes: 51 additions & 4 deletions src/buildApplication/packageManagerUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import YAML from 'js-yaml';
import { spawn } from 'child_process';
import { execFileSync, spawn } from 'child_process';
import { readFile } from 'fs/promises';
import { cliError } from '../cli';
import { validateFile } from '../utils';
Expand Down Expand Up @@ -67,22 +67,69 @@ export async function getCurrentPackageExecuter(): Promise<string> {
}

const packageManagers = {
pnpm: 'pnpx',
pnpm: 'pnpm',
'yarn (berry)': 'yarn',
'yarn (classic)': 'yarn',
yarn: 'yarn',
npm: 'npx',
};
} as const;

export type PackageManager = keyof typeof packageManagers;

type PackageManagerCommand = `${(typeof packageManagers)[PackageManager]}${
| '.cmd'
| ''}`;

export function getPackageManagerSpawnCommand(
pkgMng: keyof typeof packageManagers
): string {
): PackageManagerCommand {
const winCMD = isWindows() ? '.cmd' : '';
return `${packageManagers[pkgMng]}${winCMD}`;
}

function isWindows(): boolean {
return process.platform === 'win32';
}

export function getPackageVersion(
packageManager: PackageManager,
packageName: string
): string | null {
try {
const command = getPackageManagerSpawnCommand(packageManager);
const commandOutput = execFileSync(
command.startsWith('npx') ? 'npm' : command,
[
command === 'yarn' ? 'info' : 'list',
packageName,
'--json',
...(command === 'yarn' ? [] : ['--depth=0']),
],
{ stdio: 'pipe' }
)
.toString()
.trim();

const commandJsonOuput = JSON.parse(commandOutput);
const packageInfo =
packageManager === 'pnpm' ? commandJsonOuput[0] : commandJsonOuput;
const packageVersion =
command === 'yarn'
? packageInfo?.children?.Version
: packageInfo?.dependencies[packageName]?.version;
return packageVersion ?? null;
} catch {
return null;
}
}

export function getBinaryVersion(binaryName: PackageManager): string | null {
const commandArgs = ['--version'];
try {
return execFileSync(getPackageManagerSpawnCommand(binaryName), commandArgs)
.toString()
.trim();
} catch {
return null;
}
}
46 changes: 9 additions & 37 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import os from 'os';
import { execFileSync } from 'child_process';
import dedent from 'dedent-tabs';
import { z } from 'zod';
import { argumentParser } from 'zodcli';
import type { ChalkInstance } from 'chalk';
import chalk from 'chalk';
import { nextOnPagesVersion } from './utils';
import type { PackageManager } from './buildApplication/packageManagerUtils';
import {
getCurrentPackageManager,
getPackageManagerSpawnCommand,
getBinaryVersion,
getPackageVersion,
} from './buildApplication/packageManagerUtils';
import { getCurrentPackageManager } from './buildApplication/packageManagerUtils';

// A helper type to handle command line flags. Defaults to false
const flag = z
Expand Down Expand Up @@ -209,6 +208,7 @@ function prepareCliMessage(
}

export async function printEnvInfo(): Promise<void> {
const packageManager = await getCurrentPackageManager();
const envInfoMessage = dedent(`
System:
Platform: ${os.platform()}
Expand All @@ -219,44 +219,16 @@ export async function printEnvInfo(): Promise<void> {
Shell: ${process.env['SHELL']?.toString() ?? 'Unknown'}
Binaries:
Node: ${process.versions.node}
Yarn: ${getBinaryVersion('yarn')}
npm: ${getBinaryVersion('npm')}
pnpm: ${getBinaryVersion('pnpm')}
Yarn: ${getBinaryVersion('yarn') ?? 'N/A'}
npm: ${getBinaryVersion('npm') ?? 'N/A'}
pnpm: ${getBinaryVersion('pnpm') ?? 'N/A'}
Package Manager Used: ${await getCurrentPackageManager()}
Relevant Packages:
@cloudflare/next-on-pages: ${nextOnPagesVersion}
vercel: ${getPackageVersion('vercel')}
next: ${getPackageVersion('next')}
vercel: ${getPackageVersion(packageManager, 'vercel') ?? 'N/A'}
next: ${getPackageVersion(packageManager, 'next') ?? 'N/A'}
`);

// eslint-disable-next-line no-console
console.log(`\n${envInfoMessage}\n`);
}

function getPackageVersion(packageName: string): string {
try {
const command = getPackageManagerSpawnCommand('npm');
const commandOutput = execFileSync(
command,
['list', packageName, '--json', '--depth=0'],
{ stdio: 'pipe' }
)
.toString()
.trim();
const packageInfo = JSON.parse(commandOutput);
return packageInfo?.dependencies[packageName]?.version ?? 'N/A';
} catch {
return 'N/A';
}
}

function getBinaryVersion(binaryName: PackageManager): string {
const commandArgs = ['--version'];
try {
return execFileSync(getPackageManagerSpawnCommand(binaryName), commandArgs)
.toString()
.trim();
} catch {
return 'N/A';
}
}

0 comments on commit 97c8739

Please sign in to comment.