<commit_before>
var Proteus = require("proteus"),
    FS      = require("fs"),
    Path    = require("path"),
    nutil   = require("util"),
    sutil   = require("sake/util"),
    Task    = require("sake/task"),
    log     = require("sake/logger"),
    DEFAULT_SAKEFILES = [
        "Sakefile", "sakefile", "Sakefile.js", "sakefile.js",
        "Sakefile.coffee", "sakefile.coffee",
    ]
;

module.exports = {
    
    run: function () {
        var opts     = this.options,
            cmd      = opts._[0],
            taskArgs = opts._.slice(1).map(sutil.jsonToValue),
            task
        ;
        
        this.sake = require("sake");
        
        this.loadSakefile(opts.sakefile);
        
        this.processRunOptions();
        
        Task.invoke(opts.task, taskArgs);
    },
    
    processRunOptions: function () {
        var opts = this.options,
            exit = false;
        
        if (opts.listTasks) {
            this.listTasks();
            exit = true;
        }
        else if (opts.listPrereqs) {
            this.listTasksAndPrerequisites();
            exit = true;
        }
        
        if (exit) {
            process.exit(0);
        }
    },
    
    loadSakefile: function (filepath) {
        var dir;
        
        filepath = filepath || this.sakefileLocation();

        if (!Path.existsSync(filepath)) {
            throw new Error("Can not find a Sakefile.");
        }

        filepath = Path.resolve(filepath);
        this.options.sakefile = filepath;
        
        dir = Path.dirname(filepath);
        process.chdir(dir);
        log.info("sake in " + dir);

        this.sake.load(filepath);
    },
    
    sakefileLocation: function () {
        var here = process.cwd(),
            start = here,
            filename
        ;
            
        while (!(filename = this.haveSakefile(here)) && here !== "/") {
            process.chdir("..");
            here = process.cwd();
        }
        
        process.chdir(start);
        
        if (filename) {
            return Path.join(here, filename);
        }
    },
    
    haveSakefile: function (here) {
        var filenames = FS.readdirSync(here),
            len = filenames.length,
            i = 0,
            f
        ;
        
        for (; i < len; i++) {
            f = filenames[i];
            if (~DEFAULT_SAKEFILES.indexOf(f)) {
                return f;
            }
        }
    },
    
    listTasks: function () {
        var nameW = 0;
        
        log("Tasks:");
        
        Task.getAll().filter(function (task) {
            return task.description;
        }).map(function (task) {
            var name = task.name,
                len  = name.length
            ;
            
            nameW = len > nameW ? len : nameW;
            
            return {name: name, description: task.description};
        }).forEach(function (obj) {
            var name = obj.name,
                len  = name.length
            ;
            
            log(
                "  " + name +
                Array(nameW - len + 5).join(" ") + "# " +
                obj.description
            );
        });
    },
    
    listTasksAndPrerequisites: (function () {
        
        function formatTask (task, pad) {
            return (pad ? pad : "") + task.fqn + " (" + task.type + ")";
        }
        
        return function () {
            log("Tasks and Prerequisites: ");
            
            Task.getAll().forEach(function (task) {
                var preqs       = task.prerequisites,
                    pad         = "  "
                ;

                log(formatTask(task, pad));
                preqs.forEach(function (name) {
                    log(formatTask(Task.lookup(name), pad + pad));
                });
            });<commit_msg>Use a module's fully qualified name when listing tasks.<commit_after>
var Proteus = require("proteus"),
    FS      = require("fs"),
    Path    = require("path"),
    nutil   = require("util"),
    sutil   = require("sake/util"),
    Task    = require("sake/task"),
    log     = require("sake/logger"),
    DEFAULT_SAKEFILES = [
        "Sakefile", "sakefile", "Sakefile.js", "sakefile.js",
        "Sakefile.coffee", "sakefile.coffee",
    ]
;

module.exports = {
    
    run: function () {
        var opts     = this.options,
            cmd      = opts._[0],
            taskArgs = opts._.slice(1).map(sutil.jsonToValue),
            task
        ;
        
        this.sake = require("sake");
        
        this.loadSakefile(opts.sakefile);
        
        this.processRunOptions();
        
        Task.invoke(opts.task, taskArgs);
    },
    
    processRunOptions: function () {
        var opts = this.options,
            exit = false;
        
        if (opts.listTasks) {
            this.listTasks();
            exit = true;
        }
        else if (opts.listPrereqs) {
            this.listTasksAndPrerequisites();
            exit = true;
        }
        
        if (exit) {
            process.exit(0);
        }
    },
    
    loadSakefile: function (filepath) {
        var dir;
        
        filepath = filepath || this.sakefileLocation();

        if (!Path.existsSync(filepath)) {
            throw new Error("Can not find a Sakefile.");
        }

        filepath = Path.resolve(filepath);
        this.options.sakefile = filepath;
        
        dir = Path.dirname(filepath);
        process.chdir(dir);
        log.info("sake in " + dir);

        this.sake.load(filepath);
    },
    
    sakefileLocation: function () {
        var here = process.cwd(),
            start = here,
            filename
        ;
            
        while (!(filename = this.haveSakefile(here)) && here !== "/") {
            process.chdir("..");
            here = process.cwd();
        }
        
        process.chdir(start);
        
        if (filename) {
            return Path.join(here, filename);
        }
    },
    
    haveSakefile: function (here) {
        var filenames = FS.readdirSync(here),
            len = filenames.length,
            i = 0,
            f
        ;
        
        for (; i < len; i++) {
            f = filenames[i];
            if (~DEFAULT_SAKEFILES.indexOf(f)) {
                return f;
            }
        }
    },
    
    listTasks: function () {
        var nameW = 0;
        
        log("Tasks:");
        
        Task.getAll().filter(function (task) {
            return task.description;
        }).map(function (task) {
            var name = task.fqn, len  = name.length;
            nameW = len > nameW ? len : nameW;
            return task;
        }).forEach(function (t) {
            var name = t.fqn, len  = name.length;
            
            log("  " + name + Array(nameW - len + 5).join(" ") + "# " +
                t.description);
        });
    },
    
    listTasksAndPrerequisites: (function () {
        
        function formatTask (task, pad) {
            return (pad ? pad : "") + task.fqn + " (" + task.type + ")";
        }
        
        return function () {
            log("Tasks and Prerequisites: ");
            
            Task.getAll().forEach(function (task) {
                var preqs       = task.prerequisites,
                    pad         = "  "
                ;

                log(formatTask(task, pad));
                preqs.forEach(function (name) {
                    log(formatTask(Task.lookup(name), pad + pad));
                });
            });
{'fraction_non_alphanumeric': 0.12903225806451613, 'fraction_numerical': 0.0015929908403026682, 'mean_word_length': 1.2289940828402366, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '5979707', 'n_tokens_mistral': 2211, 'n_tokens_neox': 2147, 'n_words': 405}