UNPKG

toloframework

Version:

Javascript/HTML/CSS compiler for Firefox OS or nodewebkit apps using modules in the nodejs style.

280 lines (268 loc) 7.01 kB
#! /usr/bin/env node // -*- js -*- var DEF = { init: { desc: "start a fresh new project." }, clean: { desc: "remove all temporary files." }, build: { desc: "compile project in the www/ folder." }, debug: { desc: "JS and CSS files won't be minified." }, php: { desc: "add PHP services." }, test: { desc: "prepare Karma tests.", opts: { dir: { desc: "Karma spec folder. Default is '-dir spec'.", args: ["spec"] } } }, doc: { desc: "create documentation." }, jsdoc: { desc: "create JSDoc documentation." }, watch: { desc: "watch for files change." }, version: { desc: "increment version number." } }; /** * * @module tfw */ require("colors"); var FS = require("fs"); var Path = require("path"); var Util = require("../lib/util.js"); var Init = require("../lib/init.js"); var Project = require("../lib/project"); var Package = require("../lib/package"); var PathUtils = require("../lib/pathutils"); var OptionsParse = require("../lib/options-parser"); // Read the version in the package file. var cfg = Package; var txt = " ToloFrameWork " + cfg.version + " "; var sep = ""; for (var i = 0 ; i < txt.length ; i++) { sep += "-"; } sep = "+" + sep + "+"; txt = "| ToloFrameWork " + cfg.version.bold + " |"; console.log(sep); console.log(txt); console.log(sep); console.log(); String.prototype.err = function() { var sep = "+------------------------------------------------------------------------------------------------------------------------+"; var txt = ''; this.split("\n").forEach(function (line) { var buff = '| ', i, c, mode = 0; for (i = 0; i < line.length; i++) { c = line.charCodeAt(i); if (mode == 0) { if (c > 31) { buff += line.charAt(i); } else if (c == 7) { buff += " "; } else if (c == 27) { // Remove all color information. mode = 1; } } else { if (c == 109) { mode = 0; } } } while(buff.length < 120) { buff += ' '; } txt += (buff + " |").redBG.white.bold + "\n"; }); return sep.redBG.white.bold + "\n" + txt + sep.redBG.white.bold + "\n"; }; var firstProcess = true; var tasks = []; var options = {}; var args = process.argv; var parsedCommandLine = OptionsParse.parse( args, DEF ); if( parsedCommandLine.init ) { Init.start( cfg ); return; } if( parsedCommandLine.clean ) { tasks.push(function(prj) { console.log("Cleaning...".green); Util.cleanDir("./tmp"); var cfgFile = prj.srcPath('$.js'); if (FS.existsSync(cfgFile)) { FS.unlinkSync(filepath); } }); } if( parsedCommandLine.version ) { tasks.push(function(prj) { if (firstProcess) { console.log("Incrementing version...".green); prj.makeVersion(); } }); } if( parsedCommandLine.debug ) { tasks.push(function(prj) { console.log("Build for DEVELOPMENT. Don't minify, don't combine.".green); options.dev = true; options.debug = true; console.log("options: ", options); }); } if( parsedCommandLine.build ) { tasks.push(function(prj) { prj.compile(options); }); } if( parsedCommandLine.php ) { tasks.push(function(prj) { prj.services(options); }); } if( parsedCommandLine.doc ) { tasks.push(function(prj) { prj.makeDoc(options); }); } if( parsedCommandLine.jsdoc ) { tasks.push(function(prj) { prj.makeJSDoc(options); }); } if( parsedCommandLine.test ) { tasks.push(function(prj) { var modules = prj.getCompiledFiles(); if (modules.length == 0) { modules = prj.compile(options); } prj.makeTest( modules, parsedCommandLine.test.dir[0] ); }); } if (tasks.length == 0) { console.log(); console.log( OptionsParse.usage( DEF ) ); console.log("Examples:"); console.log(" tfw build clean"); console.log(" tfw test -dir \"./spec-jasmine\""); console.log(); } else { function start() { try { console.log(); console.log(("" + (new Date())).green); console.log(); var time = Date.now(); var prj = Project.createProject('.'); tasks.forEach(function(task) { task(prj); }); var now = Date.now(); console.log('----------------------------------------'); console.log( "Time: " + ((now - time) / 1000).toFixed(3).bold + " seconds."); return prj; } catch (x) { x.fatal = x.fatal || "" + x; x.src = x.src || [""]; x.id = x.id || "Internal javascript error"; console.error("\n"); console.error("+-------------+".redBG.white.bold); console.error("| FATAL ERROR |".redBG.white.bold + " " + (typeof x.id === 'string' ? x.id.red.bold : '')); console.error((x.fatal).err()); x.src.forEach(function (src, idx) { src = src || ""; console.error(src.red.bold); }); console.error("\n"); if (x.stack) { console.error(x.stack.trim().red); console.error("\n"); } return false; } } var timer = 0; var watchedDirectories = []; function watch(path) { if (watchedDirectories.indexOf(path) == -1) { //console.log("Watching ".cyan + path); watchedDirectories.push(path); var watcher = FS.watch(path); watcher.path = path; watcher.on('change', processLater); } } var prj = start(); firstProcess = false; function processLater(eventName, filename) { if (filename) { // Don't compile if only `manifest.webapp` changed. if (filename == 'manifest.webapp') return; if (filename.charAt(0) == '#') return; if (filename.substr(0, 2) == '.#') return; if (filename.charAt(filename.length - 1) == '~') return; var path = Path.join(this.path, filename); if (PathUtils.isDirectory(path)) { if (!FS.existsSync(path)) return; if (watchedDirectories.indexOf(filename) == -1) { watch(path); } return; } console.log("File change: " + path.bold.yellow); // If a resource file changes, we have to touch the corresponding module's JS file. prj.cascadingTouch(path); } if (timer) { clearTimeout(timer); } timer = setTimeout(start, 50); } // Watch files? if( parsedCommandLine.watch ) { if (!prj) return; console.log(); var fringe = [Path.join(__dirname, "../ker"), prj.srcPath(), prj.srcPath("../package.json")]; fringe.push.apply( fringe, prj.getExtraModulesPath() ); var path; while (fringe.length > 0) { path = fringe.pop(); watch(path); if (PathUtils.isDirectory(path)) { FS.readdirSync(path).forEach( function(filename) { var subpath = Path.join(path, filename); if (PathUtils.isDirectory(subpath)) { fringe.push(subpath); } } ); } } console.log(); } }