Skip to content

Commit

Permalink
fix an issue with patch applying crashing when branch aliases defined…
Browse files Browse the repository at this point in the history
… against root package
  • Loading branch information
allanpaiste committed Feb 24, 2021
1 parent 7cb3b4d commit 293a8ac
Show file tree
Hide file tree
Showing 19 changed files with 321 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ before_install:

env:
jobs:
- COMPOSER_VERSION=1.8.4
- COMPOSER_VERSION=1.10.20
- COMPOSER_VERSION=2.0.9

script:
Expand Down
26 changes: 26 additions & 0 deletions bin/test
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,32 @@ EOF
}
}
EOF
)
fi

if [ "${command}" == "config" ] ; then
local path=$(echo ${args}|cut -d' ' -f1)
local value=$(echo ${args}|cut -d' ' -f2)
local package_config="composer.json"

local php_script=$(cat <<EOF
if (file_exists('${package_config}')) {
\$config = json_decode(file_get_contents('${package_config}'), true);
\$pathSteps = explode('/', '${path}');
\$node = &\$config;
foreach(\$pathSteps as \$step) {
if (!isset(\$node[\$step])) {
\$node[\$step] = array();
}
\$node = &\$node[\$step];
}
\$node = ${value};
unset(\$node);
file_put_contents('${package_config}', json_encode(\$config, JSON_PRETTY_PRINT));
}
EOF
)
fi

Expand Down
9 changes: 9 additions & 0 deletions changelog.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
"possible to generate change-logs in other formats as well (when needed) and to do automatic releases based on",
"added change-log records. More on how to use it: https://github.com/vaimo/composer-changelogs"
],
"3.53.3": {
"fix": [
"patch applier crash when branch alias defined for root package (scenario: root-branch-alias) [pull/73]"
],
"maintenance": [
"make patch commands available when the plugin itself is a root package (just for the sake of allowing people to conduct quick experiments when developing)"
],
"branch": "release/3"
},
"3.53.2": {
"fix": [
"patches applied before packages properly re-installed with Composer V2 (missed the fact that installations, like downloads are now done in asynchronous manner) [issues/70]"
Expand Down
9 changes: 8 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"require-dev": {
"composer/composer": "^1.0 || ^2.0",
"vaimo/composer-patches-proxy": "1.0.0",
"phpcompatibility/php-compatibility": ">=9.1.1",
"squizlabs/php_codesniffer": ">=2.9.2",
"sebastian/phpcpd": ">=1.4.3",
Expand Down Expand Up @@ -113,5 +114,11 @@
"psr-4": {
"Vaimo\\ComposerPatches\\": "src"
}
}
},
"repositories": [
{
"type": "path",
"url": "modules/proxy-plugin"
}
]
}
52 changes: 40 additions & 12 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions modules/proxy-plugin/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "vaimo/composer-patches-proxy",
"version": "1.0.0",
"type": "composer-plugin",
"description": "Proxy package to be able to use plugin commands provided by vaimo/composer-patches when having vaimo/composer-patches as the ROOT package",
"license": "MIT",
"require": {
"composer-plugin-api": "^1.0 || ^2.0"
},
"extra": {
"class": "Vaimo\\ComposerPatchesProxy\\Plugin"
},
"autoload": {
"psr-4": {
"Vaimo\\ComposerPatchesProxy\\": "src"
}
}
}
140 changes: 140 additions & 0 deletions modules/proxy-plugin/src/Plugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php
/**
* Copyright © Vaimo Group. All rights reserved.
* See LICENSE_VAIMO.txt for license details.
*/
namespace Vaimo\ComposerPatchesProxy;

require_once 'src/Plugin.php';

/**
* @SuppressWarnings(PHPMD.ShortVariable)
*/
class Plugin extends \Vaimo\ComposerPatches\Plugin
{
public function activate(\Composer\Composer $composer, \Composer\IO\IOInterface $io)
{
$namespacePrefix = implode('\\', array_slice(explode('\\', get_parent_class($this)), 0, 2)) . '\\';
$autoloadFile = $this->resolveAutoloadFilePath($composer);

if (!$autoloadFile) {
return;
}

include $autoloadFile;

$composerCtxFactory = new \Vaimo\ComposerPatches\Factories\ComposerContextFactory($composer);
$composerContext = $composerCtxFactory->create();

$this->bootstrapFileTree($composerContext, $namespacePrefix);

parent::activate($composer, $io);
}

public function resolveAutoloadFilePath(\Composer\Composer $composer)
{
/**
* When running through the initial installation, make sure that installing the proxy
* command (to get the patch commands) does not result in crashing the whole
* installation process.
*/
$autoloadFile = $this->composePath(
$composer->getConfig()->get('vendor-dir'),
'autoload.php'
);

if (!file_exists($autoloadFile)) {
return '';
}

return $autoloadFile;
}

public function resetPackages(\Composer\Installer\PackageEvent $event)
{
$autoloadFile = $this->resolveAutoloadFilePath($event->getComposer());

if (!$autoloadFile) {
return;
}

return parent::resetPackages($event);
}

public function postInstall(\Composer\Script\Event $event)
{
$autoloadFile = $this->resolveAutoloadFilePath($event->getComposer());

if (!$autoloadFile) {
return;
}

return parent::postInstall($event);
}

private function bootstrapFileTree(\Vaimo\ComposerPatches\Composer\Context $composerContext, $namespacePrefix)
{
$composer = $composerContext->getLocalComposer();

$composerConfig = $composer->getConfig();

$vendorDir = $composerConfig->get(\Vaimo\ComposerPatches\Composer\ConfigKeys::VENDOR_DIR);

$packageResolver = new \Vaimo\ComposerPatches\Composer\Plugin\PackageResolver(
array($composer->getPackage())
);

$pluginPackage = $packageResolver->resolveForNamespace(
$composerContext->getActivePackages(),
$namespacePrefix
);

$this->createSymlink(
realpath('.'),
$this->composePath($vendorDir, $pluginPackage->getName()),
true
);
}

/**
* @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
private function createSymlink($fromPath, $toPath, $graceful = false)
{
if (is_link($toPath)) {
unlink($toPath);
}

if ($graceful && (file_exists($toPath) || !file_exists($fromPath))) {
return;
}

symlink($fromPath, $toPath);
}

private function composePath()
{
$pathSegments = array_map(function ($item) {
return rtrim($item, \DIRECTORY_SEPARATOR);
}, func_get_args());

return implode(
DIRECTORY_SEPARATOR,
array_filter($pathSegments)
);
}

/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function deactivate(\Composer\Composer $composer, \Composer\IO\IOInterface $appIO)
{
}

/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function uninstall(\Composer\Composer $composer, \Composer\IO\IOInterface $appIO)
{
}
}
2 changes: 1 addition & 1 deletion src/Composer/Commands/ValidateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private function collectInstallPaths(array $matches)

$installPaths = array();
foreach ($matches as $packageName => $package) {
$installPaths[$packageName] = $package instanceof \Composer\Package\RootPackage
$installPaths[$packageName] = $package instanceof \Composer\Package\RootPackageInterface
? $projectRoot
: $installationManager->getInstallPath($package);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Package/InfoResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function __construct(
*/
public function getSourcePath(PackageInterface $package)
{
return !$package instanceof \Composer\Package\RootPackage
return !$package instanceof \Composer\Package\RootPackageInterface
? $this->installationManager->getInstallPath($package)
: realpath(dirname(\Composer\Factory::getComposerFile()));
}
Expand Down Expand Up @@ -110,7 +110,7 @@ public function getInstallPath(PackageInterface $package, $resolveMode)
break;
case Patch::CWD_INSTALL:
default:
$this->installPathCache[$key] = $package instanceof \Composer\Package\RootPackage
$this->installPathCache[$key] = $package instanceof \Composer\Package\RootPackageInterface
? $this->vendorRoot
: $this->getSourcePath($package);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function process(array $patches, array $packagesByName)
$rootPackages = array_filter(
$packagesByName,
function ($package) {
return $package instanceof \Composer\Package\RootPackage;
return $package instanceof \Composer\Package\RootPackageInterface;
}
);

Expand Down
2 changes: 1 addition & 1 deletion src/Patch/SourceLoaders/PatchesFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function load(\Composer\Package\PackageInterface $package, $source)

$basePath = getcwd();

if (!$package instanceof \Composer\Package\RootPackage) {
if (!$package instanceof \Composer\Package\RootPackageInterface) {
$basePath = $this->installationManager->getInstallPath($package);
}

Expand Down
Loading

0 comments on commit 293a8ac

Please sign in to comment.