fix(core): ensurePackage fails on pnpm workspaces (#16002)

This commit is contained in:
Miroslav Jonaš 2023-04-06 16:47:15 +02:00 committed by GitHub
parent 443d45d74d
commit b3a3f2a724
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 80 deletions

View File

@ -13,8 +13,9 @@ import { ChildProcess, exec, execSync, ExecSyncOptions } from 'child_process';
import { join } from 'path';
import * as isCI from 'is-ci';
import { Workspaces } from '../../packages/nx/src/config/workspaces';
import { updateFile } from './file-utils';
import { exists, updateFile } from './file-utils';
import { logError, stripConsoleColors } from './log-utils';
import { existsSync } from 'fs-extra';
export interface RunCmdOpts {
silenceError?: boolean;
@ -118,6 +119,7 @@ export function getPackageManagerCommand({
} {
const npmMajorVersion = getNpmMajorVersion();
const publishedVersion = getPublishedVersion();
const isPnpmWorkspace = existsSync(join(path, 'pnpm-workspace.yaml'));
return {
npm: {
@ -158,8 +160,8 @@ export function getPackageManagerCommand({
runUninstalledPackage: 'pnpm dlx',
install: 'pnpm i',
ciInstall: 'pnpm install --frozen-lockfile',
addProd: `pnpm add`,
addDev: `pnpm add -D`,
addProd: isPnpmWorkspace ? 'pnpm add -w' : 'pnpm add',
addDev: isPnpmWorkspace ? 'pnpm add -Dw' : 'pnpm add -D',
list: 'npm ls --depth 10',
runLerna: `pnpm exec lerna`,
},

View File

@ -47,7 +47,7 @@ export function newProject({
if (!directoryExists(tmpBackupProjPath())) {
runCreateWorkspace(projScope, {
preset: 'apps',
preset: 'empty',
packageManager,
});
@ -287,12 +287,17 @@ export function packageInstall(
} ${pkgsWithVersions}${isVerbose() ? ' --verbose' : ''}`;
try {
const install = execSync(command, {
cwd,
stdio: 'pipe',
env: process.env,
encoding: 'utf-8',
});
const install = execSync(
`${mode === 'dev' ? pm.addDev : pm.addProd} ${pkgsWithVersions}${
isVerbose() ? ' --verbose' : ''
}`,
{
cwd,
stdio: 'pipe',
env: process.env,
encoding: 'utf-8',
}
);
if (isVerbose()) {
output.log({

View File

@ -1,11 +1,11 @@
/* eslint-disable */
export default {
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
'^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
globals: {},
displayName: 'e2e-workspace-create-npm',
preset: '../../jest.preset.js',
};

View File

@ -1,33 +1,48 @@
import {
checkFilesExist,
cleanupProject,
getSelectedPackageManager,
packageInstall,
readJson,
runCLI,
runCommand,
runCreateWorkspace,
uniq,
} from '@nrwl/e2e/utils';
describe('create-nx-workspace --preset=npm', () => {
let wsName;
const wsName = uniq('npm');
let orginalGlobCache;
beforeAll(() => {
orginalGlobCache = process.env.NX_PROJECT_GLOB_CACHE;
// glob cache is causing previous projects to show in Workspace for maxWorkers overrides
// which fails due to files no longer being available
process.env.NX_PROJECT_GLOB_CACHE = 'false';
beforeEach(() => {
wsName = uniq('npm');
runCreateWorkspace(wsName, {
preset: 'npm',
packageManager: getSelectedPackageManager(),
});
});
afterEach(() => cleanupProject());
afterEach(() => {
// cleanup previous projects
runCommand(`rm -rf packages/** tsconfig.base.json`);
});
afterAll(() => {
process.env.NX_PROJECT_GLOB_CACHE = orginalGlobCache;
cleanupProject({ skipReset: true });
});
it('should add angular application', () => {
packageInstall('@nrwl/angular', wsName);
const appName = uniq('my-app');
expect(() => {
runCLI(
`generate @nrwl/angular:app ${appName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/angular:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
}, 1_000_000);
@ -37,9 +52,7 @@ describe('create-nx-workspace --preset=npm', () => {
const libName = uniq('lib');
expect(() => {
runCLI(
`generate @nrwl/angular:lib ${libName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/angular:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
@ -48,32 +61,13 @@ describe('create-nx-workspace --preset=npm', () => {
});
}, 1_000_000);
it('should add workspace library', () => {
packageInstall('@nrwl/workspace', wsName);
const libName = uniq('lib');
expect(() =>
runCLI(
`generate @nrwl/workspace:library ${libName} --skipPackageJson --no-interactive`
)
).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
expect(tsconfig.compilerOptions.paths).toEqual({
[libName]: [`packages/${libName}/src/index.ts`],
});
});
it('should add js library', () => {
packageInstall('@nrwl/js', wsName);
const libName = uniq('lib');
expect(() =>
runCLI(
`generate @nrwl/js:library ${libName} --skipPackageJson --no-interactive`
)
runCLI(`generate @nrwl/js:library ${libName} --no-interactive`)
).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
@ -88,9 +82,7 @@ describe('create-nx-workspace --preset=npm', () => {
const appName = uniq('my-app');
expect(() =>
runCLI(
`generate @nrwl/web:app ${appName} --skipPackageJson --no-interactive`
)
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`)
).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
@ -101,9 +93,7 @@ describe('create-nx-workspace --preset=npm', () => {
const appName = uniq('my-app');
expect(() => {
runCLI(
`generate @nrwl/react:app ${appName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/react:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
@ -114,9 +104,7 @@ describe('create-nx-workspace --preset=npm', () => {
const libName = uniq('lib');
expect(() => {
runCLI(
`generate @nrwl/react:lib ${libName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/react:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
@ -131,9 +119,7 @@ describe('create-nx-workspace --preset=npm', () => {
const appName = uniq('my-app');
expect(() => {
runCLI(
`generate @nrwl/next:app ${appName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/next:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
@ -144,9 +130,7 @@ describe('create-nx-workspace --preset=npm', () => {
const libName = uniq('lib');
expect(() => {
runCLI(
`generate @nrwl/next:lib ${libName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/next:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
@ -162,7 +146,7 @@ describe('create-nx-workspace --preset=npm', () => {
expect(() => {
runCLI(
`generate @nrwl/react-native:app ${appName} --install=false --skipPackageJson --no-interactive`
`generate @nrwl/react-native:app ${appName} --install=false --no-interactive`
);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
@ -174,9 +158,7 @@ describe('create-nx-workspace --preset=npm', () => {
const libName = uniq('lib');
expect(() => {
runCLI(
`generate @nrwl/react-native:lib ${libName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/react-native:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
@ -191,9 +173,7 @@ describe('create-nx-workspace --preset=npm', () => {
const appName = uniq('my-app');
expect(() => {
runCLI(
`generate @nrwl/node:app ${appName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/node:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
@ -204,9 +184,7 @@ describe('create-nx-workspace --preset=npm', () => {
const libName = uniq('lib');
expect(() => {
runCLI(
`generate @nrwl/node:lib ${libName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/node:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
@ -221,9 +199,7 @@ describe('create-nx-workspace --preset=npm', () => {
const appName = uniq('my-app');
expect(() => {
runCLI(
`generate @nrwl/nest:app ${appName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/nest:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
@ -234,9 +210,7 @@ describe('create-nx-workspace --preset=npm', () => {
const libName = uniq('lib');
expect(() => {
runCLI(
`generate @nrwl/nest:lib ${libName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/nest:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
@ -251,9 +225,7 @@ describe('create-nx-workspace --preset=npm', () => {
const appName = uniq('my-app');
expect(() => {
runCLI(
`generate @nrwl/express:app ${appName} --skipPackageJson --no-interactive`
);
runCLI(`generate @nrwl/express:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});

View File

@ -11,8 +11,13 @@ import { requireNx } from '../../nx';
import { dirSync } from 'tmp';
import { join } from 'path';
const { readJson, updateJson, getPackageManagerCommand, workspaceRoot } =
requireNx();
const {
readJson,
updateJson,
getPackageManagerCommand,
workspaceRoot,
detectPackageManager,
} = requireNx();
const UNIDENTIFIED_VERSION = 'UNIDENTIFIED_VERSION';
const NON_SEMVER_TAGS = {
@ -448,9 +453,16 @@ export function ensurePackage<T extends any = any>(
const tempDir = dirSync().name;
console.log(`Fetching ${pkg}...`);
execSync(`${getPackageManagerCommand().addDev} ${pkg}@${requiredVersion}`, {
const packageManager = detectPackageManager();
let addCommand = getPackageManagerCommand(packageManager).addDev;
if (packageManager === 'pnpm') {
addCommand = 'pnpm add -D'; // we need to ensure that we are not using workspace command
}
const isVerbose = process.env.NX_VERBOSE_LOGGING === 'true';
execSync(`${addCommand} ${pkg}@${requiredVersion}`, {
cwd: tempDir,
stdio: 'ignore',
stdio: isVerbose ? 'inherit' : 'ignore',
});
addToNodePath(join(workspaceRoot, 'node_modules'));