From d9ca56549b98073271af370553bcf3180ecaaf4c Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Fri, 23 Feb 2024 15:47:36 -0500 Subject: [PATCH] Squashed commit of the following: commit 92903bcb1d68aa0ba5b45db1396e689f34d2dc8f Author: Mikael Finstad Date: Fri Feb 16 11:44:18 2024 +0800 Update source/package-manager/types.d.ts Co-authored-by: Tommy commit 9858c3dbd00cc7252dfa3be73aad0eb1aa1da834 Author: Mikael Finstad Date: Thu Feb 15 15:40:44 2024 +0800 fix bugs discovered when testing yarn berry --- source/index.js | 20 ++++++++++++++------ source/package-manager/configs.js | 22 +++++++++++----------- source/package-manager/index.js | 9 ++------- source/package-manager/types.d.ts | 13 +++++++++---- 4 files changed, 36 insertions(+), 28 deletions(-) diff --git a/source/index.js b/source/index.js index 577420ed..dd45765b 100644 --- a/source/index.js +++ b/source/index.js @@ -8,7 +8,7 @@ import {asyncExitHook} from 'exit-hook'; import logSymbols from 'log-symbols'; import prerequisiteTasks from './prerequisite-tasks.js'; import gitTasks from './git-tasks.js'; -import {getPackagePublishArguments} from './npm/publish.js'; +import {getPackagePublishArguments as getAdditionalPackagePublishArguments} from './npm/publish.js'; import enable2fa, {getEnable2faArgs} from './npm/enable-2fa.js'; import releaseTaskHelper from './release-task-helper.js'; import * as util from './util.js'; @@ -32,7 +32,7 @@ const exec = (cmd, args, options) => { */ const np = async (input = 'patch', options, {pkg, rootDir}) => { const pkgManager = getPackageManagerConfig(rootDir, pkg); - const publishCli = pkgManager.publishCli || pkgManager.cli; + const [publishCommand, publishArgsPrefix = []] = pkgManager.publishCli || [pkgManager.cli]; // TODO: Remove sometime far in the future if (options.skipCleanup) { @@ -96,6 +96,11 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => { // To prevent the process from hanging due to watch mode (e.g. when running `vitest`) const ciEnvOptions = {env: {CI: 'true'}}; + function getPackagePublishArguments(options) { + const args = getAdditionalPackagePublishArguments(options); + return [...publishArgsPrefix, ...args]; + } + const tasks = new Listr([ { title: 'Prerequisite check', @@ -117,7 +122,10 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => { task: () => new Listr([ { title: 'Running install command', - task: () => exec(...pkgManager.installCommand), + task() { + const installCommand = lockfile ? pkgManager.installCommand : pkgManager.installCommandNoLockfile; + return exec(...installCommand); + }, }, { title: 'Checking working tree is still clean', // If lockfile was out of date and tracked by git, this will fail @@ -159,19 +167,19 @@ const np = async (input = 'patch', options, {pkg, rootDir}) => { skip() { if (options.preview) { const args = getPackagePublishArguments(options); - return `[Preview] Command not executed: ${publishCli} ${args.join(' ')}.`; + return `[Preview] Command not executed: ${publishCommand} ${args.join(' ')}.`; } }, /** @type {(context, task) => Listr.ListrTaskResult} */ task(context, task) { let hasError = false; - return from(execa(publishCli, getPackagePublishArguments(options))) + return from(execa(publishCommand, getPackagePublishArguments(options))) .pipe( catchError(error => handleNpmError(error, task, otp => { context.otp = otp; - return execa(publishCli, getPackagePublishArguments({...options, otp})); + return execa(publishCommand, getPackagePublishArguments({...options, otp})); })), ) .pipe( diff --git a/source/package-manager/configs.js b/source/package-manager/configs.js index f3c52638..aed13e8a 100644 --- a/source/package-manager/configs.js +++ b/source/package-manager/configs.js @@ -3,26 +3,22 @@ export const npmConfig = { cli: 'npm', id: 'npm', installCommand: ['npm', ['ci', '--engine-strict']], + installCommandNoLockfile: ['npm', ['install', '--no-package-lock', '--no-production', '--engine-strict']], versionCommand: version => ['npm', ['version', version]], getRegistryCommand: ['npm', ['config', 'get', 'registry']], tagVersionPrefixCommand: ['npm', ['config', 'get', 'tag-version-prefix']], lockfiles: ['package-lock.json', 'npm-shrinkwrap.json'], }; -/** @type {import('./types.d.ts').PackageManagerConfig} */ -export const npmConfigNoLockfile = { - ...npmConfig, - installCommand: ['npm', ['install', '--no-package-lock', '--no-production', '--engine-strict']], -}; - /** @type {import('./types.d.ts').PackageManagerConfig} */ export const pnpmConfig = { cli: 'pnpm', id: 'pnpm', installCommand: ['pnpm', ['install']], + installCommandNoLockfile: ['pnpm', ['install']], versionCommand: version => ['pnpm', ['version', version]], tagVersionPrefixCommand: ['pnpm', ['config', 'get', 'tag-version-prefix']], - publishCli: 'npm', // Pnpm does git cleanliness checks, which np already did, and which fail because when publishing package.json has been updated + publishCli: ['npm'], // Pnpm does git cleanliness checks, which np already did, and which fail because when publishing package.json has been updated getRegistryCommand: ['pnpm', ['config', 'get', 'registry']], lockfiles: ['pnpm-lock.yaml'], }; @@ -31,7 +27,8 @@ export const pnpmConfig = { export const yarnConfig = { cli: 'yarn', id: 'yarn', - installCommand: ['yarn', ['install', '--production=false']], + installCommand: ['yarn', ['install', '--frozen-lockfile', '--production=false']], + installCommandNoLockfile: ['yarn', ['install', '--production=false']], getRegistryCommand: ['yarn', ['config', 'get', 'registry']], tagVersionPrefixCommand: ['yarn', ['config', 'get', 'version-tag-prefix']], versionCommand: version => ['yarn', ['version', '--new-version', version]], @@ -42,10 +39,13 @@ export const yarnConfig = { export const yarnBerryConfig = { cli: 'yarn', id: 'yarn-berry', - installCommand: ['yarn', ['install']], - versionCommand: version => ['yarn', ['version', '--new-version', version]], + installCommand: ['yarn', ['install', '--immutable']], + installCommandNoLockfile: ['yarn', ['install']], + // Yarn berry doesn't support git committing/tagging, so we use npm instead + versionCommand: version => ['npm', ['version', version]], tagVersionPrefixCommand: ['yarn', ['config', 'get', 'version-tag-prefix']], - publishCli: 'npm', // Yarn berry doesn't support git committing/tagging, so use npm + // Yarn berry offloads publishing to npm, e.g. `yarn npm publish x.y.z` + publishCli: ['yarn', ['npm']], getRegistryCommand: ['yarn', ['config', 'get', 'npmRegistryServer']], throwOnExternalRegistry: true, lockfiles: ['yarn.lock'], diff --git a/source/package-manager/index.js b/source/package-manager/index.js index dcd7a78c..252014f4 100644 --- a/source/package-manager/index.js +++ b/source/package-manager/index.js @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import semver from 'semver'; -import {npmConfig, yarnBerryConfig, pnpmConfig, yarnConfig, npmConfigNoLockfile} from './configs.js'; +import {npmConfig, yarnBerryConfig, pnpmConfig, yarnConfig} from './configs.js'; /** @param {string} rootDir @@ -18,12 +18,7 @@ export function findLockFile(rootDir, config) { @param {import('read-pkg').NormalizedPackageJson} pkg */ export function getPackageManagerConfig(rootDir, pkg) { - let config = configFromPackageManagerField(pkg); - - if (config === npmConfig && !findLockFile(rootDir, config)) { - config = npmConfigNoLockfile; - } - + const config = configFromPackageManagerField(pkg); return config || configFromLockfile(rootDir) || npmConfig; } diff --git a/source/package-manager/types.d.ts b/source/package-manager/types.d.ts index d437c503..9f2d1cd4 100644 --- a/source/package-manager/types.d.ts +++ b/source/package-manager/types.d.ts @@ -17,19 +17,24 @@ export type PackageManagerConfig = { id: string; /** - How to install packages, e.g. `["npm", ["install"]]`. + How to install packages when there is a lockfile, e.g. `["npm", ["install"]]`. */ installCommand: Command; + /** + How to install packages when there is no lockfile, e.g. `["npm", ["install"]]`. + */ + installCommandNoLockfile: Command; + /** Given a version string, return a version command e.g. `version => ["npm", ["version", version]]`. */ - versionCommand: (version: string) => [cli: string, args: string[]]; + versionCommand: (version: string) => [command: string, args: string[]]; /** - Use a different CLI to do the actual publish. Defaults to `cli`. + Use a different CLI (and prefix args) to do the actual publish. Defaults to [`cli`]. */ - publishCli?: string; + publishCli?: [command: string, prefixArgs?: string[]]; /** CLI command which is expected to output the npm registry to use, e.g. `['npm', ['config', 'get', 'registry']]`.