diff --git a/e2e/utils/index.ts b/e2e/utils/index.ts index e5fea16de1..fc2ee540f9 100644 --- a/e2e/utils/index.ts +++ b/e2e/utils/index.ts @@ -12,6 +12,7 @@ import { removeSync, } from 'fs-extra'; import * as path from 'path'; +import { detectPackageManager } from '@nrwl/tao/src/shared/package-manager'; interface RunCmdOpts { silenceError?: boolean; @@ -26,11 +27,6 @@ export function currentCli() { let projName: string; -function setCurrentProjName(name: string) { - projName = name; - return name; -} - export function uniq(prefix: string) { return `${prefix}${Math.floor(Math.random() * 10000000)}`; } @@ -54,18 +50,18 @@ export function runCreateWorkspace( appName?: string; style?: string; base?: string; - packageManager?: string; + packageManager?: 'npm' | 'yarn' | 'pnpm'; cli?: string; extraArgs?: string; } ) { - setCurrentProjName(name); + projName = name; + + const pm = getPackageManagerCommand({ packageManager }); const linterArg = preset === 'angular' || preset === 'angular-nest' ? ' --linter=tslint' : ''; - let command = `npx create-nx-workspace@${ - process.env.PUBLISHED_VERSION - } ${name} --cli=${ + let command = `${pm.createWorkspace} ${name} --cli=${ cli || currentCli() } --preset=${preset} ${linterArg} --no-nxCloud --no-interactive`; if (appName) { @@ -97,7 +93,8 @@ export function runCreateWorkspace( export function packageInstall(pkg: string, projName?: string) { const cwd = projName ? `./tmp/${currentCli()}/${projName}` : tmpProjPath(); - const install = execSync(`npm i ${pkg}`, { + const pm = getPackageManagerCommand({ path: cwd }); + const install = execSync(`${pm.add} ${pkg}`, { cwd, // ...{ stdio: ['pipe', 'pipe', 'pipe'] }, ...{ stdio: [0, 1, 2] }, @@ -118,9 +115,15 @@ export function runNgNew(): string { * for the currently selected CLI. */ export function newProject(): string { + const packageManager = process.env.SELECTED_PM as any; + try { - if (!directoryExists(tmpBackupProjPath())) { - runCreateWorkspace('proj', { preset: 'empty' }); + const newProjName = uniq('proj'); + const useBackupProject = packageManager !== 'pnpm'; + const projScope = useBackupProject ? 'proj' : newProjName; + + if (!useBackupProject || !directoryExists(tmpBackupProjPath())) { + runCreateWorkspace(projScope, { preset: 'empty', packageManager }); const packages = [ `@nrwl/angular`, `@nrwl/express`, @@ -131,12 +134,16 @@ export function newProject(): string { `@nrwl/nx-plugin`, `@nrwl/eslint-plugin-nx`, ]; - packageInstall(packages.join(` `), 'proj'); - moveSync(`./tmp/${currentCli()}/proj`, `${tmpBackupProjPath()}`); + packageInstall(packages.join(` `), projScope); + if (useBackupProject) { + moveSync(`./tmp/${currentCli()}/proj`, `${tmpBackupProjPath()}`); + } } - projName = uniq('proj'); - copySync(`${tmpBackupProjPath()}`, `${tmpProjPath()}`); - return 'proj'; + projName = newProjName; + if (useBackupProject) { + copySync(`${tmpBackupProjPath()}`, `${tmpProjPath()}`); + } + return projScope; } catch (e) { console.log(`Failed to set up project for e2e tests.`); console.log(e.message); @@ -178,7 +185,8 @@ export function runCommandUntil( criteria: (output: string) => boolean, { kill = true } = {} ): Promise<{ process: ChildProcess }> { - const p = exec(`npm run nx --scripts-prepend-node-path -- ${command}`, { + const pm = getPackageManagerCommand(); + const p = exec(`${pm.runNx} ${command}`, { cwd: tmpProjPath(), env: { ...process.env, FORCE_COLOR: 'false' }, }); @@ -217,10 +225,9 @@ export function runCLIAsync( silent: false, } ): Promise<{ stdout: string; stderr: string; combinedOutput: string }> { + const pm = getPackageManagerCommand(); return runCommandAsync( - `npm run nx ${ - opts.silent ? '--silent' : '' - } --scripts-prepend-node-path -- ${command}`, + `${opts.silent ? pm.runNxSilent : pm.runNx} ${command}`, opts ); } @@ -265,9 +272,10 @@ export function runCLI( } ): string { try { - let r = execSync(`npm run nx --scripts-prepend-node-path -- ${command}`, { + const pm = getPackageManagerCommand(); + let r = execSync(`${pm.runNx} ${command}`, { cwd: opts.cwd || tmpProjPath(), - env: opts.env as any, + env: opts.env, }).toString(); r = r.replace( /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, @@ -448,3 +456,40 @@ function tmpBackupProjPath(path?: string) { ? `./tmp/${currentCli()}/proj-backup/${path}` : `./tmp/${currentCli()}/proj-backup`; } + +export function getPackageManagerCommand({ + path = tmpProjPath(), + packageManager = detectPackageManager(path), + scriptsPrependNodePath = true, +} = {}): { + createWorkspace: string; + runNx: string; + runNxSilent: string; + add: string; +} { + const scriptsPrependNodePathFlag = scriptsPrependNodePath + ? ' --scripts-prepend-node-path ' + : ''; + + return { + npm: { + createWorkspace: `npx create-nx-workspace@${process.env.PUBLISHED_VERSION}`, + runNx: `npm run nx${scriptsPrependNodePathFlag} --`, + runNxSilent: `npm run nx --silent${scriptsPrependNodePathFlag} --`, + add: `npm install`, + }, + yarn: { + // `yarn create nx-workspace` is failing due to wrong global path + createWorkspace: `yarn global add create-nx-workspace@${process.env.PUBLISHED_VERSION} && create-nx-workspace`, + runNx: `yarn nx`, + runNxSilent: `yarn --silent nx`, + add: `yarn add`, + }, + pnpm: { + createWorkspace: `pnpx create-nx-workspace@${process.env.PUBLISHED_VERSION}`, + runNx: `pnpm run nx --`, + runNxSilent: `pnpm run nx --silent --`, + add: `pnpm add`, + }, + }[packageManager]; +} diff --git a/e2e/workspace/src/workspace.test.ts b/e2e/workspace/src/workspace.test.ts index 70ce357871..80e6d94898 100644 --- a/e2e/workspace/src/workspace.test.ts +++ b/e2e/workspace/src/workspace.test.ts @@ -1,5 +1,6 @@ import { NxJson } from '@nrwl/workspace'; import { + getPackageManagerCommand, listFiles, newProject, readFile, @@ -194,7 +195,7 @@ describe('run-many', () => { }); describe('affected:*', () => { - it('should print, build, and test affected apps', () => { + it('should print, build, and test affected apps', async () => { const proj = newProject(); const myapp = uniq('myapp'); const myapp2 = uniq('myapp2'); @@ -232,9 +233,12 @@ describe('affected:*', () => { ` ); expect( - runCLI( - `affected:apps --files="libs/${mylib}/src/index.ts" --plain` - ).split('\n')[4] + ( + await runCLIAsync( + `affected:apps --files="libs/${mylib}/src/index.ts" --plain`, + { silent: true } + ) + ).stdout.trim() ).toEqual(myapp); const affectedApps = runCLI( @@ -255,9 +259,12 @@ describe('affected:*', () => { expect(noAffectedApps).not.toContain(myapp2); expect( - runCLI( - `affected:libs --files="libs/${mylib}/src/index.ts" --plain` - ).split('\n')[4] + ( + await runCLIAsync( + `affected:libs --files="libs/${mylib}/src/index.ts" --plain`, + { silent: true } + ) + ).stdout.trim() ).toEqual(`${mylib} ${mypublishablelib}`); const affectedLibs = runCLI( @@ -341,7 +348,7 @@ describe('affected:*', () => { expect(isolatedTests).toContain(`- ${myapp}`); const interpolatedTests = runCLI( - `affected --target test --files="libs/${mylib}/src/index.ts" -- --jest-config {project.root}/jest.config.js` + `affected --target test --files="libs/${mylib}/src/index.ts" --jest-config {project.root}/jest.config.js` ); expect(interpolatedTests).toContain(`Running target \"test\" succeeded`); }, 1000000); @@ -480,6 +487,9 @@ describe('print-affected', () => { ).stdout.trim() ); + const { runNx } = getPackageManagerCommand({ + scriptsPrependNodePath: false, + }); expect(resWithTarget.tasks[0]).toMatchObject({ id: `${myapp}:test`, overrides: {}, @@ -487,7 +497,7 @@ describe('print-affected', () => { project: myapp, target: 'test', }, - command: `npm run nx -- test ${myapp}`, + command: `${runNx} test ${myapp}`, outputs: [`coverage/apps/${myapp}`], }); expect(resWithTarget.tasks[0].hash).toBeDefined(); @@ -509,7 +519,7 @@ describe('print-affected', () => { project: myapp, target: 'build', }, - command: `npm run nx -- build ${myapp}`, + command: `${runNx} build ${myapp}`, outputs: [`dist/apps/${myapp}`], }); expect(resWithDeps.tasks[0].hash).toBeDefined(); @@ -521,7 +531,7 @@ describe('print-affected', () => { project: mypublishablelib, target: 'build', }, - command: `npm run nx -- build ${mypublishablelib}`, + command: `${runNx} build ${mypublishablelib}`, outputs: [`dist/libs/${mypublishablelib}`], }); expect(resWithDeps.tasks[1].hash).toBeDefined(); diff --git a/packages/tao/src/shared/package-manager.ts b/packages/tao/src/shared/package-manager.ts index 602fad42e7..47ed379a3d 100644 --- a/packages/tao/src/shared/package-manager.ts +++ b/packages/tao/src/shared/package-manager.ts @@ -1,9 +1,10 @@ import { existsSync } from 'fs'; +import { join } from 'path'; -export function detectPackageManager() { - return existsSync('yarn.lock') +export function detectPackageManager(dir = '') { + return existsSync(join(dir, 'yarn.lock')) ? 'yarn' - : existsSync('pnpm-lock.yaml') + : existsSync(join(dir, 'pnpm-lock.yaml')) ? 'pnpm' : 'npm'; } diff --git a/scripts/local-registry/config.yml b/scripts/local-registry/config.yml index 1c3160a3a6..5a3cc113a8 100644 --- a/scripts/local-registry/config.yml +++ b/scripts/local-registry/config.yml @@ -3,36 +3,33 @@ storage: ../../tmp/local-registry/storage auth: htpasswd: file: ./htpasswd + max_users: 1 # a list of other known repositories we can talk to uplinks: npmjs: url: https://registry.npmjs.org/ - cache: true - yarn: - url: https://registry.yarnpkg.com - cache: true + max_fails: 100 + maxage: 30m + fail_timeout: 10m + timeout: 600s + agent_options: + keepAlive: true + maxSockets: 40 + maxFreeSockets: 10 + cache: false packages: - '@*/*': - # scoped packages + '@nrwl/*': access: $all publish: $all - unpublish: $all - proxy: npmjs '**': - # allow all users (including non-authenticated users) to read and - # publish all packages access: $all - - # allow all users (including non-authenticated users) to publish/publish packages publish: $all unpublish: $all - - # if package is not available locally, proxy requests to 'yarn' registry proxy: npmjs # log settings logs: - - { type: stdout, format: pretty, level: error } + - { type: stdout, format: pretty, level: warn }