diff --git a/lib/manager/composer/artifacts.ts b/lib/manager/composer/artifacts.ts index 277b105ae4ed0c..1567276f405d57 100644 --- a/lib/manager/composer/artifacts.ts +++ b/lib/manager/composer/artifacts.ts @@ -2,14 +2,12 @@ import is from '@sindresorhus/is'; import URL from 'url'; import fs from 'fs-extra'; import upath from 'upath'; -import { exec } from '../../util/exec'; +import { exec, ExecOptions } from '../../util/exec'; import { UpdateArtifact, UpdateArtifactsResult } from '../common'; import { logger } from '../../logger'; import * as hostRules from '../../util/host-rules'; -import { getChildProcessEnv } from '../../util/exec/env'; import { platform } from '../../platform'; import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../constants/error-messages'; -import { BinarySource } from '../../util/exec/common'; export async function updateArtifacts({ packageFileName, @@ -18,11 +16,13 @@ export async function updateArtifacts({ config, }: UpdateArtifact): Promise { logger.debug(`composer.updateArtifacts(${packageFileName})`); - const env = getChildProcessEnv(['COMPOSER_CACHE_DIR']); - env.COMPOSER_CACHE_DIR = - env.COMPOSER_CACHE_DIR || upath.join(config.cacheDir, './others/composer'); - await fs.ensureDir(env.COMPOSER_CACHE_DIR); - logger.debug('Using composer cache ' + env.COMPOSER_CACHE_DIR); + + const cacheDir = + process.env.COMPOSER_CACHE_DIR || + upath.join(config.cacheDir, './others/composer'); + await fs.ensureDir(cacheDir); + logger.debug(`Using composer cache ${cacheDir}`); + const lockFileName = packageFileName.replace(/\.json$/, '.lock'); const existingLockFileContent = await platform.getFile(lockFileName); if (!existingLockFileContent) { @@ -95,29 +95,15 @@ export async function updateArtifacts({ const localAuthFileName = upath.join(cwd, 'auth.json'); await fs.outputFile(localAuthFileName, JSON.stringify(authJson)); } - let cmd: string; - if (config.binarySource === BinarySource.Docker) { - logger.info('Running composer via docker'); - cmd = `docker run --rm `; - if (config.dockerUser) { - cmd += `--user=${config.dockerUser} `; - } - const volumes = [config.localDir, env.COMPOSER_CACHE_DIR]; - cmd += volumes.map(v => `-v "${v}":"${v}" `).join(''); - const envVars = ['COMPOSER_CACHE_DIR']; - cmd += envVars.map(e => `-e ${e} `); - cmd += `-w "${cwd}" `; - cmd += `renovate/composer composer`; - } else if ( - config.binarySource === BinarySource.Auto || - config.binarySource === BinarySource.Global - ) { - logger.info('Running composer via global composer'); - cmd = 'composer'; - } else { - logger.warn({ config }, 'Unsupported binarySource'); - cmd = 'composer'; - } + const execOptions: ExecOptions = { + extraEnv: { + COMPOSER_CACHE_DIR: cacheDir, + }, + docker: { + image: 'renovate/composer', + }, + }; + const cmd = 'composer'; let args; if (config.isLockFileMaintenance) { args = 'install'; @@ -130,10 +116,7 @@ export async function updateArtifacts({ args += ' --no-scripts --no-autoloader'; } logger.debug({ cmd, args }, 'composer command'); - await exec(`${cmd} ${args}`, { - cwd, - env, - }); + await exec(`${cmd} ${args}`, execOptions); const status = await platform.getRepoStatus(); if (!status.modified.includes(lockFileName)) { return null; diff --git a/test/manager/composer/__snapshots__/artifacts.spec.ts.snap b/test/manager/composer/__snapshots__/artifacts.spec.ts.snap index d3abf88eff6176..2a25850fe4321a 100644 --- a/test/manager/composer/__snapshots__/artifacts.spec.ts.snap +++ b/test/manager/composer/__snapshots__/artifacts.spec.ts.snap @@ -85,7 +85,13 @@ Array [ exports[`.updateArtifacts() supports docker mode 1`] = ` Array [ Object { - "cmd": "docker run --rm --user=foobar -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache/others/composer\\":\\"/tmp/renovate/cache/others/composer\\" -e COMPOSER_CACHE_DIR -w \\"/tmp/github/some/repo\\" renovate/composer composer update --with-dependencies --ignore-platform-reqs --no-ansi --no-interaction --no-scripts --no-autoloader", + "cmd": "docker pull renovate/composer", + "options": Object { + "encoding": "utf-8", + }, + }, + Object { + "cmd": "docker run --rm --user=foobar -v \\"/tmp/github/some/repo\\":\\"/tmp/github/some/repo\\" -v \\"/tmp/renovate/cache\\":\\"/tmp/renovate/cache\\" -e COMPOSER_CACHE_DIR -w \\"/tmp/github/some/repo\\" renovate/composer bash -l -c \\"composer update --with-dependencies --ignore-platform-reqs --no-ansi --no-interaction --no-scripts --no-autoloader\\"", "options": Object { "cwd": "/tmp/github/some/repo", "encoding": "utf-8", diff --git a/test/manager/composer/artifacts.spec.ts b/test/manager/composer/artifacts.spec.ts index aef0f4b9487f4b..514999cded861c 100644 --- a/test/manager/composer/artifacts.spec.ts +++ b/test/manager/composer/artifacts.spec.ts @@ -1,3 +1,4 @@ +import { join } from 'upath'; import _fs from 'fs-extra'; import { exec as _exec } from 'child_process'; import * as composer from '../../../lib/manager/composer/artifacts'; @@ -7,6 +8,8 @@ import { StatusResult } from '../../../lib/platform/git/storage'; import { envMock, mockExecAll } from '../../execUtil'; import * as _env from '../../../lib/util/exec/env'; import { BinarySource } from '../../../lib/util/exec/common'; +import { setUtilConfig } from '../../../lib/util'; +import { resetPrefetchedImages } from '../../../lib/util/exec/docker'; jest.mock('fs-extra'); jest.mock('child_process'); @@ -21,8 +24,10 @@ const env = mocked(_env); const platform = mocked(_platform); const config = { - localDir: '/tmp/github/some/repo', - cacheDir: '/tmp/renovate/cache', + // `join` fixes Windows CI + localDir: join('/tmp/github/some/repo'), + cacheDir: join('/tmp/renovate/cache'), + dockerUser: 'foobar', }; describe('.updateArtifacts()', () => { @@ -30,6 +35,8 @@ describe('.updateArtifacts()', () => { jest.resetAllMocks(); jest.resetModules(); env.getChildProcessEnv.mockReturnValue(envMock.basic); + setUtilConfig(config); + resetPrefetchedImages(); }); it('returns if no composer.lock found', async () => { expect( @@ -117,6 +124,7 @@ describe('.updateArtifacts()', () => { expect(execSnapshots).toMatchSnapshot(); }); it('supports docker mode', async () => { + setUtilConfig({ ...config, binarySource: BinarySource.Docker }); platform.getFile.mockResolvedValueOnce('Current composer.lock'); const execSnapshots = mockExecAll(exec); @@ -127,11 +135,7 @@ describe('.updateArtifacts()', () => { packageFileName: 'composer.json', updatedDeps: [], newPackageFileContent: '{}', - config: { - ...config, - binarySource: BinarySource.Docker, - dockerUser: 'foobar', - }, + config, }) ).not.toBeNull(); expect(execSnapshots).toMatchSnapshot();