UNPKG

pages

Version:

AngularJS / Node.js sidekick.

316 lines (185 loc) 8.73 kB
program = require 'commander' fs = require 'fs-extra' path = require 'path' refresh = require '../lib/refresh' log = require '../lib/log' server = require '../server' utils = require '../lib/utils' notify = require '../lib/notify' generator = require '../lib/generator' utils = require '../lib/utils' bake = require "#{global.pkgBasePath}/tasks/bake" configPath = "#{process.env.HOME}/.pages" templatePath = "#{process.env.HOME}/.pages/templates" depsPath = "#{process.env.HOME}/.pages/deps" throwError = (error) -> notify 'Pages Error', error throw new Error error setDev = () -> process.env.NODE_ENV = 'development' setProd = () -> process.env.NODE_ENV = 'production' setTest = () -> process.env.NODE_ENV = 'test' createTemplateDir = (cb) -> utils.runWithCb "mkdir #{configPath}", () -> utils.runWithCb "mkdir #{templatePath}", () -> cb() catchExceptions = () -> process.on 'uncaughtException', (error) -> log.err error setPort = (opts) -> if !opts.port then opts.port = 80 else opts.port = parseInt opts.port process.env.PORT = opts.port opts sanitize = (text) -> text.replace(/^[\s,]+/,"").replace(/[\s,]+$/,"").replace(/\s*,+\s*(,+\s*)*/g,",").split(' ').join('-').toLowerCase() camelCase = (text) -> text.replace(/^[\s,]+/,"").replace(/[\s,]+$/,"").replace(/\s*,+\s*(,+\s*)*/g,",").split(' ').join('-').toLowerCase() isTemplate = (cb) -> fs.exists templatePath, cb _todo_ This returns extremely slow if lots of files, just look for adequate file. ifNotPagesApp = (cb) -> try require "#{process.cwd()}/pages" throwError 'Already inside a Pages application, aborting.' catch error cb() ifPagesApp = (cb) -> try require "#{process.cwd()}/pages" cb() catch error throwError 'Invalid Pages application, aborting.' taskRunner = (taskName, opts, cb) -> try task = require "#{process.cwd()}/tasks/#{taskName}" task opts, () -> if cb then cb() else done() catch error Is task part of Pages? try task = require "#{global.pkgBasePath}/tasks/#{taskName}" task opts, () -> if cb then cb() else done() catch error console.log error throwError "No tasks found which match tasks/#{taskName}." serverRunner = (opts) -> opts = setPort opts if opts.cached then global.cached = true else global.cached = false Use compiled assets. if opts.packaged server.run () -> refresh opts.browser done "Pages application running on port #{process.env.PORT}." Build the assets based on the environment. else taskRunner 'bake', opts, () -> server.run () -> refresh opts.browser done "Pages application running on port #{process.env.PORT}." Generator validation. validate = (opts) -> throwError 'No type specified.' if !opts.type throwError 'No name specified.' if !opts.name types = [ 'app' 'angular_module' 'page' 'server_module' ] throwError 'Invalid type specified`.' if types.indexOf(opts.type) is -1 switch opts.type when 'page' throwError 'No route specified.' if !opts.route return true done = (msg) -> if msg then log.ok msg else log.ok 'Alright, alright.' ## Public API ## program .version JSON.parse(fs.readFileSync("#{global.pkgBasePath}/package.json")).version ### config ### This command allows you to configure Pages. program.command('config') .description('Configure Pages.') .option('--skeleton [skeleton]', 'Configure the default application skeleton by providing a local folder path.') .option('--destroy-skeleton', 'Remove the configured application skeleton.') .action (opts) -> if opts.destroySkeleton utils.runWithCb "rm -rf #{templatePath}", () -> done 'Removed configured application skeleton.' return isTemplate (template) -> setDev() throwError 'No skeleton specified.' if !opts.skeleton Strip. opts.skeleton = opts.skeleton.substring(0, opts.skeleton.length - 1) if opts.skeleton.substring(opts.skeleton.length - 1, opts.skeleton.length) is '/' copyTemplate = () -> utils.copyDir from: opts.skeleton to: templatePath , done if template utils.runWithCb "rm -rf #{templatePath}", () -> createTemplateDir () -> copyTemplate() else createTemplateDir () -> copyTemplate() ### generate ### This command allows us to generate a Pages application and its core pieces (as AngularJS modules). program.command('generate') .description('Genererate AngularJS applications, angular_modules, pages, and server_modules.') .option('--type [type]', 'The component to generate, "app", "angular_module", "page", or "server_module".') .option('--name [name]', 'The name of the generated component.') .action (opts) -> ifNotPagesApp () -> isTemplate (template) -> opts.template = template setDev() validate opts switch opts.type when 'app' opts.APPNAME = sanitize opts.name generator.app opts, done when 'server_module' opts.NAME = sanitize opts.name generator.server_module opts, done ### task ### This command allows us to invoke Pages Tasks. program .command('task [taskName]') .description('Invoke Pages Tasks: "bake", "assets".') .option('--env [env]', 'The environment to invoke the task in, `development` or `production` (if the Task does not set it).') .action (taskName, opts) -> ifPagesApp () -> isTemplate (template) -> opts.template = template if opts.env and opts.env is 'production' then setProd() else setDev() throwError 'No task specified.' if !taskName taskRunner taskName, opts ### run ### This command allows us to run a standard web server in `development` mode while also utilizing Pages Modules at both core and app levels. program .command('run') .description('Run a Pages application in `development` mode.') .option('--port [port]', 'The port to run the HTTP server on, defaults to `80`.') .option('--browser [browser', 'The browser to reload, `chrome` or `safari`.') .option('--packaged', 'The app has been `baked`, and this starts the server with pre-compiled assets`.') .action (opts) -> ifPagesApp () -> setDev() utils.runWithCb "mkdir #{configPath}", () -> utils.runWithCb "mkdir #{depsPath}", () -> opts.watch = true serverRunner opts ### start ### This command allows us to run a standard web server in `production` mode while also utilizing Pages Modules at both core and app levels. program .command('start') .description('Run a Pages application in `production` mode.') .option('--port [port]', 'The port to run the HTTP server on, defaults to `80`.') .option('--browser [browser', 'The browser to reload, `chrome` or `safari`.') .option('--packaged', 'The app has been `baked`, and this starts the server with pre-compiled assets`.') .action (opts) -> ifPagesApp () -> setProd() catchExceptions() opts.watch = false serverRunner opts ### test ### This command allows us to test both server and client code. _todo_ Expose client tests. program.command('test [file]') .description('Run the tests inside the test/ or server_modules/test directory, or specify a file. ') .option('--die', 'On a test fail, stop running tests.') .option('--timeout [timeout]', 'How long each test should take, defaults to 10 seconds.') .action (file, opts) -> setTest() if file then file = "./test/#{file}.coffee" else file = './test' if opts.die then die = '-b' else die = '' if opts.timeout then timeout = parseInt(opts.timeout) * 1000 else timeout = 10 * 1000 utils.runWithCb "#{global.pkgBasePath}/node_modules/mocha/bin/mocha --compilers coffee:coffee-script --require coffee-script #{file} --reporter spec --require should -t #{timeout} --colors -b", done program.parse process.argv program.help() unless program.args.length