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"
+ }
+}