diff --git a/.gitignore b/.gitignore index d007dee..71ee06b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ dist-compiled/* src/*.html src/*.js src/*.css +tmp/ diff --git a/bin/activate b/bin/activate index f42a42b..d074497 100644 --- a/bin/activate +++ b/bin/activate @@ -1,4 +1,8 @@ #!/bin/bash + +# /bin comes before /node_modules/.bin because sometimes I want to +# override the behaviors provided. + PROJECT_ROOT=`pwd` PATH="$PROJECT_ROOT/bin:$PROJECT_ROOT/node_modules/.bin:$PATH" export PATH diff --git a/grunt.coffee b/grunt.coffee new file mode 100644 index 0000000..8b14515 --- /dev/null +++ b/grunt.coffee @@ -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: "" + 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: "" + 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}" \ No newline at end of file diff --git a/grunt.js b/grunt.js index 4dd557f..55f2a88 100644 --- a/grunt.js +++ b/grunt.js @@ -1,209 +1,261 @@ -/* mode:javascript; tab-width:2; indent-tabs-mode:nil; */ -/*global module:false*/ +var COFFEE_TO_JS, DIST, HAML_TO_HTML, HAML_TO_JS, LESS_TO_CSS, async, coffee, fs, path, _und; -var path, _und, async; +path = require("path"); -path = require('path'); -_und = require('underscore'); -async = require('async'); -fs = require('fs'); +_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 = function(grunt) { - - grunt.loadNpmTasks('grunt-coffee'); - grunt.loadNpmTasks('grunt-recess'); - grunt.loadNpmTasks('grunt-requirejs'); - - // Project configuration. - grunt.initConfig({ - pkg: '', - 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: '', - tasks: 'lint qunit' - }, - server: { - port: 8081, - base: './dist/' - }, - haml: { - src: ['src/**/*.haml'], - dest: './src' - }, - templatize: { - src: ['src/**/*_tmpl.html'], - dest: './src' - }, - coffee: { - dev: { - src: ['src/**/*.coffee'], - dest: 'src', - options: { - bare: false - } - } - }, - 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' - }, - recess: { - dev: { - src: ['src/style.less'], - dest: 'src/style.css', - options: { - compile: true - } - } - }, - mocha: { - src: ['test/*_mocha.coffee'] - }, - uglify: {} - }); - - // Default task. - grunt.registerTask('default', 'lint qunit concat min'); - - grunt.registerHelper('haml', function(src, dest, done) { - var args = { - cmd: 'haml', - args: ["--unix-newlines", "--no-escape-attrs", "--double-quote-attributes", src] - }; - grunt.utils.spawn(args, function(err, result) { - if (err) console.log(err); - var out = path.basename(src, '.haml'); - grunt.file.write(path.join(dest, out + '.html'), result.stdout); - done(); - }); - }); - - grunt.registerTask('haml', 'Compile HAML', function() { - var done = this.async(), - sources = grunt.file.expandFiles(grunt.config([this.name, 'src'])), - dest = grunt.config([this.name, 'dest']); - - async.forEachSeries(sources, - function(path, cb) { grunt.helper('haml', path, dest, cb) }, - done); - }); - - grunt.registerHelper('templatize', function(src, dest, done) { - var 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.registerTask('templatize', 'Compile Underscored HTML to Javascript', function() { - var done = this.async(), - sources = grunt.file.expandFiles(grunt.config([this.name, 'src'])), - dest = grunt.config([this.name, 'dest']); - - if (sources.length === 0) { - return done(); + grunt.loadNpmTasks("grunt-coffee"); + grunt.loadNpmTasks("grunt-recess"); + grunt.loadNpmTasks("grunt-requirejs"); + grunt.initConfig({ + pkg: "", + 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: "", + 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 } - async.forEachSeries(sources, - function(path, cb) { grunt.helper('templatize', path, dest, cb); }, - done); + } + }, + 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", function(src, dest, done) { + var args; + args = { + cmd: "haml", + args: ["--unix-newlines", "--no-escape-attrs", "--double-quote-attributes", src] + }; + return grunt.utils.spawn(args, function(err, result) { + var out; + if (err) { + console.log(err); + } + out = path.basename(src, ".haml"); + grunt.file.write(path.join(dest, out + ".html"), result.stdout); + return done(); }); - - grunt.registerTask('dev', 'coffee:dev recess:dev haml templatize install'); - - grunt.registerHelper('install', function(src, dest, done) { - grunt.file.copy(src, path.join(dest, path.basename(src))); - if (done) { done(); } + }); + grunt.registerMultiTask("haml", "Compile HAML", function() { + var dest, done, sources; + done = this.async(); + sources = grunt.file.expandFiles(this.file.src); + dest = this.file.dest; + return async.forEachSeries(sources, (function(path, cb) { + return grunt.helper("haml", path, dest, cb); + }), done); + }); + grunt.registerHelper("templatize", function(src, dest, done) { + var file, out; + file = grunt.file.read(src); + out = path.basename(src, ".html"); + grunt.file.write(path.join(dest, out + ".js"), "define(" + _und.template(file).source + ");"); + return done(); + }); + grunt.registerMultiTask("templatize", "Compile Underscored HTML 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("templatize", path, dest, cb); + }), done); + }); + grunt.registerHelper("hamltojs", function(src, dest, done) { + var args; + args = { + cmd: "haml", + args: ["--unix-newlines", "--no-escape-attrs", "--double-quote-attributes", src] + }; + return grunt.utils.spawn(args, function(err, result) { + var out; + if (err) { + 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.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.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 = { - cmd: 'mocha', - args: ['--compilers', 'coffee:coffee-script', '-R', 'xunit', '-C', test] - }; - - grunt.utils.spawn(args, function(err, result) { - if (err) { - console.log(err.stderr) - done(); - return; - } - fs.appendFileSync('tmp/results.xml', result.stdout); - done(); - }); + }); + 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(); + return; + } + fs.appendFileSync("tmp/results.xml", result.stdout); + return done(); }); - - grunt.registerTask('mocha', 'Run Mocha Tests', function() { - var done = this.async(), - task = this.name, - sources = grunt.file.expandFiles(grunt.config([this.name, 'src'])), - dest = grunt.config([this.name, 'dest']); - - sources.sort(); - grunt.file.mkdir('tmp'); - fs.writeFileSync('tmp/results.xml', ''); - async.forEachSeries( - sources, - function(path, cb) { - grunt.helper('mocha', grunt.config([task, 'cmd']), path, cb); - }, - done); - }); - + }); + grunt.registerTask("mocha", "Run Mocha Tests", function() { + var dest, done, sources, task; + done = this.async(); + task = this.name; + sources = grunt.file.expandFiles(grunt.config([this.name, "src"])); + dest = grunt.config([this.name, "dest"]); + sources.sort(); + grunt.file.mkdir("tmp"); + fs.writeFileSync("tmp/results.xml", ""); + return async.forEachSeries(sources, (function(path, cb) { + return grunt.helper("mocha", grunt.config([task, "cmd"]), path, cb); + }), done); + }); + return grunt.registerTask("gruntjs", "convert grunt.coffee to grunt.js", function() { + 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); + }); };