Skip to content
Snippets Groups Projects
Commit f10914e7 authored by Robert Kärner's avatar Robert Kärner Committed by Stefan B�rk
Browse files

[BUGFIX] Generate correct asset symlinks on Windows

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: default avatarStefan B�rk <stefan@buerk.tech>
Tested-by: default avatarcore-ci <typo3@b13.com>
Reviewed-by: default avatarStefan B�rk <stefan@buerk.tech>
parent 1d841793
Branches
Tags
No related merge requests found
......@@ -21,6 +21,7 @@ use Composer\Package\PackageInterface;
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\Exception\InvalidPackageStateException;
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 @@ class PackageArtifactBuilder extends PackageManager implements InstallerScript
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 @@ class PackageArtifactBuilder extends PackageManager implements InstallerScript
[$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);
}
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment