151 lines
4.0 KiB
TypeScript
151 lines
4.0 KiB
TypeScript
import {
|
|
detectPackageManager,
|
|
getPackageManagerCommand,
|
|
getPackageManagerVersion,
|
|
isWorkspacesEnabled,
|
|
output,
|
|
} from '@nx/devkit';
|
|
import { execSync } from 'child_process';
|
|
import { daemonClient } from 'nx/src/daemon/client/client';
|
|
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
|
import { getLockFileName } from 'nx/src/plugins/js/lock-file/lock-file';
|
|
import { gte } from 'semver';
|
|
|
|
export async function updateLockFile(
|
|
cwd: string,
|
|
{
|
|
dryRun,
|
|
verbose,
|
|
generatorOptions,
|
|
}: {
|
|
dryRun?: boolean;
|
|
verbose?: boolean;
|
|
generatorOptions?: Record<string, unknown>;
|
|
}
|
|
) {
|
|
if (generatorOptions?.skipLockFileUpdate) {
|
|
if (verbose) {
|
|
console.log(
|
|
'\nSkipped lock file update because skipLockFileUpdate was set.'
|
|
);
|
|
}
|
|
return [];
|
|
}
|
|
|
|
const packageManager = detectPackageManager(cwd);
|
|
|
|
if (
|
|
packageManager === 'yarn' &&
|
|
!gte(getPackageManagerVersion(packageManager), '2.0.0')
|
|
) {
|
|
// yarn classic does not store workspace data in the lock file, so we don't need to update it
|
|
if (verbose) {
|
|
console.log(
|
|
'\nSkipped lock file update because it is not necessary for Yarn Classic.'
|
|
);
|
|
}
|
|
return [];
|
|
}
|
|
|
|
const workspacesEnabled = isWorkspacesEnabled(packageManager, cwd);
|
|
if (!workspacesEnabled) {
|
|
if (verbose) {
|
|
console.log(
|
|
`\nSkipped lock file update because ${packageManager} workspaces are not enabled.`
|
|
);
|
|
}
|
|
return [];
|
|
}
|
|
|
|
const isDaemonEnabled = daemonClient.enabled();
|
|
if (!dryRun && isDaemonEnabled) {
|
|
// if not in dry-run temporarily stop the daemon, as it will error if the lock file is updated
|
|
await daemonClient.stop();
|
|
}
|
|
|
|
const packageManagerCommands = getPackageManagerCommand(packageManager);
|
|
|
|
let installArgs = generatorOptions?.installArgs || '';
|
|
|
|
output.logSingleLine(`Updating ${packageManager} lock file`);
|
|
|
|
let env: object = {};
|
|
|
|
if (generatorOptions?.installIgnoreScripts) {
|
|
if (packageManager === 'yarn') {
|
|
env = { YARN_ENABLE_SCRIPTS: 'false' };
|
|
} else {
|
|
// npm and pnpm use the same --ignore-scripts option
|
|
installArgs = `${installArgs} --ignore-scripts`.trim();
|
|
}
|
|
}
|
|
|
|
const lockFile = getLockFileName(packageManager);
|
|
const command =
|
|
`${packageManagerCommands.updateLockFile} ${installArgs}`.trim();
|
|
|
|
if (verbose) {
|
|
if (dryRun) {
|
|
console.log(
|
|
`Would update ${lockFile} with the following command, but --dry-run was set:`
|
|
);
|
|
} else {
|
|
console.log(`Updating ${lockFile} with the following command:`);
|
|
}
|
|
console.log(command);
|
|
}
|
|
|
|
if (dryRun) {
|
|
return [];
|
|
}
|
|
|
|
execLockFileUpdate(command, cwd, env);
|
|
|
|
if (isDaemonEnabled) {
|
|
try {
|
|
await daemonClient.startInBackground();
|
|
} catch (e) {
|
|
// If the daemon fails to start, we don't want to prevent the user from continuing, so we just log the error and move on
|
|
if (verbose) {
|
|
output.warn({
|
|
title:
|
|
'Unable to restart the Nx Daemon. It will be disabled until you run "nx reset"',
|
|
bodyLines: [e.message],
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return [lockFile];
|
|
}
|
|
|
|
function execLockFileUpdate(
|
|
command: string,
|
|
cwd: string,
|
|
env: object = {}
|
|
): void {
|
|
try {
|
|
const LARGE_BUFFER = 1024 * 1000000;
|
|
execSync(command, {
|
|
cwd,
|
|
maxBuffer: LARGE_BUFFER,
|
|
env: {
|
|
...process.env,
|
|
...env,
|
|
},
|
|
windowsHide: false,
|
|
});
|
|
} catch (e) {
|
|
output.error({
|
|
title: `Error updating lock file with command '${command}'`,
|
|
bodyLines: [
|
|
`Verify that '${command}' succeeds when run from the workspace root.`,
|
|
`To configure a string of arguments to be passed to this command, set the 'release.version.generatorOptions.installArgs' property in nx.json.`,
|
|
`To ignore install lifecycle scripts, set 'release.version.generatorOptions.installIgnoreScripts' to true in nx.json.`,
|
|
`To disable this step entirely, set 'release.version.generatorOptions.skipLockFileUpdate' to true in nx.json.`,
|
|
],
|
|
});
|
|
throw e;
|
|
}
|
|
}
|