From f10914e7cde53f78b09c98c101a24c85eda60955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20K=C3=A4rner?= Date: Mon, 26 Sep 2022 11:27:24 +0200 Subject: [PATCH] [BUGFIX] Generate correct asset symlinks on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes two issues when generating symlinks to the public extension resources (Public/Resources) into the _assets folder during Composer installation. First, directory symlinks can't be created the same way on Windows as on Unix platforms. The creation requires elevated rights, and the required command is named differently as well. Junctions should be used on Windows instead, because they do not need elevated privileges to be created. When installing a TYPO3 extension via Composer, its Resources/Public folder is getting symlinked to the publicly accessible _assets folder. Until now, this process only used the Unix specific functions provided by Composer. It did not create any symlinks on Windows based installations, without generating any error message. This patch adds the same checks and platform-specific functions used by Composer when symlinking packages from a local path repository. The second issue that has been addressed is the naming of the symlinks themselves. When a Resources/Public directory is symlinked into the _assets folder, the symlink will be named using an md5 hash based on parts of the extension's installation path on the filesystem. During Composer installation, this relative path is derived from the absolute path provided by Composer. As Windows uses a different default path separator (backslash) compared to Unix (forward slash), the relative path will be different between both platforms, resulting in a different md5 hash being generated. Absolute path on Unix: /path/to/typo3/vendor/mycompany/myext Absolute path on Windows: C:\path\to\typo3\vendor/mycompany/myext Relative path to be used for the hash on Unix: /vendor/mycompany/myext Relative path to be used for the hash on Windows: \vendor/mycompany/myext If an uri into the _assets folder is to be generated in either frontend or backend, the md5 hash will be always be generated by using forward slashes, resulting in incorrect links on Windows installations. This difference has been solved by replacing all backslashes in the absolute extension installation path into forward slashes on Windows installations, so the symlink will be named correctly from the beginning. Resolves: #98434 Resolves: #98447 Releases: main, 12.4, 11.5 Change-Id: I221eb538312302a7af4f7c3010c9982922f1c6ce Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/80688 Tested-by: Stefan B�rk Tested-by: core-ci Reviewed-by: Stefan B�rk --- .../core/Classes/Composer/PackageArtifactBuilder.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php b/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php index 00f8e189519d..04b1a1d9158c 100644 --- a/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php +++ b/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php @@ -21,6 +21,7 @@ use Composer\Repository\PlatformRepository; use Composer\Script\Event; use Composer\Util\Filesystem; +use Composer\Util\Platform; use TYPO3\CMS\Composer\Plugin\Config; use TYPO3\CMS\Composer\Plugin\Core\InstallerScript; use TYPO3\CMS\Composer\Plugin\Util\ExtensionKeyResolver; @@ -32,6 +33,7 @@ use TYPO3\CMS\Core\Package\Package; use TYPO3\CMS\Core\Package\PackageManager; use TYPO3\CMS\Core\Service\DependencyOrderingService; +use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\PathUtility; /** @@ -160,6 +162,7 @@ private function extractPackageMapFromComposer(): array function (array $packageAndPath) use ($rootPackage, &$usedExtensionKeys) { [$composerPackage, $packagePath] = $packageAndPath; $packageName = $composerPackage->getName(); + $packagePath = GeneralUtility::fixWindowsFilePath($packagePath); try { $extensionKey = ExtensionKeyResolver::resolve($composerPackage); } catch (\Throwable $e) { @@ -268,7 +271,9 @@ private function publishResources(array $installedTypo3Packages): void [$relativePrefix] = explode('Resources/Public', $relativePath); $publicResourcesPath = $fileSystem->normalizePath($this->config->get('web-dir') . '/_assets/' . md5($relativePrefix)); $fileSystem->ensureDirectoryExists(dirname($publicResourcesPath)); - if (!$fileSystem->isSymlinkedDirectory($publicResourcesPath)) { + if (Platform::isWindows() && !$fileSystem->isJunction($publicResourcesPath)) { + $fileSystem->junction($fileSystemResourcesPath, $publicResourcesPath); + } elseif (!$fileSystem->isSymlinkedDirectory($publicResourcesPath)) { $fileSystem->relativeSymlink($fileSystemResourcesPath, $publicResourcesPath); } }