Skip to content

Commit d403845

Browse files
committed
test: remove use of global npm cache and config
1 parent 6cbb941 commit d403845

9 files changed

+78
-29
lines changed

tests/legacy-cli/e2e/setup/200-create-tmp-dir.ts renamed to tests/legacy-cli/e2e/setup/001-create-tmp-dir.ts

-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,4 @@ export default function () {
1717
}
1818
console.log(` Using "${tempRoot}" as temporary directory for a new project.`);
1919
setGlobalVariable('tmp-root', tempRoot);
20-
process.chdir(tempRoot);
2120
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { mkdir, writeFile } from 'fs/promises';
2+
import { delimiter, join } from 'path';
3+
import { getGlobalVariable } from '../utils/env';
4+
5+
/**
6+
* Configure npm to use a unique sandboxed environment.
7+
*/
8+
export default async function () {
9+
const tempRoot: string = getGlobalVariable('tmp-root');
10+
const npmModulesPrefix = join(tempRoot, 'npm-global');
11+
const npmrc = join(tempRoot, '.npmrc');
12+
13+
// Configure npm to use the sandboxed npm globals and rc file
14+
process.env.NPM_CONFIG_USERCONFIG = npmrc;
15+
process.env.NPM_CONFIG_PREFIX = npmModulesPrefix;
16+
17+
// Ensure the directory + files exists
18+
await writeFile(npmrc, '');
19+
await mkdir(npmModulesPrefix);
20+
21+
// Ensure the custom npm global bin is first on the PATH
22+
// https://docs.npmjs.com/cli/v8/configuring-npm/folders#executables
23+
if (process.platform.startsWith('win')) {
24+
process.env.PATH = npmModulesPrefix + delimiter + process.env.PATH;
25+
} else {
26+
process.env.PATH = join(npmModulesPrefix, 'bin') + delimiter + process.env.PATH;
27+
}
28+
29+
console.log(` Using "${npmModulesPrefix}" as e2e test global npm cache.`);
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { mkdir } from 'fs/promises';
2+
import { join } from 'path';
3+
import { getGlobalVariable, setGlobalVariable } from '../utils/env';
4+
5+
export default async function () {
6+
const tempRoot: string = getGlobalVariable('tmp-root');
7+
const projectsRoot = join(tempRoot, 'e2e-test');
8+
9+
setGlobalVariable('projects-root', projectsRoot);
10+
11+
await mkdir(projectsRoot);
12+
13+
console.log(` Using "${projectsRoot}" as temporary directory for a new project.`);
14+
process.chdir(projectsRoot);
15+
}

tests/legacy-cli/e2e/setup/500-create-project.ts

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { join } from 'path';
22
import { getGlobalVariable } from '../utils/env';
3-
import { expectFileToExist, writeFile } from '../utils/fs';
3+
import { expectFileToExist } from '../utils/fs';
44
import { gitClean } from '../utils/git';
5-
import { setRegistry as setNPMConfigRegistry } from '../utils/packages';
6-
import { ng, npm } from '../utils/process';
5+
import { setRegistry as setNPMConfigRegistry, setRegistry } from '../utils/packages';
6+
import { ng } from '../utils/process';
77
import { prepareProjectForE2e, updateJsonFile } from '../utils/project';
88

99
export default async function () {
@@ -18,8 +18,6 @@ export default async function () {
1818
await gitClean();
1919
} else {
2020
const extraArgs = [];
21-
const testRegistry = getGlobalVariable('package-registry');
22-
const isCI = getGlobalVariable('ci');
2321

2422
// Ensure local test registry is used when outside a project
2523
await setNPMConfigRegistry(true);
@@ -28,11 +26,7 @@ export default async function () {
2826
await expectFileToExist(join(process.cwd(), 'test-project'));
2927
process.chdir('./test-project');
3028

31-
// If on CI, the user configuration set above will handle project usage
32-
if (!isCI) {
33-
// Ensure local test registry is used inside a project
34-
await writeFile('.npmrc', `registry=${testRegistry}`);
35-
}
29+
setRegistry(true);
3630

3731
// Setup esbuild builder if requested on the commandline
3832
const useEsbuildBuilder = !!getGlobalVariable('argv')['esbuild'];

tests/legacy-cli/e2e/tests/misc/invalid-schematic-dependencies.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expectFileToMatch } from '../../utils/fs';
2-
import { execWithEnv, ng, silentNpm } from '../../utils/process';
2+
import { execWithEnv, extractNpmEnv, ng, silentNpm } from '../../utils/process';
33
import { installPackage, uninstallPackage } from '../../utils/packages';
44
import { isPrereleaseCli } from '../../utils/project';
55

@@ -29,7 +29,7 @@ async function publishOutdated(npmSpecifier: string): Promise<void> {
2929
'--registry=https://registry.npmjs.org',
3030
);
3131
await execWithEnv('npm', ['publish', stdoutPack.trim(), '--tag=outdated'], {
32-
...process.env,
32+
...extractNpmEnv(),
3333
// Also set an auth token value for the local test registry which is required by npm 7+
3434
// even though it is never actually used.
3535
'NPM_CONFIG__AUTH': 'e2e-testing',

tests/legacy-cli/e2e/tests/misc/update-git-clean-subdirectory.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ng, silentGit } from '../../utils/process';
44
import { prepareProjectForE2e } from '../../utils/project';
55

66
export default async function () {
7-
process.chdir(getGlobalVariable('tmp-root'));
7+
process.chdir(getGlobalVariable('projects-root'));
88

99
await createDir('./subdirectory');
1010
process.chdir('./subdirectory');

tests/legacy-cli/e2e/utils/assets.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export function assetDir(assetName: string) {
1111
}
1212

1313
export function copyProjectAsset(assetName: string, to?: string) {
14-
const tempRoot = join(getGlobalVariable('tmp-root'), 'test-project');
14+
const tempRoot = join(getGlobalVariable('projects-root'), 'test-project');
1515
const sourcePath = assetDir(assetName);
1616
const targetPath = join(tempRoot, to || assetName);
1717

@@ -20,7 +20,7 @@ export function copyProjectAsset(assetName: string, to?: string) {
2020

2121
export function copyAssets(assetName: string, to?: string) {
2222
const seed = +Date.now();
23-
const tempRoot = join(getGlobalVariable('tmp-root'), 'assets', assetName + '-' + seed);
23+
const tempRoot = join(getGlobalVariable('projects-root'), 'assets', assetName + '-' + seed);
2424
const root = assetDir(assetName);
2525

2626
return Promise.resolve()
@@ -30,7 +30,7 @@ export function copyAssets(assetName: string, to?: string) {
3030
return allFiles.reduce((promise, filePath) => {
3131
const toPath =
3232
to !== undefined
33-
? resolve(getGlobalVariable('tmp-root'), 'test-project', to, filePath)
33+
? resolve(getGlobalVariable('projects-root'), 'test-project', to, filePath)
3434
: join(tempRoot, filePath);
3535

3636
return promise.then(() => copyFile(join(root, filePath), toPath));

tests/legacy-cli/e2e/utils/packages.ts

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getGlobalVariable } from './env';
2-
import { ProcessOutput, npm, silentNpm, silentYarn } from './process';
2+
import { ProcessOutput, silentNpm, silentYarn } from './process';
33

44
export function getActivePackageManager(): 'npm' | 'yarn' {
55
const value = getGlobalVariable('package-manager');
@@ -49,17 +49,11 @@ export async function setRegistry(useTestRegistry: boolean): Promise<void> {
4949
? getGlobalVariable('package-registry')
5050
: 'https://registry.npmjs.org';
5151

52-
const isCI = getGlobalVariable('ci');
5352
const isSnapshotBuild = getGlobalVariable('argv')['ng-snapshots'];
5453

5554
// Ensure local test registry is used when outside a project
56-
if (isCI) {
57-
// Safe to set a user configuration on CI
58-
await npm('config', 'set', 'registry', url);
59-
} else {
60-
// Yarn supports both `NPM_CONFIG_REGISTRY` and `YARN_REGISTRY`.
61-
process.env['NPM_CONFIG_REGISTRY'] = url;
62-
}
55+
// Yarn supports both `NPM_CONFIG_REGISTRY` and `YARN_REGISTRY`.
56+
process.env['NPM_CONFIG_REGISTRY'] = url;
6357

6458
// Snapshot builds may contain versions that are not yet released (e.g., RC phase main branch).
6559
// In this case peer dependency ranges may not resolve causing npm 7+ to fail during tests.

tests/legacy-cli/e2e/utils/process.ts

+20-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ interface ExecOptions {
1515
cwd?: string;
1616
}
1717

18+
const NPM_CONFIG_RE = /^npm_config_/i;
19+
1820
let _processes: child_process.ChildProcess[] = [];
1921

2022
export type ProcessOutput = {
@@ -138,6 +140,20 @@ function _exec(options: ExecOptions, cmd: string, args: string[]): Promise<Proce
138140
});
139141
}
140142

143+
export function extractNpmEnv() {
144+
return Object.keys(process.env)
145+
.filter((v) => NPM_CONFIG_RE.test(v))
146+
.reduce(
147+
(vars, n) => {
148+
vars[n] = process.env[n];
149+
return vars;
150+
},
151+
{
152+
PATH: process.env.PATH,
153+
},
154+
);
155+
}
156+
141157
export function waitForAnyProcessOutputToMatch(
142158
match: RegExp,
143159
timeout = 30000,
@@ -269,21 +285,22 @@ export function silentNpm(
269285
{
270286
silent: true,
271287
cwd: (options as { cwd?: string } | undefined)?.cwd,
288+
env: extractNpmEnv(),
272289
},
273290
'npm',
274291
params,
275292
);
276293
} else {
277-
return _exec({ silent: true }, 'npm', args as string[]);
294+
return _exec({ silent: true, env: extractNpmEnv() }, 'npm', args as string[]);
278295
}
279296
}
280297

281298
export function silentYarn(...args: string[]) {
282-
return _exec({ silent: true }, 'yarn', args);
299+
return _exec({ silent: true, env: extractNpmEnv() }, 'yarn', args);
283300
}
284301

285302
export function npm(...args: string[]) {
286-
return _exec({}, 'npm', args);
303+
return _exec({ env: extractNpmEnv() }, 'npm', args);
287304
}
288305

289306
export function node(...args: string[]) {

0 commit comments

Comments
 (0)