gruntjs written in coffee. Nice.

This commit is contained in:
Elf M. Sternberg 2012-07-14 10:43:43 -07:00
parent d216dd89bd
commit 02b6a3fc52
4 changed files with 517 additions and 199 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ dist-compiled/*
src/*.html src/*.html
src/*.js src/*.js
src/*.css src/*.css
tmp/

View File

@ -1,4 +1,8 @@
#!/bin/bash #!/bin/bash
# /bin comes before /node_modules/.bin because sometimes I want to
# override the behaviors provided.
PROJECT_ROOT=`pwd` PROJECT_ROOT=`pwd`
PATH="$PROJECT_ROOT/bin:$PROJECT_ROOT/node_modules/.bin:$PATH" PATH="$PROJECT_ROOT/bin:$PROJECT_ROOT/node_modules/.bin:$PATH"
export PATH export PATH

261
grunt.coffee Normal file
View File

@ -0,0 +1,261 @@
path = require("path")
_und = require("underscore")
async = require("async")
fs = require("fs")
coffee = require('coffee-script')
HAML_TO_HTML = ['src/index.haml']
HAML_TO_JS = ['src/*_tmpl.haml']
LESS_TO_CSS = ['src/*.less']
COFFEE_TO_JS = ['src/*.coffee']
DIST = "./dist"
module.exports = (grunt) ->
grunt.loadNpmTasks "grunt-coffee"
grunt.loadNpmTasks "grunt-recess"
grunt.loadNpmTasks "grunt-requirejs"
grunt.initConfig
pkg: "<json:PriorityIgnore.json>"
meta:
banner: "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - " + "<%= grunt.template.today(\"yyyy-mm-dd\") %>\n" + "<%= pkg.homepage ? \"* \" + pkg.homepage + \"\n\" : \"\" %>" + "* Copyright (c) <%= grunt.template.today(\"yyyy\") %> <%= pkg.author.name %>;" + " Licensed <%= _.pluck(pkg.licenses, \"type\").join(\", \") %> */"
qunit:
files: [ "test/**/*.html" ]
lint:
files: [ "grunt.js", "src/**/*.js", "test/**/*.js" ]
watch:
files: "<config:lint.files>"
tasks: "lint qunit"
server:
port: 8081
base: DIST
haml:
dev:
src: HAML_TO_HTML
dest: DIST
hamltojs:
dev:
src: HAML_TO_JS
dest: DIST
coffee:
dev:
src: COFFEE_TO_JS
dest: DIST
options:
bare: false
recess:
dev:
src: LESS_TO_CSS
dest: path.join(DIST, '/style.css')
options:
compile: true
jshint:
options:
curly: true
eqeqeq: true
immed: true
latedef: true
newcap: true
noarg: true
sub: true
undef: true
boss: true
eqnull: true
browser: true
globals:
jQuery: true
requirejs:
dir: "dist-compiled"
appDir: "dist"
baseUrl: "."
paths:
jquery: "../libs/jquery/jquery-1.7.2"
pragmas:
doExclude: true
modules: [ name: "priority" ]
skipModuleInsertion: false
optimizeAllPluginResources: true
findNestedDependencies: true
install:
src: [
"src/index.html"
"src/priority.js"
"src/*_tmpl.js"
"src/style.css"
"libs/jquery/jquery-1.7.2.js"
"libs/require.js"
]
dest: "dist"
mocha:
src: [ "test/*_mocha.coffee" ]
uglify: {}
grunt.registerTask "default", "coffee:dev recess:dev haml:dev hamltojs:dev"
# _ _ _ __ __ _ _ _ _ _____ __ __ _
# | || | /_\ | \/ | | | |_ ___ | || |_ _| \/ | |
# | __ |/ _ \| |\/| | |__ | _/ _ \ | __ | | | | |\/| | |__
# |_||_/_/ \_\_| |_|____| \__\___/ |_||_| |_| |_| |_|____|
#
grunt.registerHelper "haml", (src, dest, done) ->
args =
cmd: "haml"
args: [ "--unix-newlines", "--no-escape-attrs", "--double-quote-attributes", src ]
grunt.utils.spawn args, (err, result) ->
console.log err if err
out = path.basename(src, ".haml")
grunt.file.write path.join(dest, out + ".html"), result.stdout
done()
grunt.registerMultiTask "haml", "Compile HAML", ->
done = @async()
sources = grunt.file.expandFiles(this.file.src)
dest = this.file.dest
async.forEachSeries sources, ((path, cb) ->
grunt.helper "haml", path, dest, cb
), done
# _ _ _____ __ __ _ _ _ ___
# | || |_ _| \/ | | | |_ ___ _ | / __|
# | __ | | | | |\/| | |__ | _/ _ \ | || \__ \
# |_||_| |_| |_| |_|____| \__\___/ \__/|___/
#
grunt.registerHelper "templatize", (src, dest, done) ->
file = grunt.file.read(src)
out = path.basename(src, ".html")
grunt.file.write path.join(dest, out + ".js"), "define(" + _und.template(file).source + ");"
done()
grunt.registerMultiTask "templatize", "Compile Underscored HTML to Javascript", ->
done = @async()
sources = grunt.file.expandFiles(this.file.src)
dest = this.file.dest
return done() if sources.length is 0
async.forEachSeries sources, ((path, cb) ->
grunt.helper "templatize", path, dest, cb
), done
# _ _ _ __ __ _ _ _ ___
# | || | /_\ | \/ | | | |_ ___ _ | / __|
# | __ |/ _ \| |\/| | |__ | _/ _ \ | || \__ \
# |_||_/_/ \_\_| |_|____| \__\___/ \__/|___/
#
grunt.registerHelper "hamltojs", (src, dest, done) ->
args =
cmd: "haml"
args: [ "--unix-newlines", "--no-escape-attrs", "--double-quote-attributes", src ]
grunt.utils.spawn args, (err, result) ->
console.log err if err
out = path.basename(src, ".haml")
grunt.file.write path.join(dest, out + ".js"), "define(" + _und.template(result.stdout).source + ");"
done()
grunt.registerMultiTask "hamltojs", "Compile Underscored HAML to Javascript", ->
done = @async()
sources = grunt.file.expandFiles(this.file.src)
dest = this.file.dest
return done() if sources.length is 0
async.forEachSeries sources, ((path, cb) ->
grunt.helper "hamltojs", path, dest, cb
), done
# ___
# / __|___ _ __ _ _
# | (__/ _ \ '_ \ || |
# \___\___/ .__/\_, |
# |_| |__/
grunt.registerHelper "install", (src, dest, done) ->
grunt.file.copy src, path.join(dest, path.basename(src))
done() if done
grunt.registerTask "install", ->
sources = grunt.file.expandFiles(grunt.config([ @name, "src" ]))
dest = grunt.config([ @name, "dest" ])
sources.forEach (path) ->
grunt.helper "install", path, dest, null
# __ __ _ _____ _
# | \/ |___ __| |_ __ _ |_ _|__ __| |_ ___
# | |\/| / _ \/ _| ' \/ _` | | |/ -_|_-< _(_-<
# |_| |_\___/\__|_||_\__,_| |_|\___/__/\__/__/
#
grunt.registerHelper "mocha", (command, test, done) ->
args =
cmd: "mocha"
args: [ "--compilers", "coffee:coffee-script", "-R", "xunit", "-C", test ]
grunt.utils.spawn args, (err, result) ->
if err
console.log err.stderr
done()
return
fs.appendFileSync "tmp/results.xml", result.stdout
done()
grunt.registerTask "mocha", "Run Mocha Tests", ->
done = @async()
task = @name
sources = grunt.file.expandFiles(grunt.config([ @name, "src" ]))
dest = grunt.config([ @name, "dest" ])
sources.sort()
grunt.file.mkdir "tmp"
fs.writeFileSync "tmp/results.xml", ""
async.forEachSeries sources, ((path, cb) ->
grunt.helper "mocha", grunt.config([ task, "cmd" ]), path, cb
), done
# ___ _ ___ __ __
# / __|_ _ _ _ _ _| |_ / __|___ / _|/ _|___ ___
# | (_ | '_| || | ' \ _| (__/ _ \ _| _/ -_) -_)
# \___|_| \_,_|_||_\__|\___\___/_| |_| \___\___|
#
grunt.registerTask "gruntjs", "convert grunt.coffee to grunt.js", ->
jFileName = path.join __dirname, "grunt.js"
cFileName = path.join __dirname, "grunt.coffee"
jStat = fs.statSync jFileName
cStat = fs.statSync cFileName
jmTime = jStat.mtime
cmTime = cStat.mtime
if cmTime < jmTime
grunt.verbose.writeln "grunt.js newer than grunt.coffee, skipping compile"
return
cSource = fs.readFileSync cFileName, "utf-8"
try
jSource = coffee.compile cSource,
bare: true
catch e
grunt.fail.fatal e
fs.writeFileSync jFileName, jSource, "utf-8"
grunt.log.writeln "compiled #{cFileName} to #{jFileName}"

312
grunt.js
View File

@ -1,60 +1,78 @@
/* mode:javascript; tab-width:2; indent-tabs-mode:nil; */ var COFFEE_TO_JS, DIST, HAML_TO_HTML, HAML_TO_JS, LESS_TO_CSS, async, coffee, fs, path, _und;
/*global module:false*/
var path, _und, async; path = require("path");
path = require('path'); _und = require("underscore");
_und = require('underscore');
async = require('async'); async = require("async");
fs = require('fs');
fs = require("fs");
coffee = require('coffee-script');
HAML_TO_HTML = ['src/index.haml'];
HAML_TO_JS = ['src/*_tmpl.haml'];
LESS_TO_CSS = ['src/*.less'];
COFFEE_TO_JS = ['src/*.coffee'];
DIST = "./dist";
module.exports = function(grunt) { module.exports = function(grunt) {
grunt.loadNpmTasks("grunt-coffee");
grunt.loadNpmTasks('grunt-coffee'); grunt.loadNpmTasks("grunt-recess");
grunt.loadNpmTasks('grunt-recess'); grunt.loadNpmTasks("grunt-requirejs");
grunt.loadNpmTasks('grunt-requirejs');
// Project configuration.
grunt.initConfig({ grunt.initConfig({
pkg: '<json:PriorityIgnore.json>', pkg: "<json:PriorityIgnore.json>",
meta: { meta: {
banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + banner: "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - " + "<%= grunt.template.today(\"yyyy-mm-dd\") %>\n" + "<%= pkg.homepage ? \"* \" + pkg.homepage + \"\n\" : \"\" %>" + "* Copyright (c) <%= grunt.template.today(\"yyyy\") %> <%= pkg.author.name %>;" + " Licensed <%= _.pluck(pkg.licenses, \"type\").join(\", \") %> */"
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
}, },
qunit: { qunit: {
files: ['test/**/*.html'] files: ["test/**/*.html"]
}, },
lint: { lint: {
files: ['grunt.js', 'src/**/*.js', 'test/**/*.js'] files: ["grunt.js", "src/**/*.js", "test/**/*.js"]
}, },
watch: { watch: {
files: '<config:lint.files>', files: "<config:lint.files>",
tasks: 'lint qunit' tasks: "lint qunit"
}, },
server: { server: {
port: 8081, port: 8081,
base: './dist/' base: DIST
}, },
haml: { haml: {
src: ['src/**/*.haml'], dev: {
dest: './src' src: HAML_TO_HTML,
dest: DIST
}
}, },
templatize: { hamltojs: {
src: ['src/**/*_tmpl.html'], dev: {
dest: './src' src: HAML_TO_JS,
dest: DIST
}
}, },
coffee: { coffee: {
dev: { dev: {
src: ['src/**/*.coffee'], src: COFFEE_TO_JS,
dest: 'src', dest: DIST,
options: { options: {
bare: false bare: false
} }
} }
}, },
recess: {
dev: {
src: LESS_TO_CSS,
dest: path.join(DIST, '/style.css'),
options: {
compile: true
}
}
},
jshint: { jshint: {
options: { options: {
curly: true, curly: true,
@ -68,142 +86,176 @@ module.exports = function(grunt) {
boss: true, boss: true,
eqnull: true, eqnull: true,
browser: true browser: true
}
}, },
globals: { globals: {
jQuery: true jQuery: true
}
}, },
requirejs: { requirejs: {
dir: 'dist-compiled', dir: "dist-compiled",
appDir: 'dist', appDir: "dist",
baseUrl: '.', baseUrl: ".",
paths: { paths: {
jquery : '../libs/jquery/jquery-1.7.2' jquery: "../libs/jquery/jquery-1.7.2"
}, },
pragmas: { pragmas: {
doExclude: true doExclude: true
}, },
modules: [{name: 'priority'}], modules: [
{
name: "priority"
}
],
skipModuleInsertion: false, skipModuleInsertion: false,
optimizeAllPluginResources: true, optimizeAllPluginResources: true,
findNestedDependencies: true findNestedDependencies: true
}, },
install: { install: {
src: [ src: ["src/index.html", "src/priority.js", "src/*_tmpl.js", "src/style.css", "libs/jquery/jquery-1.7.2.js", "libs/require.js"],
'src/index.html', dest: "dist"
'src/priority.js',
'src/*_tmpl.js',
'src/style.css',
'libs/jquery/jquery-1.7.2.js',
'libs/require.js' ],
dest: 'dist'
},
recess: {
dev: {
src: ['src/style.less'],
dest: 'src/style.css',
options: {
compile: true
}
}
}, },
mocha: { mocha: {
src: ['test/*_mocha.coffee'] src: ["test/*_mocha.coffee"]
}, },
uglify: {} uglify: {}
}); });
grunt.registerTask("default", "coffee:dev recess:dev haml:dev hamltojs:dev");
// Default task. grunt.registerHelper("haml", function(src, dest, done) {
grunt.registerTask('default', 'lint qunit concat min'); var args;
args = {
grunt.registerHelper('haml', function(src, dest, done) { cmd: "haml",
var args = {
cmd: 'haml',
args: ["--unix-newlines", "--no-escape-attrs", "--double-quote-attributes", src] args: ["--unix-newlines", "--no-escape-attrs", "--double-quote-attributes", src]
}; };
grunt.utils.spawn(args, function(err, result) { return grunt.utils.spawn(args, function(err, result) {
if (err) console.log(err); var out;
var out = path.basename(src, '.haml'); if (err) {
grunt.file.write(path.join(dest, out + '.html'), result.stdout); console.log(err);
done(); }
out = path.basename(src, ".haml");
grunt.file.write(path.join(dest, out + ".html"), result.stdout);
return done();
}); });
}); });
grunt.registerMultiTask("haml", "Compile HAML", function() {
grunt.registerTask('haml', 'Compile HAML', function() { var dest, done, sources;
var done = this.async(), done = this.async();
sources = grunt.file.expandFiles(grunt.config([this.name, 'src'])), sources = grunt.file.expandFiles(this.file.src);
dest = grunt.config([this.name, 'dest']); dest = this.file.dest;
return async.forEachSeries(sources, (function(path, cb) {
async.forEachSeries(sources, return grunt.helper("haml", path, dest, cb);
function(path, cb) { grunt.helper('haml', path, dest, cb) }, }), done);
done);
}); });
grunt.registerHelper("templatize", function(src, dest, done) {
grunt.registerHelper('templatize', function(src, dest, done) { var file, out;
var file = grunt.file.read(src), file = grunt.file.read(src);
out = path.basename(src, '.html'); out = path.basename(src, ".html");
grunt.file.write(path.join(dest, out + '.js'), 'define(' + _und.template(file).source + ');'); grunt.file.write(path.join(dest, out + ".js"), "define(" + _und.template(file).source + ");");
done(); return done();
}); });
grunt.registerMultiTask("templatize", "Compile Underscored HTML to Javascript", function() {
grunt.registerTask('templatize', 'Compile Underscored HTML to Javascript', function() { var dest, done, sources;
var done = this.async(), done = this.async();
sources = grunt.file.expandFiles(grunt.config([this.name, 'src'])), sources = grunt.file.expandFiles(this.file.src);
dest = grunt.config([this.name, 'dest']); dest = this.file.dest;
if (sources.length === 0) { if (sources.length === 0) {
return done(); return done();
} }
async.forEachSeries(sources, return async.forEachSeries(sources, (function(path, cb) {
function(path, cb) { grunt.helper('templatize', path, dest, cb); }, return grunt.helper("templatize", path, dest, cb);
done); }), done);
}); });
grunt.registerHelper("hamltojs", function(src, dest, done) {
grunt.registerTask('dev', 'coffee:dev recess:dev haml templatize install'); var args;
args = {
grunt.registerHelper('install', function(src, dest, done) { cmd: "haml",
grunt.file.copy(src, path.join(dest, path.basename(src))); args: ["--unix-newlines", "--no-escape-attrs", "--double-quote-attributes", src]
if (done) { done(); }
});
grunt.registerTask('install', function() {
var sources = grunt.file.expandFiles(grunt.config([this.name, 'src'])),
dest = grunt.config([this.name, 'dest']);
sources.forEach(function(path) { grunt.helper('install', path, dest, null);});
});
grunt.registerHelper('mocha', function(command, test, done) {
var args = {
cmd: 'mocha',
args: ['--compilers', 'coffee:coffee-script', '-R', 'xunit', '-C', test]
}; };
return grunt.utils.spawn(args, function(err, result) {
grunt.utils.spawn(args, function(err, result) { var out;
if (err) { if (err) {
console.log(err.stderr) console.log(err);
}
out = path.basename(src, ".haml");
grunt.file.write(path.join(dest, out + ".js"), "define(" + _und.template(result.stdout).source + ");");
return done();
});
});
grunt.registerMultiTask("hamltojs", "Compile Underscored HAML to Javascript", function() {
var dest, done, sources;
done = this.async();
sources = grunt.file.expandFiles(this.file.src);
dest = this.file.dest;
if (sources.length === 0) {
return done();
}
return async.forEachSeries(sources, (function(path, cb) {
return grunt.helper("hamltojs", path, dest, cb);
}), done);
});
grunt.registerHelper("install", function(src, dest, done) {
grunt.file.copy(src, path.join(dest, path.basename(src)));
if (done) {
return done();
}
});
grunt.registerTask("install", function() {
var dest, sources;
sources = grunt.file.expandFiles(grunt.config([this.name, "src"]));
dest = grunt.config([this.name, "dest"]);
return sources.forEach(function(path) {
return grunt.helper("install", path, dest, null);
});
});
grunt.registerHelper("mocha", function(command, test, done) {
var args;
args = {
cmd: "mocha",
args: ["--compilers", "coffee:coffee-script", "-R", "xunit", "-C", test]
};
return grunt.utils.spawn(args, function(err, result) {
if (err) {
console.log(err.stderr);
done(); done();
return; return;
} }
fs.appendFileSync('tmp/results.xml', result.stdout); fs.appendFileSync("tmp/results.xml", result.stdout);
done(); return done();
}); });
}); });
grunt.registerTask("mocha", "Run Mocha Tests", function() {
grunt.registerTask('mocha', 'Run Mocha Tests', function() { var dest, done, sources, task;
var done = this.async(), done = this.async();
task = this.name, task = this.name;
sources = grunt.file.expandFiles(grunt.config([this.name, 'src'])), sources = grunt.file.expandFiles(grunt.config([this.name, "src"]));
dest = grunt.config([this.name, 'dest']); dest = grunt.config([this.name, "dest"]);
sources.sort(); sources.sort();
grunt.file.mkdir('tmp'); grunt.file.mkdir("tmp");
fs.writeFileSync('tmp/results.xml', ''); fs.writeFileSync("tmp/results.xml", "");
async.forEachSeries( return async.forEachSeries(sources, (function(path, cb) {
sources, return grunt.helper("mocha", grunt.config([task, "cmd"]), path, cb);
function(path, cb) { }), done);
grunt.helper('mocha', grunt.config([task, 'cmd']), path, cb); });
}, return grunt.registerTask("gruntjs", "convert grunt.coffee to grunt.js", function() {
done); var cFileName, cSource, cStat, cmTime, jFileName, jSource, jStat, jmTime;
jFileName = path.join(__dirname, "grunt.js");
cFileName = path.join(__dirname, "grunt.coffee");
jStat = fs.statSync(jFileName);
cStat = fs.statSync(cFileName);
jmTime = jStat.mtime;
cmTime = cStat.mtime;
if (cmTime < jmTime) {
grunt.verbose.writeln("grunt.js newer than grunt.coffee, skipping compile");
return;
}
cSource = fs.readFileSync(cFileName, "utf-8");
try {
jSource = coffee.compile(cSource, {
bare: true
});
} catch (e) {
grunt.fail.fatal(e);
}
fs.writeFileSync(jFileName, jSource, "utf-8");
return grunt.log.writeln("compiled " + cFileName + " to " + jFileName);
}); });
}; };