1111
1212namespace Symfony \Bundle \FrameworkBundle \Command ;
1313
14+ use Symfony \Component \Console \Helper \Table ;
1415use Symfony \Component \Console \Input \InputArgument ;
1516use Symfony \Component \Console \Input \InputOption ;
1617use Symfony \Component \Console \Input \InputInterface ;
2223 * Command that places bundle web assets into a given directory.
2324 *
2425 * @author Fabien Potencier <fabien@symfony.com>
26+ * @author Gábor Egyed <gabor.egyed@gmail.com>
2527 */
2628class AssetsInstallCommand extends ContainerAwareCommand
2729{
30+ /**
31+ * @var \Symfony\Component\Filesystem\Filesystem
32+ */
33+ private $ filesystem ;
34+
2835 /**
2936 * {@inheritdoc}
3037 */
@@ -74,11 +81,11 @@ protected function execute(InputInterface $input, OutputInterface $output)
7481 throw new \InvalidArgumentException (sprintf ('The target directory "%s" does not exist. ' , $ input ->getArgument ('target ' )));
7582 }
7683
77- $ filesystem = $ this ->getContainer ()->get ('filesystem ' );
84+ $ this -> filesystem = $ this ->getContainer ()->get ('filesystem ' );
7885
7986 // Create the bundles directory otherwise symlink will fail.
8087 $ bundlesDir = $ targetArg .'/bundles/ ' ;
81- $ filesystem ->mkdir ($ bundlesDir , 0777 );
88+ $ this -> filesystem ->mkdir ($ bundlesDir , 0777 );
8289
8390 // relative implies symlink
8491 $ symlink = $ input ->getOption ('symlink ' ) || $ input ->getOption ('relative ' );
@@ -89,50 +96,78 @@ protected function execute(InputInterface $input, OutputInterface $output)
8996 $ output ->writeln ('Installing assets as <comment>hard copies</comment>. ' );
9097 }
9198
99+ $ table = new Table ($ output );
100+ $ table ->setHeaders (array ('Source ' , 'Target ' , 'Method / Error ' ));
101+
102+ $ ret = 0 ;
92103 foreach ($ this ->getContainer ()->get ('kernel ' )->getBundles () as $ bundle ) {
93104 if (is_dir ($ originDir = $ bundle ->getPath ().'/Resources/public ' )) {
94105 $ targetDir = $ bundlesDir .preg_replace ('/bundle$/ ' , '' , strtolower ($ bundle ->getName ()));
95106
96- $ output ->writeln (sprintf ('Installing assets for <comment>%s</comment> into <comment>%s</comment> ' , $ bundle ->getNamespace (), $ targetDir ));
97-
98- $ filesystem ->remove ($ targetDir );
107+ $ this ->filesystem ->remove ($ targetDir );
99108
100109 if ($ symlink ) {
101- if ($ input ->getOption ('relative ' )) {
102- $ relativeOriginDir = $ filesystem ->makePathRelative ($ originDir , realpath ($ bundlesDir ));
103- } else {
104- $ relativeOriginDir = $ originDir ;
105- }
106-
107110 try {
108- $ filesystem ->symlink ($ relativeOriginDir , $ targetDir );
109- if (!file_exists ($ targetDir )) {
110- throw new IOException ('Symbolic link is broken ' );
111- }
112- $ output ->writeln ('The assets were installed using symbolic links. ' );
111+ $ relative = $ this ->symlink ($ originDir , $ targetDir , $ input ->getOption ('relative ' ));
112+ $ table ->addRow (array (
113+ $ bundle ->getNamespace (),
114+ $ targetDir ,
115+ sprintf ('%s symbolic link ' , $ relative ? 'relative ' : 'absolute ' ),
116+ ));
117+
118+ continue ;
113119 } catch (IOException $ e ) {
114- if (!$ input ->getOption ('relative ' )) {
115- $ this ->hardCopy ($ originDir , $ targetDir );
116- $ output ->writeln ('It looks like your system doesn \'t support symbolic links, so the assets were installed by copying them. ' );
117- }
118-
119- // try again without the relative option
120- try {
121- $ filesystem ->symlink ($ originDir , $ targetDir );
122- if (!file_exists ($ targetDir )) {
123- throw new IOException ('Symbolic link is broken ' );
124- }
125- $ output ->writeln ('It looks like your system doesn \'t support relative symbolic links, so the assets were installed by using absolute symbolic links. ' );
126- } catch (IOException $ e ) {
127- $ this ->hardCopy ($ originDir , $ targetDir );
128- $ output ->writeln ('It looks like your system doesn \'t support symbolic links, so the assets were installed by copying them. ' );
129- }
120+ // fall back to hard copy
130121 }
131- } else {
122+ }
123+
124+ try {
132125 $ this ->hardCopy ($ originDir , $ targetDir );
126+ $ table ->addRow (array ($ bundle ->getNamespace (), $ targetDir , 'hard copy ' ));
127+ } catch (IOException $ e ) {
128+ $ table ->addRow (array ($ bundle ->getNamespace (), $ targetDir , sprintf ('<error>%s</error> ' , $ e ->getMessage ())));
129+ $ ret = 1 ;
133130 }
134131 }
135132 }
133+
134+ $ table ->render ();
135+
136+ return $ ret ;
137+ }
138+
139+ /**
140+ * Creates links with absolute as a fallback.
141+ *
142+ * @param string $origin
143+ * @param string $target
144+ * @param bool $relative
145+ *
146+ * @throws IOException If link can not be created.
147+ *
148+ * @return bool Created a relative link or not.
149+ */
150+ private function symlink ($ origin , $ target , $ relative = true )
151+ {
152+ try {
153+ $ this ->filesystem ->symlink (
154+ $ relative ? $ this ->filesystem ->makePathRelative ($ origin , realpath (dirname ($ target ))) : $ origin ,
155+ $ target
156+ );
157+
158+ if (!file_exists ($ target )) {
159+ throw new IOException (sprintf ('Symbolic link "%s" is created but appears to be broken. ' , $ target ), 0 , null , $ target );
160+ }
161+ } catch (IOException $ e ) {
162+ if ($ relative ) {
163+ // try again with absolute
164+ return $ this ->symlink ($ origin , $ target , false );
165+ }
166+
167+ throw $ e ;
168+ }
169+
170+ return $ relative ;
136171 }
137172
138173 /**
@@ -141,10 +176,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
141176 */
142177 private function hardCopy ($ originDir , $ targetDir )
143178 {
144- $ filesystem = $ this ->getContainer ()->get ('filesystem ' );
145-
146- $ filesystem ->mkdir ($ targetDir , 0777 );
179+ $ this ->filesystem ->mkdir ($ targetDir , 0777 );
147180 // We use a custom iterator to ignore VCS files
148- $ filesystem ->mirror ($ originDir , $ targetDir , Finder::create ()->ignoreDotFiles (false )->in ($ originDir ));
181+ $ this -> filesystem ->mirror ($ originDir , $ targetDir , Finder::create ()->ignoreDotFiles (false )->in ($ originDir ));
149182 }
150183}
0 commit comments