diff --git a/composer.json b/composer.json index c22b206bd19c757af84aa9b5a3bb738147261698..d49a26ea1b37c875e7673692c7a00b908c60bf29 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ "ext-pcre": "*", "ext-session": "*", "ext-xml": "*", - "composer-runtime-api": "^2.0", + "composer-runtime-api": "^2.1", "bacon/bacon-qr-code": "^2.0", "christian-riesen/base32": "^1.6", "cogpowered/finediff": "~0.3.1", @@ -50,8 +50,8 @@ "egulias/email-validator": "^3.1", "enshrined/svg-sanitize": "^0.14.1", "guzzlehttp/guzzle": "^7.3.0", - "guzzlehttp/psr7": "^1.7.0 || ^2.0", "guzzlehttp/promises": "^1.4.0", + "guzzlehttp/psr7": "^1.7.0 || ^2.0", "nikic/php-parser": "^4.10.4", "phpdocumentor/reflection-docblock": "^5.2", "phpdocumentor/type-resolver": "^1.4", diff --git a/composer.lock b/composer.lock index 994fca3ac9387085081e34e79a52c242944b1e55..dfe49e158eb1b809b4518966bc36e8c3376814fe 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e2dcfec64d2bf1cd1df99b52b5c362ca", + "content-hash": "1b0a189cecb7784c25b2a2e33e2de299", "packages": [ { "name": "bacon/bacon-qr-code", @@ -8275,7 +8275,7 @@ "ext-pcre": "*", "ext-session": "*", "ext-xml": "*", - "composer-runtime-api": "^2.0" + "composer-runtime-api": "^2.1" }, "platform-dev": [], "platform-overrides": { diff --git a/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php b/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php index f05a8edc17b71d6039b7dea5e1bcb073b76771e6..2b143f4730587ed0b48c52f7c57fa3d0c626359a 100644 --- a/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php +++ b/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php @@ -47,6 +47,7 @@ use TYPO3\CMS\Core\Utility\PathUtility; class PackageArtifactBuilder extends PackageManager implements InstallerScript { private Event $event; + private Config $config; /** * Array of package keys that are installed by Composer but have no relation to TYPO3 extension API @@ -78,11 +79,12 @@ class PackageArtifactBuilder extends PackageManager implements InstallerScript public function run(Event $event): bool { $this->event = $event; + $this->config = Config::load($this->event->getComposer(), $this->event->getIO()); $composer = $this->event->getComposer(); $basePath = Config::load($composer)->get('base-dir'); $this->packagesBasePath = $basePath . '/'; foreach ($this->extractPackageMapFromComposer() as [$composerPackage, $path, $extensionKey]) { - $packagePath = PathUtility::sanitizeTrailingSeparator($path ?: $basePath); + $packagePath = PathUtility::sanitizeTrailingSeparator($path); $package = new Package($this, $extensionKey, $packagePath, true); $package->makePathRelative(new Filesystem(), $basePath); $package->getPackageMetaData()->setVersion($composerPackage->getPrettyVersion()); @@ -180,17 +182,18 @@ class PackageArtifactBuilder extends PackageManager implements InstallerScript */ private function handleRootPackage(PackageInterface $rootPackage, string $extensionKey): array { - if ($rootPackage->getType() !== 'typo3-cms-extension' || !file_exists($this->packagesBasePath . 'Resources/Public/')) { - return [$rootPackage, $this->packagesBasePath, $extensionKey]; + $baseDir = $this->config->get('base-dir'); + if ($rootPackage->getType() !== 'typo3-cms-extension' || !file_exists($baseDir . '/Resources/Public/')) { + return [$rootPackage, $baseDir, $extensionKey]; } $composer = $this->event->getComposer(); $typo3ExtensionInstallPath = $composer->getInstallationManager()->getInstaller('typo3-cms-extension')->getInstallPath($rootPackage); $filesystem = new Filesystem(); $filesystem->ensureDirectoryExists(dirname($typo3ExtensionInstallPath)); if (!file_exists($typo3ExtensionInstallPath) && !$filesystem->isSymlinkedDirectory($typo3ExtensionInstallPath)) { - $filesystem->relativeSymlink($this->packagesBasePath, $typo3ExtensionInstallPath); + $filesystem->relativeSymlink($baseDir, $typo3ExtensionInstallPath); } - if (realpath($this->packagesBasePath) !== realpath($typo3ExtensionInstallPath)) { + if (realpath($baseDir) !== realpath($typo3ExtensionInstallPath)) { $this->event->getIO()->warning('The root package is of type "typo3-cms-extension" and has public resources, but could not be linked to typo3conf/ext directory, because target directory already exits.'); } diff --git a/typo3/sysext/core/Classes/Core/Environment.php b/typo3/sysext/core/Classes/Core/Environment.php index 8ce8c9eb3f76dc4d13bbc1bf4b5b0f50999d8e1a..dfe0ac1d56124e0fd63fb3d62e9ef359553761e9 100644 --- a/typo3/sysext/core/Classes/Core/Environment.php +++ b/typo3/sysext/core/Classes/Core/Environment.php @@ -17,6 +17,9 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Core; +use Composer\InstalledVersions; +use TYPO3\CMS\Core\Utility\PathUtility; + /** * This class is initialized once in the SystemEnvironmentBuilder, and can then * be used throughout the application to access common variables @@ -70,6 +73,11 @@ class Environment */ protected static $projectPath; + /** + * @var string + */ + protected static $composerRootPath; + /** * @var string */ @@ -126,6 +134,7 @@ class Environment self::$composerMode = $composerMode; self::$context = $context; self::$projectPath = $projectPath; + self::$composerRootPath = $composerMode ? PathUtility::getCanonicalPath(InstalledVersions::getRootPackage()['install_path']) : ''; self::$publicPath = $publicPath; self::$varPath = $varPath; self::$configPath = $configPath; @@ -181,6 +190,24 @@ class Environment return self::$projectPath; } + /** + * In most cases in composer-mode setups this is the same as project path. + * However since the project path is configurable, the paths may differ. + * In future versions this configurability will go away and this method will be removed. + * This path is only required for some internal path handling regarding package paths until then. + * @internal + * + * @return string The absolute path to the composer root directory without the trailing slash + */ + public static function getComposerRootPath(): string + { + if (self::$composerMode === false) { + throw new \BadMethodCallException('Composer root path is only available in Composer mode', 1631700480); + } + + return self::$composerRootPath; + } + /** * The public web folder where index.php (= the frontend application) is put, without trailing slash. * For non-composer installations, the project path = the public path. diff --git a/typo3/sysext/core/Classes/Package/Package.php b/typo3/sysext/core/Classes/Package/Package.php index be1b7e36ac0ce6e5c60a46880015e1f0951941d4..2b5d2eb97246627ccb20069a7b02b733043fdc1c 100644 --- a/typo3/sysext/core/Classes/Package/Package.php +++ b/typo3/sysext/core/Classes/Package/Package.php @@ -15,12 +15,11 @@ namespace TYPO3\CMS\Core\Package; -use Composer\InstalledVersions; use Composer\Util\Filesystem; +use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Package\Exception\InvalidPackageKeyException; use TYPO3\CMS\Core\Package\Exception\InvalidPackagePathException; use TYPO3\CMS\Core\Package\MetaData\PackageConstraint; -use TYPO3\CMS\Core\Utility\PathUtility; /** * A Package representing the details of an extension and/or a composer package @@ -235,7 +234,7 @@ class Package implements PackageInterface } $this->isRelativePackagePath = false; - return $this->packagePath = PathUtility::getCanonicalPath(InstalledVersions::getRootPackage()['install_path'] . '/' . $this->packagePath) . '/'; + return $this->packagePath = Environment::getComposerRootPath() . '/' . $this->packagePath; } /** @@ -248,7 +247,7 @@ class Package implements PackageInterface public function makePathRelative(Filesystem $filesystem, string $composerRootPath): void { $this->isRelativePackagePath = true; - $this->packagePath = $filesystem->findShortestPath($composerRootPath, $this->packagePath, true); + $this->packagePath = ($composerRootPath . '/') === $this->packagePath ? '' : $filesystem->findShortestPath($composerRootPath, $this->packagePath, true) . '/'; } /** diff --git a/typo3/sysext/core/composer.json b/typo3/sysext/core/composer.json index a45bc7c679a9a55d0bef25288defe9db15b5c45e..30184367c65339b84b6ee1ca9e240fb5b549ce5c 100644 --- a/typo3/sysext/core/composer.json +++ b/typo3/sysext/core/composer.json @@ -26,7 +26,7 @@ "ext-pcre": "*", "ext-session": "*", "ext-xml": "*", - "composer-runtime-api": "^2.0", + "composer-runtime-api": "^2.1", "bacon/bacon-qr-code": "^2.0", "christian-riesen/base32": "^1.6", "cogpowered/finediff": "~0.3.1",