Skip to content

Commit

Permalink
Merge pull request #967 from robfrawley/feature-add-force-resolve-com…
Browse files Browse the repository at this point in the history
…mand-and-prettify

[Console] Add forced resolve to command and prittify and detail output
  • Loading branch information
robfrawley authored Aug 31, 2017
2 parents d62b2d9 + 1c9811e commit 67b058c
Show file tree
Hide file tree
Showing 5 changed files with 526 additions and 131 deletions.
44 changes: 33 additions & 11 deletions Command/RemoveCacheCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,44 +26,66 @@ protected function configure()
->setName('liip:imagine:cache:remove')
->setDescription('Remove cache for given paths and set of filters.')
->addArgument('paths', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Image paths')
->addOption(
'filters',
'f',
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
'Filters list'
)
->addOption('filters', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
'List of filters to remove for passed images (Deprecated, use "filter").')
->addOption('filter', 'f', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
'List of filters to remove for passed images.')
->setHelp(<<<'EOF'
The <info>%command.name%</info> command removes cache by specified parameters.
Paths should be separated by spaces:
<info>php app/console %command.name% path1 path2</info>
All cache for a given `paths` will be lost.
If you use --filters parameter:
<info>php app/console %command.name% --filters=thumb1 --filters=thumb2</info>
If you use --filter parameter:
<info>php app/console %command.name% --filter=thumb1 --filter=thumb2</info>
All cache for a given filters will be lost.
You can combine these parameters:
<info>php app/console %command.name% path1 path2 --filters=thumb1 --filters=thumb2</info>
<info>php app/console %command.name% path1 path2 --filter=thumb1 --filter=thumb2</info>
<info>php app/console %command.name%</info>
Cache for all paths and filters will be lost when executing this command without parameters.
EOF
);
}

/**
* @param InputInterface $input
* @param OutputInterface $output
*
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$paths = $input->getArgument('paths');
$filters = $input->getOption('filters');
$filters = $this->resolveInputFilters($input);

if (empty($filters)) {
$filters = null;
}

/* @var CacheManager cacheManager */
$cacheManager = $this->getContainer()->get('liip_imagine.cache.manager');

$cacheManager->remove($paths, $filters);

return 0;
}

/**
* @param InputInterface $input
*
* @return array|mixed
*/
private function resolveInputFilters(InputInterface $input)
{
$filters = $input->getOption('filter');

if (count($filtersDeprecated = $input->getOption('filters'))) {
$filters = array_merge($filters, $filtersDeprecated);
@trigger_error('As of 1.9, use of the "--filters" option has been deprecated in favor of "--filter" and will be removed in 2.0.', E_USER_DEPRECATED);
}

return $filters;
}
}
200 changes: 155 additions & 45 deletions Command/ResolveCacheCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,67 +27,177 @@ protected function configure()
$this
->setName('liip:imagine:cache:resolve')
->setDescription('Resolve cache for given path and set of filters.')
->addArgument('paths', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Image paths')
->addOption(
'filters',
'f',
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
'Filters list'
)->setHelp(<<<'EOF'
The <info>%command.name%</info> command resolves cache by specified parameters.
It returns list of urls.
<info>php app/console %command.name% path1 path2 --filters=thumb1</info>
Cache for this two paths will be resolved with passed filter.
As a result you will get<info>
http://localhost/media/cache/thumb1/path1
http://localhost/media/cache/thumb1/path2</info>
You can pass few filters:
<info>php app/console %command.name% path1 --filters=thumb1 --filters=thumb2</info>
As a result you will get<info>
http://localhost/media/cache/thumb1/path1
http://localhost/media/cache/thumb2/path1</info>
If you omit --filters parameter then to resolve given paths will be used all configured and available filters in application:
<info>php app/console %command.name% path1</info>
As a result you will get<info>
http://localhost/media/cache/thumb1/path1
http://localhost/media/cache/thumb2/path1</info>
->addArgument('paths', InputArgument::REQUIRED | InputArgument::IS_ARRAY,
'Any number of image paths to act on.')
->addOption('filters', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
'List of filters to apply to passed images (Deprecated, use "filter").')
->addOption('filter', 'f', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
'List of filters to apply to passed images.')
->addOption('force', 'F', InputOption::VALUE_NONE,
'Force image resolution regardless of cache.')
->addOption('as-script', 's', InputOption::VALUE_NONE,
'Only print machine-parseable results.')
->setHelp(<<<'EOF'
The <comment>%command.name%</comment> command resolves the passed image(s) for the resolved
filter(s), outputting results using the following basic format:
<info>- "image.ext[filter]" (resolved|cached|failed) as "path/to/cached/image.ext"</>
<comment># bin/console %command.name% --filter=thumb1 foo.ext bar.ext</comment>
Resolve <options=bold>both</> <comment>foo.ext</comment> and <comment>bar.ext</comment> using <comment>thumb1</comment> filter, outputting:
<info>- "foo.ext[thumb1]" resolved as "http://localhost/media/cache/thumb1/foo.ext"</>
<info>- "bar.ext[thumb1]" resolved as "http://localhost/media/cache/thumb1/bar.ext"</>
<comment># bin/console %command.name% --filter=thumb1 --filter=thumb2 foo.ext</comment>
Resolve <comment>foo.ext</comment> using <options=bold>both</> <comment>thumb1</comment> and <comment>thumb2</comment> filters, outputting:
<info>- "foo.ext[thumb1]" resolved as "http://localhost/media/cache/thumb1/foo.ext"</>
<info>- "foo.ext[thumb2]" resolved as "http://localhost/media/cache/thumb2/foo.ext"</>
<comment># bin/console %command.name% foo.ext</comment>
Resolve <comment>foo.ext</comment> using <options=bold>all configured filters</> (as none are specified), outputting:
<info>- "foo.ext[thumb1]" resolved as "http://localhost/media/cache/thumb1/foo.ext"</>
<info>- "foo.ext[thumb2]" resolved as "http://localhost/media/cache/thumb2/foo.ext"</>
<comment># bin/console %command.name% --force --filter=thumb1 foo.ext</comment>
Resolve <comment>foo.ext</comment> using <comment>thumb1</comment> and <options=bold>force creation</> regardless of cache, outputting:
<info>- "foo.ext[thumb1]" resolved as "http://localhost/media/cache/thumb1/foo.ext"</>

EOF
);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$force = $input->getOption('force');
$paths = $input->getArgument('paths');
$filters = $input->getOption('filters');
$filters = $this->resolveInputFilters($input);
$machine = $input->getOption('as-script');
$failed = 0;

/* @var FilterManager filterManager */
$filterManager = $this->getContainer()->get('liip_imagine.filter.manager');
/* @var CacheManager cacheManager */
$cacheManager = $this->getContainer()->get('liip_imagine.cache.manager');
/* @var DataManager dataManager */
$dataManager = $this->getContainer()->get('liip_imagine.data.manager');
$filterManager = $this->getFilterManager();
$dataManager = $this->getDataManager();
$cacheManager = $this->getCacheManager();

if (empty($filters)) {
if (0 === count($filters)) {
$filters = array_keys($filterManager->getFilterConfiguration()->all());
}

$this->outputTitle($output, $machine);

foreach ($paths as $path) {
foreach ($filters as $filter) {
if (!$cacheManager->isStored($path, $filter)) {
$binary = $dataManager->find($filter, $path);

$cacheManager->store(
$filterManager->applyFilter($binary, $filter),
$path,
$filter
);
}
$output->write(sprintf('- %s[%s] ', $path, $filter));

try {
if ($force || !$cacheManager->isStored($path, $filter)) {
$cacheManager->store($filterManager->applyFilter($dataManager->find($filter, $path), $filter), $path, $filter);
$output->write('resolved: ');
} else {
$output->write('cached: ');
}

$output->writeln($cacheManager->resolve($path, $filter));
$output->writeln($cacheManager->resolve($path, $filter));
} catch (\Exception $e) {
$output->writeln(sprintf('failed: %s', $e->getMessage()));
++$failed;
}
}
}

$this->outputSummary($output, $machine, count($filters), count($paths), $failed);

return 0 === $failed ? 0 : 255;
}

/**
* @param OutputInterface $output
* @param bool $machine
*/
private function outputTitle(OutputInterface $output, $machine)
{
if (!$machine) {
$title = '[liip/imagine-bundle] Image Resolver';

$output->writeln(sprintf('<info>%s</info>', $title));
$output->writeln(str_repeat('=', strlen($title)));
$output->writeln('');
}
}

/**
* @param OutputInterface $output
* @param bool $machine
* @param int $filters
* @param int $paths
* @param int $failed
*/
private function outputSummary(OutputInterface $output, $machine, $filters, $paths, $failed)
{
if (!$machine) {
$operations = ($filters * $paths) - $failed;

$output->writeln('');
$output->writeln(vsprintf('Completed %d %s (%d %s on %d %s) <fg=red;options=bold>%s</>', array(
$operations,
$this->pluralizeWord($operations, 'operation'),
$filters,
$this->pluralizeWord($filters, 'filter'),
$paths,
$this->pluralizeWord($paths, 'image'),
0 === $failed ? '' : sprintf('[encountered %d %s]', $failed, $this->pluralizeWord($failed, 'failure')),
)));
}
}

/**
* @param int $count
* @param string $singular
* @param string $pluralEnding
*
* @return string
*/
private function pluralizeWord($count, $singular, $pluralEnding = 's')
{
return 1 === $count ? $singular : $singular.$pluralEnding;
}

/**
* @param InputInterface $input
*
* @return array|mixed
*/
private function resolveInputFilters(InputInterface $input)
{
$filters = $input->getOption('filter');

if (count($filtersDeprecated = $input->getOption('filters'))) {
$filters = array_merge($filters, $filtersDeprecated);
@trigger_error('As of 1.9, use of the "--filters" option has been deprecated in favor of "--filter" and will be removed in 2.0.', E_USER_DEPRECATED);
}

return $filters;
}

/**
* @return FilterManager
*/
private function getFilterManager()
{
return $this->getContainer()->get('liip_imagine.filter.manager');
}

/**
* @return DataManager
*/
private function getDataManager()
{
return $this->getContainer()->get('liip_imagine.data.manager');
}

/**
* @return CacheManager
*/
private function getCacheManager()
{
return $this->getContainer()->get('liip_imagine.cache.manager');
}
}
7 changes: 3 additions & 4 deletions Tests/Functional/Command/AbstractCommandTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,21 @@ class AbstractCommandTestCase extends AbstractSetupWebTestCase
/**
* @param Command $command
* @param array $arguments
* @param array $options
* @param int $return
*
* @return string
*/
protected function executeConsole(Command $command, array $arguments = array(), array $options = array())
protected function executeConsole(Command $command, array $arguments = array(), &$return = null)
{
$command->setApplication(new Application($this->createClient()->getKernel()));
if ($command instanceof ContainerAwareCommand) {
$command->setContainer($this->createClient()->getContainer());
}

$arguments = array_replace(array('command' => $command->getName()), $arguments);
$options = array_replace(array('--env' => 'test'), $options);

$commandTester = new CommandTester($command);
$commandTester->execute($arguments, $options);
$return = $commandTester->execute($arguments, array('--env' => 'test'));

return $commandTester->getDisplay();
}
Expand Down
26 changes: 20 additions & 6 deletions Tests/Functional/Command/RemoveCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function testExecuteSuccessfullyWithEmptyCacheAndOnePathAndOneFilter()
new RemoveCacheCommand(),
array(
'paths' => array('images/cats.jpeg'),
'--filters' => array('thumbnail_web_path'),
'--filter' => array('thumbnail_web_path'),
));
}

Expand All @@ -53,7 +53,7 @@ public function testExecuteSuccessfullyWithEmptyCacheAndMultipleFilters()

$this->executeConsole(
new RemoveCacheCommand(),
array('--filters' => array('thumbnail_web_path', 'thumbnail_default'))
array('--filter' => array('thumbnail_web_path', 'thumbnail_default'))
);
}

Expand Down Expand Up @@ -160,7 +160,7 @@ public function testShouldRemoveCacheBySingleFilter()

$this->executeConsole(
new RemoveCacheCommand(),
array('--filters' => array('thumbnail_default'))
array('--filter' => array('thumbnail_default'))
);

$this->assertFileNotExists($this->cacheRoot.'/thumbnail_default/images/cats.jpeg');
Expand Down Expand Up @@ -190,7 +190,7 @@ public function testShouldRemoveCacheByMultipleFilters()

$this->executeConsole(
new RemoveCacheCommand(),
array('--filters' => array('thumbnail_default', 'thumbnail_web_path'))
array('--filter' => array('thumbnail_default', 'thumbnail_web_path'))
);

$this->assertFileNotExists($this->cacheRoot.'/thumbnail_web_path/images/cats.jpeg');
Expand Down Expand Up @@ -218,7 +218,7 @@ public function testShouldRemoveCacheByOnePathAndMultipleFilters()
new RemoveCacheCommand(),
array(
'paths' => array('images/cats.jpeg'),
'--filters' => array('thumbnail_default', 'thumbnail_web_path'), )
'--filter' => array('thumbnail_default', 'thumbnail_web_path'), )
);

$this->assertFileNotExists($this->cacheRoot.'/thumbnail_web_path/images/cats.jpeg');
Expand All @@ -245,11 +245,25 @@ public function testShouldRemoveCacheByMultiplePathsAndSingleFilter()
new RemoveCacheCommand(),
array(
'paths' => array('images/cats.jpeg', 'images/cats2.jpeg'),
'--filters' => array('thumbnail_web_path'), )
'--filter' => array('thumbnail_web_path'), )
);

$this->assertFileNotExists($this->cacheRoot.'/thumbnail_web_path/images/cats.jpeg');
$this->assertFileNotExists($this->cacheRoot.'/thumbnail_web_path/images/cats2.jpeg');
$this->assertFileExists($this->cacheRoot.'/thumbnail_default/images/cats.jpeg');
}

/**
* @group legacy
* @expectedDeprecation As of 1.9, use of the "--filters" option has been deprecated in favor of "--filter" and will be removed in 2.0.
*/
public function testDeprecatedFiltersOption()
{
$this->executeConsole(
new RemoveCacheCommand(),
array(
'paths' => array('images/cats.jpeg', 'images/cats2.jpeg'),
'--filters' => array('thumbnail_web_path'), )
);
}
}
Loading

0 comments on commit 67b058c

Please sign in to comment.