Skip to content
Snippets Groups Projects
Unverified Commit d474fd2a authored by Rhys Arkins's avatar Rhys Arkins Committed by GitHub
Browse files

feat(yarn): optimize installs by skipping node_modules (#6381)

parent e0a0e373
No related branches found
No related tags found
No related merge requests found
...@@ -112,6 +112,45 @@ Array [ ...@@ -112,6 +112,45 @@ Array [
] ]
`; `;
exports[`manager/npm/post-update/yarn performs lock file updates and full install using yarn v1.22.0 1`] = `
Array [
Object {
"cmd": "yarn install --ignore-scripts --ignore-engines --ignore-platform",
"options": Object {
"cwd": "some-dir",
"encoding": "utf-8",
"env": Object {
"HOME": "/home/user",
"HTTPS_PROXY": "https://example.com",
"HTTP_PROXY": "http://example.com",
"LANG": "en_US.UTF-8",
"LC_ALL": "en_US",
"NO_PROXY": "localhost",
"PATH": "/tmp/path",
},
"timeout": 900000,
},
},
Object {
"cmd": "yarn upgrade some-dep --ignore-scripts --ignore-engines --ignore-platform",
"options": Object {
"cwd": "some-dir",
"encoding": "utf-8",
"env": Object {
"HOME": "/home/user",
"HTTPS_PROXY": "https://example.com",
"HTTP_PROXY": "http://example.com",
"LANG": "en_US.UTF-8",
"LC_ALL": "en_US",
"NO_PROXY": "localhost",
"PATH": "/tmp/path",
},
"timeout": 900000,
},
},
]
`;
exports[`manager/npm/post-update/yarn performs lock file updates using yarn v1.22.0 1`] = ` exports[`manager/npm/post-update/yarn performs lock file updates using yarn v1.22.0 1`] = `
Array [ Array [
Object { Object {
......
...@@ -35,13 +35,14 @@ describe(getName(__filename), () => { ...@@ -35,13 +35,14 @@ describe(getName(__filename), () => {
stdout: yarnVersion, stdout: yarnVersion,
stderr: '', stderr: '',
}); });
fs.readFile = jest.fn(() => 'package-lock-contents') as never; fs.readFile.mockResolvedValue(null); // .yarnrc
fs.readFile.mockResolvedValue('package-lock-contents' as never);
const config = { const config = {
dockerMapDotfiles: true, dockerMapDotfiles: true,
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'], postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
}; };
const res = await yarnHelper.generateLockFile('some-dir', {}, config); const res = await yarnHelper.generateLockFile('some-dir', {}, config);
expect(fs.readFile).toHaveBeenCalledTimes(1); expect(fs.readFile).toHaveBeenCalledTimes(2);
expect(res.lockFile).toEqual('package-lock-contents'); expect(res.lockFile).toEqual('package-lock-contents');
expect(fixSnapshots(execSnapshots)).toMatchSnapshot(); expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
} }
...@@ -54,7 +55,30 @@ describe(getName(__filename), () => { ...@@ -54,7 +55,30 @@ describe(getName(__filename), () => {
stderr: '', stderr: '',
}); });
fs.readFile = jest.fn(() => 'package-lock-contents') as never; fs.readFile.mockResolvedValue(null); // .yarnrc
fs.readFile.mockResolvedValue('package-lock-contents' as never);
const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [
{
depName: 'some-dep',
isLockfileUpdate: true,
},
]);
expect(res.lockFile).toEqual('package-lock-contents');
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
}
);
it.each([['1.22.0']])(
'performs lock file updates and full install using yarn v%s',
async (yarnVersion) => {
const execSnapshots = mockExecAll(exec, {
stdout: yarnVersion,
stderr: '',
});
fs.readFile.mockReturnValueOnce(
'yarn-offline-mirror ./npm-packages-offline-cache' as never
);
fs.readFile.mockReturnValueOnce('package-lock-contents' as never);
const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [ const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [
{ {
depName: 'some-dep', depName: 'some-dep',
...@@ -70,11 +94,12 @@ describe(getName(__filename), () => { ...@@ -70,11 +94,12 @@ describe(getName(__filename), () => {
stdout: '1.9.4', stdout: '1.9.4',
stderr: 'some-error', stderr: 'some-error',
}); });
fs.readFile = jest.fn(() => { fs.readFile.mockImplementationOnce(() => null);
throw new Error('not found'); fs.readFile.mockImplementationOnce(() => {
}) as never; throw new Error('not-found');
});
const res = await yarnHelper.generateLockFile('some-dir'); const res = await yarnHelper.generateLockFile('some-dir');
expect(fs.readFile).toHaveBeenCalledTimes(1); expect(fs.readFile).toHaveBeenCalledTimes(2);
expect(res.error).toBe(true); expect(res.error).toBe(true);
expect(res.lockFile).not.toBeDefined(); expect(res.lockFile).not.toBeDefined();
expect(fixSnapshots(execSnapshots)).toMatchSnapshot(); expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
......
import is from '@sindresorhus/is';
import { readFile } from 'fs-extra'; import { readFile } from 'fs-extra';
import { join } from 'upath'; import { join } from 'upath';
import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages'; import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
...@@ -12,6 +13,19 @@ export interface GenerateLockFileResult { ...@@ -12,6 +13,19 @@ export interface GenerateLockFileResult {
stderr?: string; stderr?: string;
} }
export async function hasYarnOfflineMirror(cwd: string): Promise<boolean> {
const yarnrc = await readFile(`${cwd}/.yarnrc`, 'utf8');
if (is.string(yarnrc)) {
const mirrorLine = yarnrc
.split('\n')
.find((line) => line.startsWith('yarn-offline-mirror '));
if (mirrorLine) {
return true;
}
}
return false;
}
export async function generateLockFile( export async function generateLockFile(
cwd: string, cwd: string,
env?: NodeJS.ProcessEnv, env?: NodeJS.ProcessEnv,
...@@ -22,6 +36,16 @@ export async function generateLockFile( ...@@ -22,6 +36,16 @@ export async function generateLockFile(
let lockFile = null; let lockFile = null;
try { try {
const preCommands = ['npm i -g yarn']; const preCommands = ['npm i -g yarn'];
if (
config.skipInstalls !== false &&
(await hasYarnOfflineMirror(cwd)) === false
) {
logger.debug('Updating yarn.lock only - skipping node_modules');
// The following change causes Yarn 1.x to exit gracefully after updating the lock file but without installing node_modules
preCommands.push(
"sed -i 's/ steps,/ steps.slice(0,1),/' /home/ubuntu/.npm-global/lib/node_modules/yarn/lib/cli.js"
);
}
const commands = []; const commands = [];
let cmdOptions = ''; let cmdOptions = '';
if (global.trustLevel !== 'high' || config.ignoreScripts) { if (global.trustLevel !== 'high' || config.ignoreScripts) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment