Skip to content

Commit 995da74

Browse files
committed
feature #11312 Make assets:install smarter with symlinks (Roy Van Ginneken)
This PR was squashed before being merged into the 2.6-dev branch (closes #11312). Discussion ---------- Make assets:install smarter with symlinks | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | - | Fixed tickets | #11297 | License | MIT | Doc PR | - Commits ------- 6537333 Make assets:install smarter with symlinks
2 parents 0811b29 + 6537333 commit 995da74

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
@@ -282,9 +282,10 @@ public function rename($origin, $target, $overwrite = false)
282282
*/
283283
public function symlink($originDir, $targetDir, $copyOnWindows = false)
284284
{
285-
if (!function_exists('symlink') && $copyOnWindows) {
286-
$this->mirror($originDir, $targetDir);
285+
$onWindows = strtoupper(substr(php_uname('s'), 0, 3)) === 'WIN';
287286

287+
if ($onWindows && $copyOnWindows) {
288+
$this->mirror($originDir, $targetDir);
288289
return;
289290
}
290291

@@ -307,9 +308,12 @@ public function symlink($originDir, $targetDir, $copyOnWindows = false)
307308
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?');
308309
}
309310
}
310-
311311
throw new IOException(sprintf('Failed to create symbolic link from "%s" to "%s".', $originDir, $targetDir), 0, null, $targetDir);
312312
}
313+
314+
if (!file_exists($targetDir)) {
315+
throw new IOException(sprintf('Symbolic link "%s" is created but appears to be broken.', $targetDir), 0, null, $targetDir);
316+
}
313317
}
314318
}
315319

@@ -388,7 +392,7 @@ public function mirror($originDir, $targetDir, \Traversable $iterator = null, $o
388392
}
389393

390394
$copyOnWindows = false;
391-
if (isset($options['copy_on_windows']) && !function_exists('symlink')) {
395+
if (isset($options['copy_on_windows'])) {
392396
$copyOnWindows = $options['copy_on_windows'];
393397
}
394398

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