Skip to content

Commit

Permalink
Merge pull request markstory#219 from markstory/cache-builds
Browse files Browse the repository at this point in the history
Cache build outputs
  • Loading branch information
markstory committed Nov 1, 2014
2 parents 48404cb + 27e66d6 commit 6a17cab
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 25 deletions.
14 changes: 14 additions & 0 deletions Console/Command/AssetCompressShell.php
Expand Up @@ -113,11 +113,25 @@ protected function _clearBuilds($ext) {
$this->err('No ' . $ext . ' build files defined, skipping');
return;
}
$this->_clearPath(TMP, $themes, $targets);

$path = $this->_Config->cachePath($ext);
if (!file_exists($path)) {
$this->err('Build directory ' . $path . ' for ' . $ext . ' does not exist.');
return;
}
$this->_clearPath($path, $themes, $targets);
}

/**
* Clear a path of build targets.
*
* @param string $path The path to clear.
* @param array $themes The themes to clear.
* @param array $targets The build targets to clear.
* @return void
*/
protected function _clearPath($path, $themes, $targets) {
$dir = new DirectoryIterator($path);
foreach ($dir as $file) {
$name = $base = $file->getFilename();
Expand Down
51 changes: 32 additions & 19 deletions Routing/Filter/AssetCompressor.php
Expand Up @@ -4,6 +4,7 @@
App::uses('AssetConfig', 'AssetCompress.Lib');
App::uses('AssetCompiler', 'AssetCompress.Lib');
App::uses('AssetCache', 'AssetCompress.Lib');
App::uses('Folder', 'Utility');

class AssetCompressor extends DispatcherFilter {

Expand All @@ -29,10 +30,12 @@ class AssetCompressor extends DispatcherFilter {
* @return CakeResponse if the client is requesting a recognized asset, null otherwise
*/
public function beforeDispatch(CakeEvent $event) {
$url = $event->data['request']->url;
$Config = $this->_getConfig();
$request = $event->data['request'];
$response = $event->data['response'];
$url = $request->url;
$config = $this->_getConfig();
$production = !Configure::read('debug');
if ($production && !$Config->general('alwaysEnableController')) {
if ($production && !$config->general('alwaysEnableController')) {
return;
}

Expand All @@ -41,37 +44,47 @@ public function beforeDispatch(CakeEvent $event) {
return;
}

if (isset($event->data['request']->query['theme'])) {
$Config->theme($event->data['request']->query['theme']);
if (isset($request->query['theme'])) {
$config->theme($event->data['request']->query['theme']);
}

// Dynamically defined build file. Disabled in production for
// hopefully obvious reasons.
if ($Config->files($build) === array()) {
if ($config->files($build) === array()) {
$files = array();
if (isset($event->data['request']->query['file'])) {
$files = $event->data['request']->query['file'];
if (isset($request->query['file'])) {
$files = $request->query['file'];
}
$Config->files($build, $files);
$config->files($build, $files);
}

// Use the TMP dir for dev builds.
// This is to avoid permissions issues with the configured paths.
$cachePath = CACHE . 'asset_compress' . DS;
$folder = new Folder($cachePath, true);
$folder->chmod($cachePath, 0777);

$ext = $config->getExt($build);
$config->cachePath($ext, $cachePath);
$config->set("$ext.timestamp", false);

try {
$Compiler = new AssetCompiler($Config);
$mtime = $Compiler->getLastModified($build);
$event->data['response']->modified($mtime);
if ($event->data['response']->checkNotModified($event->data['request'])) {
$event->stopPropagation();
return $event->data['response'];
$compiler = new AssetCompiler($config);
$cache = new AssetCache($config);
if ($cache->isFresh($build)) {
$contents = file_get_contents($cachePath . $build);
} else {
$contents = $compiler->generate($build);
$cache->write($build, $contents);
}
$contents = $Compiler->generate($build);
} catch (Exception $e) {
throw new NotFoundException($e->getMessage());
}

$event->data['response']->type($Config->getExt($build));
$event->data['response']->body($contents);
$response->type($config->getExt($build));
$response->body($contents);
$event->stopPropagation();
return $event->data['response'];
return $response;
}

/**
Expand Down
31 changes: 25 additions & 6 deletions Test/Case/Routing/Filter/AssetCompressorTest.php
Expand Up @@ -70,20 +70,39 @@ public function testPluginIniBuildFile() {
$this->assertTrue($event->isStopped());
}

public function testDynamicBuildFileCheckNotModified() {
$this->response
->expects($this->once())->method('checkNotModified')
->with($this->request)
->will($this->returnValue(true));
/**
* test that predefined builds get cached to disk.
*
* @return void
*/
public function testBuildFileIsCached() {
$this->request->url = 'cache_js/libs.js';
$data = array('request' => $this->request, 'response' => $this->response);
$event = new CakeEvent('Dispatcher.beforeDispatch', $this, $data);
$this->assertSame($this->response, $this->Compressor->beforeDispatch($event));

$this->assertContains('BaseClass', $this->response->body());
$this->assertTrue($event->isStopped());
$this->assertTrue(file_exists(CACHE . 'asset_compress' . DS . 'libs.js'), 'Cache file was created.');
unlink(CACHE . 'asset_compress' . DS . 'libs.js');
}

/**
* test that dynamic builds get cached to disk.
*
* @return void
*/
public function testDynamicBuildFileIsCached() {
$this->request->url = 'cache_js/dynamic.js';
$this->request->query['file'] = array('library_file.js', 'lots_of_comments.js');
$data = array('request' => $this->request, 'response' => $this->response);
$event = new CakeEvent('Dispatcher.beforeDispatch', $this, $data);
$this->assertSame($this->response, $this->Compressor->beforeDispatch($event));

$this->assertEquals('', $this->response->body());
$this->assertNotEquals('', $this->response->body());
$this->assertTrue($event->isStopped());
$this->assertTrue(file_exists(CACHE . 'asset_compress' . DS . 'dynamic.js'), 'Cache file was created.');
unlink(CACHE . 'asset_compress' . DS . 'dynamic.js');
}

/**
Expand Down

0 comments on commit 6a17cab

Please sign in to comment.