<commit_before>#! /usr/bin/env node
/*jslint node: true */

'use strict';

var fs = require('fs'),
    log,
    path = require('path'),
    argv = require('optimist')
        .usage('Usage: dust-compiler -s|--source source_path -d|--destination destination_path [--bootstrap] [--nonotify] [--includepath]')
        .demand(['source', 'destination'])
        .alias('source', 's')
        .alias('destination', 'd')
        .describe('source', 'The source .dust templates to watch.')
        .describe('destination', 'The destination destination to write compiles .js files out to.')
        .describe('bootstrap', 'Does not replicate.  Displays the curl command that would be used.')
        .describe('nonotify', 'Do not notify.')
        .describe('includepath', 'Include the path in the name of the compiled dust template.')
        .argv,
    dust = require('dustjs-linkedin'),
    watch = require('watch'),
    colors = require('colors'),
    mkdirp = require('mkdirp'),
    wrench = require('wrench'),
    source = argv.s.match('/$') ? path.normalize(argv.s) : path.normalize(argv.s + '/'),      // must end in slash
    destination = argv.d.match('/$') ? path.normalize(argv.d) : path.normalize(argv.d + '/'); // must end in slash


if (argv.nonotify) {
    log = console.log;
} else {
    log = (function () {
        var notifier;

        switch (process.platform) {
        case 'darwin':
            notifier = require('terminal-notifier');
            return function (message) {
                notifier(message.stripColors, {
                    title: 'Dust Compiler',
                    activate: 'com.apple.Terminal'
                });
                console.log(message);
            };

        case 'linux':
            notifier = require('notify-send');
            return function (message) {
                notifier.notify('Dust Compiler', message.stripColors);
                console.log(message);
            };

        default:
            return console.log;
        }
    }());
}


function compile(src, curr, prev) {
    var data,
        error = false,
        filename,
        basename,
        filepath,
        compileFilename;

    src = path.normalize(src);

    if (path.extname(src) === '.dust') {
        fs.stat(src, function (err, stat) {
            if (err) {
                log('[ERROR]'.red + ' fs.stat');
                throw err;
            }

            if (!stat.isDirectory()) {

                filename = src.substring(source.length);
                basename = filename.substring(0, filename.length - 5);
                filepath = destination + basename + '.js';
                compileFilename = argv.includepath ? source + basename : basename;

                fs.readFile(src, function (err, data) {
                    if (err) {
                        log('[ERROR]'.red + ' fs.readFile');
                        throw err;
                    }

                    try {
                        data = dust.compile(data.toString(), compileFilename);
                    } catch (e) {
                        error = true;
                        log(e);
                    }

                    if (!error) {
                        mkdirp.mkdirp(path.dirname(filepath), function (err) {
                            if (err) {
                                log('[ERROR]'.red + ' mkdirp.mkdirp: ' + err);
                                throw err;
                            }

                            fs.writeFile(filepath, data, function (err) {
                                if (err) {
                                    log('[ERROR]'.red + ' fs.writeFile: ' + err);
                                    throw err;
                                }
                                log('Compiled '.green + source + filename + ' as '.green + compileFilename);
                            });
                        });
                    }
                });
            }
        });
    }
}



if (argv.bootstrap) {
    wrench.readdirRecursive(source, function (error, fileList) {
        if (fileList) {
            fileList.forEach(function (filename) {
                compile(source + filename);
            });
        }
    });
}


if (!fs.existsSync(source)) {
    console.log('[ERROR]'.red + ' ' + source + ' does not exist');
    process.exit();
}


if (!fs.existsSync(destination)) {
    console.log('[ERROR]'.red + ' ' + destination + ' does not exist');
    process.exit();
}


watch.createMonitor(source, function (monitor) {
    log('Watching '.green + source);
    log('Will write to '.yellow + destination.yellow);
    log('Type ^C to cancel'.yellow);

    monitor.on('created', compile);
    monitor.on('changed', compile);
});<commit_msg>Fixes #10 - clearer messaging on compile errors<commit_after>#! /usr/bin/env node
/*jslint node: true */

'use strict';

var fs = require('fs'),
    log,
    path = require('path'),
    argv = require('optimist')
        .usage('Usage: dust-compiler -s|--source source_path -d|--destination destination_path [--bootstrap] [--nonotify] [--includepath]')
        .demand(['source', 'destination'])
        .alias('source', 's')
        .alias('destination', 'd')
        .describe('source', 'The source .dust templates to watch.')
        .describe('destination', 'The destination destination to write compiles .js files out to.')
        .describe('bootstrap', 'Does not replicate.  Displays the curl command that would be used.')
        .describe('nonotify', 'Do not notify.')
        .describe('includepath', 'Include the path in the name of the compiled dust template.')
        .argv,
    dust = require('dustjs-linkedin'),
    watch = require('watch'),
    colors = require('colors'),
    mkdirp = require('mkdirp'),
    wrench = require('wrench'),
    sourcePath = argv.s.match('/$') ? path.normalize(argv.s) : path.normalize(argv.s + '/'),      // must end in slash
    destinationPath = argv.d.match('/$') ? path.normalize(argv.d) : path.normalize(argv.d + '/'); // must end in slash


if (argv.nonotify) {
    log = console.log;
} else {
    log = (function () {
        var notifier;

        switch (process.platform) {
        case 'darwin':
            notifier = require('terminal-notifier');
            return function (message) {
                notifier(message.stripColors, {
                    title: 'Dust Compiler',
                    activate: 'com.apple.Terminal'
                });
                console.log(message);
            };

        case 'linux':
            notifier = require('notify-send');
            return function (message) {
                notifier.notify('Dust Compiler', message.stripColors);
                console.log(message);
            };

        default:
            return console.log;
        }
    }());
}


function compile(source, currentStat, previousStat) {
    var data,
        errorFlag = false,
        filename,
        basename,
        filepath,
        compileFilename;

    source = path.normalize(source);

    if (path.extname(source) === '.dust') {
        fs.stat(source, function (error, stat) {
            if (error) {
                log('ERROR: '.red + 'fs.stat: ' + error.message);
                throw error;
            }

            if (!stat.isDirectory()) {

                filename = source.substring(sourcePath.length);
                basename = filename.substring(0, filename.length - 5);
                filepath = destinationPath + basename + '.js';
                compileFilename = argv.includepath ? sourcePath + basename : basename;

                fs.readFile(source, function (error, data) {
                    if (error) {
                        log('ERROR: '.red + 'fs.readFile: ' + error.message);
                        throw error;
                    }

                    try {
                        data = dust.compile(data.toString(), compileFilename);
                    } catch (err) {
                        /* error is passed into fs.readFile, so this catch can't be on error */
                        errorFlag = true;
                        log('ERROR: '.red + compileFilename.red + ': ' + err.message);
                    }

                    if (!errorFlag) {
                        mkdirp.mkdirp(path.dirname(filepath), function (error) {
                            if (error) {
                                log('ERROR: '.red + 'mkdirp.mkdirp: ' + error.message);
                                throw error;
                            }

                            fs.writeFile(filepath, data, function (error) {
                                if (error) {
                                    log('ERROR: '.red + 'fs.writeFile: ' + error.message);
                                    throw error;
                                }
                                log('Compiled '.green + sourcePath + filename + ' as '.green + compileFilename);
                            });
                        });
                    }
                });
            }
        });
    }
}



if (argv.bootstrap) {
    wrench.readdirRecursive(sourcePath, function (error, fileList) {
        if (fileList) {
            fileList.forEach(function (filename) {
                compile(sourcePath + filename);
            });
        }
    });
}


if (!fs.existsSync(sourcePath)) {
    console.log('ERROR: '.red + sourcePath + ' does not exist');
    process.exit();
}


if (!fs.existsSync(destinationPath)) {
    console.log('ERROR: '.red + destinationPath + ' does not exist');
    process.exit();
}


watch.createMonitor(sourcePath, function (monitor) {
    log('Watching '.green + sourcePath);
    log('Will write to '.yellow + destinationPath.yellow);
    log('Type ^C to cancel'.yellow);

    monitor.on('created', compile);
    monitor.on('changed', compile);
});
{'fraction_non_alphanumeric': 0.13595288861813382, 'fraction_numerical': 0.0006091989034419738, 'mean_word_length': 1.4905183312262957, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6295569', 'n_tokens_mistral': 2692, 'n_tokens_neox': 2543, 'n_words': 595}