Skip to content

Instantly share code, notes, and snippets.

@hostep
Last active February 27, 2020 08:00
Show Gist options
  • Save hostep/55c7c5b02b40f8e102720da909a6413f to your computer and use it in GitHub Desktop.
Save hostep/55c7c5b02b40f8e102720da909a6413f to your computer and use it in GitHub Desktop.
<?php
// The idea here is:
// - install Magento 2.3.3 and 2.3.3-p1 using composer in two different directories
// - loop over all directories in vendor/magento of those two installations
// - generate diff using 'git diff --no-index'
// - search and replace file paths in the diff and write it back as is
// - also output composer.patches.json file which can be used with the cweagans/composer-patches package
declare(strict_types=1);
// make sure the directories in $outputDir and $patchesDir exists before running the script, the script won't create them automatically
// modify the variables below to your hearts content
$patchName = 'Magento-2.3.3-p1'; // name of the patch files
$outputDir = "/Users/me/Desktop/$patchName-patches"; // directory where the generated patches and the patch file itself will be outputted
$patchesSubDir = 'vendor_patches'; // subdirectory for the generated patches
$patchesDir = $outputDir . '/' . $patchesSubDir;
$composerPatchesFilename = $outputDir . '/composer.patches.json'; // filename of where the json for the cweagans/composer-patches package package will be outputted
$nonPatchedInstall = '/Volumes/Projects/magento2/magento233'; // directory with the installation of Magento 2.3.3
$patchedInstall = '/Volumes/Projects/magento2/magento233-p1'; // directory with the installation of Magento 2.3.3-p1
// end of modifyiable variables
$fromDir = "$nonPatchedInstall/vendor/magento";
$toDir = "$patchedInstall/vendor/magento";
$composerPatchesContents = [];
$moduleDirs = findAllModuleDirs([$fromDir, $toDir]);
foreach ($moduleDirs as $moduleDir) {
$moduleDirFrom = $fromDir . '/' . $moduleDir;
$moduleDirTo = $toDir . '/' . $moduleDir;
$diff = shell_exec("git diff --no-index '$moduleDirFrom' '$moduleDirTo'");
if ($diff === null) {
continue;
}
$packageName = getComposerPackageName($moduleDirFrom, $moduleDirTo);
$diff = getModuleDiffData($diff, $moduleDirFrom, $moduleDirTo);
$patchFilename = $patchName . '-' . getPatchFilename($packageName);
$patchFullFilename = $patchesDir . '/' . $patchFilename;
file_put_contents($patchFullFilename, $diff);
echo "Outputted file '$patchFullFilename\n";
$composerPatchesContents['patches'][$packageName] = ["Patch from $patchName release" => $patchesSubDir . '/' . $patchFilename];
}
file_put_contents($composerPatchesFilename, json_encode($composerPatchesContents, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
echo "\nOutputted file '$composerPatchesFilename\n";
function findAllModuleDirs(array $dirs): array
{
$moduleDirs = [];
foreach ($dirs as $dir) {
$dirIt = new DirectoryIterator($dir);
foreach ($dirIt as $fileInfo) {
if ($fileInfo->isDir() && !$fileInfo->isDot()) {
$moduleDirs[] = $fileInfo->getFilename();
}
}
}
$moduleDirs = array_unique($moduleDirs);
sort($moduleDirs);
return $moduleDirs;
}
function getComposerPackageName(string $fromModuleDir, string $toModuleDir): string
{
$composerFile = '';
$composerFileFrom = $fromModuleDir . '/composer.json';
$composerFileTo = $toModuleDir . '/composer.json';
if (file_exists($composerFileFrom)) {
$composerFile = $composerFileFrom;
} else {
$composerFile = $composerFileTo;
}
$parsedComposerFile = json_decode(file_get_contents($composerFile));
$packageName = $parsedComposerFile->name;
return $packageName;
}
function getModuleDiffData(string $diff, string $fromParentDir, string $toParentDir): string
{
$diff = str_replace($fromParentDir, '', $diff);
$diff = str_replace($toParentDir, '', $diff);
return $diff;
}
function getPatchFilename(string $packageName): string
{
$patchFilename = str_replace('magento/', '', str_replace('magento/module-', '', $packageName));
$patchFilename = str_replace(' ', '', ucwords(str_replace('-', ' ', $patchFilename))) . '.diff';
return $patchFilename;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment