diff --git a/lib/manager/npm/post-update/index.ts b/lib/manager/npm/post-update/index.ts index e40b103529d03a1bb6e199ceb75c657087fb9b25..6207c66889aaa5ac7a7236d1fcd13e95f44c9212 100644 --- a/lib/manager/npm/post-update/index.ts +++ b/lib/manager/npm/post-update/index.ts @@ -541,7 +541,7 @@ export async function getAdditionalFiles( (upgrade) => upgrade.npmLock === npmLock ); const res = await npm.generateLockFile( - lockFileDir, + fullLockFileDir, env, fileName, config, diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index ebd4cddb00c21139839e55cddb15a39c48409d26..776b4c75c70f4f9ad68ed66151c871fc77337898 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -26,7 +26,7 @@ export function getLernaVersion( export async function generateLockFiles( lernaPackageFile: Partial<PackageFile>, - lockFileDir: string, + cwd: string, config: PostUpdateConfig, env: NodeJS.ProcessEnv, skipInstalls?: boolean @@ -75,7 +75,7 @@ export async function generateLockFiles( lernaCommand += cmdOptions; const tagConstraint = await getNodeConstraint(config); const execOptions: ExecOptions = { - cwd: lockFileDir, + cwd, extraEnv: { NPM_CONFIG_CACHE: env.NPM_CONFIG_CACHE, npm_config_store: env.npm_config_store, diff --git a/lib/manager/npm/post-update/npm.spec.ts b/lib/manager/npm/post-update/npm.spec.ts index 7ba640af365772651f7003aa4d36d8b316fcac2c..e4f9341151427be2b7b907f2b7f5a208fc1b8552 100644 --- a/lib/manager/npm/post-update/npm.spec.ts +++ b/lib/manager/npm/post-update/npm.spec.ts @@ -1,25 +1,30 @@ +import { exec as _exec } from 'child_process'; import upath from 'upath'; -import { envMock, exec, mockExecAll } from '../../../../test/exec-util'; -import { env, fs } from '../../../../test/util'; -import { GlobalConfig } from '../../../config/global'; + +import { envMock, mockExecAll } from '../../../../test/exec-util'; +import { mocked } from '../../../../test/util'; +import * as _env from '../../../util/exec/env'; +import * as _fs from '../../../util/fs/proxies'; import * as npmHelper from './npm'; jest.mock('child_process'); jest.mock('../../../util/exec/env'); -jest.mock('../../../util/fs'); +jest.mock('../../../util/fs/proxies'); jest.mock('./node-version'); +const exec: jest.Mock<typeof _exec> = _exec as any; +const env = mocked(_env); +const fs = mocked(_fs); + describe('manager/npm/post-update/npm', () => { beforeEach(() => { jest.resetAllMocks(); jest.resetModules(); env.getChildProcessEnv.mockReturnValue(envMock.basic); - GlobalConfig.set({ localDir: '' }); }); - it('generates lock files', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValueOnce('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const skipInstalls = true; const postUpdateOptions = ['npmDedupe']; const updates = [ @@ -32,15 +37,14 @@ describe('manager/npm/post-update/npm', () => { { skipInstalls, postUpdateOptions }, updates ); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBeUndefined(); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); - it('performs lock file updates', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValueOnce('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const skipInstalls = true; const updates = [ { depName: 'some-dep', newVersion: '1.0.1', isLockfileUpdate: true }, @@ -52,16 +56,16 @@ describe('manager/npm/post-update/npm', () => { { skipInstalls }, updates ); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBeUndefined(); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); - it('performs npm-shrinkwrap.json updates', async () => { const execSnapshots = mockExecAll(exec); - fs.localPathExists.mockResolvedValueOnce(true); - fs.readLocalFile.mockResolvedValueOnce('package-lock-contents'); + fs.pathExists.mockResolvedValueOnce(true); + fs.move = jest.fn(); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const skipInstalls = true; const res = await npmHelper.generateLockFile( 'some-dir', @@ -69,25 +73,28 @@ describe('manager/npm/post-update/npm', () => { 'npm-shrinkwrap.json', { skipInstalls } ); + expect(fs.pathExists).toHaveBeenCalledWith( + upath.join('some-dir', 'package-lock.json') + ); expect(fs.move).toHaveBeenCalledTimes(1); expect(fs.move).toHaveBeenCalledWith( upath.join('some-dir', 'package-lock.json'), upath.join('some-dir', 'npm-shrinkwrap.json') ); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); - expect(fs.readLocalFile).toHaveBeenCalledWith( - 'some-dir/npm-shrinkwrap.json', + expect(fs.readFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledWith( + upath.join('some-dir', 'npm-shrinkwrap.json'), 'utf8' ); expect(res.error).toBeUndefined(); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); - it('performs npm-shrinkwrap.json updates (no package-lock.json)', async () => { const execSnapshots = mockExecAll(exec); - fs.findLocalSiblingOrParent.mockResolvedValueOnce(null); - fs.readLocalFile.mockResolvedValueOnce('package-lock-contents'); + fs.pathExists.mockResolvedValueOnce(false); + fs.move = jest.fn(); + fs.readFile = jest.fn((_, _1) => 'package-lock-contents') as never; const skipInstalls = true; const res = await npmHelper.generateLockFile( 'some-dir', @@ -95,20 +102,22 @@ describe('manager/npm/post-update/npm', () => { 'npm-shrinkwrap.json', { skipInstalls } ); + expect(fs.pathExists).toHaveBeenCalledWith( + upath.join('some-dir', 'package-lock.json') + ); expect(fs.move).toHaveBeenCalledTimes(0); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); - expect(fs.readLocalFile).toHaveBeenCalledWith( - 'some-dir/npm-shrinkwrap.json', + expect(fs.readFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledWith( + upath.join('some-dir', 'npm-shrinkwrap.json'), 'utf8' ); expect(res.error).toBeUndefined(); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); - it('performs full install', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValueOnce('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const skipInstalls = false; const binarySource = 'global'; const res = await npmHelper.generateLockFile( @@ -117,15 +126,14 @@ describe('manager/npm/post-update/npm', () => { 'package-lock.json', { skipInstalls, binarySource } ); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBeUndefined(); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); - it('runs twice if remediating', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValueOnce('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const binarySource = 'global'; const res = await npmHelper.generateLockFile( 'some-dir', @@ -134,58 +142,54 @@ describe('manager/npm/post-update/npm', () => { { binarySource }, [{ isRemediation: true }] ); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBeUndefined(); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toHaveLength(2); }); - it('catches errors', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockImplementation(() => { + fs.readFile = jest.fn(() => { throw new Error('not found'); - }); + }) as never; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'package-lock.json' ); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBeTrue(); expect(res.lockFile).toBeUndefined(); expect(execSnapshots).toMatchSnapshot(); }); - it('finds npm globally', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValue('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'package-lock.json' ); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); - it('uses docker npm', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValue('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'package-lock.json', { binarySource: 'docker', constraints: { npm: '^6.0.0' } } ); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); - it('performs lock file maintenance', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValue('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await npmHelper.generateLockFile( 'some-dir', {}, @@ -193,8 +197,8 @@ describe('manager/npm/post-update/npm', () => { {}, [{ isLockFileMaintenance: true }] ); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); - expect(fs.deleteLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); + expect(fs.remove).toHaveBeenCalledTimes(1); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index 1e1e4740e29d46de0d612121bde3cbe49b38bd96..f13a4f1b3cf42298a474251495f42c109b19a59e 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -7,27 +7,19 @@ import { import { logger } from '../../../logger'; import { exec } from '../../../util/exec'; import type { ExecOptions, ToolConstraint } from '../../../util/exec/types'; -import { - deleteLocalFile, - localPathExists, - move, - readLocalFile, -} from '../../../util/fs'; +import { move, pathExists, readFile, remove } from '../../../util/fs'; import type { PostUpdateConfig, Upgrade } from '../../types'; import { getNodeConstraint } from './node-version'; import type { GenerateLockFileResult } from './types'; export async function generateLockFile( - lockFileDir: string, + cwd: string, env: NodeJS.ProcessEnv, - fileName: string, + filename: string, config: PostUpdateConfig = {}, upgrades: Upgrade[] = [] ): Promise<GenerateLockFileResult> { - // TODO: don't assume package-lock.json is in the same directory - const lockFileName = upath.join(lockFileDir, fileName); - - logger.debug(`Spawning npm install to create ${lockFileDir}/${fileName}`); + logger.debug(`Spawning npm install to create ${cwd}/${filename}`); const { skipInstalls, postUpdateOptions } = config; let lockFile = null; @@ -52,7 +44,7 @@ export async function generateLockFile( const tagConstraint = await getNodeConstraint(config); const execOptions: ExecOptions = { - cwdFile: lockFileName, + cwd, extraEnv: { NPM_CONFIG_CACHE: env.NPM_CONFIG_CACHE, npm_config_store: env.npm_config_store, @@ -98,12 +90,15 @@ export async function generateLockFile( commands.push('npm dedupe'); } + // TODO: don't assume package-lock.json is in the same directory + const lockFileName = upath.join(cwd, filename); + if (upgrades.find((upgrade) => upgrade.isLockFileMaintenance)) { logger.debug( `Removing ${lockFileName} first due to lock file maintenance upgrade` ); try { - await deleteLocalFile(lockFileName); + await remove(lockFileName); } catch (err) /* istanbul ignore next */ { logger.debug( { err, lockFileName }, @@ -117,17 +112,17 @@ export async function generateLockFile( // massage to shrinkwrap if necessary if ( - fileName === 'npm-shrinkwrap.json' && - (await localPathExists(upath.join(lockFileDir, 'package-lock.json'))) + filename === 'npm-shrinkwrap.json' && + (await pathExists(upath.join(cwd, 'package-lock.json'))) ) { await move( - upath.join(lockFileDir, 'package-lock.json'), - upath.join(lockFileDir, 'npm-shrinkwrap.json') + upath.join(cwd, 'package-lock.json'), + upath.join(cwd, 'npm-shrinkwrap.json') ); } // Read the result - lockFile = await readLocalFile(lockFileName, 'utf8'); + lockFile = await readFile(upath.join(cwd, filename), 'utf8'); } catch (err) /* istanbul ignore next */ { if (err.message === TEMPORARY_ERROR) { throw err; diff --git a/lib/manager/npm/post-update/pnpm.spec.ts b/lib/manager/npm/post-update/pnpm.spec.ts index 6b484acbb8278c6dddb32b4a40ec1317d7ad4756..14c46e2dcac12296151820474bb35a949c233274 100644 --- a/lib/manager/npm/post-update/pnpm.spec.ts +++ b/lib/manager/npm/post-update/pnpm.spec.ts @@ -1,69 +1,70 @@ -import { envMock, exec, mockExecAll } from '../../../../test/exec-util'; -import { env, fs, mocked } from '../../../../test/util'; -import { GlobalConfig } from '../../../config/global'; +import { exec as _exec } from 'child_process'; +import { envMock, mockExecAll } from '../../../../test/exec-util'; +import { mocked } from '../../../../test/util'; +import * as _env from '../../../util/exec/env'; +import * as _fs from '../../../util/fs/proxies'; import type { PostUpdateConfig } from '../../types'; import * as _pnpmHelper from './pnpm'; jest.mock('child_process'); jest.mock('../../../util/exec/env'); -jest.mock('../../../util/fs'); +jest.mock('../../../util/fs/proxies'); jest.mock('./node-version'); +const exec: jest.Mock<typeof _exec> = _exec as any; +const env = mocked(_env); +const fs = mocked(_fs); const pnpmHelper = mocked(_pnpmHelper); delete process.env.NPM_CONFIG_CACHE; describe('manager/npm/post-update/pnpm', () => { let config: PostUpdateConfig; beforeEach(() => { - jest.clearAllMocks(); config = { cacheDir: 'some-cache-dir', constraints: { pnpm: '^2.0.0' } }; env.getChildProcessEnv.mockReturnValue(envMock.basic); - GlobalConfig.set({ localDir: '' }); }); - it('generates lock files', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValueOnce('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await pnpmHelper.generateLockFile('some-dir', {}, config); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); - it('catches errors', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockRejectedValue(new Error('not found')); + fs.readFile = jest.fn(() => { + throw new Error('not found'); + }) as never; const res = await pnpmHelper.generateLockFile('some-dir', {}, config); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBeTrue(); expect(res.lockFile).toBeUndefined(); expect(execSnapshots).toMatchSnapshot(); }); - it('finds pnpm globally', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValueOnce('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await pnpmHelper.generateLockFile('some-dir', {}, config); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); - it('performs lock file maintenance', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValueOnce('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await pnpmHelper.generateLockFile('some-dir', {}, config, [ { isLockFileMaintenance: true }, ]); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); - expect(fs.deleteLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); + expect(fs.remove).toHaveBeenCalledTimes(1); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); }); it('uses the new version if packageManager is updated', async () => { const execSnapshots = mockExecAll(exec); - fs.readLocalFile.mockResolvedValueOnce('package-lock-contents'); + fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await pnpmHelper.generateLockFile('some-dir', {}, config, [ { depType: 'packageManager', @@ -71,7 +72,7 @@ describe('manager/npm/post-update/pnpm', () => { newValue: '6.16.1', }, ]); - expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.lockFile).toBe('package-lock-contents'); expect(execSnapshots).toMatchSnapshot(); // TODO: check docker preCommands diff --git a/lib/manager/npm/post-update/pnpm.ts b/lib/manager/npm/post-update/pnpm.ts index 2ad2ec9090af4cfc55efdcfe83027224c660e03d..20b72530a558e31ee0585d9c5e4db215d988f901 100644 --- a/lib/manager/npm/post-update/pnpm.ts +++ b/lib/manager/npm/post-update/pnpm.ts @@ -4,18 +4,18 @@ import { TEMPORARY_ERROR } from '../../../constants/error-messages'; import { logger } from '../../../logger'; import { exec } from '../../../util/exec'; import type { ExecOptions, ToolConstraint } from '../../../util/exec/types'; -import { deleteLocalFile, readLocalFile } from '../../../util/fs'; +import { readFile, remove } from '../../../util/fs'; import type { PostUpdateConfig, Upgrade } from '../../types'; import { getNodeConstraint } from './node-version'; import type { GenerateLockFileResult } from './types'; export async function generateLockFile( - lockFileDir: string, + cwd: string, env: NodeJS.ProcessEnv, config: PostUpdateConfig, upgrades: Upgrade[] = [] ): Promise<GenerateLockFileResult> { - const lockFileName = upath.join(lockFileDir, 'pnpm-lock.yaml'); + const lockFileName = upath.join(cwd, 'pnpm-lock.yaml'); logger.debug(`Spawning pnpm install to create ${lockFileName}`); let lockFile = null; let stdout: string; @@ -32,7 +32,7 @@ export async function generateLockFile( }; const tagConstraint = await getNodeConstraint(config); const execOptions: ExecOptions = { - cwdFile: lockFileName, + cwd, extraEnv: { NPM_CONFIG_CACHE: env.NPM_CONFIG_CACHE, npm_config_store: env.npm_config_store, @@ -62,7 +62,7 @@ export async function generateLockFile( `Removing ${lockFileName} first due to lock file maintenance upgrade` ); try { - await deleteLocalFile(lockFileName); + await remove(lockFileName); } catch (err) /* istanbul ignore next */ { logger.debug( { err, lockFileName }, @@ -72,7 +72,7 @@ export async function generateLockFile( } await exec(`${cmd} ${args}`, execOptions); - lockFile = await readLocalFile(lockFileName, 'utf8'); + lockFile = await readFile(lockFileName, 'utf8'); } catch (err) /* istanbul ignore next */ { if (err.message === TEMPORARY_ERROR) { throw err; diff --git a/lib/manager/npm/post-update/yarn.spec.ts b/lib/manager/npm/post-update/yarn.spec.ts index 05d494571a73803252753b395d7c06bb82e7313e..0a3ceceb76b688961a00c1f66cb4ea9ec524b55c 100644 --- a/lib/manager/npm/post-update/yarn.spec.ts +++ b/lib/manager/npm/post-update/yarn.spec.ts @@ -1,13 +1,13 @@ +import { exec as _exec } from 'child_process'; import fs from 'fs-extra'; import { ExecSnapshots, envMock, - exec, mockExecAll, } from '../../../../test/exec-util'; import { Fixtures } from '../../../../test/fixtures'; -import { env } from '../../../../test/util'; -import { GlobalConfig } from '../../../config/global'; +import { mocked } from '../../../../test/util'; +import * as _env from '../../../util/exec/env'; import * as yarnHelper from './yarn'; jest.mock('fs-extra', () => @@ -17,6 +17,9 @@ jest.mock('child_process'); jest.mock('../../../util/exec/env'); jest.mock('./node-version'); +const exec: jest.Mock<typeof _exec> = _exec as any; +const env = mocked(_env); + delete process.env.NPM_CONFIG_CACHE; // TODO: figure out snapshot similarity for each CI platform (#9617) @@ -32,7 +35,6 @@ describe('manager/npm/post-update/yarn', () => { jest.clearAllMocks(); jest.resetModules(); env.getChildProcessEnv.mockReturnValue(envMock.basic); - GlobalConfig.set({ localDir: '' }); }); it.each([ @@ -186,7 +188,6 @@ describe('manager/npm/post-update/yarn', () => { ])( 'performs lock file maintenance using yarn v%s', async (yarnVersion, yarnCompatibility, expectedFsCalls) => { - GlobalConfig.set({ localDir: '.' }); Fixtures.mock( { '.yarnrc': null, diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index 5f717ba7cee847e36de31e41b4ae311eed3d8688..5420e46b27963c4b2fe1280a26ba442d70c9b6ef 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -12,27 +12,19 @@ import { logger } from '../../../logger'; import { ExternalHostError } from '../../../types/errors/external-host-error'; import { exec } from '../../../util/exec'; import type { ExecOptions } from '../../../util/exec/types'; -import { - deleteLocalFile, - exists, - readLocalFile, - writeLocalFile, -} from '../../../util/fs'; +import { exists, readFile, remove, writeFile } from '../../../util/fs'; import { newlineRegex, regEx } from '../../../util/regex'; import type { PostUpdateConfig, Upgrade } from '../../types'; import { getNodeConstraint } from './node-version'; import type { GenerateLockFileResult } from './types'; export async function checkYarnrc( - lockFileDir: string + cwd: string ): Promise<{ offlineMirror: boolean; yarnPath: string | null }> { let offlineMirror = false; let yarnPath: string = null; try { - const yarnrc = await readLocalFile( - upath.join(lockFileDir, '.yarnrc'), - 'utf8' - ); + const yarnrc = await readFile(`${cwd}/.yarnrc`, 'utf8'); if (is.string(yarnrc)) { const mirrorLine = yarnrc .split(newlineRegex) @@ -50,10 +42,7 @@ export async function checkYarnrc( regEx(/^yarn-path\s+"?.+?"?$/gm), '' ); - await writeLocalFile( - upath.join(lockFileDir, '.yarnrc'), - scrubbedYarnrc - ); + await writeFile(`${cwd}/.yarnrc`, scrubbedYarnrc); yarnPath = null; } } @@ -74,12 +63,12 @@ export function isYarnUpdate(upgrade: Upgrade): boolean { } export async function generateLockFile( - lockFileDir: string, + cwd: string, env: NodeJS.ProcessEnv, config: PostUpdateConfig = {}, upgrades: Upgrade[] = [] ): Promise<GenerateLockFileResult> { - const lockFileName = upath.join(lockFileDir, 'yarn.lock'); + const lockFileName = upath.join(cwd, 'yarn.lock'); logger.debug(`Spawning yarn install to create ${lockFileName}`); let lockFile = null; try { @@ -113,7 +102,7 @@ export async function generateLockFile( let cmdOptions = ''; // should have a leading space if (config.skipInstalls !== false) { if (isYarn1) { - const { offlineMirror, yarnPath } = await checkYarnrc(lockFileDir); + const { offlineMirror, yarnPath } = await checkYarnrc(cwd); if (!offlineMirror) { 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 @@ -156,7 +145,7 @@ export async function generateLockFile( } const tagConstraint = await getNodeConstraint(config); const execOptions: ExecOptions = { - cwdFile: lockFileName, + cwd, extraEnv, docker: { image: 'node', @@ -226,7 +215,7 @@ export async function generateLockFile( `Removing ${lockFileName} first due to lock file maintenance upgrade` ); try { - await deleteLocalFile(lockFileName); + await remove(lockFileName); } catch (err) /* istanbul ignore next */ { logger.debug( { err, lockFileName }, @@ -239,10 +228,7 @@ export async function generateLockFile( await exec(commands, execOptions); // Read the result - lockFile = await readLocalFile(lockFileName, 'utf8'); - if (lockFile === null) { - throw new Error('Error reading local file'); - } + lockFile = await readFile(lockFileName, 'utf8'); } catch (err) /* istanbul ignore next */ { if (err.message === TEMPORARY_ERROR) { throw err;