Skip to content

Commit 6537333

Browse files
rvanginnekenfabpot
authored andcommitted
Make assets:install smarter with symlinks
1 parent 8b54211 commit 6537333

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Console\Input\InputOption;
1616
use Symfony\Component\Console\Input\InputInterface;
1717
use Symfony\Component\Console\Output\OutputInterface;
18+
use Symfony\Component\Filesystem\Exception\IOException;
1819
use Symfony\Component\Finder\Finder;
1920

2021
/**
@@ -47,7 +48,7 @@ protected function configure()
4748
"Resources/public" directory of each bundle will be copied into it.
4849
4950
To create a symlink to each bundle instead of copying its assets, use the
50-
<info>--symlink</info> option:
51+
<info>--symlink</info> option (will fall back to hard copies when symbolic links aren't possible:
5152
5253
<info>php %command.full_name% web --symlink</info>
5354
@@ -73,17 +74,17 @@ protected function execute(InputInterface $input, OutputInterface $output)
7374
throw new \InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target')));
7475
}
7576

76-
if (!function_exists('symlink') && $input->getOption('symlink')) {
77-
throw new \InvalidArgumentException('The symlink() function is not available on your system. You need to install the assets without the --symlink option.');
78-
}
79-
8077
$filesystem = $this->getContainer()->get('filesystem');
8178

8279
// Create the bundles directory otherwise symlink will fail.
8380
$bundlesDir = $targetArg.'/bundles/';
8481
$filesystem->mkdir($bundlesDir, 0777);
8582

86-
$output->writeln(sprintf('Installing assets as <comment>%s</comment>', $input->getOption('symlink') ? 'symlinks' : 'hard copies'));
83+
if ($input->getOption('symlink')) {
84+
$output->writeln('Trying to install assets as symbolic links.');
85+
} else {
86+
$output->writeln('Installing assets as <comment>hard copies</comment>');
87+
}
8788

8889
foreach ($this->getContainer()->get('kernel')->getBundles() as $bundle) {
8990
if (is_dir($originDir = $bundle->getPath().'/Resources/public')) {
@@ -99,13 +100,32 @@ protected function execute(InputInterface $input, OutputInterface $output)
99100
} else {
100101
$relativeOriginDir = $originDir;
101102
}
102-
$filesystem->symlink($relativeOriginDir, $targetDir);
103+
104+
try {
105+
$filesystem->symlink($relativeOriginDir, $targetDir);
106+
$output->writeln('The assets were installed using symbolic links.');
107+
} catch (IOException $e) {
108+
$this->hardCopy($originDir, $targetDir);
109+
$output->writeln('It looks like your system doesn\'t support symbolic links, so the assets were installed by copying them.');
110+
}
103111
} else {
104-
$filesystem->mkdir($targetDir, 0777);
105-
// We use a custom iterator to ignore VCS files
106-
$filesystem->mirror($originDir, $targetDir, Finder::create()->ignoreDotFiles(false)->in($originDir));
112+
$this->hardCopy($originDir, $targetDir);
107113
}
108114
}
109115
}
110116
}
117+
118+
/**
119+
* @param string $originDir
120+
* @param string $targetDir
121+
*/
122+
private function hardCopy($originDir, $targetDir)
123+
{
124+
$filesystem = $this->getContainer()->get('filesystem');
125+
126+
$filesystem->mkdir($targetDir, 0777);
127+
// We use a custom iterator to ignore VCS files
128+
$filesystem->mirror($originDir, $targetDir, Finder::create()->ignoreDotFiles(false)->in($originDir));
129+
}
130+
111131
}

src/Symfony/Component/Filesystem/Filesystem.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,10 @@ public function rename($origin, $target, $overwrite = false)
268268
*/
269269
public function symlink($originDir, $targetDir, $copyOnWindows = false)
270270
{
271-
if (!function_exists('symlink') && $copyOnWindows) {
272-
$this->mirror($originDir, $targetDir);
271+
$onWindows = strtoupper(substr(php_uname('s'), 0, 3)) === 'WIN';
273272

273+
if ($onWindows && $copyOnWindows) {
274+
$this->mirror($originDir, $targetDir);
274275
return;
275276
}
276277

@@ -293,9 +294,12 @@ public function symlink($originDir, $targetDir, $copyOnWindows = false)
293294
throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?');
294295
}
295296
}
296-
297297
throw new IOException(sprintf('Failed to create symbolic link from "%s" to "%s".', $originDir, $targetDir), 0, null, $targetDir);
298298
}
299+
300+
if (!file_exists($targetDir)) {
301+
throw new IOException(sprintf('Symbolic link "%s" is created but appears to be broken.', $targetDir), 0, null, $targetDir);
302+
}
299303
}
300304
}
301305

@@ -374,7 +378,7 @@ public function mirror($originDir, $targetDir, \Traversable $iterator = null, $o
374378
}
375379

376380
$copyOnWindows = false;
377-
if (isset($options['copy_on_windows']) && !function_exists('symlink')) {
381+
if (isset($options['copy_on_windows'])) {
378382
$copyOnWindows = $options['copy_on_windows'];
379383
}
380384

0 commit comments

Comments
 (0)
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