<commit_before>var fs = require("fs");
var lib = require("./lib/index");
var path = require('path');

module.exports = function (grunt) {
    grunt.task.loadNpmTasks("grunt-contrib-clean");
    grunt.task.loadNpmTasks("grunt-contrib-concat");
    grunt.task.loadNpmTasks("grunt-contrib-copy");
    grunt.task.loadNpmTasks("grunt-contrib-cssmin");
    grunt.task.loadNpmTasks("grunt-contrib-uglify");
    grunt.task.loadNpmTasks("grunt-contrib-jshint");

    //恢复已经暂存的配置信息
    grunt.task.registerTask("easy-hybrid-rescue", "clean and rescue the old config", function () {
        grunt.config.init(grunt.config.get("easy-hybrid-rescue"));
    });

    //书写文件ID，将node.js模式的代码 转化成供loader加载的代码
    grunt.task.registerTask("easy-hybrid-rename", "rename file", function () {
        var config = grunt.config.get("easy-hybrid-rename");
        var deep = config.target.split("/").length;
        var match_type = new RegExp("^(cordova-)?" + config.platform + "-(.+)$");
        var match_url = /require *\( *['"](.+?)['"] *\)/ig;
        var mapping = grunt.file.expandMapping(["**", "!source/**"], config.target, {
            cwd: config.path,
            rename: function (dest, src) {
                return dest + src.split(/\/|\\/).map(function (item) {
                    return item.replace(match_type, "$1$2").replace(".html", "-tpl.js");
                }).join("/");
            }
        });
        mapping.forEach(function (item) {
            var src = item.src[0];
            var dest = item.dest;
            var arr = dest.split(/\/|\\/);
            var basename = arr.pop();
            if (basename.indexOf(".") < 0) {
                grunt.file.mkdir(dest);
                return;
            }
            var id = ("hybrid/" + arr.slice(deep - 1).join("/") + "/" + basename.split(".")[0]).replace(/\/+/g, "/");
            grunt.file.copy(src, dest, {
                encoding: "utf8",
                process: function (content) {
                    if (/\.html$/.test(src)) {
                        content = lib.run(content);
                    }
                    var lines = content.split("\n");
                    content = "    " + lines.join("\n    ");
                    return 'define("' + id + '", function (require, exports, module) {\n' + content.replace(match_url, function () {
                        var pfix = arguments[1].replace(config.platform + "-", "").replace(".html", "-tpl");
                        if (pfix.charAt(0) === ".") {
                            return ("require(\"" + path.join(id, "..", pfix).replace(/\\/g, "/") + "\")").replace("\\", "/");
                        }
                        return "require(\"" + pfix + "\")";
                    }) + '\n});'
                }
            });
        });
    });

    //生成index.js文件
    grunt.task.registerTask("easy-hybrid-index", function () {
        var config = grunt.config.get("easy-hybrid-index");
        var src = config.path;
        //生成index.js文件
        var content = 'define("hybrid/index", function (require, exports, module) {\n';
        content += "\n    //下边为加载patch代码\n";
        var list3 = grunt.file.expand({
            cwd: src + "patch/"
        }, "*.js");
        list3.forEach(function (item) {
            content += '    require("hybrid/patch/' + item.split(".")[0] + '");\n';
        });
        content += '\n    var core = require("hybrid/core");\n';

        function quickend(type) {
            content += '\n    //下边为' + type + '注册代码\n';
            var list = grunt.file.expand({
                cwd: src + type + "/"
            }, "*.js");
            list.forEach(function (item) {
                content += '    core.register("' + type + '", require("hybrid/' + type + "/" + item.split(".")[0] + '"));\n';
            });
        }

        [ "util", "plugin", "ui"].forEach(quickend);

        content += '\n    //下边为config注册代码\n';
        content += '\n    core.config = require("hybrid/config");\n';

        content += '\n    //下边为navigation注册代码\n';
        var list4 = grunt.file.expand({
            cwd: src + "/navigation/"
        }, "*.js");
        list4.forEach(function (item) {
            var id = item.split(".")[0];
            content += '    core.registerNavigation("' + id + '", require("hybrid/navigation/' + item.split(".")[0] + '")(core));\n';
        });

        content += '\n    //下边为view注册代码\n';
        var list2 = grunt.file.expand({
            cwd: src + "/view/"
        }, "*/*.js");
        list2.forEach(function (item) {
            content += '    core.registerView("' + item.split(".")[0] + '", require("hybrid/view/' + item.split(".")[0] + '"));\n';
        });

        content += '\n    //下边为初始化项目代码\n';
        if (config.proxy) {
            content += '\n    window.devProxy = "' + config.proxy + '";\n';
        }
        if (config.native) {
            content += '    window.cordova = require("cordova");\n';
            content += '    require("cordova/exec");\n';
        }
        content += '    exports.init = require("hybrid/init")(core);\n';
        content += '});';
        grunt.file.write(config.dest, content);
    });

    //根据配置生成index.html
    grunt.task.registerTask("easy-hybrid-build", function () {
        var config = grunt.config.get("easy-hybrid-build");
        var target = config.target;
        var src = config.path;
        var css = config.sources.css;
        var js = config.sources.js;
        var content = '\n    ' +
            '\n        <meta charset="utf-8"/>' +
            '\n        <base target="_self"/>' +
            '\n        <title>' + config.name + '</title>';
        css.forEach(function (item) {
            content += '\n        <link href="' + item + '" rel="stylesheet"/>';
        });
        content += '\n    \n    ';
        js.forEach(function (item) {
            content += '\n         ';
        });
        content += '\n    \n';
        grunt.file.write(target, content);
    });

    //修复easy-hybrid-build在开发版本时的错误
    grunt.task.registerTask("easy-hybrid-fix", function () {
        var config = grunt.config.get("easy-hybrid-build");
        var target = config.target;
        var src = config.path;
        var css = config.sources.css;
        var js = config.sources.js;
        js.push("js/require.js");
        grunt.file.expand({
            cwd: src + ""
        }, "css/*.css").forEach(function (item) {
            css.push(item);
        });
        grunt.file.expand({
            cwd: src + "compress/"
        }, "**/*.js").forEach(function (item) {
            js.push("js/" + item);
        });
        js.push("js/load.js");
        var content = '\n    ' +
            '\n        <meta charset="utf-8"/>' +
            '\n        <base target="_self"/>' +
            '\n        <title>' + config.name + '</title>';
        css.forEach(function (item) {
            content += '\n        <link href="' + item + '" rel="stylesheet"/>';
        });
        content += '\n    \n    ';
        js.forEach(function (item) {
            content += '\n         ';
        });
        content += '\n    \n';
        grunt.file.write(target, content);
    });

    //用于根据配置信息对一个平台进行编译
    grunt.task.registerMultiTask("easy-hybrid-platform", "fetch each platform", function () {
        var config = this.data;
        grunt.config.init({
            "easy-hybrid-rescue": grunt.config.get(),//缓存现有文件
            copy: {
                "lib-css": {
                    files: [
                        {
                            expand: true,
                            cwd: config.lib + "css/",
                            src: ["**"],
                            dest: ".tmp/css/",
                            filter: config.filter.lib
                        }
                    ]
                },
                "lib-js": {
                    files: [
                        {
                            expand: true,
                            cwd: config.lib,
                            src: ["**", "!css/**"],
                            dest: ".tmp/js/",
                            filter: config.filter.lib
                        }
                    ]
                },
                "source-css": {
                    files: [
                        {
                            expand: true,
                            flatten: true,
                            cwd: config.src,
                            src: ["**/*.css"],
                            dest: ".tmp/css/",
                            filter: config.filter.source

                        },
                        {
                            expand: true,
                            flatten: true,
                            cwd: config.src,
                            src: ["**/img/*.*"],
                            dest: ".tmp/css/img/",
                            filter: config.filter.source

                        }
                    ]
                },
                "source-js": {
                    files: [
                        {
                            expand: true,
                            cwd: config.src,
                            src: ["**", "!**/css/**"],
                            dest: ".tmp/js/",
                            filter: config.filter.source
                        }
                    ]
                },
                "build": {
                    files: [
                        {
                            expand: true,
                            cwd: ".tmp/css/",
                            src: ["img/**"],
                            dest: config.build + "css/"
                        },
                        {
                            expand: true,
                            cwd: ".tmp/",
                            src: ["index.html"],
                            dest: config.build
                        },
                        {
                            expand: true,
                            cwd: ".tmp/js/source/" + (config.cordova ? "cordova" : "self") + "/",
                            src: config.native ? ["load.js", "require.js", "channel.js" , "cordova.js" , config.platform + "-exec.js" ] : ["load.js", "require.js"],
                            dest: ".tmp/"
                        }
                    ]
                }
            },
            "easy-hybrid-rename": {
                path: ".tmp/js/",
                platform: config.platform,
                target: ".tmp/compress/"
            },
            "easy-hybrid-index": {
                platform: config.platform,
                native: config.native,
                proxy: "",
                path: ".tmp/compress/",
                dest: ".tmp/compress/index.js"
            },
            "easy-hybrid-build": {
                path: ".tmp/",
                target: ".tmp/index.html",
                sources: config.sources,
                name: config.name
            },
            jshint: {
                all: [
                    '.tmp/compress/**/*.js'
                ],
                options: {
                    jshintrc: '.jshintrc'
                }
            },
            clean: {
                tmp: [".tmp/"],
                target: config.target
            },
            concat: {
                build: {
                    options: {
                        separator: '\n\n',
                        banner: '(function(){\n',
                        footer: '\n})();',
                        process: function (src, filepath) {
                            return '// Source: ' + filepath.replace("./tmp/compress/", "") + '\n' + src;
                        }
                    },
                    files: {
                        ".tmp/all.js": [".tmp/require.js", ".tmp/cordova.js", ".tmp/channel.js", ".tmp/" + config.platform + "-exec.js", ".tmp/compress/**/*.js", ".tmp/load.js"]
                    }
                }
            },
            uglify: {
                build: {
                    src: [".tmp/all.js"],
                    dest: config.build + "js/index.js"
                }
            },
            cssmin: {
                build: {
                    src: [".tmp/css/*.css"],
                    dest: config.build + "css/index.css"

                }
            }
        });
        var task = [
            "clean",
            "copy:lib-css",
            "copy:lib-js",
            "copy:source-css",
            "copy:source-js",
            "easy-hybrid-rename",
            "easy-hybrid-index",
            "easy-hybrid-build",
            "clean:target",
            "jshint",
            "copy:build",
            "concat",
            "uglify",
            "cssmin",
            "clean:tmp",
            "easy-hybrid-rescue"
        ];
        grunt.task.run(task);
    });

    //用于根据信息生成编译信息
    grunt.task.registerMultiTask("easy-hybrid-dev", "fetch each platform", function () {
        var config = this.data;
        if (config === false) {
            return;
        }
        grunt.config.init({
            "easy-hybrid-rescue": grunt.config.get(),//缓存现有文件
            copy: {
                "lib-css": {
                    files: [
                        {
                            expand: true,
                            cwd: config.lib + "css/",
                            src: ["**"],
                            dest: ".tmp/css/",
                            filter: config.filter.lib
                        }
                    ]
                },
                "lib-js": {
                    files: [
                        {
                            expand: true,
                            cwd: config.lib,
                            src: ["**", "!css/**"],
                            dest: ".tmp/js/",
                            filter: config.filter.lib
                        }
                    ]
                },
                "source-css": {
                    files: [
                        {
                            expand: true,
                            flatten: true,
                            cwd: config.src,
                            src: ["**/*.css"],
                            dest: ".tmp/css/",
                            filter: config.filter.source

                        },
                        {
                            expand: true,
                            flatten: true,
                            cwd: config.src,
                            src: ["**/img/*.*"],
                            dest: ".tmp/css/img/",
                            filter: config.filter.source

                        }
                    ]
                },
                "source-js": {
                    files: [
                        {
                            expand: true,
                            cwd: config.src,
                            src: ["**", "!**/css/**"],
                            dest: ".tmp/js/",
                            filter: config.filter.source
                        }
                    ]
                },
                "build": {
                    files: [
                        {
                            expand: true,
                            cwd: ".tmp/css/",
                            src: ["**"],
                            dest: config.build + "css/"
                        },
                        {
                            expand: true,
                            cwd: ".tmp/compress/",
                            src: ["**"],
                            dest: config.build + "js/"
                        },
                        {
                            expand: true,
                            cwd: ".tmp/js/source/" + (config.cordova ? "cordova" : "self") + "/",
                            src: [ "load.js", "require.js"],
                            dest: config.build + "js/"
                        },
                        {
                            expand: true,
                            cwd: ".tmp/",
                            src: ["index.html"],
                            dest: config.build
                        }
                    ]
                }
            },
            "easy-hybrid-rename": {
                path: ".tmp/js/",
                platform: config.platform,
                target: ".tmp/compress/"
            },
            "easy-hybrid-index": {
                platform: config.platform,
                native: config.native,
                proxy: config.proxy,
                path: ".tmp/compress/",
                dest: ".tmp/compress/index.js"
            },
            "easy-hybrid-build": {
                path: ".tmp/",
                target: ".tmp/index.html",
                sources: config.sources,
                name: config.name
            },
            jshint: {
                all: [
                    '.tmp/compress/**/*.js'
                ],
                options: {
                    jshintrc: '.jshintrc'
                }
            },
            clean: {
                tmp: [".tmp/"],
                target: config.target
            }
        });
        var task = [
            "copy:lib-css",
            "copy:lib-js",
            "copy:source-css",
            "copy:source-js",
            "easy-hybrid-rename",
            "easy-hybrid-index",
            "easy-hybrid-fix",
            "clean:target",
            "jshint",
            "copy:build",
            "clean:tmp",
            "easy-hybrid-rescue"
        ];
        grunt.task.run(task);
    });

    //入口函数，用于产生新的配置文件，并对文件进行处理
    grunt.task.registerMultiTask("hybrid", "an javascript development approach base on cordova-js", function () {
        var me = this;
        //重新生成请求参数
        grunt.config.init({
            "easy-hybrid-rescue": grunt.config.get(),//缓存现有文件
            "easy-hybrid-platform": lib.platformInit(me.target, me.data)
        });
        var task = ["easy-hybrid-platform"];
        var dev = lib.developInit(me.target, me.data);
        if (dev) {
            grunt.config.set("easy-hybrid-dev", {
                dev: dev
            });
            task.push("easy-hybrid-dev");
        }
        task.push("easy-hybrid-rescue");
        grunt.task.run(task);
    });
};
<commit_msg>update to version 0.1.5<commit_after>var fs = require("fs");
var lib = require("./lib/index");
var path = require('path');

module.exports = function (grunt) {
    grunt.task.loadNpmTasks("grunt-contrib-clean");
    grunt.task.loadNpmTasks("grunt-contrib-concat");
    grunt.task.loadNpmTasks("grunt-contrib-copy");
    grunt.task.loadNpmTasks("grunt-contrib-cssmin");
    grunt.task.loadNpmTasks("grunt-contrib-uglify");
    grunt.task.loadNpmTasks("grunt-contrib-jshint");

    //恢复已经暂存的配置信息
    grunt.task.registerTask("easy-hybrid-rescue", "clean and rescue the old config", function () {
        grunt.config.init(grunt.config.get("easy-hybrid-rescue"));
    });

    //书写文件ID，将node.js模式的代码 转化成供loader加载的代码
    grunt.task.registerTask("easy-hybrid-rename", "rename file", function () {
        var config = grunt.config.get("easy-hybrid-rename");
        var deep = config.target.split("/").length;
        var match_type = new RegExp("^(cordova-)?" + config.platform + "-(.+)$");
        var match_url = /require *\( *['"](.+?)['"] *\)/ig;
        var mapping = grunt.file.expandMapping(["**", "!source/**"], config.target, {
            cwd: config.path,
            rename: function (dest, src) {
                return dest + src.split(/\/|\\/).map(function (item) {
                    return item.replace(match_type, "$1$2").replace(".html", "-tpl.js");
                }).join("/");
            }
        });
        mapping.forEach(function (item) {
            var src = item.src[0];
            var dest = item.dest;
            var arr = dest.split(/\/|\\/);
            var basename = arr.pop();
            if (basename.indexOf(".") < 0) {
                grunt.file.mkdir(dest);
                return;
            }
            var id = ("hybrid/" + arr.slice(deep - 1).join("/") + "/" + basename.split(".")[0]).replace(/\/+/g, "/");
            grunt.file.copy(src, dest, {
                encoding: "utf8",
                process: function (content) {
                    if (/\.html$/.test(src)) {
                        content = lib.run(content);
                    }
                    var lines = content.split("\n");
                    content = "    " + lines.join("\n    ");
                    return 'define("' + id + '", function (require, exports, module) {\n' + content.replace(match_url, function () {
                        var pfix = arguments[1].replace(config.platform + "-", "").replace(".html", "-tpl");
                        if (pfix.charAt(0) === ".") {
                            return ("require(\"" + path.join(id, "..", pfix).replace(/\\/g, "/") + "\")").replace("\\", "/");
                        }
                        return "require(\"" + pfix + "\")";
                    }) + '\n});'
                }
            });
        });
    });

    //生成index.js文件
    grunt.task.registerTask("easy-hybrid-index", function () {
        var config = grunt.config.get("easy-hybrid-index");
        var src = config.path;
        //生成index.js文件
        var content = 'define("hybrid/index", function (require, exports, module) {\n';
        content += "\n    //下边为加载patch代码\n";
        var list3 = grunt.file.expand({
            cwd: src + "patch/"
        }, "*.js");
        list3.forEach(function (item) {
            content += '    require("hybrid/patch/' + item.split(".")[0] + '");\n';
        });
        content += '\n    var core = require("hybrid/core");\n';

        function quickend(type) {
            content += '\n    //下边为' + type + '注册代码\n';
            var list = grunt.file.expand({
                cwd: src + type + "/"
            }, "*.js");
            list.forEach(function (item) {
                content += '    core.register("' + type + '", require("hybrid/' + type + "/" + item.split(".")[0] + '"));\n';
            });
        }

        [ "util", "plugin", "ui"].forEach(quickend);

        content += '\n    //下边为config注册代码\n';
        content += '\n    core.config = require("hybrid/config");\n';

        content += '\n    //下边为navigation注册代码\n';
        var list4 = grunt.file.expand({
            cwd: src + "/navigation/"
        }, "*.js");
        list4.forEach(function (item) {
            var id = item.split(".")[0];
            content += '    core.registerNavigation("' + id + '", require("hybrid/navigation/' + item.split(".")[0] + '")(core));\n';
        });

        content += '\n    //下边为view注册代码\n';
        var list2 = grunt.file.expand({
            cwd: src + "/view/"
        }, "*/*.js");
        list2.forEach(function (item) {
            content += '    core.registerView("' + item.split(".")[0] + '", require("hybrid/view/' + item.split(".")[0] + '"));\n';
        });

        content += '\n    //下边为初始化项目代码\n';
        if (config.proxy) {
            content += '\n    window.devProxy = "' + config.proxy + '";\n';
        }
        if (config.native) {
            content += '    window.cordova = require("cordova");\n';
            content += '    require("cordova/exec");\n';
        }
        content += '    exports.init = require("hybrid/init")(core);\n';
        content += '});';
        grunt.file.write(config.dest, content);
    });

    //根据配置生成index.html
    grunt.task.registerTask("easy-hybrid-build", function () {
        var config = grunt.config.get("easy-hybrid-build");
        var target = config.target;
        var src = config.path;
        var css = config.sources.css;
        var js = config.sources.js;
        var content = '\n    ' +
            '\n        <meta charset="utf-8"/>' +
            '\n        <base target="_self"/>' +
            '\n        <title>' + config.name + '</title>';
        css.forEach(function (item) {
            content += '\n        <link href="' + item + '" rel="stylesheet"/>';
        });
        content += '\n    \n    ';
        js.forEach(function (item) {
            content += '\n         ';
        });
        content += '\n    \n';
        grunt.file.write(target, content);
    });

    //修复easy-hybrid-build在开发版本时的错误
    grunt.task.registerTask("easy-hybrid-fix", function () {
        var config = grunt.config.get("easy-hybrid-build");
        var target = config.target;
        var src = config.path;
        var css = config.sources.css;
        var js = config.sources.js;
        js.push("js/require.js");
        grunt.file.expand({
            cwd: src + ""
        }, "css/*.css").forEach(function (item) {
            css.push(item);
        });
        grunt.file.expand({
            cwd: src + "compress/"
        }, "**/*.js").forEach(function (item) {
            js.push("js/" + item);
        });
        js.push("js/load.js");
        var content = '\n    ' +
            '\n        <meta charset="utf-8"/>' +
            '\n        <base target="_self"/>' +
            '\n        <title>' + config.name + '</title>';
        css.forEach(function (item) {
            content += '\n        <link href="' + item + '" rel="stylesheet"/>';
        });
        content += '\n    \n    ';
        js.forEach(function (item) {
            content += '\n         ';
        });
        content += '\n    \n';
        grunt.file.write(target, content);
    });

    //用于根据配置信息对一个平台进行编译
    grunt.task.registerMultiTask("easy-hybrid-platform", "fetch each platform", function () {
        var config = this.data;
        grunt.config.init({
            "easy-hybrid-rescue": grunt.config.get(),//缓存现有文件
            copy: {
                "lib-css": {
                    files: [
                        {
                            expand: true,
                            cwd: config.lib + "css/",
                            src: ["**"],
                            dest: ".tmp/css/",
                            filter: config.filter.lib
                        }
                    ]
                },
                "lib-js": {
                    files: [
                        {
                            expand: true,
                            cwd: config.lib,
                            src: ["**", "!css/**"],
                            dest: ".tmp/js/",
                            filter: config.filter.lib
                        }
                    ]
                },
                "source-css": {
                    files: [
                        {
                            expand: true,
                            flatten: true,
                            cwd: config.src,
                            src: ["**/*.css"],
                            dest: ".tmp/css/",
                            filter: config.filter.source

                        },
                        {
                            expand: true,
                            flatten: true,
                            cwd: config.src,
                            src: ["**/img/*.*"],
                            dest: ".tmp/css/img/",
                            filter: config.filter.source

                        }
                    ]
                },
                "source-js": {
                    files: [
                        {
                            expand: true,
                            cwd: config.src,
                            src: ["**", "!**/css/**"],
                            dest: ".tmp/js/",
                            filter: config.filter.source
                        }
                    ]
                },
                "build": {
                    files: [
                        {
                            expand: true,
                            cwd: ".tmp/css/",
                            src: ["img/**"],
                            dest: config.build + "css/"
                        },
                        {
                            expand: true,
                            cwd: ".tmp/",
                            src: ["index.html"],
                            dest: config.build
                        },
                        {
                            expand: true,
                            cwd: ".tmp/js/source/" + (config.cordova ? "cordova" : "self") + "/",
                            src: config.native ? ["load.js", "require.js", "channel.js" , "cordova.js" , config.platform + "-exec.js" ] : ["load.js", "require.js"],
                            dest: ".tmp/"
                        }
                    ]
                }
            },
            "easy-hybrid-rename": {
                path: ".tmp/js/",
                platform: config.platform,
                target: ".tmp/compress/"
            },
            "easy-hybrid-index": {
                platform: config.platform,
                native: config.native,
                proxy: "",
                path: ".tmp/compress/",
                dest: ".tmp/compress/index.js"
            },
            "easy-hybrid-build": {
                path: ".tmp/",
                target: ".tmp/index.html",
                sources: config.sources,
                name: config.name
            },
            jshint: {
                all: [
                    '.tmp/compress/**/*.js'
                ],
                options: {
                    jshintrc: '.jshintrc'
                }
            },
            clean: {
                tmp: [".tmp/"],
                target: config.target
            },
            concat: {
                build: {
                    options: {
                        separator: '\n\n',
                        banner: '(function(){\n',
                        footer: '\n})();',
                        process: function (src, filepath) {
                            return '// Source: ' + filepath.replace("./tmp/compress/", "") + '\n' + src;
                        }
                    },
                    files: {
                        ".tmp/all.js": [".tmp/require.js", ".tmp/cordova.js", ".tmp/channel.js", ".tmp/" + config.platform + "-exec.js", ".tmp/compress/**/*.js", ".tmp/load.js"]
                    }
                }
            },
            uglify: {
                build: {
                    src: [".tmp/all.js"],
                    dest: config.build + "js/index.js"
                }
            },
            cssmin: {
                build: {
                    src: [".tmp/css/*.css"],
                    dest: config.build + "css/index.css"

                }
            }
        });
        var task = [
            "clean",
            "copy:lib-css",
            "copy:lib-js",
            "copy:source-css",
            "copy:source-js",
            "easy-hybrid-rename",
            "easy-hybrid-index",
            "easy-hybrid-build",
            "clean:target",
            "jshint",
            "copy:build",
            "concat",
            "uglify",
            "cssmin",
            "clean:tmp",
            "easy-hybrid-rescue"
        ];
        grunt.task.run(task);
    });

    //用于根据信息生成编译信息
    grunt.task.registerMultiTask("easy-hybrid-dev", "fetch each platform", function () {
        var config = this.data;
        if (config === false) {
            return;
        }
        grunt.config.init({
            "easy-hybrid-rescue": grunt.config.get(),//缓存现有文件
            copy: {
                "lib-css": {
                    files: [
                        {
                            expand: true,
                            cwd: config.lib + "css/",
                            src: ["**"],
                            dest: ".tmp/css/",
                            filter: config.filter.lib
                        }
                    ]
                },
                "lib-js": {
                    files: [
                        {
                            expand: true,
                            cwd: config.lib,
                            src: ["**", "!css/**"],
                            dest: ".tmp/js/",
                            filter: config.filter.lib
                        }
                    ]
                },
                "source-css": {
                    files: [
                        {
                            expand: true,
                            flatten: true,
                            cwd: config.src,
                            src: ["**/*.css"],
                            dest: ".tmp/css/",
                            filter: config.filter.source

                        },
                        {
                            expand: true,
                            flatten: true,
                            cwd: config.src,
                            src: ["**/img/*.*"],
                            dest: ".tmp/css/img/",
                            filter: config.filter.source

                        }
                    ]
                },
                "source-js": {
                    files: [
                        {
                            expand: true,
                            cwd: config.src,
                            src: ["**", "!**/css/**"],
                            dest: ".tmp/js/",
                            filter: config.filter.source
                        }
                    ]
                },
                "build": {
                    files: [
                        {
                            expand: true,
                            cwd: ".tmp/css/",
                            src: ["**"],
                            dest: config.build + "css/"
                        },
                        {
                            expand: true,
                            cwd: ".tmp/compress/",
                            src: ["**"],
                            dest: config.build + "js/"
                        },
                        {
                            expand: true,
                            cwd: ".tmp/js/source/" + (config.cordova ? "cordova" : "self") + "/",
                            src: [ "load.js", "require.js"],
                            dest: config.build + "js/"
                        },
                        {
                            expand: true,
                            cwd: ".tmp/",
                            src: ["index.html"],
                            dest: config.build
                        }
                    ]
                }
            },
            "easy-hybrid-rename": {
                path: ".tmp/js/",
                platform: config.platform,
                target: ".tmp/compress/"
            },
            "easy-hybrid-index": {
                platform: config.platform,
                native: config.native,
                proxy: config.proxy,
                path: ".tmp/compress/",
                dest: ".tmp/compress/index.js"
            },
            "easy-hybrid-build": {
                path: ".tmp/",
                target: ".tmp/index.html",
                sources: config.sources,
                name: config.name
            },
            jshint: {
                all: [
                    '.tmp/compress/**/*.js'
                ],
                options: {
                    jshintrc: '.jshintrc'
                }
            },
            clean: {
                tmp: [".tmp/"],
                target: config.target
            }
        });
        var task = [
            "clean",
            "copy:lib-css",
            "copy:lib-js",
            "copy:source-css",
            "copy:source-js",
            "easy-hybrid-rename",
            "easy-hybrid-index",
            "easy-hybrid-fix",
            "clean:target",
            "jshint",
            "copy:build",
            "clean:tmp",
            "easy-hybrid-rescue"
        ];
        grunt.task.run(task);
    });

    //入口函数，用于产生新的配置文件，并对文件进行处理
    grunt.task.registerMultiTask("hybrid", "an javascript development approach base on cordova-js", function () {
        var me = this;
        //重新生成请求参数
        grunt.config.init({
            "easy-hybrid-rescue": grunt.config.get(),//缓存现有文件
            "easy-hybrid-platform": lib.platformInit(me.target, me.data)
        });
        var task = ["easy-hybrid-platform"];
        var dev = lib.developInit(me.target, me.data);
        if (dev) {
            grunt.config.set("easy-hybrid-dev", {
                dev: dev
            });
            task.push("easy-hybrid-dev");
        }
        task.push("easy-hybrid-rescue");
        grunt.task.run(task);
    });
};
<|endoftext|>


<commit_before>/*
 * grunt-contrib-clean
 * http://gruntjs.com/
 *
 * Copyright (c) 2013 Tim Branyen, contributors
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
    var TARGET_DESC_PADDING_LEN = 4;

    // Set column widths.
    var widths,
        col1len = 0;

    // Render an array in table form.
    function table (arr) {
        arr.forEach(function(item) {
            var targetProps;

            grunt.log.writetableln(widths, ['', grunt.util._.pad(item[0], col1len), '', item[1]]);

            if(item[2]) {
                grunt.log.writetableln(widths, ['', grunt.util._.pad("", col1len), '', item[2]]);
            }

            targetProps = Object.keys(item[3]);

            if(targetProps.length > 0) {
                grunt.log.writetableln(widths, ['', grunt.util._.pad('', col1len), '',
                    'Targets: [' + targetProps.join(', ') + ']' ]);

                targetProps.forEach(function(prop) {
                    var targetMsg;

                    if(item[3][prop]) {
                        targetMsg = prop + ": " + item[3][prop];

                        grunt.log.writetableln(widths,
                            ['', grunt.util._.pad("", col1len + TARGET_DESC_PADDING_LEN), '', targetMsg]);
                    }
                });
            }
        });
    };

    grunt.registerTask ('manual', 'Print manual.', function() {

        var self = this,
            options = this.options({
                printAllTasks: true
            });

        var tasks = [];

        var packageJSON = grunt.file.readJSON('package.json');

        // Build object of tasks by info (where they were loaded from).
        Object.keys(grunt.task._tasks).forEach(function(name) {

            var task = grunt.task._tasks[name],
                config = grunt.config(name) || {};

//            if(name === self.name) {
//                return;
//            }

            if(!options.printAllTasks) {

                if(!(config.options && config.options.includeToManual)) {
                    return;
                }

            }

            col1len = Math.max(col1len, name.length);
            tasks.push(task);
        });

        // Init withs
        widths = [1, col1len, 2, 76 - col1len];

        // Start print!
        grunt.log
            .subhead("=== " + packageJSON.name + " application grunt task manual ===");

        grunt.log.subhead('Available tasks');

        table(tasks.map(function(task) {
            var info = task.info,
                targets = {},
                config = grunt.config(task.name) || {},
                moreInfo = "";

            if(config.options && config.options.manualText) {
                moreInfo = config.options.manualText;
            }

            if (task.multi) {
                info += ' *';

                Object.keys(config).forEach(function(target) {
                    if(target === 'options') {
                        return;
                    }

                    targets[target] = "";

                    if(config[target].options && config[target].options.manualText) {
                        targets[target] = config[target].options.manualText;
                    }
                });
            }

            return [task.name, info, moreInfo, targets];
        }));

    });

};
<commit_msg>Change tasks title<commit_after>/*
 * grunt-contrib-clean
 * http://gruntjs.com/
 *
 * Copyright (c) 2013 Tim Branyen, contributors
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
    var TARGET_DESC_PADDING_LEN = 4;

    // Set column widths.
    var widths,
        col1len = 0;

    // Render an array in table form.
    function table (arr) {
        arr.forEach(function(item) {
            var targetProps;

            grunt.log.writetableln(widths, ['', grunt.util._.pad(item[0], col1len), '', item[1]]);

            if(item[2]) {
                grunt.log.writetableln(widths, ['', grunt.util._.pad("", col1len), '', item[2]]);
            }

            targetProps = Object.keys(item[3]);

            if(targetProps.length > 0) {
                grunt.log.writetableln(widths, ['', grunt.util._.pad('', col1len), '',
                    'Targets: [' + targetProps.join(', ') + ']' ]);

                targetProps.forEach(function(prop) {
                    var targetMsg;

                    if(item[3][prop]) {
                        targetMsg = prop + ": " + item[3][prop];

                        grunt.log.writetableln(widths,
                            ['', grunt.util._.pad("", col1len + TARGET_DESC_PADDING_LEN), '', targetMsg]);
                    }
                });
            }
        });
    };

    grunt.registerTask ('manual', 'Print manual.', function() {

        var self = this,
            options = this.options({
                printAllTasks: true
            });

        var tasks = [];

        var packageJSON = grunt.file.readJSON('package.json');

        // Build object of tasks by info (where they were loaded from).
        Object.keys(grunt.task._tasks).forEach(function(name) {

            var task = grunt.task._tasks[name],
                config = grunt.config(name) || {};

//            if(name === self.name) {
//                return;
//            }

            if(!options.printAllTasks) {

                if(!(config.options && config.options.includeToManual)) {
                    return;
                }

            }

            col1len = Math.max(col1len, name.length);
            tasks.push(task);
        });

        // Init withs
        widths = [1, col1len, 2, 76 - col1len];

        // Start print!
        grunt.log
            .subhead("=== " + packageJSON.name + " application grunt task manual ===");

        grunt.log.subhead('Main tasks');

        table(tasks.map(function(task) {
            var info = task.info,
                targets = {},
                config = grunt.config(task.name) || {},
                moreInfo = "";

            if(config.options && config.options.manualText) {
                moreInfo = config.options.manualText;
            }

            if (task.multi) {
                info += ' *';

                Object.keys(config).forEach(function(target) {
                    if(target === 'options') {
                        return;
                    }

                    targets[target] = "";

                    if(config[target].options && config[target].options.manualText) {
                        targets[target] = config[target].options.manualText;
                    }
                });
            }

            return [task.name, info, moreInfo, targets];
        }));

    });

};
<|endoftext|>


<commit_before>const FBSDK = require('react-native-fbsdk')

import React, { Component } from 'react'
import {
  AppRegistry,
  StyleSheet,
  Text,
  TouchableHighlight,
  View,
} from 'react-native'
const {
  LoginButton,
  ShareDialog,
  AccessToken,
} = FBSDK

import { graphql } from 'react-apollo'
import gql from 'graphql-tag'

export default class nap extends Component {
  constructor(props) {
    super(props)
    const shareLinkContent = {
      contentType: 'link',
      contentUrl: 'https://www.facebook.com/',
    }

    this.state = {
      shareLinkContent: shareLinkContent,
      isLoggedIn: false,
      name: ''
    }
  }

  shareLinkWithShareDialog() {
    var tmp = this
    ShareDialog.canShow(this.state.shareLinkContent).then(
      function (canShow) {
        if (canShow) {
          return ShareDialog.show(tmp.state.shareLinkContent)
        }
      }
    ).then(
      function (result) {
        if (result.isCancelled) {
          alert('Share cancelled')
        } else {
          alert('Share success with postId: '
            + result.postId)
        }
      },
      function (error) {
        alert('Share fail with error: ' + error)
      }
      )
  }

  onLoginFinished(error, result) {
    if (error) {
      alert("login has error: " + result.error)
    } else if (result.isCancelled) {
      alert("login is cancelled.")
    } else {
      AccessToken.getCurrentAccessToken().then(
        (data) => {
          // TODO : Handle bad token
          const access_token = data.accessToken.toString()
          console.log('access_token :', access_token)

          // TODO : Secure header?
          access_token && fetch(`http://localhost:3000/auth/facebook/token`,
            {
              method: 'post',
              headers: {
                'Authorization': `Bearer ${access_token}`
              }
            }
          ).then((response) => {
            if (response.status >= 400) {
              throw new Error("Bad response from server")
            }
            return response.text()
          }).then((text) => {
            console.log(text)
            this.setState({ isLoggedIn: true })
          })
        }
      )
    }
  }

  render() {

    const query = gql`{
      userOne {
        name
      }
    }`

    const UserProfile = ({ data }) => this.state.isLoggedIn ?
      <View style={{ paddingLeft: 20, paddingTop: 20 }}>
        <Text>Name: {data.userOne && data.userOne.name}</Text>
      </View>
      :
      <View style={{ paddingLeft: 20, paddingTop: 20 }}>
        <Text>Please log in</Text>
      </View>

    const ViewWithData = graphql(query, {
      options: { variables: { name: this.state.name } }
    })(UserProfile)

    return (
      <View style={styles.container}>
        <LoginButton
          onLoginFinished={this.onLoginFinished.bind(this)}
          onLogoutFinished={() => alert("logout.")} />
        <ViewWithData />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  shareText: {
    fontSize: 20,
    margin: 10,
  },
})<commit_msg>Add logout<commit_after>const FBSDK = require('react-native-fbsdk')

import React, { Component } from 'react'
import {
  AppRegistry,
  StyleSheet,
  Text,
  TouchableHighlight,
  View,
} from 'react-native'
const {
  LoginButton,
  ShareDialog,
  AccessToken,
} = FBSDK

import { graphql } from 'react-apollo'
import gql from 'graphql-tag'

export default class nap extends Component {
  constructor(props) {
    super(props)
    const shareLinkContent = {
      contentType: 'link',
      contentUrl: 'https://www.facebook.com/',
    }

    this.state = {
      shareLinkContent: shareLinkContent,
      isLoggedIn: false,
      name: ''
    }
  }

  shareLinkWithShareDialog() {
    var tmp = this
    ShareDialog.canShow(this.state.shareLinkContent).then(
      function (canShow) {
        if (canShow) {
          return ShareDialog.show(tmp.state.shareLinkContent)
        }
      }
    ).then(
      function (result) {
        if (result.isCancelled) {
          alert('Share cancelled')
        } else {
          alert('Share success with postId: '
            + result.postId)
        }
      },
      function (error) {
        alert('Share fail with error: ' + error)
      }
      )
  }

  onLoginFinished(error, result) {
    if (error) {
      alert("login has error: " + result.error)
    } else if (result.isCancelled) {
      alert("login is cancelled.")
    } else {
      AccessToken.getCurrentAccessToken().then(
        (data) => {
          // TODO : Handle bad token
          const access_token = data.accessToken.toString()
          console.log('access_token :', access_token)

          // TODO : Secure header?
          access_token && fetch(`http://localhost:3000/auth/facebook/token`,
            {
              method: 'post',
              headers: {
                'Authorization': `Bearer ${access_token}`
              }
            }
          ).then((response) => {
            if (response.status >= 400) {
              throw new Error("Bad response from server")
            }
            return response.text()
          }).then((text) => {
            console.log(text)
            this.setState({ isLoggedIn: true })
          })
        }
      )
    }
  }

  render() {

    const query = gql`{
      userOne {
        name
      }
    }`

    const UserProfile = ({ data }) => this.state.isLoggedIn ?
      <View style={{ paddingLeft: 20, paddingTop: 20 }}>
        <Text>Name: {data.userOne && data.userOne.name}</Text>
      </View>
      :
      <View style={{ paddingLeft: 20, paddingTop: 20 }}>
        <Text>Please log in</Text>
      </View>

    const ViewWithData = graphql(query, {
      options: { variables: { name: this.state.name } }
    })(UserProfile)

    return (
      <View style={styles.container}>
        <LoginButton
          onLoginFinished={this.onLoginFinished.bind(this)}
          onLogoutFinished={() => this.setState({ isLoggedIn: false }) } />
        <ViewWithData />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  shareText: {
    fontSize: 20,
    margin: 10,
  },
})<|endoftext|>


<commit_before>'use strict';

/**
 * module deps
 */

var fs = require('fs'),
  path = require('path'),
  crypto = require('crypto');

/**
 * grunt-md5tag
 */

module.exports = function(grunt) {
  grunt.registerMultiTask('md5tag', 'tag and replace references to your prod file with md5 hash', function() {

    /**
     * get md5 for filepath
     */

    function md5(file) {
      var hash = crypto.createHash('md5');
      hash.update(grunt.file.read(file));
      var hashPath = hash.digest('hex').slice(0,8),
          extname = path.extname(file),
          basename = path.basename(file),
          name = options.pattern
            .replace('{md5}', hashPath)
            .replace('{basename}', basename.slice(0, basename.length - extname.length))
            .replace('{extname}', extname);
      return file.replace(basename, name);
    }

    var files = this.filesSrc,
        mappings = {},
        options;

    // merge options with defaults
    options = this.options({
      pattern: '{basename}.{md5}{extname}'
    });

    // add md5 hash to transform group
    grunt.file
      .match({matchBase: true}, options.rename, files)
      .forEach(function (f) {
        var fileOut = md5(f),
            basename = path.basename(f);

        // check mapping is unique
        if (mappings[basename]) {
          grunt.fail.fatal('basename ' + basename + ' is not unique');
        }

        // save mapping
        mappings[basename] = path.basename(fileOut);

        // rename file
        fs.renameSync(f, fileOut);
        grunt.log.writeln('rename ' + basename + ' to ' + mappings[basename]);
      });

    // update references to update group
    files.forEach(function (file) {
      var basename = path.basename(file),
          mapping = mappings[basename],
          data;

      // get md5 filepath
      if (mapping) file = file.replace(basename, mapping);

      // search and replace file content
      data = grunt.file.read(file);
      Object.keys(mappings).forEach(function(key) {
        data = data.replace(new RegExp(key, 'g'), mappings[key]);
      });

      // update file
      grunt.verbose.writeln('updating file', file);
      grunt.file.write(file, data);
    });
  });
};
<commit_msg>only write file if it has changed<commit_after>'use strict';

/**
 * module deps
 */

var fs = require('fs'),
  path = require('path'),
  crypto = require('crypto');

/**
 * grunt-md5tag
 */

module.exports = function(grunt) {
  grunt.registerMultiTask('md5tag', 'tag and replace references to your prod file with md5 hash', function() {

    /**
     * get md5 for filepath
     */

    function md5(file) {
      var hash = crypto.createHash('md5');
      hash.update(grunt.file.read(file));
      var hashPath = hash.digest('hex').slice(0,8),
          extname = path.extname(file),
          basename = path.basename(file),
          name = options.pattern
            .replace('{md5}', hashPath)
            .replace('{basename}', basename.slice(0, basename.length - extname.length))
            .replace('{extname}', extname);
      return file.replace(basename, name);
    }

    var files = this.filesSrc,
        mappings = {},
        options;

    // merge options with defaults
    options = this.options({
      pattern: '{basename}.{md5}{extname}'
    });

    // add md5 hash to transform group
    grunt.file
      .match({matchBase: true}, options.rename, files)
      .forEach(function (f) {
        var fileOut = md5(f),
            basename = path.basename(f);

        // check mapping is unique
        if (mappings[basename]) {
          grunt.fail.fatal('basename ' + basename + ' is not unique');
        }

        // save mapping
        mappings[basename] = path.basename(fileOut);

        // rename file
        fs.renameSync(f, fileOut);
        grunt.log.writeln('rename ' + basename + ' to ' + mappings[basename]);
      });

    // update references to update group
    files.forEach(function (file) {
      var basename = path.basename(file),
          mapping = mappings[basename],
          data, update;

      // get md5 filepath
      if (mapping) file = file.replace(basename, mapping);

      // search and replace file content
      data = update = grunt.file.read(file);
      Object.keys(mappings).forEach(function(key) {
        update = update.replace(new RegExp(key, 'g'), mappings[key]);
      });

      // update file
      if (data !== update) {
        grunt.log.writeln('updating file', file);
        grunt.file.write(file, update);
      }
    });
  });
};
<|endoftext|>


<commit_before>/**!
 * grunt-readme
 * http://github.com/assemble/grunt-readme
 * Partially derived from and inspired by grunt-contrib-internal
 *
 * Copyright (c) 2013, Jon Schlinkert, contributors
 * Licensed under the MIT license.
 */

'use strict';

// Node.js
var path = require('path');

// node_modules
var load    = require('resolve-dep');
var name    = require('node-name');
var yaml    = require('assemble-yaml');
var makeTOC = require('marked-toc');
var marked  = require('marked');
var glob    = require('glob-utils');
var grunt   = require('grunt');
var _       = grunt.util._;

module.exports = function(grunt) {

  // Local utils
  var Utils = require('./lib/utils');

  _.mixin(require('./lib/mixins'));
  _.mixin(require('./lib/badges'));

  // Add custom template delimiters for our templates.
  grunt.template.addDelimiters('readme', '{%', '%}');

  grunt.registerTask('readme', "Generate your project's README from a template. If you already use Grunt, this is a no brainer.", function() {

    // The 'readme' task options.
    var options = this.options({
      templates: '',
      includes: '',
      readme: '',
      config: '',
      sep: '\n',
      remove: [],
      contributing: false
    });

    /**
     * options.metadata
     * @type {Object}
     */
    var metadata = Utils.readOptionsData(options.metadata);
    grunt.verbose.ok('README metadata:'.yellow, metadata);

    /**
     * meta: {}
     * Root context object passed to templates with a value of "this"
     * @type {Object}
     */
    if(grunt.file.exists(path.resolve(process.cwd(),'package.json'))) {
      options.config = _.extend(require('./lib/pkg.js'), grunt.file.readJSON(path.resolve(process.cwd(),'package.json')));
    } else {
      options.config = require('./lib/pkg.js');
    }
    var meta = _.defaults(metadata, options.config);
    grunt.verbose.ok(">> Meta:".yellow, JSON.stringify(meta, null, 2));

    /**
     * Convenience variables.
     */
    meta.copyright = _.copyright();
    meta.homepage  = _.homepage();
    meta.license   = _.license();
    meta.n         = '\n';
    meta.safename  = _.safename(meta.name);
    meta.shortname = _.shortname(meta.name);
    meta.username  = _.username();
    meta.repo      = _.username() + '/' + meta.name;

    /**
     * Templates directory.
     * If `options: { templates: '' }` is not defined, then the task will use the
     * templates directory in the `./templates` directory of the grunt-readme task.
     * @type {String}
     */
    if(_.isEmpty(options.templates)) {
      options.templates = root('templates');
    } else {
      options.templates = bind(options.templates);
    }
    var templates = options.templates;

    /**
     * Docs directory
     * The location where all of your docs will be stored
     * This defaults to './docs' in the root of your project.
     * @example:
     *   options: {
     *     docs: 'foo/'
     *   }
     */
    var baseDocs = root('docs');
    if(!options.docs) {
      options.docs = path.join.bind(options.docs, 'docs');
    } else if (options.docs) {
      options.docs = path.join.bind(process.cwd(), options.docs, '');
    } else {
      options.docs = baseDocs;
    }
    var docs = options.docs;

    /**
     * README template used to create README.md. Unless a template
     * is defined in the task options, a start template from
     * grunt-readme will be used.
     *
     * @example:
     *   options: {
     *     readme: './foo/README.tmpl.md'
     *   }
     */

    // If `readme` option is defined with a readme template, use that,
    // otherwise, see if the README template is in the `docs()` dir
    if (!options.readme && grunt.file.exists(docs('README.tmpl.md'))) {
      options.readme = docs('README.tmpl.md');
    // As a last resort, use a template from grunt-readme
    } else {
      options.readme = templates('README.tmpl.md');
    }

    // Extract and parse YAML front matter
    var yfm = yaml.extract(options.readme).context;

    // Extend context with data from YFM
    meta = _.extend({}, meta, yfm);

    // Extract content from template
    options.readme = yaml.extract(options.readme).content;

    grunt.verbose.writeln("yfm: ", yfm);
    grunt.verbose.writeln("options.readme: ", options.readme);
    grunt.verbose.writeln("meta: ", meta);

    // Add mixins for use in our templates.
    // TODO: externalize these.
    _.mixin({
      meta: function (key) {
        return Utils.meta(key, meta);
      },
      doc: function (filepath, sep) {
        sep = sep || options.sep;
        return glob.content(docs(filepath), sep).replace(/^#/gm, '##');
      },
      include: function (filepath, sep) {
        sep = sep || options.sep;
        var includesPath = path.join(templates('includes'), filepath);
        return glob.content(includesPath, sep).replace(/^#/gm, '##');
      },
      contrib: function (filepath, sep) {
        sep = sep || options.sep;
        var includesPath = path.join(templates('contrib'), filepath);
        return glob.content(includesPath, sep).replace(/^#/gm, '##');
      },
      badge: function (badge) {
        return grunt.file.read(templates('badges/' + badge + '.md'));
      }
    });

    /**
     * TRAVIS
     */
    meta.travis = grunt.file.exists('.travis.yml');
    if (meta.travis) {
      meta.travis = meta.repository.url.replace(/.*:\/\/github.com\/(.*)\.git/, 'https://travis-ci.org/$1');
    }

    /**
     * CHANGELOG
     */
    meta.changelog = grunt.file.exists('CHANGELOG');
    if (meta.changelog) {
      meta.changelog = grunt.file.readYAML('CHANGELOG');
    }

    /**
     * CONTRIBUTING.md
     * Copy contributing guide from templates.
     */
    if (!grunt.file.exists('CONTRIBUTING.md') && options.contributing) {
      grunt.file.copy(templates('CONTRIBUTING.md'), 'CONTRIBUTING.md');
      grunt.log.ok('Created CONTRIBUTING.md');
    }

    /**
     * AUTHORS
     */
    var authors = grunt.file.exists('AUTHORS');
    if (authors) {
      authors = grunt.file.readYAML('AUTHORS');
      meta.authors = authors.split('\n').map(function(author) {
        var matches = author.match(/(.*?)\s*\((.*)\)/) || [];
        return {name: matches[1], url: matches[2]};
      });
    }

    /**
     * Generate a Table of Contents
     * @usage: {%= toc %}
     */
    meta.toc = makeTOC(options.readme);

    /**
     * Generalized template configuration
     */
    var tmplConfig = {
      data: meta,
      delimiters: 'readme'
    };

    /**
     * Generate README
     */
    var newReadme = Utils.compileTmpl(options.readme, tmplConfig, Utils.frep);
    grunt.file.write('README.md', newReadme);
    grunt.log.ok('Created README.md');

    // Optionally generate a HTML page from the README.
    if(options.html) {
      meta.content = marked(newReadme);
      meta.content = meta.content.replace(/\{%=/g, '[%=').replace(/%}/g, '%]');
      var layout =  grunt.file.read(options.layout || templates('html/layout.tmpl'));
      var html = Utils.compileTmpl(layout, tmplConfig, Utils.frep);
      grunt.file.write(options.html, html);
    }

    function makeOptionsObject(prop) {
      if(!_.isUndefined(options[prop])) {
        options[prop] = options[prop] || {};
        grunt.file.expand(options[prop].src).map(function(file) {
          var propSrc = yaml.extract(file).content || '';
          var propDest = path.join(options[prop].dest, name.base(file)) + '.md';
          meta.toc = makeTOC(propSrc);
          var output = Utils.compileTmpl(propSrc, tmplConfig, Utils.frep);
          grunt.file.write(propDest, output);
        });
      }
    }

    makeOptionsObject('alt');
    makeOptionsObject('test');

    // Fail task if any errors were logged.
    if (this.errorCount > 0) {return false;}
  });

  var bind = function(filepath) {
    return path.join.bind(null, filepath, '');
  };

  // The root of the project. This is where the Gruntfile is.
  var root = function(filepath) {
    return path.join.bind(null, __dirname, '../', filepath);
  };
};
<commit_msg>adding support for copying boilerplate files to local docs<commit_after>/**!
 * grunt-readme
 * http://github.com/assemble/grunt-readme
 * Partially derived from and inspired by grunt-contrib-internal
 *
 * Copyright (c) 2013, Jon Schlinkert, contributors
 * Licensed under the MIT license.
 */

'use strict';

// Node.js
var path = require('path');

// node_modules
var load    = require('resolve-dep');
var name    = require('node-name');
var yaml    = require('assemble-yaml');
var makeTOC = require('marked-toc');
var marked  = require('marked');
var glob    = require('glob-utils');
var grunt   = require('grunt');
var _       = grunt.util._;

module.exports = function(grunt) {

  // Local utils
  var Utils = require('./lib/utils');

  _.mixin(require('./lib/mixins'));
  _.mixin(require('./lib/badges'));

  // Add custom template delimiters for our templates.
  grunt.template.addDelimiters('readme', '{%', '%}');

  grunt.registerTask('readme', "Generate your project's README from a template. If you already use Grunt, this is a no brainer.", function() {

    // The 'readme' task options.
    var options = this.options({
      templates: '',
      includes: '',
      readme: '',
      config: '',
      sep: '\n',
      remove: [],
      contributing: false
    });

    /**
     * options.metadata
     * @type {Object}
     */
    var metadata = Utils.readOptionsData(options.metadata);
    grunt.verbose.ok('README metadata:'.yellow, metadata);

    /**
     * meta: {}
     * Root context object passed to templates with a value of "this"
     * @type {Object}
     */
    if(grunt.file.exists(path.resolve(process.cwd(),'package.json'))) {
      options.config = _.extend(require('./lib/pkg.js'), grunt.file.readJSON(path.resolve(process.cwd(),'package.json')));
    } else {
      options.config = require('./lib/pkg.js');
    }
    var meta = _.defaults(metadata, options.config);
    grunt.verbose.ok(">> Meta:".yellow, JSON.stringify(meta, null, 2));

    /**
     * Convenience variables.
     */
    meta.copyright = _.copyright();
    meta.homepage  = _.homepage();
    meta.license   = _.license();
    meta.n         = '\n';
    meta.safename  = _.safename(meta.name);
    meta.shortname = _.shortname(meta.name);
    meta.username  = _.username();
    meta.repo      = _.username() + '/' + meta.name;

    /**
     * Templates directory.
     * If `options: { templates: '' }` is not defined, then the task will use the
     * templates directory in the `./templates` directory of the grunt-readme task.
     * @type {String}
     */
    if(_.isEmpty(options.templates)) {
      options.templates = root('templates');
    } else {
      options.templates = bind(options.templates);
    }
    var templates = options.templates;

    /**
     * Docs directory
     * The location where all of your docs will be stored
     * This defaults to './docs' in the root of your project.
     * @example:
     *   options: {
     *     docs: 'foo/'
     *   }
     */
    var baseDocs = root('docs');
    if(!options.docs) {
      options.docs = path.join.bind(options.docs, 'docs');
    } else if (options.docs) {
      options.docs = path.join.bind(process.cwd(), options.docs, '');
    } else {
      options.docs = baseDocs;
    }
    var docs = options.docs;

    if(!_.isEmpty(options.boilerplate)) {
      var boilerplate = root(path.join('templates', 'boilerplates'))(options.boilerplate);

      if(grunt.file.isDir(boilerplate)) {
        grunt.file.recurse(boilerplate, function(filepath, rootdir, subdir, filename) {
          if(!grunt.file.exists(docs(filename))) {
            grunt.file.copy(filepath, docs(filename));
          }
        });
      }
    }

    /**
     * README template used to create README.md. Unless a template
     * is defined in the task options, a start template from
     * grunt-readme will be used.
     *
     * @example:
     *   options: {
     *     readme: './foo/README.tmpl.md'
     *   }
     */

    // If `readme` option is defined with a readme template, use that,
    // otherwise, see if the README template is in the `docs()` dir
    if (!options.readme && grunt.file.exists(docs('README.tmpl.md'))) {
      options.readme = docs('README.tmpl.md');
    // As a last resort, use a template from grunt-readme
    } else {
      options.readme = templates('README.tmpl.md');
    }

    // Extract and parse YAML front matter
    var yfm = yaml.extract(options.readme).context;

    // Extend context with data from YFM
    meta = _.extend({}, meta, yfm);

    // Extract content from template
    options.readme = yaml.extract(options.readme).content;

    grunt.verbose.writeln("yfm: ", yfm);
    grunt.verbose.writeln("options.readme: ", options.readme);
    grunt.verbose.writeln("meta: ", meta);

    // Add mixins for use in our templates.
    // TODO: externalize these.
    _.mixin({
      meta: function (key) {
        return Utils.meta(key, meta);
      },
      doc: function (filepath, sep) {
        sep = sep || options.sep;
        return glob.content(docs(filepath), sep).replace(/^#/gm, '##');
      },
      include: function (filepath, sep) {
        sep = sep || options.sep;
        var includesPath = path.join(templates('includes'), filepath);
        return glob.content(includesPath, sep).replace(/^#/gm, '##');
      },
      contrib: function (filepath, sep) {
        sep = sep || options.sep;
        var includesPath = path.join(templates('contrib'), filepath);
        return glob.content(includesPath, sep).replace(/^#/gm, '##');
      },
      badge: function (badge) {
        return grunt.file.read(templates('badges/' + badge + '.md'));
      }
    });

    /**
     * TRAVIS
     */
    meta.travis = grunt.file.exists('.travis.yml');
    if (meta.travis) {
      meta.travis = meta.repository.url.replace(/.*:\/\/github.com\/(.*)\.git/, 'https://travis-ci.org/$1');
    }

    /**
     * CHANGELOG
     */
    meta.changelog = grunt.file.exists('CHANGELOG');
    if (meta.changelog) {
      meta.changelog = grunt.file.readYAML('CHANGELOG');
    }

    /**
     * CONTRIBUTING.md
     * Copy contributing guide from templates.
     */
    if (!grunt.file.exists('CONTRIBUTING.md') && options.contributing) {
      grunt.file.copy(templates('CONTRIBUTING.md'), 'CONTRIBUTING.md');
      grunt.log.ok('Created CONTRIBUTING.md');
    }

    /**
     * AUTHORS
     */
    var authors = grunt.file.exists('AUTHORS');
    if (authors) {
      authors = grunt.file.readYAML('AUTHORS');
      meta.authors = authors.split('\n').map(function(author) {
        var matches = author.match(/(.*?)\s*\((.*)\)/) || [];
        return {name: matches[1], url: matches[2]};
      });
    }

    /**
     * Generate a Table of Contents
     * @usage: {%= toc %}
     */
    meta.toc = makeTOC(options.readme);

    /**
     * Generalized template configuration
     */
    var tmplConfig = {
      data: meta,
      delimiters: 'readme'
    };

    /**
     * Generate README
     */
    var newReadme = Utils.compileTmpl(options.readme, tmplConfig, Utils.frep);
    grunt.file.write('README.md', newReadme);
    grunt.log.ok('Created README.md');

    // Optionally generate a HTML page from the README.
    if(options.html) {
      meta.content = marked(newReadme);
      meta.content = meta.content.replace(/\{%=/g, '[%=').replace(/%}/g, '%]');
      var layout =  grunt.file.read(options.layout || templates('html/layout.tmpl'));
      var html = Utils.compileTmpl(layout, tmplConfig, Utils.frep);
      grunt.file.write(options.html, html);
    }

    function makeOptionsObject(prop) {
      if(!_.isUndefined(options[prop])) {
        options[prop] = options[prop] || {};
        grunt.file.expand(options[prop].src).map(function(file) {
          var propSrc = yaml.extract(file).content || '';
          var propDest = path.join(options[prop].dest, name.base(file)) + '.md';
          meta.toc = makeTOC(propSrc);
          var output = Utils.compileTmpl(propSrc, tmplConfig, Utils.frep);
          grunt.file.write(propDest, output);
        });
      }
    }

    makeOptionsObject('alt');
    makeOptionsObject('test');

    // Fail task if any errors were logged.
    if (this.errorCount > 0) {return false;}
  });

  var bind = function(filepath) {
    return path.join.bind(null, filepath, '');
  };

  // The root of the project. This is where the Gruntfile is.
  var root = function(filepath) {
    return path.join.bind(null, __dirname, '../', filepath);
  };

};

<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var sh = require('execSync');
var AWS = require('aws-sdk');

module.exports = function(grunt) {
	grunt.registerTask('upload_builds_to_s3', function() {
		var done = this.async();
		var hash = sh.exec('git rev-parse HEAD').stdout.trim();
		var debugBuild = fs.readFileSync('./dist/ember-graph.js', { encoding: 'utf8' });
		var productionBuild = fs.readFileSync('./dist/ember-graph.prod.js', { encoding: 'utf8' });
		var minifiedBuild = fs.readFileSync('./dist/ember-graph.min.js', { encoding: 'utf8' });

		var count = 0;
		var counter = function(success, fileName) {
			count = count + 1;

			if (!success) {
				console.log('Error uploading file to S3: ' + fileName);
			}

			if (count >= 6) {
				done();
			}
		};

		var s3 = new AWS.S3();
		uploadFile(s3, 'latest/ember-graph.js', debugBuild, counter);
		uploadFile(s3, hash + '/ember-graph-.js', debugBuild, counter);
		uploadFile(s3, 'latest/ember-graph.prod.js', productionBuild, counter);
		uploadFile(s3, hash + '/ember-graph-.prod.js', productionBuild, counter);
		uploadFile(s3, 'latest/ember-graph.min.js', minifiedBuild, counter);
		uploadFile(s3, hash + '/ember-graph-.min.js', minifiedBuild, counter);
	});
};

function uploadFile(s3, fileName, contents, callback) {
	s3.putObject({
		ACL: 'public-read',
		Body: contents,
		Bucket: 'ember-graph-builds',
		ContentType: 'application/javascript',
		Key: fileName
	}, function(err, data) {
		callback(!err, fileName);
	});
}<commit_msg>Small bug fix.<commit_after>'use strict';

var fs = require('fs');
var sh = require('execSync');
var AWS = require('aws-sdk');

module.exports = function(grunt) {
	grunt.registerTask('upload_builds_to_s3', function() {
		var done = this.async();
		var hash = sh.exec('git rev-parse HEAD').stdout.trim();
		var debugBuild = fs.readFileSync('./dist/ember-graph.js', { encoding: 'utf8' });
		var productionBuild = fs.readFileSync('./dist/ember-graph.prod.js', { encoding: 'utf8' });
		var minifiedBuild = fs.readFileSync('./dist/ember-graph.min.js', { encoding: 'utf8' });

		var count = 0;
		var counter = function(success, fileName) {
			count = count + 1;

			if (!success) {
				console.log('Error uploading file to S3: ' + fileName);
			}

			if (count >= 6) {
				done();
			}
		};

		var s3 = new AWS.S3();
		uploadFile(s3, 'latest/ember-graph.js', debugBuild, counter);
		uploadFile(s3, hash + '/ember-graph.js', debugBuild, counter);
		uploadFile(s3, 'latest/ember-graph.prod.js', productionBuild, counter);
		uploadFile(s3, hash + '/ember-graph.prod.js', productionBuild, counter);
		uploadFile(s3, 'latest/ember-graph.min.js', minifiedBuild, counter);
		uploadFile(s3, hash + '/ember-graph.min.js', minifiedBuild, counter);
	});
};

function uploadFile(s3, fileName, contents, callback) {
	s3.putObject({
		ACL: 'public-read',
		Body: contents,
		Bucket: 'ember-graph-builds',
		ContentType: 'application/javascript',
		Key: fileName
	}, function(err, data) {
		callback(!err, fileName);
	});
}<|endoftext|>


<commit_before>var machina = require('machina');
var request = require('request');
//var data = require('./data');

var experiment = new machina.Fsm( {

    // the initialize method is called right after the FSM
    // instance is constructed, giving you a place for any
    // setup behavior, etc. It receives the same arguments
    // (options) as the constructor function.
    initialize: function( options ) {
        // your setup code goes here...
    },

    namespace: "controller",

    // The initial State the FSM will be started in
    initialState: "uninitialized",

    // Experimental States
    states: {
        uninitialized: {
            _onEnter: function() {
                this.transition( "freeForm" );
            },

            "*": function() {

            },

            _onExit: function() {

            },

            initialize: function() {

            }

        },

        freeForm: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

            dropMeat: function() {
                request('http://192.168.1.16:8001/values?id=23.11.0&value=2', function (error, response, body) {
                  if (!error && response.statusCode == 200) {
                    console.log("Sent") // Show the HTML for the Google homepage.
                  }
                })
                console.log("MEAT DROPPED");
            },

            lightOn: function() {

            },

            lightsOff: function() {

            },

            startExperiment: function() {

            },

            perchEvent: function() {

            }

        },

        experiment: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

            startSession: function() {

            },

            cancelExperiment: function() {

            },

        },

        session: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

            endSession: function() {

            },

        },

        trial: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

            perchEvent: function() {

            },

        },

        failedSession: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

        },

        endedSession: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

        },

    },
    // External Facing API

    initializeDevices: function() {
        console.log("initialize API");
        this.handle( "initialize" );
    },

    startExperiment: function() {
        console.log("startExperiment API");
        this.handle( "startExperiment" );
    },

    cancelExperiment: function() {
        console.log("cancelExperiment API");
        this.handle( "cancelExperiment" );
    },

    startSession: function() {
        console.log("startSession API");
        this.handle( "startSession" );
    },

    endSession: function() {
        console.log("endSession API");
        this.handle( "endSession" );
    },

    dropMeat: function() {
        console.log("dropMeat API");
        this.handle( "dropMeat" );
    },

    lightOn: function() {
        console.log("lightOn API");
        this.handle( "lightOn" );
    },

    lightsOff: function() {
        console.log("lightsOff API");
        this.handle( "lightsOff" );
    },

    perchEvent: function() {
        console.log("perchEvent API");
        this.handle( "perchEvent" );
    },

} );

experiment.on("*", function (eventName, data){
    console.log("this thing happened:", eventName, data);
});

module.exports.experiment = experiment;<commit_msg>updated lagarto hostname<commit_after>var machina = require('machina');
var request = require('request');
//var data = require('./data');

var experiment = new machina.Fsm( {

    // the initialize method is called right after the FSM
    // instance is constructed, giving you a place for any
    // setup behavior, etc. It receives the same arguments
    // (options) as the constructor function.
    initialize: function( options ) {
        // your setup code goes here...
    },

    namespace: "controller",

    // The initial State the FSM will be started in
    initialState: "uninitialized",

    // Experimental States
    states: {
        uninitialized: {
            _onEnter: function() {
                this.transition( "freeForm" );
            },

            "*": function() {

            },

            _onExit: function() {

            },

            initialize: function() {

            }

        },

        freeForm: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

            dropMeat: function() {
                request('http://127.0.0.1:8001/values?id=7.11.0&value=true', function (error, response, body) {
                  if (!error && response.statusCode == 200) {
                    console.log("Sent") // Show the HTML for the Google homepage.
                  }
                })
                console.log("MEAT DROPPED");
            },

            lightOn: function() {

            },

            lightsOff: function() {

            },

            startExperiment: function() {

            },

            perchEvent: function() {

            }

        },

        experiment: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

            startSession: function() {

            },

            cancelExperiment: function() {

            },

        },

        session: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

            endSession: function() {

            },

        },

        trial: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

            perchEvent: function() {

            },

        },

        failedSession: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

        },

        endedSession: {
            _onEnter: function() {

            },

            "*": function() {

            },

            _onExit: function() {

            },

        },

    },
    // External Facing API

    initializeDevices: function() {
        console.log("initialize API");
        this.handle( "initialize" );
    },

    startExperiment: function() {
        console.log("startExperiment API");
        this.handle( "startExperiment" );
    },

    cancelExperiment: function() {
        console.log("cancelExperiment API");
        this.handle( "cancelExperiment" );
    },

    startSession: function() {
        console.log("startSession API");
        this.handle( "startSession" );
    },

    endSession: function() {
        console.log("endSession API");
        this.handle( "endSession" );
    },

    dropMeat: function() {
        console.log("dropMeat API");
        this.handle( "dropMeat" );
    },

    lightOn: function() {
        console.log("lightOn API");
        this.handle( "lightOn" );
    },

    lightsOff: function() {
        console.log("lightsOff API");
        this.handle( "lightsOff" );
    },

    perchEvent: function() {
        console.log("perchEvent API");
        this.handle( "perchEvent" );
    },

} );

experiment.on("*", function (eventName, data){
    console.log("this thing happened:", eventName, data);
});

module.exports.experiment = experiment;<|endoftext|>


<commit_before><commit_msg>pushing online status to client<commit_after><|endoftext|>


<commit_before>/**
 * Configuration
 */
var config = {
  styles: {
    destination: 'dist',
    fileName: 'avalanche.css',
    extractDestination: 'dist-extract',
    watchDirectories: ['scss/**/*']
  },
  scripts: {
    destination: 'dist',
    fileName: 'avalanche.js',
    extractDestination: 'dist-extract',
    watchDirectories: ['js/**/*']
  },
  styleGuide: {
    destination: 'style-guide'
  },
  sassOptions: {
    precision: 7
  }
};

/**
 * Plugins
 */
var browserify   = require('browserify');
var del          = require('del');
var eyeglass     = require('eyeglass');
var fs           = require('fs');
var gulp         = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var cssGlobbing  = require('gulp-css-globbing');
var cssnano      = require('gulp-cssnano');
var livereload   = require('gulp-livereload');
var minifyCss    = require('gulp-minify-css');
var postcss      = require('gulp-postcss');
var rename       = require('gulp-rename');
var replace      = require('gulp-replace');
var sass         = require('gulp-sass');
var sourcemaps   = require('gulp-sourcemaps');
var uglify       = require('gulp-uglify');
var buffer       = require('vinyl-buffer');
var source       = require('vinyl-source-stream');

/**
 * Styles
 */
gulp.task('styles:build', ['clean:styles'], function () {
  return gulp.src('scss/**/*.scss')
    .pipe(cssGlobbing({
      extensions: ['.scss'],
      scssImportPath: {
        leading_underscore: false,
        filename_extension: false
      }
    }))
    .pipe(sourcemaps.init())
    .pipe(sass(eyeglass(config.sassOptions)).on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest(config.styles.destination))
    .pipe(livereload());
});

gulp.task('styles:extract', ['clean:styles:extract', 'styles:minify'], function () {
  fs.readFile(config.styles.destination + '/' + config.styles.fileName, 'utf8', function (error, data) {
    if (error) throw error;

    var files = stylesExtractFiles(data);

    for (var fileName in files) {
      var fileData = files[fileName];
      var fileDir = config.styles.extractDestination;
      var filePath = fileDir + '/' + fileName;
      // Create directory if it doesn't exist.
      if (!fs.existsSync(fileDir)){
        fs.mkdirSync(fileDir);
      }
      // Create the file.
      fs.openSync(filePath, 'w');
      fs.writeFileSync(filePath, fileData);
      // Create a minified version of the file.
      stylesMinify(filePath, fileDir);
    }
  });
});

gulp.task('styles:minify', ['styles:build'], function () {
  stylesMinify(config.styles.destination + '/' + config.styles.fileName, config.styles.destination);
});

function stylesExtractFiles(data) {
  var files = {};
  var extractRegExp = /\/\* extract (.*?) \*\/((.|\n)*?)\/\* end extract \1 \*\//g;

  // Find extract placeholders in the CSS file.
  while (match = extractRegExp.exec(data)) {
    var extractFileName = match[1];
    var extractFileData = match[0].replace('/* extract ' + extractFileName + ' */', '').replace('/* end extract ' + extractFileName + ' */', '');
    if (!files[extractFileName]) {
      files[extractFileName] = '';
    }
    // Append the file data if it already exists.
    files[extractFileName] += extractFileData;

    // Find nested extraction placeholders.
    var nestedFiles = stylesExtractFiles(extractFileData);
    for (var nestedFileName in nestedFiles) {
      var nestedFileData = nestedFiles[nestedFileName];
      if (!files[nestedFileName]) {
        files[nestedFileName] = '';
      }
      files[nestedFileName] += nestedFileData;
    }
  }

  return files;
}

function stylesMinify(files, dest) {
  return gulp.src(files)
    .pipe(minifyCss())
    .pipe(replace(/[^;\{]+:[^;\}]+;?\/\*\!remove\*\//g, ''))
    .pipe(cssnano())
    .pipe(rename(function (path) {
      path.basename += '.min';
    }))
    .pipe(gulp.dest(dest))
    .pipe(livereload());
}

/**
 * Scripts
 */
gulp.task('scripts:build', ['clean:scripts'], function () {
  // set up the browserify instance on a task basis
  var b = browserify({
    entries: './js/avalanche.js',
    debug: true
  });

  return b.bundle()
    .pipe(source('avalanche.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(uglify())
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest(config.scripts.destination));
});

/**
 * Style guide
 *
 * Create a mdcss style guide.
 */
gulp.task('style_guide', ['styles:minify'], function () {
  return gulp.src(config.styles.destination + '/' + config.styles.fileName)
    .pipe(postcss([
      require('mdcss')({
        theme: require('mdcss-theme-github')({
          logo: '../logo.svg',
          examples: {
            css: ['../' + config.styles.destination + '/' + config.styles.fileName],
            bodyjs: ['../dist/avalanche.js'],
            htmlcss: '',
            bodycss: ''
          }
        }),
        destination: config.styleGuide.destination
      })
    ]));
});

/**
 * Clean
 *
 * Remove compiled files before regenerating them.
 */
gulp.task('clean:styles', function () {
  return del([
    // Remove everything inside the destination direcotry.
    config.styles.destination + '/**/*.css',
    config.styles.destination + '/**/*.css.map'
  ]);
});

gulp.task('clean:scripts', function () {
  return del([
    // Remove everything inside the destination direcotry.
    config.styles.destination + '/**/*.js',
    config.styles.destination + '/**/*.js.map'
  ]);
});

gulp.task('clean:styles:extract', function () {
  return del([
    config.styles.extractDestination + '/**/*.css',
    config.styles.extractDestination + '/**/*.css.map'
  ]);
});

gulp.task('clean:scripts:extract', function () {
  return del([
    config.styles.extractDestination + '/**/*.js',
    config.styles.extractDestination + '/**/*.js.map'
  ]);
});

/**
 * Watch
 */
gulp.task('watch', function () {
  livereload.listen();
  gulp.watch(config.styles.watchDirectories, ['styles:minify']);
});

gulp.task('watch:extract', function () {
  livereload.listen();
  gulp.watch(config.styles.watchDirectories, ['styles:extract']);
});

gulp.task('watch:style_guide', function () {
  livereload.listen();
  gulp.watch(config.styles.watchDirectories, ['style_guide']);
});

/**
 * Default task
 *
 * Run this task with `gulp`.
 */
gulp.task('default', function () {
  gulp.start('watch');
});
<commit_msg>rename "fileName" gulp configuration option to "fileNameDestination" to be more clear (fixes #193), remove script extract functionality, add config options for the script build task, use variables in the script build task, add the script build task to the watch tasks<commit_after>/**
 * Configuration
 */
var config = {
  styles: {
    destination: 'dist',
    destinationFileName: 'avalanche.css',
    extractDestination: 'dist-extract',
    watchDirectories: ['scss/**/*']
  },
  scripts: {
    destination: 'dist',
    destinationFileName: 'avalanche.js',
    browserifyEntries: ['js/avalanche.js'],
    watchDirectories: ['js/**/*']
  },
  styleGuide: {
    destination: 'style-guide'
  },
  sassOptions: {
    precision: 7
  }
};

/**
 * Plugins
 */
var browserify   = require('browserify');
var del          = require('del');
var eyeglass     = require('eyeglass');
var fs           = require('fs');
var gulp         = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var cssGlobbing  = require('gulp-css-globbing');
var cssnano      = require('gulp-cssnano');
var livereload   = require('gulp-livereload');
var minifyCss    = require('gulp-minify-css');
var postcss      = require('gulp-postcss');
var rename       = require('gulp-rename');
var replace      = require('gulp-replace');
var sass         = require('gulp-sass');
var sourcemaps   = require('gulp-sourcemaps');
var uglify       = require('gulp-uglify');
var buffer       = require('vinyl-buffer');
var source       = require('vinyl-source-stream');

/**
 * Styles
 */
gulp.task('styles:build', ['clean:styles'], function () {
  return gulp.src('scss/**/*.scss')
    .pipe(cssGlobbing({
      extensions: ['.scss'],
      scssImportPath: {
        leading_underscore: false,
        filename_extension: false
      }
    }))
    .pipe(sourcemaps.init())
    .pipe(sass(eyeglass(config.sassOptions)).on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest(config.styles.destination))
    .pipe(livereload());
});

gulp.task('styles:extract', ['clean:styles:extract', 'styles:minify'], function () {
  fs.readFile(config.styles.destination + '/' + config.styles.destinationFileName, 'utf8', function (error, data) {
    if (error) throw error;

    var files = stylesExtractFiles(data);

    for (var fileName in files) {
      var fileData = files[fileName];
      var fileDir = config.styles.extractDestination;
      var filePath = fileDir + '/' + fileName;
      // Create directory if it doesn't exist.
      if (!fs.existsSync(fileDir)){
        fs.mkdirSync(fileDir);
      }
      // Create the file.
      fs.openSync(filePath, 'w');
      fs.writeFileSync(filePath, fileData);
      // Create a minified version of the file.
      stylesMinify(filePath, fileDir);
    }
  });
});

gulp.task('styles:minify', ['styles:build'], function () {
  stylesMinify(config.styles.destination + '/' + config.styles.destinationFileName, config.styles.destination);
});

function stylesExtractFiles(data) {
  var files = {};
  var extractRegExp = /\/\* extract (.*?) \*\/((.|\n)*?)\/\* end extract \1 \*\//g;

  // Find extract placeholders in the CSS file.
  while (match = extractRegExp.exec(data)) {
    var extractFileName = match[1];
    var extractFileData = match[0].replace('/* extract ' + extractFileName + ' */', '').replace('/* end extract ' + extractFileName + ' */', '');
    if (!files[extractFileName]) {
      files[extractFileName] = '';
    }
    // Append the file data if it already exists.
    files[extractFileName] += extractFileData;

    // Find nested extraction placeholders.
    var nestedFiles = stylesExtractFiles(extractFileData);
    for (var nestedFileName in nestedFiles) {
      var nestedFileData = nestedFiles[nestedFileName];
      if (!files[nestedFileName]) {
        files[nestedFileName] = '';
      }
      files[nestedFileName] += nestedFileData;
    }
  }

  return files;
}

function stylesMinify(files, dest) {
  return gulp.src(files)
    .pipe(minifyCss())
    .pipe(replace(/[^;\{]+:[^;\}]+;?\/\*\!remove\*\//g, ''))
    .pipe(cssnano())
    .pipe(rename(function (path) {
      path.basename += '.min';
    }))
    .pipe(gulp.dest(dest))
    .pipe(livereload());
}

/**
 * Scripts
 */
gulp.task('scripts:build', ['clean:scripts'], function () {
  // Set up the browserify instance.
  var b = browserify({
    entries: config.scripts.browserifyEntries,
    debug: true
  });

  return b.bundle()
    .pipe(source(config.scripts.destinationFileName))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(uglify())
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest(config.scripts.destination));
});

/**
 * Style guide
 *
 * Create a mdcss style guide.
 */
gulp.task('style_guide', ['styles:minify'], function () {
  return gulp.src(config.styles.destination + '/' + config.styles.destinationFileName)
    .pipe(postcss([
      require('mdcss')({
        theme: require('mdcss-theme-github')({
          logo: '../logo.svg',
          examples: {
            css: ['../' + config.styles.destination + '/' + config.styles.destinationFileName],
            bodyjs: ['../dist/avalanche.js'],
            htmlcss: '',
            bodycss: ''
          }
        }),
        destination: config.styleGuide.destination
      })
    ]));
});

/**
 * Clean
 *
 * Remove compiled files before regenerating them.
 */
gulp.task('clean:styles', function () {
  return del([
    // Remove everything inside the destination direcotry.
    config.styles.destination + '/**/*.css',
    config.styles.destination + '/**/*.css.map'
  ]);
});

gulp.task('clean:scripts', function () {
  return del([
    // Remove everything inside the destination direcotry.
    config.styles.destination + '/**/*.js',
    config.styles.destination + '/**/*.js.map'
  ]);
});

gulp.task('clean:styles:extract', function () {
  return del([
    config.styles.extractDestination + '/**/*.css',
    config.styles.extractDestination + '/**/*.css.map'
  ]);
});

/**
 * Watch
 */
gulp.task('watch', function () {
  livereload.listen();
  gulp.watch(config.styles.watchDirectories, ['styles:minify']);
  gulp.watch(config.scripts.watchDirectories, ['scripts:build']);
});

gulp.task('watch:extract', function () {
  livereload.listen();
  gulp.watch(config.styles.watchDirectories, ['styles:extract']);
});

gulp.task('watch:style_guide', function () {
  livereload.listen();
  gulp.watch(config.styles.watchDirectories, ['style_guide']);
  gulp.watch(config.scripts.watchDirectories, ['scripts:build']);
});

/**
 * Default task
 *
 * Run this task with `gulp`.
 */
gulp.task('default', function () {
  gulp.start('watch');
});
<|endoftext|>


<commit_before>const chalk = require('chalk')
const {jsVariants} = require('interpret')
const Liftoff = require('liftoff')

/**
 * Lifts off the bulbo.
 * @param {string} name The name of the module
 * @param {object} options The options
 * @return {Promise}
 */
module.exports = (name, options) => {
  const logger = require('../util/logger')(name)
  options = options || {}

  return new Promise((resolve, reject) => {
    new Liftoff({name, extensions: jsVariants})

    .on('require', moduleName => { logger.log('Requiring external module', chalk.magenta(moduleName)) })

    .on('requireFail', moduleName => { logger.log(chalk.red(`Failed to load external module ${moduleName}`)) })

    .launch({}, env => {
      if (!env.modulePath) {
        logger.log(chalk.red(`Error: Local ${name} module not found`))
        logger.log('Try running:', chalk.green(`npm install ${name}`))

        process.exit(1)
      }

      const moduleIf = require(env.modulePath)

      moduleIf.setLogger(logger)

      if (!options.noConfig && !env.configPath) {
        logger.log(chalk.red(`Error: No ${name}file found`))

        process.exit(1)
      }

      logger.log('Using:', chalk.magenta(env.configPath))

      require(env.configPath)

      if (moduleIf.isEmpty()) {
        logger.log(chalk.red('Error: No asset defined'))

        process.exit(1)
      }

      resolve(moduleIf)
    })
  })
}
<commit_msg>refactor(liftoff.js): remove noConfig option<commit_after>const chalk = require('chalk')
const {jsVariants} = require('interpret')
const Liftoff = require('liftoff')

/**
 * Lifts off the module using js-liftoff.
 * @param {string} name The name of the module
 * @param {object} options The options
 * @return {Promise}
 */
module.exports = (name, options) => {
  const logger = require('../util/logger')(name)
  options = options || {}

  return new Promise((resolve, reject) => {
    new Liftoff({name, extensions: jsVariants})

    .on('require', moduleName => { logger.log('Requiring external module', chalk.magenta(moduleName)) })

    .on('requireFail', moduleName => { logger.log(chalk.red(`Failed to load external module ${moduleName}`)) })

    .launch({}, env => {
      if (!env.modulePath) {
        logger.log(chalk.red(`Error: Local ${name} module not found`))
        logger.log('Try running:', chalk.green(`npm install ${name}`))

        process.exit(1)
      }

      const moduleIf = require(env.modulePath)

      moduleIf.setLogger(logger)

      if (!env.configPath) {
        logger.log(chalk.red(`Error: No ${name}file found`))

        process.exit(1)
      }

      logger.log('Using:', chalk.magenta(env.configPath))

      require(env.configPath)

      if (moduleIf.isEmpty()) {
        logger.log(chalk.red('Error: No asset defined'))

        process.exit(1)
      }

      resolve(moduleIf)
    })
  })
}
<|endoftext|>