Skip to content

Commit

Permalink
Initial Commit - Adding module, tests, and readme
Browse files Browse the repository at this point in the history
  • Loading branch information
Polyneue committed Jul 19, 2016
1 parent 313e860 commit d26b91d
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 0 deletions.
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
##gulp-asset-cache
A disk based caching task for [gulp](http://gulpjs.com/). This plugin was built mainly to deal with the issues around having no dist directory and wanting to prevent image/video compression from happening multiple times on larger teams. If you do have the luxury of a src/dist file structure I recommend [gulp-changed](https://www.npmjs.com/package/gulp-changed) or [gulp-newer](https://www.npmjs.com/package/gulp-newer) as they easily integrate with that file structure.

##Installation
Install package with NPM and add it to your development dependencies:
`npm install --save-dev gulp-asset-cache`

##Usage
```
var gulp = require('gulp'),
imagemin = require('gulp-imagemin'),
assetCache = require('gulp-asset-cache');
gulp.task('images', function() {
return gulp.src('./images/*.{jpg,png,jpeg,gif,svg})
// Specify the location and name of the cache file
.pipe(assetCache('./images/.image-cache))
.pipe(imagemin({
verbose: true
}))
.pipe(gulp.dest('./images/'));
});
```

This will create a cache file named `.image-cache` of all files passed through the pipeline to be excluded from subsequent runs.

##Parameters
####`cacheName`
```
.pipe(assetCache( <cacheName> ))
```
> [Optional] The location to store the cache-file.
* Defaults to `./.asset-cache`


##Tests
```
npm test
```

##To Do
* Add a method to identify when already cached files have changed and should be rerun.

##License
[The MIT License(MIT)](https://github.com/Polyneue/gulp-asset-cache/blob/master/LICENSE)

Copyright (c) 2016 [Ed Mendoza](http://www.edmendoza.com)
87 changes: 87 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
'use strict';

// Dependencies
var fs = require('fs'),
through = require('through2'),
path = require('path'),
gutil = require('gulp-util'),
md5 = require('md5');

// Helpers
var PluginError = gutil.PluginError,
gc = gutil.colors;

// Constants
const PLUGIN_NAME = 'gulp-asset-cache';

/**
* Create a cache file for filtering
* @param {string} cacheName - Path to cache file
* @return stream
*/
var assetCache = function(cacheName) {
var currentCache = {},
cacheFile = {};

// Set default cache if not specified
if (!cacheName) {
cacheName = './.asset-cache';
}

// Try to load an existing cache file
try {
cacheFile = JSON.parse(fs.readFileSync(cacheName));
} catch (err) {
cacheFile = {};
}

/**
* Update the cache and pass through uncached files
* @param {File} file - A vinyl file
* @param {enc} encoding - Encoding (ignored)
* @param {function(err, file)} done - Callback
*/
function transform(file, enc, cb) {

if (file.isNull()) {
return cb();
}

if (file.isStream()) {
throw new PluginError(PLUGIN_NAME, 'Streams not currently supported.');
}

if (file.isBuffer()) {
var relativePath = path.relative(__dirname, path.dirname(file.path)) + '/' + path.basename(file.path),
hash = md5(relativePath);

// Update cache object
currentCache[relativePath] = hash;

if (cacheFile[relativePath] === currentCache[relativePath]) {
// Skip cached file
gutil.log(PLUGIN_NAME + ':' + gc.green(' ✔ ') + relativePath + gc.grey(' (cached)'));
return cb();
} else {
// Push uncached file
gutil.log(PLUGIN_NAME + ':' + gc.red(' ✖ ') + relativePath + gc.grey(' (uncached)'));
this.push(file);
return cb();
}
}
}

/**
* Flush updated cache file to disk
* @param {function(err, file)} done - Callback
*/
function flush(cb) {
fs.writeFile(cacheName, JSON.stringify(currentCache), cb);
}

// Return stream
return through.obj(transform, flush);
}

// Exports
module.exports = assetCache;
34 changes: 34 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "gulp-asset-cache",
"version": "1.0.0",
"description": "A disk based caching task for gulp",
"main": "index.js",
"scripts": {
"test": "mocha --reporter spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Polyneue/gulp-asset-cache.git"
},
"keywords": [
"cache",
"gulp",
"gulpplugin"
],
"author": "Ed Mendoza <polyneue@gmail.com> (http://www.edmendoza.com)",
"license": "MIT",
"bugs": {
"url": "https://github.com/Polyneue/gulp-asset-cache/issues"
},
"homepage": "https://github.com/Polyneue/gulp-asset-cache#readme",
"devDependencies": {
"chai": "^3.5.0",
"gulp-util": "^3.0.7",
"mocha": "^2.5.3"
},
"dependencies": {
"gulp-util": "^3.0.7",
"md5": "^2.1.0",
"through2": "^2.0.1"
}
}
1 change: 1 addition & 0 deletions test/.test-existing-cache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"test/foo.png":"9a00e3f54e6a23ee446348a075ddcfb1"}
94 changes: 94 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
'use strict';

// Dependencies
var assetCache = require('../index'),
chai = require('chai'),
gutil = require('gulp-util'),
fs = require('fs'),
expect = chai.expect;

describe('gulp-asset-cache', function() {
var cacheNewTest = './test/.test-new-cache',
cacheExistingTest = './test/.test-existing-cache',
fileOne = new gutil.File({ path: './test/foo.png', contents: new Buffer('Foo') }),
fileTwo = new gutil.File({ path: './test/deep/bar.jpg', contents: new Buffer('Bar') }),
fileThree = new gutil.File({ path: './test/baz.gif', contents: new Buffer('Baz') });

describe('with an existing cache', function() {

it('should filter files out of the pipe and pass on uncached ones', function(done) {
var stream = assetCache(cacheExistingTest);

stream.pipe(gutil.buffer(function(err, files) {
expect(files).to.not.have.keys(['./test/deep/bar.jpg']);
done();
// Reset test file
fs.writeFile(cacheExistingTest, '{"test/foo.png":"9a00e3f54e6a23ee446348a075ddcfb1"}', 'utf8');
}));

stream.write(fileOne);
stream.write(fileTwo);
stream.end();
});

it('should update the cache with piped files', function(done) {
var stream = assetCache(cacheExistingTest);

stream.on('finish', function() {
fs.readFile(cacheExistingTest, 'utf8', function(err, data) {
var cacheObj = JSON.parse(data);
expect(cacheObj).to.have.keys(['test/deep/bar.jpg', 'test/baz.gif']);
expect(cacheObj).to.not.have.keys(['test/foo.png']);
done();
});

// Reset test file
fs.unlink(cacheExistingTest, function() {
fs.writeFile(cacheExistingTest, '{"test/foo.png":"9a00e3f54e6a23ee446348a075ddcfb1"}', 'utf8');
})
});

stream.write(fileTwo);
stream.write(fileThree);
stream.end();
});
});

describe('without a cache', function() {

it('should create a cache file and populate with piped files', function(done) {
var stream = assetCache(cacheNewTest);

stream.on('finish', function() {
fs.readFile(cacheNewTest, 'utf8', function(err, data) {
expect(JSON.parse(data)).to.have.keys(['test/foo.png', 'test/deep/bar.jpg']);
done();
});
// Remove test File
fs.unlink(cacheNewTest);
});

stream.write(fileOne);
stream.write(fileTwo);
stream.end();
});

it('should create a default test file and populate with piped files', function(done) {
var stream = assetCache();

stream.on('finish', function() {
fs.readFile('./.asset-cache', 'utf8', function(err, data) {
expect(JSON.parse(data)).to.have.keys(['test/foo.png', 'test/deep/bar.jpg'])
done();
})

// Remove test file
fs.unlink('./.asset-cache');
});

stream.write(fileOne);
stream.write(fileTwo);
stream.end();
});
});
});

0 comments on commit d26b91d

Please sign in to comment.