diff --git a/README.md b/README.md index e6bb1ad..c697e2c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ Duster.js - Node script to watch & precompile directory of dustjs templates ============== +Based on the original script by Dan McGrady http://dmix.ca + A simple Node script Duster.js to watch a directory of .dust templates and compile them into .js files which can be included into an HTML file. Why? The dust.js documentation does not mentioned a clear way to work with dust templates in a purely client-side approach, instead focusing on server-side node.js applications. @@ -10,33 +12,41 @@ For my backbone.js app, the only option was to include the dust-full.js file and So I wrote a script to pre-compile dust.js files whenever they are modified in a folder. ## Install -Download duster.js to your project root folder and install dependencies: +Clone this repository + +Run the installation + $ npm install - npm install dustjs-linkedin - npm install watch-tree +Get the growl app from the App Store (*not free) or from here https://bitbucket.org/pmetzger/growl/downloads + +Be sure to install growlnotify plugin ## Usage -Create dust.js templates in ./src/dusts/ with the file extension .dust and create ./public/dusts directory where files will be compiled to, then run watcher script: +Create a file named .dusterjs in your home directory and add the input and output paths to it. The file is expected to be in YAML format - $ node duster.js +Example: -You can modify folder paths in the duster.js file + --- + input_path: /Users//src.dust/ + output_path: /Users//dust/ + +Create dust.js templates in the dir with the file extension .dust and create directory where files will be compiled to, then run watcher script: + + $ node duster.js ## Example: - ./src/dusts/tweet.dust - ./src/dusts/user.dust + /tweet.dust + /user.dust Compiles to: - ./public/dusts/tweet.js - ./public/dusts/user.js + /tweet.js + /user.js -Then you include them in the html: +## Changes by Suresh Jayanty - - - +* Added support for growl notifications -I then use Jammit to concatenate all the JS files before production deployment. +* Added support for settings file -by Dan McGrady http://dmix.ca \ No newline at end of file +* Ignoring .swp files created when some one uses vim to edit the dust files diff --git a/duster.js b/duster.js index 4b09103..d392cf3 100644 --- a/duster.js +++ b/duster.js @@ -1,32 +1,146 @@ // duster.js // Watch directory of dust.js templates and automatically compile them // by Dan McGrady http://dmix.ca +// slight modifications by Suresh Jayanty +var fs = require('fs'), + dust = require('dustjs-linkedin'), + watch = require('watch'), + yaml = require('js-yaml'), + colors = require('colors'), + childprocess = require('child_process'), + file_options = { + 'input_path': './src.dust', + 'output_path': './dust' + }, + user_settings_file = process.env['HOME'] + '/.dusterjs', + svnRegex = /\.svn/, + swpRegex = /\.swp/, + gitRegex = /\.git/ + dustRegex = /\.dust$/; -var input_path = "./dusts"; // directory of dust templates are stored with .dust file extension -var output_path = "./javascripts/dusts/"; // directory where the compiled .js files should be saved to -var fs = require('fs'); -var dust = require('dustjs-linkedin'); -var watch = require('watch'); +function growl(message, sticky) { + var command = '/usr/local/bin/growlnotify -p 1 -m "' + message + '"', + growlnotice; + if (sticky) { + command += ' -s'; + } + + growlnotice = childprocess.exec(command, function(error, stdout, stderr) {}); + growlnotice.on('exit', function(code) {}); +} function compile_dust(path, curr, prev) { - fs.readFile(path, function(err, data) { - if (err) throw err; + if (swpRegex.exec(path)) { + console.log(('Ignoring file: ' + path).red); + return; + } + if (svnRegex.exec(path)) { + console.log(('Ignoring file: ' + path).red); + return; + } + if (gitRegex.exec(path)) { + console.log(('Ignoring file: ' + path).red); + return; + } + fs.readFile(path, function(err, data) { + if (err) { + + growl('Error: ' + err + ' : ' + path , true); + throw err; + } + + var filename = path.split("/").reverse()[0].replace(".dust", ""); + var filepath = file_options.output_path + '/' + filename + ".js"; + var compiled = ''; + try { + compiled = dust.compile(new String(data), filename); - var filename = path.split("/").reverse()[0].replace(".dust", ""); - var filepath = output_path + filename + ".js"; - var compiled = dust.compile(new String(data), filename); + fs.writeFile(filepath, compiled, function(err) { + if (err) { + growl('Error: ' + err, true); + throw err; + } + console.log('Saved ' + filepath); + growl('Saved ' + filepath); + }); + } catch (err) { + growl('Error: ' + err, true); + } + }); +} + +function createMonitor() { + try { + watch.createMonitor(file_options.input_path, { + 'ignoreDotFiles': true + }, function(monitor) { + console.log("Watching " + file_options.input_path); + monitor.files['*.dust', '*/*']; + monitor.on("created", compile_dust); + monitor.on("changed", compile_dust); + }); + } catch (err) { + growl('Error: ' + err, true); + console.log(err); + } +} - fs.writeFile(filepath, compiled, function(err) { - if (err) throw err; - console.log('Saved ' + filepath); +function processCurrentFiles() { + fs.readdir(file_options.input_path, function(err, files) { + if(!err) { + files.forEach(function(filename) { + var dustFile; + if(!dustRegex.exec(filename)) { + return; + } + dustFile = filename.replace('.dust', '') + '.js'; + fs.stat(file_options.output_path + '/' + dustFile, function(err, props) { + if(err) { + console.log('file not found: ' + file_options.output_path + '/' + dustFile); + compile_dust(file_options.input_path + '/' + filename); + } + }); + }); + } }); - }); } -watch.createMonitor(input_path, function (monitor) { - console.log("Watching " + input_path); - monitor.files['*.dust', '*/*']; - monitor.on("created", compile_dust); - monitor.on("changed", compile_dust); -}) +function main() { + fs.exists(user_settings_file, function(exists) { + if (exists) { + fs.readFile(user_settings_file, 'utf8', function(err, data) { + if (err) { + return; + } + + try { + yaml.loadAll(data, function(doc) { + if (doc.input_path) { + file_options.input_path = doc.input_path; + } + if (doc.output_path) { + file_options.output_path = doc.output_path; + } + + growl('Watching ' + file_options.input_path + ' for changes'); + growl('Saving compiled templates to ' + file_options.output_path); + + processCurrentFiles(); + createMonitor(); + }); + } catch (err) { + growl('Error: ' + err, true); + } + }); + } else { + growl('Watching ' + file_options.input_path + ' for changes'); + growl('Saving compiled templates to ' + file_options.output_path); + + processCurrentFiles(); + createMonitor(); + } + }); +} + +main(); diff --git a/package.json b/package.json new file mode 100644 index 0000000..86b890e --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "dusterjs", + "description": "Duster.js - Node script to watch & precompile directory of dustjs templates", + "version": "0.0.1", + "main": "duster.js", + "dependencies": { + "dustjs-linkedin": ">= 1.1.0", + "watch": ">= 0.5.1", + "watch-tree": ">= 0.1.1", + "js-yaml": ">= 1.0.2", + "colors": ">= 0.6.0-1" + } +}