-
Notifications
You must be signed in to change notification settings - Fork 5
Working with grunt
grunt
and bbb
are neat task based tools that help you
build web applications conforming to best practices (minified everything, test
driven, sensible code layout etc.). Using these as helpers for your situp.py
projects is desirable - since much of the grunt work (arf!) is taken care of
for you.
Situp now has pre and post processors. These allow you to run commands before
and after pushing to the server and are a great place to hook in tools like
grunt or bbb. Consult situp.py push -h
for a list of available pre/post
processors.
To trigger grunt
or bbb
you'll want to use the cmd processor, which is
available both for pre and post actions:
situp.py push -d my_app -s host --pre=cmd "bbb package" -e bbb-app
situp.py push -d my_app -s host --post=cmd "bbb clean" -e bbb-app
situp.py push -d my_app -s host --pre=cmd "bbb package" --post=cmd "bbb clean" -e bbb-app
Triggering bbb package
is only useful if you have the necessary task
defined. The package
task builds the application (e.g. cat's and minifies
js/css) and copies the build artifacts and any assets into a predefined
location. For use with situp.py
this is the _attachments
directory of your
design document.
At the moment you'll need to include the following task definition and alias to enable
the package
task:
// Copy files and folders into a new directory structure
grunt.registerTask("relocate", "Relocate files and directories.", function(){
// bail if release hasn't run
grunt.task.requires('release');
// TODO: ditch this when grunt v0.4 is released
grunt.util = grunt.util || grunt.utils;
var _ = grunt.util._;
var options = _.defaults(grunt.config("relocate") || {}, {
destination: 'bundle',
files: ['*.html'],
folders: {'dist': ''}
});
grunt.file.mkdir(options.destination);
function recurse_expand(source, dest){
var files = {};
grunt.file.recurse(source, function(abspath, r, s, f){
files[abspath] = abspath.replace(source, dest);
});
return files;
}
function copyPath(the_list){
_.each(the_list, function(source){
var destination = options.destination + '/' + source;
destination = destination.replace(/\/+/g, '/');
grunt.log.writeln('copy ' + source + ' to ' + destination);
grunt.file.copy(source, destination);
});
}
function relocateToPath(the_list){
_.each(the_list, function(newpath, path, l){
var destination = options.destination + '/' + newpath;
destination = destination.replace(/\/+/g, '/');
grunt.log.writeln('copy ' + path + ' to ' + destination);
grunt.file.copy(path, destination);
});
}
if (_.isArray(options.files)){
// files to copy into the bundle
_.each(options.files, function(f){
copyPath(grunt.file.expand(f));
});
} else {
// files to relocate into the bundle
var expandedFiles = {};
_.each(options.files, function(value, key, list){
// grunt.file.expand returns a list, make suitable object
_.each(grunt.file.expand(key), function(file){
expandedFiles[file] = value + '/' + _.last(file.split('/'));
});
});
relocateToPath(expandedFiles);
}
if (_.isArray(options.folders)){
// directories to copy into the bundle
_.each(options.folders, function(f){
copyPath(recurse_expand(f, f));
});
} else {
// directories to relocate into the bundle
_.map(options.folders, function(value, key, list){
relocateToPath(recurse_expand(key, value));
});
}
});
// Build a release (lint, test, minify css/js) then copy resulting
// files and all other assets into a bundle directory
grunt.registerTask("package", "release bundle");
This is then configured like:
relocate: {
// Files to bundle up. Can be copied into same directory structure
//files: ['*.html'],
// or relocated into a new one:
files: {'*.html': '',
'dist/release/*.css': 'assets/css/',
'dist/release/*.js': 'assets/js/libs'
},
// Folders to bundle up. Copy files and folders:
folders: ['things'],
// or relocate them:
//folders: {'things': 'thangs'},
// all locations are relative to the destination parameter.
destination: '_design/my_app/_attachments/'
}
You can see a sample application, including a full grunt.js
file using bbb
to manage client side code here. The application is also live up
on Cloudant.