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

feat(internal): yarn use util/env/docker (#6286)

parent 43ea34e6
No related branches found
Tags rabbitmq-0.7.12
No related merge requests found
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`workers/branch/lock-files/yarn catches errors 1`] = `
exports[`manager/npm/post-update/yarn catches errors 1`] = `
Array [
Object {
"cmd": "yarn install --ignore-scripts --ignore-engines --ignore-platform",
......@@ -22,27 +22,10 @@ Array [
]
`;
exports[`workers/branch/lock-files/yarn docker using yarn v1.0.0 1`] = `
exports[`manager/npm/post-update/yarn generates lock files using yarn v1.22.0 1`] = `
Array [
Object {
"cmd": "docker run --rm -v \\"some-dir\\":\\"some-dir\\" -v \\"dummy/dir\\":\\"dummy/dir\\" -e NPM_CONFIG_CACHE -e npm_config_store -w \\"some-dir\\" renovate/yarn 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": "docker run --rm -v \\"some-dir\\":\\"some-dir\\" -v \\"dummy/dir\\":\\"dummy/dir\\" -e NPM_CONFIG_CACHE -e npm_config_store -w \\"some-dir\\" renovate/yarn yarn upgrade some-dep --ignore-scripts --ignore-engines --ignore-platform",
"cmd": "yarn install --ignore-scripts --ignore-engines --ignore-platform",
"options": Object {
"cwd": "some-dir",
"encoding": "utf-8",
......@@ -58,13 +41,8 @@ Array [
"timeout": 900000,
},
},
]
`;
exports[`workers/branch/lock-files/yarn finds yarn v1.0.0 globally 1`] = `
Array [
Object {
"cmd": "yarn install --ignore-scripts --ignore-engines --ignore-platform",
"cmd": "npx yarn-deduplicate --strategy fewer",
"options": Object {
"cwd": "some-dir",
"encoding": "utf-8",
......@@ -80,11 +58,6 @@ Array [
"timeout": 900000,
},
},
]
`;
exports[`workers/branch/lock-files/yarn generates lock files using yarn v1.0.0 1`] = `
Array [
Object {
"cmd": "yarn install --ignore-scripts --ignore-engines --ignore-platform",
"options": Object {
......@@ -103,7 +76,7 @@ Array [
},
},
Object {
"cmd": "npx yarn-deduplicate --strategy fewer && yarn",
"cmd": "npx yarn-deduplicate --strategy highest",
"options": Object {
"cwd": "some-dir",
"encoding": "utf-8",
......@@ -120,7 +93,7 @@ Array [
},
},
Object {
"cmd": "npx yarn-deduplicate --strategy highest && yarn",
"cmd": "yarn install --ignore-scripts --ignore-engines --ignore-platform",
"options": Object {
"cwd": "some-dir",
"encoding": "utf-8",
......@@ -139,7 +112,7 @@ Array [
]
`;
exports[`workers/branch/lock-files/yarn performs lock file updates using yarn v1.0.0 1`] = `
exports[`manager/npm/post-update/yarn performs lock file updates using yarn v1.22.0 1`] = `
Array [
Object {
"cmd": "yarn install --ignore-scripts --ignore-engines --ignore-platform",
......
......@@ -2,9 +2,8 @@ import { exec as _exec } from 'child_process';
import _fs from 'fs-extra';
import { ExecSnapshots, envMock, mockExecAll } from '../../../../test/execUtil';
import { getName, mocked } from '../../../../test/util';
import * as _yarnHelper from '../../../manager/npm/post-update/yarn';
import { BinarySource } from '../../../util/exec/common';
import * as _env from '../../../util/exec/env';
import * as _yarnHelper from './yarn';
jest.mock('fs-extra');
jest.mock('child_process');
......@@ -15,6 +14,8 @@ const env = mocked(_env);
const fs = mocked(_fs);
const yarnHelper = mocked(_yarnHelper);
delete process.env.NPM_CONFIG_CACHE;
// TODO: figure out snapshot similarity for each CI platform
const fixSnapshots = (snapshots: ExecSnapshots): ExecSnapshots =>
snapshots.map((snapshot) => ({
......@@ -27,7 +28,7 @@ describe(getName(__filename), () => {
jest.resetAllMocks();
env.getChildProcessEnv.mockReturnValue(envMock.basic);
});
it.each([['1.0.0']])(
it.each([['1.22.0']])(
'generates lock files using yarn v%s',
async (yarnVersion) => {
const execSnapshots = mockExecAll(exec, {
......@@ -36,6 +37,7 @@ describe(getName(__filename), () => {
});
fs.readFile = jest.fn(() => 'package-lock-contents') as never;
const config = {
dockerMapDotfiles: true,
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
};
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
......@@ -44,7 +46,7 @@ describe(getName(__filename), () => {
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
}
);
it.each([['1.0.0']])(
it.each([['1.22.0']])(
'performs lock file updates using yarn v%s',
async (yarnVersion) => {
const execSnapshots = mockExecAll(exec, {
......@@ -54,30 +56,15 @@ describe(getName(__filename), () => {
fs.readFile = jest.fn(() => 'package-lock-contents') as never;
const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [
{ depName: 'some-dep', isLockfileUpdate: true },
{
depName: 'some-dep',
isLockfileUpdate: true,
},
]);
expect(res.lockFile).toEqual('package-lock-contents');
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
}
);
it.each([['1.0.0']])('docker using yarn v%s', async (yarnVersion) => {
const execSnapshots = mockExecAll(exec, {
stdout: yarnVersion,
stderr: '',
});
fs.readFile = jest.fn(() => 'package-lock-contents') as never;
const config = {
upgrades: [{}],
binarySource: BinarySource.Docker,
cacheDir: 'dummy/dir',
};
const res = await yarnHelper.generateLockFile('some-dir', {}, config, [
{ depName: 'some-dep', isLockfileUpdate: true },
]);
expect(res.lockFile).toEqual('package-lock-contents');
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
});
it('catches errors', async () => {
const execSnapshots = mockExecAll(exec, {
stdout: '1.9.4',
......@@ -92,17 +79,4 @@ describe(getName(__filename), () => {
expect(res.lockFile).not.toBeDefined();
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
});
it.each([['1.0.0']])('finds yarn v%s globally', async (yarnVersion) => {
const execSnapshots = mockExecAll(exec, {
stdout: yarnVersion,
stderr: '',
});
fs.readFile = jest.fn(() => 'package-lock-contents') as never;
const res = await yarnHelper.generateLockFile('some-dir');
expect(fs.readFile).toHaveBeenCalledTimes(1);
expect(res.lockFile).toEqual('package-lock-contents');
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
});
});
......@@ -3,8 +3,7 @@ import { join } from 'upath';
import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
import { DatasourceError } from '../../../datasource';
import { logger } from '../../../logger';
import { exec } from '../../../util/exec';
import { BinarySource } from '../../../util/exec/common';
import { ExecOptions, exec } from '../../../util/exec';
import { PostUpdateConfig, Upgrade } from '../../common';
export interface GenerateLockFileResult {
......@@ -21,101 +20,68 @@ export async function generateLockFile(
): Promise<GenerateLockFileResult> {
logger.debug(`Spawning yarn install to create ${cwd}/yarn.lock`);
let lockFile = null;
let stdout = '';
let stderr = '';
let cmd = 'yarn';
try {
if (config.binarySource === BinarySource.Docker) {
logger.debug('Running yarn via docker');
cmd = `docker run --rm `;
// istanbul ignore if
if (config.dockerUser) {
cmd += `--user=${config.dockerUser} `;
}
const volumes = [cwd];
if (config.cacheDir) {
volumes.push(config.cacheDir);
}
cmd += volumes.map((v) => `-v "${v}":"${v}" `).join('');
// istanbul ignore if
if (config.dockerMapDotfiles) {
const homeDir =
process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
const homeNpmrc = join(homeDir, '.npmrc');
cmd += `-v ${homeNpmrc}:/home/ubuntu/.npmrc `;
}
const envVars = ['NPM_CONFIG_CACHE', 'npm_config_store'];
cmd += envVars.map((e) => `-e ${e} `).join('');
cmd += `-w "${cwd}" `;
cmd += `renovate/yarn yarn`;
const preCommands = ['npm i -g yarn'];
const commands = [];
let cmdOptions = '';
if (global.trustLevel !== 'high' || config.ignoreScripts) {
cmdOptions = '--ignore-scripts --ignore-engines --ignore-platform';
}
let cmdExtras = '';
const cmdEnv = { ...env };
cmdExtras += ' --ignore-scripts';
cmdExtras += ' --ignore-engines';
cmdExtras += ' --ignore-platform';
const installCmd = cmd + ' install' + cmdExtras;
// TODO: Switch to native util.promisify once using only node 8
await exec(installCmd, {
const execOptions: ExecOptions = {
cwd,
env: cmdEnv,
});
extraEnv: {
NPM_CONFIG_CACHE: env?.NPM_CONFIG_CACHE,
npm_config_store: env?.npm_config_store,
},
docker: {
image: 'renovate/node',
preCommands,
},
};
if (config.dockerMapDotfiles) {
const homeDir =
process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
const homeNpmrc = join(homeDir, '.npmrc');
execOptions.docker.volumes = [[homeNpmrc, '/home/ubuntu/.npmrc']];
}
// This command updates the lock file based on package.json
commands.push(`yarn install ${cmdOptions}`.trim());
// rangeStrategy = update-lockfile
const lockUpdates = upgrades
.filter((upgrade) => upgrade.isLockfileUpdate)
.map((upgrade) => upgrade.depName);
if (lockUpdates.length) {
logger.debug('Performing lockfileUpdate (yarn)');
const updateCmd =
cmd +
' upgrade' +
lockUpdates.map((depName) => ` ${depName}`).join('') +
cmdExtras;
const updateRes = await exec(updateCmd, {
cwd,
env,
});
// istanbul ignore next
stdout += updateRes.stdout || '';
stderr += updateRes.stderr || '';
commands.push(
`yarn upgrade ${lockUpdates.join(' ')} ${cmdOptions}`.trim()
);
}
if (
config.postUpdateOptions &&
config.postUpdateOptions.includes('yarnDedupeFewer')
) {
// postUpdateOptions
if (config.postUpdateOptions?.includes('yarnDedupeFewer')) {
logger.debug('Performing yarn dedupe fewer');
const dedupeCommand = 'npx yarn-deduplicate --strategy fewer && yarn';
const dedupeRes = await exec(dedupeCommand, {
cwd,
env,
});
// istanbul ignore next
stdout += dedupeRes.stdout || '';
stderr += dedupeRes.stderr || '';
commands.push('npx yarn-deduplicate --strategy fewer');
// Run yarn again in case any changes are necessary
commands.push(`yarn install ${cmdOptions}`.trim());
}
if (
config.postUpdateOptions &&
config.postUpdateOptions.includes('yarnDedupeHighest')
) {
if (config.postUpdateOptions?.includes('yarnDedupeHighest')) {
logger.debug('Performing yarn dedupe highest');
const dedupeCommand = 'npx yarn-deduplicate --strategy highest && yarn';
const dedupeRes = await exec(dedupeCommand, {
cwd,
env,
});
// istanbul ignore next
stdout += dedupeRes.stdout || '';
stderr += dedupeRes.stderr || '';
commands.push('npx yarn-deduplicate --strategy highest');
// Run yarn again in case any changes are necessary
commands.push(`yarn install ${cmdOptions}`.trim());
}
// Run the commands
await exec(commands, execOptions);
// Read the result
lockFile = await readFile(join(cwd, 'yarn.lock'), 'utf8');
} catch (err) /* istanbul ignore next */ {
logger.debug(
{
cmd,
err,
stdout,
stderr,
type: 'yarn',
},
'lock file error'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment