pure/Gruntfile.js
Eric Ferraiuolo bd63012fa1 Add Grunt license task to stamp the Normalize.css and Yahoo! licenses
This task prepends the proper licenses to the built files as the very
last step of the `default` Grunt task.
2013-05-14 16:59:18 -04:00

351 lines
11 KiB
JavaScript

var path = require('path');
module.exports = function (grunt) {
// -- Config -------------------------------------------------------------------
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// -- Constants ------------------------------------------------------------
BUILD_COMMENT: 'THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT!',
// -- Clean Config ---------------------------------------------------------
clean: {
build : ['build/'],
build_res: ['build/*-r.css'],
release : ['release/<%= pkg.version %>/'],
base : ['src/base/css/', 'src/base/tests/', 'src/base/LICENSE.md']
},
// -- Copy Config ----------------------------------------------------------
copy: {
build: {
expand : true,
flatten: true,
src : 'src/**/css/*.css',
dest : 'build/',
rename: function (dest, src) {
// normalize -> base
src = src.replace(/^normalize(-.+\.css|\.css)$/, 'base$1');
return path.join(dest, src);
}
},
normalize: {
expand : true,
flatten: true,
cwd : '../normalize.css/',
src : '{LICENSE.md,normalize.css,test.html}',
dest : 'src/base/',
rename: function (dest, file) {
if (grunt.file.isMatch('*.css', file)) {
return path.join(dest, 'css', file);
}
if (grunt.file.isMatch('*.html', file)) {
return path.join(dest, 'tests', 'manual', file);
}
return path.join(dest, file);
},
options: {
processContent: function (content, file) {
var comment = grunt.config('BUILD_COMMENT');
if (grunt.file.isMatch({matchBase: true}, '*.css', file)) {
content = '/* ' + comment + ' */\n' + content;
} else if (grunt.file.isMatch({matchBase: true}, '*.html', file)) {
content = '<!-- ' + comment + ' -->\n' + content;
}
return content;
}
}
}
},
// -- Concat Config --------------------------------------------------------
concat: {
build: {
files: [
{'build/buttons.css': [
'build/buttons-core.css',
'build/buttons.css'
]},
{'build/forms-nr.css': [
'build/forms-core.css',
'build/forms.css'
]},
{'build/forms.css': [
'build/forms-nr.css',
'build/forms-r.css'
]},
{'build/grids-nr.css': [
'build/grids-core.css',
'build/grids-units.css'
]},
{'build/grids.css': [
'build/grids-nr.css',
'build/grids-r.css'
]},
{'build/menus-nr.css': [
'build/menus-core.css',
'build/menus.css',
'build/menus-paginator.css'
]},
{'build/menus.css': [
'build/menus-nr.css',
'build/menus-r.css'
]}
]
},
kimono: {
files: {
'build/kimono-min.css': [
'build/base-min.css',
'build/buttons-min.css',
'build/forms-min.css',
'build/grids-min.css',
'build/menus-min.css',
'build/tables-min.css'
],
'build/kimono-nr-min.css': [
'build/base-min.css',
'build/buttons-min.css',
'build/forms-nr-min.css',
'build/grids-nr-min.css',
'build/menus-nr-min.css',
'build/tables-min.css'
]
}
}
},
// -- CSSMin Config --------------------------------------------------------
cssmin: {
options: {
// report: 'gzip'
},
files: {
expand: true,
src : 'build/*.css',
ext : '-min.css'
}
},
// -- Compress Config ------------------------------------------------------
compress: {
release: {
options: {
archive: 'release/<%= pkg.version %>/<%= pkg.name %>-<%= pkg.version %>.zip'
},
expand : true,
flatten: true,
src : 'build/*.css',
dest : '<%= pkg.name %>/<%= pkg.version %>/'
}
},
// -- License Config -------------------------------------------------------
license: {
normalize: {
options: {
banner: [
'/*!',
'normalize.css v1.1.1 | MIT License | git.io/normalize',
'Copyright (c) Nicolas Gallagher and Jonathan Neal',
'*/\n'
].join('\n')
},
expand: true,
cwd : 'build/',
src : ['base*.css', 'forms*.css', 'tables*.css', 'kimono*.css']
},
yahoo: {
options: {
banner: [
'/*!',
'Kimono <%= pkg.version %>',
'Copyright 2013 Yahoo! Inc. All rights reserved.',
'Licensed under the BSD License.',
'https://github.com/yui/kimono/blob/master/LICENSE.md',
'*/\n'
].join('\n')
},
expand: true,
src : ['build/*.css']
}
},
// -- Contextualize Config -------------------------------------------------
contextualize: {
normalize: {
src : 'src/base/css/normalize.css',
dest: 'src/base/css/normalize-context.css',
options: {
prefix: '.k',
banner: '/* <%= BUILD_COMMENT %> */\n'
}
}
}
});
// -- Main Tasks ---------------------------------------------------------------
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.registerTask('default', [
'clean:build',
'copy:build',
'concat:build',
'clean:build_res',
'cssmin',
'concat:kimono',
'license'
]);
grunt.registerTask('import', [
'import-normalize'
]);
grunt.registerTask('release', [
'default',
'clean:release',
'compress:release'
]);
// -- Import Tasks -------------------------------------------------------------
grunt.registerTask('import-normalize', [
'clean:base',
'copy:normalize',
'contextualize:normalize'
]);
// -- License Task -------------------------------------------------------------
grunt.registerMultiTask('license', 'Stamps license banners on files.', function () {
var options = this.options({banner: ''}),
banner = grunt.template.process(options.banner),
tally = 0;
this.files.forEach(function (filePair) {
filePair.src.forEach(function (file) {
grunt.file.write(file, banner + grunt.file.read(file));
tally += 1;
});
});
grunt.log.writeln('Stampped license on ' + String(tally).cyan + ' files.');
});
// -- Contextualize Task -------------------------------------------------------
grunt.registerMultiTask('contextualize', 'Makes Contextualized CSS files.', function () {
var Parser = require('parserlib').css.Parser,
done = this.async(),
options = this.options({banner: ''}),
banner = grunt.template.process(options.banner),
processing = 0;
function oneDone() {
if (!(processing -= 1)) {
done();
}
}
this.files.forEach(function (filePair) {
filePair.src.forEach(function (file) {
var src = grunt.file.read(file),
contextual = banner,
parser = new Parser();
parser.addListener('endstylesheet', function () {
grunt.file.write(filePair.dest, contextual);
grunt.log.writeln('File "' + filePair.dest + '" created.');
oneDone();
});
// Fired right before CSS properties are parsed for a certain rule.
// Go through and add all the selectors to the `css` string.
parser.addListener('startrule', function (event) {
var prefix = options.prefix;
event.selectors.forEach(function (selector, i) {
var nextSelector = event.selectors[i + 1];
// If the selector does not contain the html selector, we
// can go ahead and prepend .k in front of it.
if (selector.text.indexOf('html') === -1) {
contextual += prefix + ' ' + selector.text;
} else if (selector.text.indexOf('html') !== -1) {
// If it contains `html`, replace the `html` with `.k`.
// Replace multiple spaces with a single space. This is
// for the case where `html input[type='button']` comes
// through as `html input[type='button']`.
contextual += selector.text.replace('html', prefix).replace(/ +/g, ' ');
}
// If theres another selector, add a comma.
if (nextSelector) {
contextual += ',\n';
} else {
// Otherwise, add an opening bracket for properties
contextual += ' {\n';
}
});
});
// Fired right after CSS properties are parsed for a certain rule.
// Add the closing bracket to end the CSS Rule.
parser.addListener('endrule', function (event) {
contextual += '}\n';
});
// Fired for each property that the parser encounters. Add these
// properties to the `css` string with 4 spaces.
parser.addListener('property', function (event) {
// Add 4 spaces tab.
contextual += ' ' + event.property + ': ' + event.value + ';\n';
});
// Do the parsing.
processing += 1;
parser.parse(src);
});
});
});
};