<commit_before>var path = require('path'),
    _ = require('underscore'),
    async = require('async'),
    urlTools = require('urltools'),
    passError = require('passerror'),
    AssetGraph = require('../');

module.exports = function (queryObj) {
    var less;
    try {
        less = require('less');
    } catch (e) {
        throw new Error('transforms.compileLessToCss: The "less" module is required. Please run "npm install less" and try again (tested with version 1.5.1).');
    }

    return function compileLessToCss(assetGraph, cb) {
        async.each(assetGraph.findAssets(_.extend({type: 'Less'}, queryObj)), function (lessAsset, cb) {
            var lessOptions = {relativeUrls: true},
                nonInlineAncestor = lessAsset.nonInlineAncestor;
                // If the Less asset has a file:// url, add its directory to the Less parser's search path
            // so @import statements work:
            if (/^file:/.test(nonInlineAncestor.url)) {
                lessOptions.paths = [path.dirname(urlTools.fileUrlToFsPath(nonInlineAncestor.url))];
            }
            try {
                less.render(lessAsset.text, lessOptions, passError(cb, function (cssText) {
                    var cssAsset = new AssetGraph.Css({
                        text: cssText
                    });
                    if (lessAsset.url) {
                        cssAsset.url = lessAsset.url.replace(/\.less$|$/, cssAsset.defaultExtension);
                    }
                    lessAsset.replaceWith(cssAsset);
                    cssAsset.incomingRelations.forEach(function (incomingRelation) {
                        if (incomingRelation.type === 'HtmlStyle') {
                            var relAttributeValue = incomingRelation.node.getAttribute('rel');
                            if (relAttributeValue) {
                                incomingRelation.node.setAttribute('rel', relAttributeValue.replace(/\bstylesheet\/less\b/, 'stylesheet'));
                                incomingRelation.from.markDirty();
                            }
                        }
                    });
                    cb();
                }));
            } catch (e) {
                cb(new Error('Less compiler threw an exception: ' + require('util').inspect(e)));
            }
        }, cb);
    };
};
<commit_msg>compileLessToCss: Only try to load the less compiler if less assets are actually found.<commit_after>/*global setImmediate:true*/
// node 0.8 compat
if (typeof setImmediate === 'undefined') {
    setImmediate = process.nextTick;
}

var path = require('path'),
    _ = require('underscore'),
    async = require('async'),
    urlTools = require('urltools'),
    passError = require('passerror'),
    AssetGraph = require('../');

module.exports = function (queryObj) {
    return function compileLessToCss(assetGraph, cb) {
        var less,
            lessAssets = assetGraph.findAssets(_.extend({type: 'Less'}, queryObj));
        if (lessAssets.length > 0) {
            try {
                less = require('less');
            } catch (e) {
                assetGraph.emit('warn', new Error('compileLessToCss: Found ' + lessAssets.length + ' less asset(s), but no less compiler is available. Please install less in your project so compileLessToCss can require it.'));
                return setImmediate(cb);
            }
        }
        async.each(lessAssets, function (lessAsset, cb) {
            var lessOptions = {relativeUrls: true},
                nonInlineAncestor = lessAsset.nonInlineAncestor;
                // If the Less asset has a file:// url, add its directory to the Less parser's search path
            // so @import statements work:
            if (/^file:/.test(nonInlineAncestor.url)) {
                lessOptions.paths = [path.dirname(urlTools.fileUrlToFsPath(nonInlineAncestor.url))];
            }
            try {
                less.render(lessAsset.text, lessOptions, passError(cb, function (cssText) {
                    var cssAsset = new AssetGraph.Css({
                        text: cssText
                    });
                    if (lessAsset.url) {
                        cssAsset.url = lessAsset.url.replace(/\.less$|$/, cssAsset.defaultExtension);
                    }
                    lessAsset.replaceWith(cssAsset);
                    cssAsset.incomingRelations.forEach(function (incomingRelation) {
                        if (incomingRelation.type === 'HtmlStyle') {
                            var relAttributeValue = incomingRelation.node.getAttribute('rel');
                            if (relAttributeValue) {
                                incomingRelation.node.setAttribute('rel', relAttributeValue.replace(/\bstylesheet\/less\b/, 'stylesheet'));
                                incomingRelation.from.markDirty();
                            }
                        }
                    });
                    cb();
                }));
            } catch (e) {
                cb(new Error('Less compiler threw an exception: ' + require('util').inspect(e)));
            }
        }, cb);
    };
};

{'fraction_non_alphanumeric': 0.11620198869175277, 'fraction_numerical': 0.0011698186781048938, 'mean_word_length': 1.65527950310559, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2212507', 'n_tokens_mistral': 1338, 'n_tokens_neox': 1288, 'n_words': 287}