From 80256655e262502e3916933a2a7f76b65435d4ca Mon Sep 17 00:00:00 2001 From: Kris Wallsmith Date: Fri, 25 Feb 2011 09:52:37 -0800 Subject: [PATCH] [AsseticBundle] added a --watch option to the assetic:dump command --- .../AsseticBundle/Command/DumpCommand.php | 99 +++++++++++++++++-- 1 file changed, 90 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php b/src/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php index 1d948ec5e8..d0de874bd2 100644 --- a/src/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php +++ b/src/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php @@ -11,9 +11,12 @@ namespace Symfony\Bundle\AsseticBundle\Command; +use Assetic\Asset\AssetInterface; +use Assetic\Factory\LazyAssetManager; use Symfony\Bundle\FrameworkBundle\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; /** @@ -29,6 +32,7 @@ class DumpCommand extends Command ->setName('assetic:dump') ->setDescription('Dumps all assets to the filesystem') ->addArgument('base_dir', InputArgument::OPTIONAL, 'The base directory') + ->addOption('watch', null, InputOption::VALUE_NONE, 'Check for changes every second') ; } @@ -39,18 +43,95 @@ class DumpCommand extends Command } $am = $this->container->get('assetic.asset_manager'); - foreach ($am->all() as $name => $asset) { - $output->writeln('[asset] '.$name); - $asset->load(); - $target = $baseDir . '/' . $asset->getTargetUrl(); - if (!is_dir($dir = dirname($target))) { - $output->writeln('[dir+] '.$dir); - mkdir($dir); + if ($input->getOption('watch')) { + return $this->watch($am, $baseDir, $output, $this->container->getParameter('kernel.debug')); + } + + foreach ($am->getNames() as $name) { + $this->dumpAsset($am->get($name), $baseDir, $output); + } + } + + /** + * Watches a asset manager for changes. + * + * This method includes an infinite loop the continuously polls the asset + * manager for changes. + * + * @param LazyAssetManager $am The asset manager + * @param string $baseDir The base directory to write to + * @param OutputInterface $output The command output + * @param Boolean $debug Debug mode + */ + protected function watch(LazyAssetManager $am, $baseDir, OutputInterface $output, $debug = false) + { + $previously = array(); + + while (true) { + // reload formulae when in debug + if ($debug) { + $am->load(); } - $output->writeln('[file+] '.$asset->getTargetUrl()); - file_put_contents($target, $asset->dump()); + foreach ($am->getNames() as $name) { + if ($asset = $this->checkAsset($am, $name, $previously)) { + $this->dumpAsset($asset, $baseDir, $output); + } + } + + sleep(1); + } + } + + /** + * Checks if an asset should be dumped. + * + * @param LazyAssetManager $am The asset manager + * @param string $name The asset name + * @param array $previously An array of previous visits + * + * @return AssetInterface|Boolean The asset if it should be dumped + */ + protected function checkAsset(LazyAssetManager $am, $name, array &$previously) + { + $formula = serialize($am->getFormula($name)); + $asset = $am->get($name); + $mtime = $asset->getLastModified(); + + if (isset($previously[$name])) { + $changed = $previously[$name]['mtime'] != $mtime || $previously[$name]['formula'] != $formula; + } else { + $changed = true; + } + + $previously[$name] = array('mtime' => $mtime, 'formula' => $formula); + + return $changed ? $asset : false; + } + + /** + * Writes an asset. + * + * @param AssetInterface $asset An asset + * @param string $baseDir The base directory to write to + * @param OutputInterface $output The command output + * + * @throws RuntimeException If there is a problem writing the asset + */ + protected function dumpAsset(AssetInterface $asset, $baseDir, OutputInterface $output) + { + $target = rtrim($baseDir, '/') . '/' . $asset->getTargetUrl(); + if (!is_dir($dir = dirname($target))) { + $output->writeln('[dir+] '.$dir); + if (false === @mkdir($dir)) { + throw new \RuntimeException('Unable to create directory '.$dir); + } + } + + $output->writeln('[file+] '.$target); + if (false === @file_put_contents($target, $asset->dump())) { + throw new \RuntimeException('Unable to write file '.$target); } } }