Skip to content

Commit

Permalink
feat(composer): composer.lock support (#2255)
Browse files Browse the repository at this point in the history
Adds logic to support updating the accompanying `composer.lock` file whenever `composer.json` is updated.

Closes #2098
  • Loading branch information
rarkins authored Jul 19, 2018
1 parent 449f721 commit c4389cb
Show file tree
Hide file tree
Showing 9 changed files with 450 additions and 13 deletions.
13 changes: 11 additions & 2 deletions lib/manager/composer/extract.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = {
extractDependencies,
};

function extractDependencies(content, packageFile) {
async function extractDependencies(content, packageFile) {
logger.debug('composer.extractDependencies()');
let packageJson;
try {
Expand Down Expand Up @@ -50,5 +50,14 @@ function extractDependencies(content, packageFile) {
if (!deps.length) {
return null;
}
return { deps };
let composerLock = false;
const filePath = packageFile.replace(/\.json$/, '.lock');
if (await platform.getFile(filePath)) {
logger.debug(
{ packageFile: packageFile.packageFile },
'Found composer.lock'
);
composerLock = filePath;
}
return { deps, composerLock };
}
2 changes: 2 additions & 0 deletions lib/manager/composer/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
const { extractDependencies } = require('./extract');
const { updateDependency } = require('../npm/update');
const { getLockFile } = require('./lock-file');

const language = 'php';

module.exports = {
extractDependencies,
getLockFile,
language,
updateDependency,
// TODO: support this
Expand Down
69 changes: 69 additions & 0 deletions lib/manager/composer/lock-file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const { exec } = require('child-process-promise');
const fs = require('fs-extra');
const tmp = require('tmp-promise');
const upath = require('upath');

module.exports = {
getLockFile,
};

async function getLockFile(
packageFileName,
updatedDeps,
newPackageFileContent
) {
logger.debug(`composer.getLockFile(${packageFileName})`);
const composerLockPath = packageFileName.replace(/\.json$/, '.lock');
const existingComposerLockContent = await platform.getFile(composerLockPath);
if (!existingComposerLockContent) {
logger.debug('No composer.lock found');
return null;
}
const tmpDir = await tmp.dir({ unsafeCleanup: true });
let stdout;
let stderr;
try {
const composerJsonFileName = upath.join(tmpDir.path, 'composer.json');
await fs.outputFile(composerJsonFileName, newPackageFileContent);
const composerLockFileName = upath.join(tmpDir.path, 'composer.lock');
await fs.outputFile(composerLockFileName, existingComposerLockContent);
const env = { HOME: process.env.HOME, PATH: process.env.PATH };
const startTime = process.hrtime();
const cmd = ('composer update ' + updatedDeps.join(' ')).trim();
logger.debug({ cmd });
({ stdout, stderr } = await exec(cmd, {
cwd: tmpDir.path,
shell: true,
env,
}));
logger.debug(`composer stdout:\n${stdout}`);
logger.debug(`composer stderr:\n${stderr}`);
const duration = process.hrtime(startTime);
const seconds = Math.round(duration[0] + duration[1] / 1e9);
const newComposerLockContent = await fs.readFile(
composerLockFileName,
'utf8'
);
logger.info(
{ seconds, type: 'composer.lock', stdout, stderr },
'Generated lockfile'
);
if (newComposerLockContent === existingComposerLockContent) {
logger.debug('composer.lock is unchanged');
return null;
}
logger.debug('Returning updated composer.lock');
return {
name: composerLockPath,
contents: newComposerLockContent,
};
} catch (err) {
logger.warn(
{ err, message: err.message },
'Failed to generate composer.lock'
);
return null;
} finally {
tmpDir.cleanup();
}
}
25 changes: 24 additions & 1 deletion lib/workers/branch/get-updated.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ async function getUpdatedPackageFiles(config) {
logger.debug('manager.getUpdatedPackageFiles()');
logger.trace({ config });
const updatedFileContents = {};
const packageFileManagers = {};
const packageFileUpdatedDeps = {};

for (const upgrade of config.upgrades) {
const { manager, packageFile } = upgrade;
const { manager, packageFile, depName } = upgrade;
packageFileManagers[packageFile] = manager;
packageFileUpdatedDeps[packageFile] =
packageFileUpdatedDeps[packageFile] || [];
packageFileUpdatedDeps[packageFile].push(depName);
if (upgrade.updateType !== 'lockFileMaintenance') {
const existingContent =
updatedFileContents[packageFile] ||
Expand Down Expand Up @@ -46,8 +52,25 @@ async function getUpdatedPackageFiles(config) {
name,
contents: updatedFileContents[name],
}));
const updatedLockFiles = [];
for (const packageFile of updatedPackageFiles) {
const manager = packageFileManagers[packageFile.name];
const updatedDeps = packageFileUpdatedDeps[packageFile.name];
const getLockFile = get(manager, 'getLockFile');
if (getLockFile) {
const updatedLockFile = await getLockFile(
packageFile.name,
updatedDeps,
packageFile.contents
);
if (updatedLockFile) {
updatedLockFiles.push(updatedLockFile);
}
}
}
return {
parentBranch: config.parentBranch, // Need to overwrite original config
updatedPackageFiles,
updatedLockFiles,
};
}
Loading

0 comments on commit c4389cb

Please sign in to comment.