Browse Source

improved asset converter command running

now also gets stderr output.

fixes #1140
tags/2.0.0-beta
Carsten Brandt 11 years ago
parent
commit
58589e03bd
  1. 41
      framework/yii/web/AssetConverter.php
  2. 42
      tests/unit/framework/web/AssetConverterTest.php

41
framework/yii/web/AssetConverter.php

@ -47,17 +47,46 @@ class AssetConverter extends Component implements AssetConverterInterface
list ($ext, $command) = $this->commands[$ext]; list ($ext, $command) = $this->commands[$ext];
$result = substr($asset, 0, $pos + 1) . $ext; $result = substr($asset, 0, $pos + 1) . $ext;
if (@filemtime("$basePath/$result") < filemtime("$basePath/$asset")) { if (@filemtime("$basePath/$result") < filemtime("$basePath/$asset")) {
$output = []; $this->runCommand($command, $basePath, $asset, $result);
}
return $result;
}
}
return $asset;
}
/**
* Runs a command to convert asset files.
* @param string $command the command to run
* @param string $basePath asset base path and command working directory
* @param string $asset the name of the asset file
* @param string $result the name of the file to be generated by the converter command
* @return bool true on success, false on failure. Failures will be logged.
*/
protected function runCommand($command, $basePath, $asset, $result)
{
$command = strtr($command, [ $command = strtr($command, [
'{from}' => escapeshellarg("$basePath/$asset"), '{from}' => escapeshellarg("$basePath/$asset"),
'{to}' => escapeshellarg("$basePath/$result"), '{to}' => escapeshellarg("$basePath/$result"),
]); ]);
exec($command, $output); $descriptor = array(
Yii::trace("Converted $asset into $result: " . implode("\n", $output), __METHOD__); 1 => array('pipe', 'w'),
} 2 => array('pipe', 'w'),
return $result; );
$pipes = array();
$proc = proc_open($command, $descriptor, $pipes, $basePath);
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
foreach($pipes as $pipe) {
fclose($pipe);
} }
$status = proc_close($proc);
if ($status !== 0) {
Yii::error("AssetConverter command '$command' failed with exit code $status:\nSTDOUT:\n$stdout\nSTDERR:\n$stderr\n");
} else {
Yii::trace("Converted $asset into $result:\nSTDOUT:\n$stdout\nSTDERR:\n$stderr", __METHOD__);
} }
return $asset; return $status === 0;
} }
} }

42
tests/unit/framework/web/AssetConverterTest.php

@ -0,0 +1,42 @@
<?php
/**
* @author Carsten Brandt <mail@cebe.cc>
*/
namespace yiiunit\framework\web;
use yii\web\AssetConverter;
/**
* @group web
*/
class AssetConverterTest extends \yiiunit\TestCase
{
protected function setUp()
{
parent::setUp();
$this->mockApplication();
}
public function testConvert()
{
$tmpPath = \Yii::$app->runtimePath . '/assetConverterTest';
if (!is_dir($tmpPath)) {
mkdir($tmpPath, 0777, true);
}
file_put_contents($tmpPath . '/test.php', <<<EOF
<?php
echo "Hello World!\n";
echo "Hello Yii!";
EOF
);
$converter = new AssetConverter();
$converter->commands['php'] = ['txt', 'php {from} > {to}'];
$this->assertEquals('test.txt', $converter->convert('test.php', $tmpPath));
$this->assertTrue(file_exists($tmpPath . '/test.txt'), 'Failed asserting that asset output file exists.');
$this->assertEquals("Hello World!\nHello Yii!", file_get_contents($tmpPath . '/test.txt'));
}
}
Loading…
Cancel
Save