diff --git a/src/shared/file/PharActivatorFactory.php b/src/shared/file/PharActivatorFactory.php index e3ee5a64..43cd790f 100644 --- a/src/shared/file/PharActivatorFactory.php +++ b/src/shared/file/PharActivatorFactory.php @@ -17,4 +17,12 @@ public function getSymlinkPharActivator() { return new SymlinkPharActivator(); } + + /** + * @return WindowsPharActivator + */ + public function getWindowsPharActivator() { + return new WindowsPharActivator(file_get_contents(__DIR__ . '/../../../conf/pharBat.template')); + } + } diff --git a/src/shared/file/PharActivatorLocator.php b/src/shared/file/PharActivatorLocator.php index c6ab315a..423fbcb0 100644 --- a/src/shared/file/PharActivatorLocator.php +++ b/src/shared/file/PharActivatorLocator.php @@ -22,7 +22,7 @@ public function __construct(PharActivatorFactory $factory) { */ public function getPharActivator(Environment $environment) { if ($environment instanceof WindowsEnvironment) { - return $this->factory->getBatPharActivator(); + return $this->factory->getWindowsPharActivator(); } return $this->factory->getSymlinkPharActivator(); diff --git a/src/shared/file/WindowsPharActivator.php b/src/shared/file/WindowsPharActivator.php new file mode 100644 index 00000000..397b725b --- /dev/null +++ b/src/shared/file/WindowsPharActivator.php @@ -0,0 +1,73 @@ +template = $template; + } + + /** + * @param Filename $pharLocation + * @param Filename $linkDestination + * + * @return Filename + */ + public function activate(Filename $pharLocation, Filename $linkDestination) { + $this->ensureDestinationIsWritable($linkDestination); + + $destination = new Filename($linkDestination->asString().'.phar'); + if ($this->addFileLink($pharLocation, $destination)) { + $template = str_replace(self::PHAR_PLACEHOLDER, $destination->asString(), $this->template); + } else { + $template = str_replace(self::PHAR_PLACEHOLDER, $pharLocation->asString(), $this->template); + } + $linkFilename = new Filename($linkDestination->asString().'.bat'); + file_put_contents($linkFilename, $template); + return $destination; + } + + /** + * Set a windows hardlink + * + * @param Filename $source + * @param Filename $target + * @return bool + */ + private function addFileLink(Filename $source, Filename $target) { + $output = []; + $returnValue = 0; + exec( + 'mklink /H '.escapeshellarg($source).' '.escapeshellarg($target), + $output, + $returnValue + ); + return $returnValue === 0; + } + + /** + * @param Filename $destination + * + * @throws FileNotWritableException + */ + private function ensureDestinationIsWritable(Filename $destination) { + if (!$destination->getDirectory()->isWritable()) { + throw new FileNotWritableException(sprintf('File %s is not writable.', $destination->asString())); + } + } +}