diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php index 5b627ded6ae66..647dc0fd58506 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php @@ -11,20 +11,34 @@ namespace Symfony\Bundle\FrameworkBundle\Command; +use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; /** * Command that places bundle web assets into a given directory. * * @author Fabien Potencier + * @author Gábor Egyed */ class AssetsInstallCommand extends ContainerAwareCommand { + const METHOD_COPY = 'copy'; + const METHOD_ABSOLUTE_SYMLINK = 'absolute symlink'; + const METHOD_RELATIVE_SYMLINK = 'relative symlink'; + + /** + * @var Filesystem + */ + private $filesystem; + /** * {@inheritdoc} */ @@ -63,8 +77,6 @@ protected function configure() /** * {@inheritdoc} - * - * @throws \InvalidArgumentException When the target directory does not exist or symlink cannot be used */ protected function execute(InputInterface $input, OutputInterface $output) { @@ -74,77 +86,164 @@ protected function execute(InputInterface $input, OutputInterface $output) throw new \InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target'))); } - $filesystem = $this->getContainer()->get('filesystem'); + $this->filesystem = $this->getContainer()->get('filesystem'); // Create the bundles directory otherwise symlink will fail. $bundlesDir = $targetArg.'/bundles/'; - $filesystem->mkdir($bundlesDir, 0777); + $this->filesystem->mkdir($bundlesDir, 0777); - // relative implies symlink - $symlink = $input->getOption('symlink') || $input->getOption('relative'); + $io = new SymfonyStyle($input, $output); + $io->newLine(); - if ($symlink) { - $output->writeln('Trying to install assets as symbolic links.'); + if ($input->getOption('relative')) { + $expectedMethod = self::METHOD_RELATIVE_SYMLINK; + $io->text('Trying to install assets as relative symbolic links.'); + } elseif ($input->getOption('symlink')) { + $expectedMethod = self::METHOD_ABSOLUTE_SYMLINK; + $io->text('Trying to install assets as absolute symbolic links.'); } else { - $output->writeln('Installing assets as hard copies.'); + $expectedMethod = self::METHOD_COPY; + $io->text('Installing assets as hard copies.'); } + $io->newLine(); + + $rows = array(); + $copyUsed = false; + $exitCode = 0; + /** @var BundleInterface $bundle */ foreach ($this->getContainer()->get('kernel')->getBundles() as $bundle) { - if (is_dir($originDir = $bundle->getPath().'/Resources/public')) { - $targetDir = $bundlesDir.preg_replace('/bundle$/', '', strtolower($bundle->getName())); - - $output->writeln(sprintf('Installing assets for %s into %s', $bundle->getNamespace(), $targetDir)); - - $filesystem->remove($targetDir); - - if ($symlink) { - if ($input->getOption('relative')) { - $relativeOriginDir = $filesystem->makePathRelative($originDir, realpath($bundlesDir)); - } else { - $relativeOriginDir = $originDir; - } - - try { - $filesystem->symlink($relativeOriginDir, $targetDir); - if (!file_exists($targetDir)) { - throw new IOException('Symbolic link is broken'); - } - $output->writeln('The assets were installed using symbolic links.'); - } catch (IOException $e) { - if (!$input->getOption('relative')) { - $this->hardCopy($originDir, $targetDir); - $output->writeln('It looks like your system doesn\'t support symbolic links, so the assets were installed by copying them.'); - } - - // try again without the relative option - try { - $filesystem->symlink($originDir, $targetDir); - if (!file_exists($targetDir)) { - throw new IOException('Symbolic link is broken'); - } - $output->writeln('It looks like your system doesn\'t support relative symbolic links, so the assets were installed by using absolute symbolic links.'); - } catch (IOException $e) { - $this->hardCopy($originDir, $targetDir); - $output->writeln('It looks like your system doesn\'t support symbolic links, so the assets were installed by copying them.'); - } - } + if (!is_dir($originDir = $bundle->getPath().'/Resources/public')) { + continue; + } + + $targetDir = $bundlesDir.preg_replace('/bundle$/', '', strtolower($bundle->getName())); + + if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { + $message = sprintf("%s\n-> %s", $bundle->getName(), $targetDir); + } else { + $message = $bundle->getName(); + } + + try { + $this->filesystem->remove($targetDir); + + if (self::METHOD_RELATIVE_SYMLINK === $expectedMethod) { + $method = $this->relativeSymlinkWithFallback($originDir, $targetDir); + } elseif (self::METHOD_ABSOLUTE_SYMLINK === $expectedMethod) { + $method = $this->absoluteSymlinkWithFallback($originDir, $targetDir); + } else { + $method = $this->hardCopy($originDir, $targetDir); + } + + if (self::METHOD_COPY === $method) { + $copyUsed = true; + } + + if ($method === $expectedMethod) { + $rows[] = array(sprintf('%s', '\\' === DIRECTORY_SEPARATOR ? 'OK' : "\xE2\x9C\x94" /* HEAVY CHECK MARK (U+2714) */), $message, $method); } else { - $this->hardCopy($originDir, $targetDir); + $rows[] = array(sprintf('%s', '\\' === DIRECTORY_SEPARATOR ? 'WARNING' : '!'), $message, $method); } + } catch (\Exception $e) { + $exitCode = 1; + $rows[] = array(sprintf('%s', '\\' === DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */), $message, $e->getMessage()); + } + } + + $io->table(array('', 'Bundle', 'Method / Error'), $rows); + + if (0 !== $exitCode) { + $io->error('Some errors occurred while installing assets.'); + } else { + if ($copyUsed) { + $io->note('Some assets were installed via copy. If you make changes to these assets you have to run this command again.'); } + $io->success('All assets were successfully installed.'); } + + return $exitCode; } /** + * Try to create relative symlink. + * + * Falling back to absolute symlink and finally hard copy. + * * @param string $originDir * @param string $targetDir + * + * @return string */ - private function hardCopy($originDir, $targetDir) + private function relativeSymlinkWithFallback($originDir, $targetDir) + { + try { + $this->symlink($originDir, $targetDir, true); + $method = self::METHOD_RELATIVE_SYMLINK; + } catch (IOException $e) { + $method = $this->absoluteSymlinkWithFallback($originDir, $targetDir); + } + + return $method; + } + + /** + * Try to create absolute symlink. + * + * Falling back to hard copy. + * + * @param string $originDir + * @param string $targetDir + * + * @return string + */ + private function absoluteSymlinkWithFallback($originDir, $targetDir) + { + try { + $this->symlink($originDir, $targetDir); + $method = self::METHOD_ABSOLUTE_SYMLINK; + } catch (IOException $e) { + // fall back to copy + $method = $this->hardCopy($originDir, $targetDir); + } + + return $method; + } + + /** + * Creates symbolic link. + * + * @param string $originDir + * @param string $targetDir + * @param bool $relative + * + * @throws IOException If link can not be created. + */ + private function symlink($originDir, $targetDir, $relative = false) { - $filesystem = $this->getContainer()->get('filesystem'); + if ($relative) { + $originDir = $this->filesystem->makePathRelative($originDir, realpath(dirname($targetDir))); + } + $this->filesystem->symlink($originDir, $targetDir); + if (!file_exists($targetDir)) { + throw new IOException(sprintf('Symbolic link "%s" was created but appears to be broken.', $targetDir), 0, null, $targetDir); + } + } - $filesystem->mkdir($targetDir, 0777); + /** + * Copies origin to target. + * + * @param string $originDir + * @param string $targetDir + * + * @return string + */ + private function hardCopy($originDir, $targetDir) + { + $this->filesystem->mkdir($targetDir, 0777); // We use a custom iterator to ignore VCS files - $filesystem->mirror($originDir, $targetDir, Finder::create()->ignoreDotFiles(false)->in($originDir)); + $this->filesystem->mirror($originDir, $targetDir, Finder::create()->ignoreDotFiles(false)->in($originDir)); + + return self::METHOD_COPY; } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy