Skip to content

Instantly share code, notes, and snippets.

@driskell
Last active November 29, 2020 11:53
Show Gist options
  • Save driskell/74c3683cd01708ac6115cfa174705aeb to your computer and use it in GitHub Desktop.
Save driskell/74c3683cd01708ac6115cfa174705aeb to your computer and use it in GitHub Desktop.
Raise minimum composer version constraint to match lock file
#!/usr/bin/env php
<?php
// Raise minimum dependency version to that within the lock file
// Be sure to update lock file hash with composer update --lock
$composerJsonPlain = file_get_contents('composer.json');
$composerJson = json_decode($composerJsonPlain, true);
$lockJson = json_decode(file_get_contents('composer.lock'), true);
$lockIndex = [];
foreach ($lockJson['packages'] as $package) {
$lockIndex[$package['name']] = $package;
}
const CONSTRAINT_LOOSE = 'loose';
const CONSTRAINT_WILD = 'wild';
$replaceConstraints = [];
foreach ($composerJson['require'] as $packageName => $constraint) {
$split = explode('.', $constraint);
if ($constraint[0] === '^') {
$updateCount = count($split) - 1;
} else if ($constraint[0] === '~') {
$updateCount = 1;
} else {
echo 'Unsupported constraint for ', $packageName, ' of ', $constraint, PHP_EOL;
continue;
}
if (empty($lockIndex[$packageName])) {
echo 'Package ', $packageName, ' with loose constraint ', $constraint, ' is not installed', PHP_EOL;
continue;
}
$installedVersion = $lockIndex[$packageName]['version'];
$stability = '';
$matches = null;
if (preg_match('/-([A-Za-z]+)/', $installedVersion, $matches)) {
if ($matches[1] === 'rc') {
$matches[1] = 'RC';
}
$stability = '@' . $matches[1];
}
$lockSplit = explode('.', $installedVersion, count($split) + 1);
if (count($lockSplit) < count($split)) {
echo 'Package ', $packageName, ' with loose constraint ', $constraint, ' is installed as ', $installedVersion, ' with an unexpected number of parts', PHP_EOL;
continue;
} else if (count($lockSplit) > count($split)) {
array_pop($lockSplit);
}
for ($i = 0; $i < $updateCount; $i++) {
$split[count($split) - 1 - $i] = $lockSplit[count($split) - 1 - $i];
}
$newConstraint = implode('.', $split) . $stability;
if ($constraint === $newConstraint) {
continue;
}
echo $packageName, ' with ', $constraint, ' is now ', $newConstraint, PHP_EOL;
$replaceConstraints[$packageName] = $newConstraint;
}
if (empty($replaceConstraints)) {
exit;
}
$composerJsonPlain = preg_replace_callback(
'#"require(?:-dev)?"\\s*:\\s*\\{[^\\}]*}#m', function ($matches) use ($replaceConstraints) {
foreach ($replaceConstraints as $packageName => $newConstraint) {
$matches[0] = preg_replace('#("' . preg_quote($packageName, '#') . '"\\s*:\\s*")[^"]+(")#m', '${1}' . $newConstraint . '${2}', $matches[0]);
}
return $matches[0];
},
$composerJsonPlain
);
file_put_contents('composer.json', $composerJsonPlain);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment