diff --git a/src/Filter/AssetFilter.php b/src/Filter/AssetFilter.php index 3bea0b77..bc73b689 100644 --- a/src/Filter/AssetFilter.php +++ b/src/Filter/AssetFilter.php @@ -82,6 +82,16 @@ public function getDependencies(AssetTarget $file) return []; } + /** + * Overloaded in filters that can't handle dependencies + * + * @return boolean True when the filter supports dependencies + */ + public function hasDependencies() + { + return true; + } + /** * Run the compressor command and get the output * diff --git a/src/Filter/FilterInterface.php b/src/Filter/FilterInterface.php index 8c002b77..09922c01 100644 --- a/src/Filter/FilterInterface.php +++ b/src/Filter/FilterInterface.php @@ -59,4 +59,11 @@ public function settings(array $settings = null); * @return array An array of MiniAsset\File\Local objects. */ public function getDependencies(AssetTarget $target); + + /** + * Returns a boolean whether the filter supports dependencies. + * + * @return boolean True when the filter supports dependencies + */ + public function hasDependencies(); } diff --git a/src/Filter/PipeInputFilter.php b/src/Filter/PipeInputFilter.php new file mode 100644 index 00000000..e33332f2 --- /dev/null +++ b/src/Filter/PipeInputFilter.php @@ -0,0 +1,87 @@ + '.css', + 'dependencies' => false, + 'optional_dependency_prefix' => false, + 'command' => '/bin/cat', + 'path' => '/bin', + ); + + /** + * It will use prefixed files if they exist. + * + * @var string + */ + protected $optionalDependencyPrefix = null; + + public function hasDependencies() + { + return $this->_settings['dependencies']; + } + + public function getDependencies(AssetTarget $file) + { + if ($this->_settings['dependencies']) { + $this->optionalDependencyPrefix = $this->_settings['optional_dependency_prefix']; + + return $this->getCssDependencies($file); + } + + return []; + } + + /** + * Runs command against any files that match the configured extension. + * + * @param string $filename The name of the input file. + * @param string $input The content of the file. + * @return string + */ + public function input($filename, $input) + { + if (substr($filename, strlen($this->_settings['ext']) * -1) !== $this->_settings['ext']) { + return $input; + } + $filename = escapeshellarg($filename); + $bin = $this->_settings['command'] . ' ' . $filename; + $return = $this->_runCmd($bin, '', array('PATH' => $this->_settings['path'])); + + return $return; + } +} diff --git a/src/Filter/PipeOutputFilter.php b/src/Filter/PipeOutputFilter.php new file mode 100644 index 00000000..ea3ef34d --- /dev/null +++ b/src/Filter/PipeOutputFilter.php @@ -0,0 +1,47 @@ + '/bin/cat', + 'path' => '/bin', + ); + + /** + * Run command against the output and compress it. + * + * @param string $filename Name of the file being generated. + * @param string $input The raw contents for $filename. + * @return string Processed contents. + */ + public function output($filename, $input) + { + $cmd = $this->_settings['command']; + + return $this->_runCmd($cmd, $input, array('PATH' => $this->_settings['path'])); + } +} diff --git a/src/Output/FreshTrait.php b/src/Output/FreshTrait.php index c78d0a33..b994d6bd 100644 --- a/src/Output/FreshTrait.php +++ b/src/Output/FreshTrait.php @@ -90,6 +90,9 @@ public function isFresh(AssetTarget $target) $filters = $this->filterRegistry->collection($target); foreach ($filters->filters() as $filter) { + if (!$filter->hasDependencies()) { + return false; + } foreach ($filter->getDependencies($target) as $child) { $time = $child->modifiedTime(); if ($time >= $buildTime) { diff --git a/tests/TestCase/Filter/PipeInputFilterTest.php b/tests/TestCase/Filter/PipeInputFilterTest.php new file mode 100644 index 00000000..9b85ee3c --- /dev/null +++ b/tests/TestCase/Filter/PipeInputFilterTest.php @@ -0,0 +1,96 @@ +_cssDir = APP . 'css' . DS; + $this->filter = new PipeInputFilter(); + $this->filter->settings([ + 'paths' => [$this->_cssDir], + 'ext' => '.scss', + ]); + } + + public function testParsing() + { + $this->filter->settings(array('command' => '/bin/cat')); + + $content = file_get_contents($this->_cssDir . 'test.scss'); + $result = $this->filter->input($this->_cssDir . 'test.scss', $content); + $expected = file_get_contents($this->_cssDir . 'test.scss'); + $this->assertEquals($expected, $result); + } + + public function testGetDependenciesFalse() + { + $this->filter->settings(array( + 'dependencies' => false, + 'optional_dependency_prefix' => false, + )); + + $files = [ + new Local($this->_cssDir . 'test.scss') + ]; + $target = new AssetTarget('test.css', $files); + $result = $this->filter->getDependencies($target); + + $this->assertEmpty($result); + } + + public function testGetDependenciesTrue() + { + $this->filter->settings(array( + 'dependencies' => true, + 'optional_dependency_prefix' => '_', + )); + + $files = [ + new Local($this->_cssDir . 'test.scss') + ]; + $target = new AssetTarget('test.css', $files); + $result = $this->filter->getDependencies($target); + + $this->assertCount(3, $result); + $this->assertEquals('colors.scss', $result[0]->name()); + $this->assertEquals('_utilities.scss', $result[1]->name()); + $this->assertEquals('_reset.scss', $result[2]->name()); + } + + public function testGetDependenciesMissingDependency() + { + $this->filter->settings(array( + 'dependencies' => true, + 'optional_dependency_prefix' => '_', + )); + + $files = [ + new Local($this->_cssDir . 'broken.scss') + ]; + $target = new AssetTarget('test.css', $files); + $result = $this->filter->getDependencies($target); + + $this->assertCount(1, $result); + $this->assertEquals('colors.scss', $result[0]->name()); + } +} diff --git a/tests/TestCase/Filter/PipeOutputFilterTest.php b/tests/TestCase/Filter/PipeOutputFilterTest.php new file mode 100644 index 00000000..216187c8 --- /dev/null +++ b/tests/TestCase/Filter/PipeOutputFilterTest.php @@ -0,0 +1,36 @@ +_cssDir = APP . 'css' . DS; + $this->filter = new PipeOutputFilter(); + } + + public function testOutput() + { + $content = file_get_contents($this->_cssDir . 'unminified.css'); + $result = $this->filter->output($this->_cssDir . 'unminified.css', $content); + $expected = file_get_contents($this->_cssDir . 'unminified.css'); + $this->assertEquals($expected, $result); + } +}