Merge pull request #4962 from curry684/issue-4955
Improve handling of removing junctions in Windows path repositoriespull/4966/head
commit
3753ccf25d
|
@ -101,4 +101,25 @@ class PathDownloader extends FileDownloader
|
|||
|
||||
$this->io->writeError('');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function remove(PackageInterface $package, $path)
|
||||
{
|
||||
/**
|
||||
* For junctions don't blindly rely on Filesystem::removeDirectory as it may be overzealous. If a process
|
||||
* inadvertently locks the file the removal will fail, but it would fall back to recursive delete which
|
||||
* is disastrous within a junction. So in that case we have no other real choice but to fail hard.
|
||||
*/
|
||||
if (Platform::isWindows() && $this->filesystem->isJunction($path)) {
|
||||
$this->io->writeError(" - Removing junction for <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>)");
|
||||
if (!$this->filesystem->removeJunction($path)) {
|
||||
$this->io->writeError("<warn>Could not remove junction at " . $path . " - is another process locking it?</warn>");
|
||||
throw new \RuntimeException('Could not reliably remove junction for package ' . $package->getName());
|
||||
}
|
||||
} else {
|
||||
parent::remove($package, $path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -618,10 +618,17 @@ class Filesystem
|
|||
if (!is_dir($junction) || is_link($junction)) {
|
||||
return false;
|
||||
}
|
||||
// Junctions have no link stat but are otherwise indistinguishable from real directories
|
||||
/**
|
||||
* According to MSDN at https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx we can detect a junction now
|
||||
* using the 'mode' value from stat: "The _S_IFDIR bit is set if path specifies a directory; the _S_IFREG bit
|
||||
* is set if path specifies an ordinary file or a device." We have just tested for a directory above, so if
|
||||
* we have a directory that isn't one according to lstat(...) we must have a junction.
|
||||
*
|
||||
* #define _S_IFDIR 0x4000
|
||||
* #define _S_IFREG 0x8000
|
||||
*/
|
||||
$stat = lstat($junction);
|
||||
|
||||
return ($stat['mode'] === 0);
|
||||
return !($stat['mode'] & 0xC000);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue