Skip to content

Commit

Permalink
Fix broken junctions leading to installation failure on Windows (#11550)
Browse files Browse the repository at this point in the history
  • Loading branch information
Attia-Ahmed authored Jul 21, 2023
1 parent 77e89fb commit 3d5f475
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/Composer/Util/Filesystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,12 @@ public function junction($target, $junction)
if (!is_dir($target)) {
throw new IOException(sprintf('Cannot junction to "%s" as it is not a directory.', $target), 0, null, $target);
}

// Removing any previously junction to ensure clean execution.
if (!is_dir($junction) || $this->isJunction($junction)) {
@rmdir($junction);
}

$cmd = sprintf(
'mklink /J %s %s',
ProcessExecutor::escape(str_replace('/', DIRECTORY_SEPARATOR, $junction)),
Expand Down
33 changes: 33 additions & 0 deletions tests/Composer/Test/Util/FilesystemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace Composer\Test\Util;

use Composer\Util\Platform;
use Composer\Util\Filesystem;
use Composer\Test\TestCase;

Expand Down Expand Up @@ -327,6 +328,38 @@ public function testJunctions()
$this->assertFalse(is_dir($junction), $junction . ' is not a directory');
}

public function testOverrideJunctions()
{
if (!Platform::isWindows()) {
$this->markTestSkipped('Only runs on windows');
}

@mkdir($this->workingDir.'/real/nesting/testing', 0777, true);
$fs = new Filesystem();

$old_target = $this->workingDir.'/real/nesting/testing';
$target = $this->workingDir.'/real/../real/nesting';
$junction = $this->workingDir.'/junction';

// Override non-broken junction
$fs->junction($old_target, $junction);
$fs->junction($target, $junction);

$this->assertTrue($fs->isJunction($junction), $junction.': is a junction');
$this->assertTrue($fs->isJunction($target.'/../../junction'), $target.'/../../junction: is a junction');

//Remove junction
$this->assertTrue($fs->removeJunction($junction), $junction . ' has been removed');

// Override broken junction
$fs->junction($old_target, $junction);
$fs->removeDirectory($old_target);
$fs->junction($target, $junction);

$this->assertTrue($fs->isJunction($junction), $junction.': is a junction');
$this->assertTrue($fs->isJunction($target.'/../../junction'), $target.'/../../junction: is a junction');
}

public function testCopy()
{
@mkdir($this->workingDir . '/foo/bar', 0777, true);
Expand Down

0 comments on commit 3d5f475

Please sign in to comment.