Skip to content

Instantly share code, notes, and snippets.

@avalanche123
Created October 15, 2010 00:52
Show Gist options
  • Save avalanche123/627384 to your computer and use it in GitHub Desktop.
Save avalanche123/627384 to your computer and use it in GitHub Desktop.
<?php
namespace Symfony\Bundle\FrameworkBundle\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\Output;
use Symfony\Bundle\FrameworkBundle\Util\Filesystem;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Console\Command\Command as BaseCommand;
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
/**
* AssetsInstallCommand.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class AssetsInstallCommand extends BaseCommand
{
/**
* Holds Kernel instance
*
* @var Symfony\Component\HttpKernel\Kernel
*/
private $kernel;
/**
* Holds Filesystem instance
*
* @var Symfony\Bundle\FrameworkBundle\Util\Filesystem
*/
private $filesystem;
/**
* Sets Kernel instance
*
* @param Symfony\Component\HttpKernel\Kernel $kernel
*/
public function setKernel(Kernel $kernel)
{
$this->kernel = $kernel;
}
/**
* Sets Filesystem instance
*
* @param Symfony\Bundle\FrameworkBundle\Util\Filesystem $fs
*/
public function setFilesystem(Filesystem $fs)
{
$this->filesystem = $fs;
}
/**
* @see Command
*/
protected function configure()
{
$this
->setDefinition(array(
new InputArgument('target', InputArgument::REQUIRED, 'The target directory'),
))
->addOption('symlink', null, InputOption::PARAMETER_NONE, 'Symlinks the assets instead of copying it')
->setName('assets:install')
;
}
/**
* @see Command
*
* @throws \InvalidArgumentException When the target directory does not exist
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (!is_dir($input->getArgument('target'))) {
throw new \InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target')));
}
foreach ($this->kernel->getBundles() as $bundle) {
if (is_dir($originDir = $bundle->getPath().'/Resources/public')) {
$output->writeln(sprintf('Installing assets for <comment>%s\\%s</comment>', $bundle->getNamespacePrefix(), $bundle->getName()));
$targetDir = $input->getArgument('target').'/bundles/'.preg_replace('/bundle$/', '', strtolower($bundle->getName()));
$this->filesystem->remove($targetDir);
if ($input->getOption('symlink')) {
$this->filesystem->symlink($originDir, $targetDir);
} else {
$this->filesystem->mkdirs($targetDir, 0777);
$this->filesystem->mirror($originDir, $targetDir);
}
}
}
}
}
<?php
namespace Symfony\Bundle\FrameworkBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\AssetsInstallCommand;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
class AssetsInstallCommandTest extends \PHPUnit_Framework_TestCase
{
/**
* @covers Symfony\Bundle\FrameworkBundle\AssetsInstallCommand::execute()
*/
public function testRun()
{
$originDir = __DIR__ . '/Resources/public';
$targetDir = __DIR__ . '/bundles/test';
$filesystem = $this->getMockFilesystem();
$filesystem->expects($this->once())
->method('remove')
->with($targetDir)
;
$filesystem->expects($this->once())
->method('mkdirs')
->with($targetDir, 0777)
;
$filesystem->expects($this->once())
->method('mirror')
->with($originDir, $targetDir)
;
$bundle = $this->getMockBundle();
$bundle->expects($this->any())
->method('getName')
->will($this->returnValue('TestBundle'))
;
$bundle->expects($this->once())
->method('getPath')
->will($this->returnValue(__DIR__))
;
$kernel = $this->getMockKernel();
$kernel->expects($this->once())
->method('getBundles')
->will($this->returnValue(array($bundle)))
;
$command = new AssetsInstallCommand();
$command->setKernel($kernel);
$command->setFilesystem($filesystem);
$command->run(new ArrayInput(array('target' => __DIR__)), new NullOutput());
}
/**
* Gets Filesystem mock instance
*
* @return Symfony\Bundle\FrameworkBundle\Util\Filesystem
*/
private function getMockFilesystem()
{
return $this->getMock('Symfony\Bundle\FrameworkBundle\Util\Filesystem', array(), array(), '', false, false);
}
/**
* Gets Bundle mock instance
*
* @return Symfony\Component\HttpKernel\Bundle\Bundle
*/
private function getMockBundle()
{
return $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle', array(), array(), '', false, false);
}
/**
* Gets Kernel mock instance
*
* @return Symfony\Component\HttpKernel\Kernel
*/
private function getMockKernel()
{
return $this->getMock('Symfony\Component\HttpKernel\Kernel', array(), array(), '', false, false);
}
}
<?xml version="1.0" ?>
<container xmlns="http://www.symfony-project.org/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="console.command.assets_install.class">Symfony\Bundle\FrameworkBundle\Command\AssetsInstallCommand</parameter>
<parameter key="console.command.init_bundle.class">Symfony\Bundle\FrameworkBundle\Command\InitBundleCommand</parameter>
<parameter key="console.command.router_debug.class">Symfony\Bundle\FrameworkBundle\Command\RouterDebugCommand</parameter>
<parameter key="console.command.router_apache_dumper.class">Symfony\Bundle\FrameworkBundle\Command\RouterApacheDumperCommand</parameter>
</parameters>
<services>
<service id="console.command.assets_install" class="%console.command.assets_install.class%">
<tag name="console.command" />
<call method="setKernel">
<argument type="service" id="kernel">
</call>
<call method="setFilesystem">
<service class="Symfony\Bundle\FrameworkBundle\Util\Filesystem" shared="false">
</call>
</service>
<service id="console.command.init_bundle" class="%console.command.init_bundle.class%">
<tag name="console.command" />
</service>
<service id="console.command.router_debug" class="%console.command.router_debug.class%">
<tag name="console.command" />
</service>
<service id="console.command.router_apache_dumper" class="%console.command.router_apache_dumper.class%">
<tag name="console.command" />
</service>
</services>
</container>
@kriswallsmith
Copy link

I like the looks of this. How about adding an attribute to the tag that identifies the command tag name so they can be lazily loaded, similar to template helpers?

@avalanche123
Copy link
Author

good idea Kris, this is a work in progress for tomorrow's blog post:)

@henrikbjorn
Copy link

Why not have the kernel and filesystem injected into the constructor of the command? since they are required for the execute method to be used anyway. Like this http://gist.github.com/627873.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment