mathjs/tools/jake-utils.js
2013-08-14 15:00:12 +04:00

322 lines
9.7 KiB
JavaScript

/**
* Utility methods for jake
*
* Dependencies:
* jake
* uglify-js
* dateable
*
* Usage:
* var util = require('jake-utils');
*
* // minify, concatenate, replace patterns in files
* var result = util.minify({...});
* var result = util.concat({...});
* var result = util.replace({...});
*
* // get date and version
* var version = util.version();
* var today = util.today();
*
* // read and write files
* var data = util.read(filename);
* util.write(filename, data);
*/
var fs = require('fs'),
jake = require('jake'),
uglify = require('uglify-js'),
dateable = require('dateable');
/**
* Returns today's date as a formatted string.
* Default format is 'YYYY-MM-DD', for example '2013-02-18'
* @param {String} [format]
* @return {String} today
*/
function today (format) {
var date = new Date();
return dateable.format(date, format || 'YYYY-MM-DD');
}
/**
* Read the version number from the package.json file.
* If not found, an error is thrown
* @return {String} version
* @throws {Error}
*/
function version() {
var pkg = JSON.parse(read('./package.json'));
if (!pkg.version) {
throw new Error('No version found in package.json');
}
return pkg.version;
}
/**
* Replace patterns in text files.
* Patterns can be a string or a regular expression.
*
* Example usage:
* var result = replace({
* replacements: [
* {pattern: '@@date', replacement: '2013-02-18'},
* {pattern: '@@version', replacement: '1.4.0'}
* },
* src: [
* 'main.js',
* 'other/*.js'
* ]
* });
*
* @param {Object} params Object containing parameters:
* {Object[]} replacements Array containing objects with
* parameters:
* {String | RegExp} pattern
* {String} replacement
* {String | String[]} src The filenames. Can contain
* patterns.
* @return {Object} res Result information. The object contains:
* {String[]} src List with the filenames on which
* the replacement is executed
* @throws {Error}
*/
// TODO: change params of src such that we can also use regex expressions
function replace (params) {
// do some checks on the provided parameters
if (!(params instanceof Object)) {
throw new Error('Object with parameters expected as first argument.');
}
if (!params.replacements) {
throw new Error('Parameter "replacements" missing.');
}
if (!Array.isArray(params.replacements)) {
throw new Error('Parameter "replacements" must be an array.');
}
if (!params.src) {
throw new Error('Parameter "src" containing an array with filenames missing.');
}
var filelist = new jake.FileList();
filelist.include(params.src);
var filenames = filelist.toArray();
filenames.forEach(function (filename) {
var file = String(read(filename));
params.replacements.forEach(function (replacement, index) {
// check the replacement parameters
if (!(replacement instanceof Object)) {
throw new Error('Parameter "replacement" must be an object.');
}
if (!replacement.pattern) {
throw new Error('Parameter "pattern" in missing replacement object ' +
'(index ' + index + ')');
}
if (!replacement.replacement) {
throw new Error('Parameter "replacement" missing in replacement object ' +
'(index ' + index + ')');
}
file = file.replace(replacement.pattern, replacement.replacement);
});
write(filename, file);
});
return {
src: filenames
}
}
/**
* Concatenate a list with files into one file
*
* Example:
* var result = concat({
* src: [
* './lib/main.js',
* './lib/extra.js',
* './lib/functions/**',
* ],
* dest: './lib/mylibrary.js', // optional
* header: '// license information...', // optional
* separator: '\n', // optional
* footer: '// the end...' // optional
* });
*
* @param {Object} params Object containing:
* {String[]} src A list with source files to be
* Included. Can contain patterns.
* {String} [dest] The target file. Optional
* {String} [separator] Text to be inserted between the
* files. Optional.
* {String} [header] Text to be added on top.
* Optional.
* {String} [footer] Text to be added at the bottom.
* Optional.
* @return {Object} res Result information. The object contains:
* {String[]} src List with the filenames of the
* files which are concatenated
* {String} code The contents of the concatenated
* file
*/
function concat (params) {
// do some checks on the provided parameters
if (!(params instanceof Object)) {
throw new Error('Object with parameters expected as first argument.');
}
if (!params.src) {
throw new Error('Parameter "src" containing an array with filenames missing.');
}
var code = '';
var separator = params.separator ? String(params.separator) : '';
// header
if (params.header) {
code += String(params.header) + separator;
}
// files
var filelist = new jake.FileList();
filelist.include(params.src);
var filenames = filelist.toArray();
filenames.map(function(filename) {
code += read(filename) + separator;
});
// footer
if (params.footer) {
code += String(params.footer);
}
// write output
if (params.dest) {
// write file
write(params.dest, code);
}
return {
src: filenames,
code: code
};
}
/**
* Minify files using uglify-js.
*
* Example:
* var result = minify({
* src: [
* './lib/mylibrary.js'
* ],
* dest: './lib/mylibrary.min.js', // optional
* options: {}, // uglify-js options. optional
* header: '// license information...', // optional
* separator: '\n', // optional
* footer: '// the end...' // optional
* });
*
* @param {Object} params Object containing:
* {String | String[]} src One source file or an array
* with source files to be
* minified. The file names
* can contain patterns.
* {String} [dest] The target file. Optional
* {Object} [options] uglify-js options.
* {String} [header] Text to be added on top.
* Optional.
* {String} [separator] Text to be inserted between
* header, contents and footer.
* Optional.
* {String} [footer] Text to be added at the bottom.
* Optional.
* @return {Object} res Result information. The object contains:
* {String[]} src List with the filenames of the
* files which are minified
* {String} code The contents of the minified
* file.
*/
function minify (params) {
// do some checks on the provided parameters
if (!(params instanceof Object)) {
throw new Error('Object with parameters expected as first argument.');
}
if (!params.src) {
throw new Error('Parameter "src" containing an array with filenames missing.');
}
if (params.options) {
if (!(params.options instanceof Object)) {
throw new Error('Parameter "options" must be an object.');
}
}
var code = '';
var separator = params.separator ? String(params.separator) : '';
var options = params.options || {};
// header
if (params.header) {
code += String(params.header) + separator;
}
// src
var filelist = new jake.FileList();
filelist.include(params.src);
var filenames = filelist.toArray();
var minified = uglify.minify(filenames, options);
code += minified.code;
// footer
if (params.footer) {
code += separator + String(params.footer);
}
// write output
if (params.dest) {
write(params.dest, code);
}
return {
src: filenames,
code: code
};
}
/**
* Read a file from disk.
*
* Example:
* var data = read(filename);
*
* @param {String} filename
* @param {String} [encoding]
* @return {String} data
*/
function read(filename, encoding) {
return fs.readFileSync(filename, encoding);
}
/**
* Write a file to disk
*
* Example:
* write(filename, data);
*
* @param {String} filename
* @param {String} data
* @param {String} [encoding]
*/
function write(filename, data, encoding) {
fs.writeFileSync(filename, data, encoding);
}
// export all methods
module.exports = exports = {
read: read,
write: write,
concat: concat,
minify: minify,
replace: replace,
version: version,
today: today
};