diff --git a/lib/manager/composer/lock-file.js b/lib/manager/composer/lock-file.js index f679bab58f084f5e43bc652eea55811e8c4b4a9a..6fc3efa092457ddad5d0007ded50cfcc921314b7 100644 --- a/lib/manager/composer/lock-file.js +++ b/lib/manager/composer/lock-file.js @@ -2,9 +2,13 @@ const { exec } = require('child-process-promise'); const fs = require('fs-extra'); const upath = require('upath'); const os = require('os'); +const Docker = require('dockerode'); +const { WritableStreamBuffer } = require('stream-buffers'); const hostRules = require('../../util/host-rules'); +const docker = new Docker(); + module.exports = { getLockFile, }; @@ -59,17 +63,36 @@ async function getLockFile( COMPOSER_CACHE_DIR: process.env.COMPOSER_CACHE_DIR, }; const startTime = process.hrtime(); - const cmd = - ('composer update ' + updatedDeps.join(' ')).trim() + - ' --ignore-platform-reqs'; - logger.debug({ cmd }); - ({ stdout, stderr } = await exec(cmd, { - cwd, - shell: true, - env, - })); - logger.debug(`composer stdout:\n${stdout}`); - logger.debug(`composer stderr:\n${stderr}`); + const args = + ('update ' + updatedDeps.join(' ')).trim() + + ' --ignore-platform-reqs --no-ansi'; + logger.debug({ args }, 'composer update command'); + if (config.binarySource === 'docker') { + logger.info('Running composer via docker'); + const outBuf = new WritableStreamBuffer(); + const errBuf = new WritableStreamBuffer(); + const container = await docker.run( + 'composer', + args.split(' '), + [outBuf, errBuf], + { + Hostconfig: { + Binds: [`${config.localDir}:${config.localDir}`], + }, + WorkingDir: `${cwd}`, + } + ); + await container.remove(); + stdout = outBuf.getContentsAsString() || null; + stderr = errBuf.getContentsAsString() || null; + } else { + logger.info('Running composer via global'); + ({ stdout, stderr } = await exec('composer ' + args, { + cwd, + shell: true, + env, + })); + } const duration = process.hrtime(startTime); const seconds = Math.round(duration[0] + duration[1] / 1e9); logger.info( diff --git a/package.json b/package.json index 0d9c7e778a41b63e7b442abf48c1f55193842126..9ee98c12b3f55f10dac7cf60b607ec982f76d18b 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "delay": "4.0.1", "detect-indent": "5.0.0", "docker-registry-client": "3.3.0", + "dockerode": "2.5.7", "email-addresses": "3.0.2", "fast-clone": "1.5.3", "fast-xml-parser": "3.12.5", @@ -113,6 +114,7 @@ "semver-utils": "1.1.2", "simple-git": "1.102.0", "slugify": "1.3.1", + "stream-buffers": "3.0.2", "traverse": "0.6.6", "upath": "1.1.0", "validator": "10.8.0", diff --git a/test/manager/composer/lock-file.spec.js b/test/manager/composer/lock-file.spec.js index 14bd7d8bda868cfd164cdf12a019e8ecb73d7535..f4291362295dfe5cacfad3dc0db143b95a28bb2b 100644 --- a/test/manager/composer/lock-file.spec.js +++ b/test/manager/composer/lock-file.spec.js @@ -40,6 +40,20 @@ describe('.getLockFile()', () => { await composer.getLockFile('composer.json', [], '{}', config) ).not.toBeNull(); }); + it('supports docker mode', async () => { + platform.getFile.mockReturnValueOnce('Current composer.lock'); + exec.mockReturnValueOnce({ + stdout: '', + stderror: '', + }); + fs.readFile = jest.fn(() => 'New composer.lock'); + expect( + await composer.getLockFile('composer.json', [], '{}', { + ...config, + binarySource: 'docker', + }) + ).not.toBeNull(); + }); it('catches errors', async () => { platform.getFile.mockReturnValueOnce('Current composer.lock'); fs.outputFile = jest.fn(() => { diff --git a/yarn.lock b/yarn.lock index f29fe994e02b39780c3076e7b2c47f8ac08aeb41..36a2fd651c88daf795da9326758051b0c80e4dce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -145,6 +145,13 @@ version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" +JSONStream@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + JSONStream@^1.0.4, JSONStream@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.3.tgz#27b4b8fbbfeab4e71bcf551e7f27be8d952239bf" @@ -689,6 +696,13 @@ bin-links@^1.1.2: graceful-fs "^4.1.11" write-file-atomic "^2.3.0" +bl@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + block-stream@*: version "0.0.9" resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" @@ -779,10 +793,25 @@ btoa-lite@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + buffer-from@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04" @@ -1269,7 +1298,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.5.0, concat-stream@^1.5.2: +concat-stream@^1.5.0, concat-stream@^1.5.2, concat-stream@~1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" dependencies: @@ -1505,6 +1534,12 @@ debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: dependencies: ms "2.0.0" +debug@^3.2.5: + version "3.2.5" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.5.tgz#c2418fbfd7a29f4d4f70ff4cea604d4b64c46407" + dependencies: + ms "^2.1.1" + debug@^4.0.0, debug@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.0.1.tgz#f9bb36d439b8d1f0dd52d8fb6b46e4ebb8c1cd5b" @@ -1664,6 +1699,15 @@ dir-glob@^2.0.0: arrify "^1.0.1" path-type "^3.0.0" +docker-modem@1.0.x: + version "1.0.7" + resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-1.0.7.tgz#69702a95c060eeb6775f79ccdcc734e5946972a4" + dependencies: + JSONStream "1.3.2" + debug "^3.2.5" + readable-stream "~1.0.26-4" + split-ca "^1.0.0" + docker-registry-client@3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/docker-registry-client/-/docker-registry-client-3.3.0.tgz#11cd40255f31462587c799ed5df9ac81dfef3d09" @@ -1681,6 +1725,14 @@ docker-registry-client@3.3.0: verror "1.x >=1.6.0" www-authenticate "0.6.x >=0.6.2" +dockerode@2.5.7: + version "2.5.7" + resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-2.5.7.tgz#13dc9ec0f7f353ac0e512249e77f32d1aaa1199e" + dependencies: + concat-stream "~1.6.2" + docker-modem "1.0.x" + tar-fs "~1.16.3" + doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -2363,6 +2415,10 @@ from2@^2.1.0, from2@^2.1.1: inherits "^2.0.1" readable-stream "^2.0.0" +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + fs-extra@7.0.0, fs-extra@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.0.tgz#8cc3f47ce07ef7b3593a11b9fb245f7e34c041d6" @@ -5929,6 +5985,13 @@ psl@^1.1.24: version "1.1.29" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" +pump@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + pump@^2.0.0, pump@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" @@ -6128,7 +6191,7 @@ read@1, read@~1.0.1, read@~1.0.7: dependencies: mute-stream "~0.0.4" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: @@ -6140,6 +6203,15 @@ read@1, read@~1.0.1, read@~1.0.7: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@~1.0.26-4: + version "1.0.34" + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readable-stream@~1.1.10, readable-stream@~1.1.9: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -6884,6 +6956,10 @@ spdx-license-ids@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" +split-ca@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6" + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -6961,6 +7037,10 @@ stealthy-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" +stream-buffers@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-3.0.2.tgz#5249005a8d5c2d00b3a32e6e0a6ea209dc4f3521" + stream-combiner2@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" @@ -7122,6 +7202,27 @@ table@^4.0.3: slice-ansi "1.0.0" string-width "^2.1.1" +tar-fs@~1.16.3: + version "1.16.3" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" + dependencies: + chownr "^1.0.1" + mkdirp "^0.5.1" + pump "^1.0.0" + tar-stream "^1.1.2" + +tar-stream@^1.1.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + tar@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" @@ -7224,6 +7325,10 @@ tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" @@ -7800,7 +7905,7 @@ xregexp@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.1.1.tgz#eb8a032aa028d403f7b1b22c47a5f16c24b21d8d" -xtend@^4.0.1, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"