Skip to content

Commit

Permalink
Change to new syntax, add tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
satazor committed Mar 2, 2013
1 parent 35003a9 commit 81d0445
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 78 deletions.
12 changes: 7 additions & 5 deletions .jshintrc
@@ -1,8 +1,11 @@
{
"predef": [
"console",
"require",
"define"
"describe",
"it",
"before",
"beforeEach",
"after",
"afterEach"
],

"node": true,
Expand Down Expand Up @@ -30,7 +33,7 @@
"boss": false,
"debug": false,
"eqnull": true,
"es5": false,
"es5": true,
"esnext": false,
"evil": false,
"expr": false,
Expand All @@ -55,4 +58,3 @@
"onevar": false,
"white": true
}

2 changes: 1 addition & 1 deletion .npmignore
Expand Up @@ -55,4 +55,4 @@ npm-debug.*

# Project specific #
####################

test/
4 changes: 2 additions & 2 deletions README.md
@@ -1,9 +1,9 @@
`automaton task` - http://indigounited.com/automaton

rm
scaffolding-file-rename
===

Remove file or set of files.
Replaces {{placeholders}} in a set of file names.

*Indigo United 2013*

Expand Down
115 changes: 49 additions & 66 deletions autofile.js
@@ -1,71 +1,54 @@
/*jshint es5:true*/

'use strict';

var fs = require('fs'),
glob = require('glob'),
async = require('async'),
utils = require('mout'),
path = require('path'),
interp = require('../lib/string/interpolate')
var fs = require('fs'),
glob = require('glob'),
async = require('async'),
path = require('path')
;

var task = {
id : 'scaffolding-file-rename',
author : 'Indigo United',
name : 'Scaffolding: file rename.',
description : 'Replaces {{placeholders}} in a set of files.',
options: {
files: {
description: 'From which dir to start looking for files with placeholders. Accepts a dir and array of dirs. Also note that the dirs can be minimatch patterns.'
},
data: {
description: 'The data to be used while renaming. Keys are placeholder names and the values are the content for each placeholder.'
},
glob: {
description: 'The options to pass to glob (check https://npmjs.org/package/glob for details).',
default: null
}
},
tasks:
[
{
task: function (opt, ctx, next) {
var files = utils.lang.isArray(opt.files) ? opt.files : [opt.files];

// Do this in series, because it can give problems if the directories intersect eachother
async.forEachSeries(files, function (file, next) {
glob(file, opt.glob, function (err, matches) {
if (err) {
return next(err);
}

// Grab the list of files to rename
// Note that matches must be traversed backwards
var x;
var filesToRename = [];
var before;
var after;

for (x = matches.length - 1; x >= 0; --x) {
before = path.basename(matches[x]);
after = interp(before, opt.data);

if (before !== after) {
filesToRename.push({ before: matches[x], after: path.dirname(matches[x]) + '/' + after });
}
}

// Foreach file found, rename it (has to be in series)
async.forEachSeries(filesToRename, function (obj, next) {
ctx.log.debugln('Renaming from ' + obj.before + ' to ' + obj.after);
fs.rename(obj.before, obj.after, next);
}, next);
});
module.exports = function (task) {
task
.id('scaffolding-file-rename')
.name('Scaffolding: file rename.')
.description('Replaces {{placeholders}} in a set of file names.')
.author('Indigo United')

.option('files', 'From which dir to start looking for files with placeholders. Accepts a dir and array of dirs. Also note that the dirs can be minimatch patterns.')
.option('data', 'The data to be used while renaming. Keys are placeholder names and the values are the content for each placeholder.')
.option('glob', 'The options to pass to glob (check https://npmjs.org/package/glob for details).', null)

.do(function (opt, ctx, next) {
var files = Array.isArray(opt.files) ? opt.files : [opt.files];

// Do this in series, because it can give problems if the directories intersect eachother
async.forEachSeries(files, function (file, next) {
glob(file, opt.glob, function (err, matches) {
if (err) {
return next(err);
}

// Grab the list of files to rename
// Note that matches must be traversed backwards
var x;
var filesToRename = [];
var before;
var after;

for (x = matches.length - 1; x >= 0; --x) {
before = path.basename(matches[x]);
after = ctx.string.interpolate(before, opt.data);

if (before !== after) {
filesToRename.push({ before: matches[x], after: path.dirname(matches[x]) + '/' + after });
}
}

// Foreach file found, rename it (has to be in series)
async.forEachSeries(filesToRename, function (obj, next) {
ctx.log.debugln('Renaming from ' + obj.before + ' to ' + obj.after);
fs.rename(obj.before, obj.after, next);
}, next);
}
}
]
};

module.exports = task;
});
}, next);
});
};
19 changes: 15 additions & 4 deletions package.json
@@ -1,10 +1,10 @@
{
"name": "autofile-scaffolding-file-rename",
"version": "0.0.1",
"description": "Replaces {{placeholders}} in a set of files.",
"version": "0.0.0",
"description": "Replaces {{placeholders}} in a set of file names.",
"main": "autofile.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "mocha -R spec"
},
"repository": {
"type": "git",
Expand All @@ -22,5 +22,16 @@
],
"author": "Indigo United",
"license": "MIT",
"readmeFilename": "README.md"
"readmeFilename": "README.md",
"dependencies": {
"async": "~0.2.5",
"glob": "~3.1.21"
},
"devDependencies": {
"expect.js": "~0.2.0",
"rimraf": "~2.1.4",
"mocha": "~1.8.1",
"automaton": "~0.1.4",
"fstream": "~0.1.22"
}
}
155 changes: 155 additions & 0 deletions test/test.js
@@ -0,0 +1,155 @@
'use strict';

var fs = require('fs'),
expect = require('expect.js'),
rimraf = require('rimraf'),
fstream = require('fstream'),
isFile = require('./util/is-file'),
isDir = require('./util/is-dir'),
rename = require('../autofile'),
automaton = require('automaton').create()
;

describe('scaffolding-close', function () {
function clean(done) {
rimraf(__dirname + '/tmp', done);
}

beforeEach(function (done) {
clean(function (err) {
if (err) {
throw err;
}

fs.mkdirSync(__dirname + '/tmp');
fs.mkdirSync(__dirname + '/tmp/file-rename');

// Create some assets in tmp/file-rename
fs.writeFileSync(__dirname + '/tmp/file-rename/file1_{{placeholder1}}_{{placeholder2}}.json', '');
fs.mkdirSync(__dirname + '/tmp/file-rename/dummy{{empty}}');
fs.writeFileSync(__dirname + '/tmp/file-rename/dummy{{empty}}/file1_{{placeholder1}}_{{placeholder2}}.json', '');


done();
});
});
after(clean);

it('should replace filename placeholders with string', function (done) {
// Copy file-rename to file-rename-copy to test multiple dirs
var reader = fstream.Reader(__dirname + '/tmp/file-rename').pipe(
fstream.Writer({
type: 'Directory',
path: __dirname + '/tmp/file-rename-copy'
})
);

reader.on('error', function (err) {
throw err;
});

reader.on('end', function () {
automaton.run({
setup: function (opts, ctx, next) {
opts.__dirname = __dirname;
next();
},
tasks: [
{
task: rename,
options: {
files: ['{{__dirname}}/tmp/file-rename/**/*', '{{__dirname}}/tmp/file-rename-copy/**/*'],
data: {
placeholder1: 'foo',
placeholder2: 'bar',
empty: ''
}
}
}
]
}, null, function (err) {
if (err) {
throw err;
}

expect(isFile(__dirname + '/tmp/file-rename/file1_foo_bar.json')).to.equal(true);
expect(isDir(__dirname + '/tmp/file-rename/dummy')).to.equal(true);
expect(isFile(__dirname + '/tmp/file-rename/dummy/file1_foo_bar.json')).to.equal(true);
expect(isFile(__dirname + '/tmp/file-rename-copy/file1_foo_bar.json')).to.equal(true);
expect(isFile(__dirname + '/tmp/file-rename-copy/dummy/file1_foo_bar.json')).to.equal(true);

done();
});
});
});

it('should accept minimatch patterns', function (done) {
automaton.run({
setup: function (opts, ctx, next) {
opts.__dirname = __dirname;
next();
},
tasks: [
{
task: rename,
options: {
files: ['{{__dirname}}/tmp/file*rename/**/*'],
data: {
placeholder1: 'foo',
placeholder2: 'bar',
empty: ''
}
}
}
]
}, null, function (err) {
if (err) {
throw err;
}

expect(isFile(__dirname + '/tmp/file-rename/file1_foo_bar.json')).to.equal(true);
expect(isDir(__dirname + '/tmp/file-rename/dummy')).to.equal(true);
expect(isFile(__dirname + '/tmp/file-rename/dummy/file1_foo_bar.json')).to.equal(true);

done();
});
});

it('should pass over the glob options', function (done) {
// Rename to .file-rename and tell glob to match files starting with dot
fs.renameSync(__dirname + '/tmp/file-rename', __dirname + '/tmp/.file-rename');

automaton.run({
setup: function (opts, ctx, next) {
opts.__dirname = __dirname;
next();
},
tasks: [
{
task: rename,
options: {
files: ['{{__dirname}}/tmp/*file-rename/**/*'],
data: {
placeholder1: 'foo',
placeholder2: 'bar',
empty: ''
},
glob: {
dot: true
}
}
}
]
}, null, function (err) {
if (err) {
throw err;
}

expect(isFile(__dirname + '/tmp/.file-rename/file1_{{placeholder1}}_{{placeholder2}}.json')).to.equal(false);
expect(isDir(__dirname + '/tmp/.file-rename/dummy')).to.equal(true);
expect(isFile(__dirname + '/tmp/.file-rename/dummy/file1_{{placeholder1}}_{{placeholder2}}.json')).to.equal(false);

done();
});
});
});
15 changes: 15 additions & 0 deletions test/util/is-dir.js
@@ -0,0 +1,15 @@
'use strict';

var fs = require('fs');

module.exports = function (file) {
var stat;

try {
stat = fs.statSync(file);
} catch (e) {
return false;
}

return stat.isDirectory();
};
15 changes: 15 additions & 0 deletions test/util/is-file.js
@@ -0,0 +1,15 @@
'use strict';

var fs = require('fs');

module.exports = function (file) {
var stat;

try {
stat = fs.statSync(file);
} catch (e) {
return false;
}

return stat.isFile();
};

0 comments on commit 81d0445

Please sign in to comment.