Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 290 lines (254 sloc) 5.988 kb
#!/usr/bin/env node
/**
* Module dependencies.
*/
var sys = require('sys'),
fs = require('fs'),
childProcess = require('child_process');
/**
* Framework version.
*/
var version = '1.0.0rc4';
/**
* stdin stream.
*/
var stdin;
/**
* Usage documentation.
*/
var usage = ''
+ '\x1b[1mUsage\x1b[0m: express [options] [PATH]\n'
+ '\n'
+ '\x1b[1mOptions\x1b[0m:\n'
+ ' -v, --version Output framework version\n'
+ ' -h, --help Output help information\n';
/**
* Jade layout template.
*/
var jadeLayout = [
'!!!',
'html',
' head',
' title= title',
' link(rel=\'stylesheet\', href=\'/stylesheets/style.css\')',
' body!= body'
].join('\n');
/**
* Default less template.
*/
var less = [
'body {',
' padding: 50px;',
' font: 14px "Lucida Grande", "Helvetica Nueue", Arial, sans-serif;',
'}'
].join('\n');
/**
* Jade index template.
*/
var jadeIndex = [
'h1= title',
'p Welcome to #{title}'
].join('\n');
/**
* App test template.
*/
var appTest = [
"",
"// Run $ expresso",
"",
"/**",
" * Module dependencies.",
" */",
"",
"var app = require('../app');",
"",
"module.exports = {",
" 'GET /': function(assert){",
" assert.response(app,",
" { url: '/' },",
" { status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8' }},",
" function(res){",
" assert.includes(res.body, '<title>Express</title>');",
" });",
" }",
"};",
].join('\n');
/**
* App template.
*/
var app = [
'',
'/**',
' * Module dependencies.',
' */',
'',
'var express = require(\'express\');',
'',
'var app = module.exports = express.createServer();',
'',
'// Configuration',
'',
'app.configure(function(){',
' app.set(\'views\', __dirname + \'/views\');',
' app.use(express.bodyDecoder());',
' app.use(express.methodOverride());',
' app.use(express.compiler({ src: __dirname + \'/public\', enable: [\'less\'] }));',
' app.use(app.router);',
' app.use(express.staticProvider(__dirname + \'/public\'));',
'});',
'',
'app.configure(\'development\', function(){',
' app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); ',
'});',
'',
'app.configure(\'production\', function(){',
' app.use(express.errorHandler()); ',
'});',
'',
'// Routes',
'',
'app.get(\'/\', function(req, res){',
' res.render(\'index.jade\', {',
' locals: {',
' title: \'Express\'',
' }',
' });',
'});',
'',
'// Only listen on $ node app.js',
'',
'if (!module.parent) {',
' app.listen(3000);',
' console.log("Express server listening on port %d", app.address().port)',
'}',
''
].join('\n');
// Parse arguments
var args = process.argv.slice(2),
path = '.';
while (args.length) {
var arg = args.shift();
switch (arg) {
case '-h':
case '--help':
abort(usage);
break;
case '-v':
case '--version':
abort(version);
break;
default:
path = arg;
}
}
// Generate application
(function createApplication(path) {
emptyDirectory(path, function(empty){
if (empty) {
createApplicationAt(path);
} else {
confirm('destination is not empty, continue? ', function(ok){
if (ok) {
stdin.destroy();
createApplicationAt(path);
} else {
abort('aborting');
}
});
}
});
})(path);
/**
* Create application at the given directory `path`.
*
* @param {String} path
*/
function createApplicationAt(path) {
mkdir(path, function(){
mkdir(path + '/pids');
mkdir(path + '/logs');
mkdir(path + '/public/javascripts');
mkdir(path + '/public/images');
mkdir(path + '/public/stylesheets', function(){
write(path + '/public/stylesheets/style.less', less);
});
mkdir(path + '/views/partials', function(){
write(path + '/views/layout.jade', jadeLayout);
write(path + '/views/index.jade', jadeIndex);
});
mkdir(path + '/test', function(){
write(path + '/test/app.test.js', appTest);
});
write(path + '/app.js', app);
});
}
/**
* Check if the given directory `path` is empty.
*
* @param {String} path
* @param {Function} fn
*/
function emptyDirectory(path, fn) {
fs.readdir(path, function(err, files){
if (err && err.errno !== process.ENOENT) throw err;
fn(!files || !files.length);
});
}
/**
* echo str > path.
*
* @param {String} path
* @param {String} str
*/
function write(path, str) {
fs.writeFile(path, str);
sys.puts(' create : ' + path);
}
/**
* Prompt confirmation with the given `msg`.
*
* @param {String} msg
* @param {Function} fn
*/
function confirm(msg, fn) {
prompt(msg, function(val){
fn(/^ *y(es)?/i.test(val));
});
}
/**
* Prompt input with the given `msg` and callback `fn`.
*
* @param {String} msg
* @param {Function} fn
*/
function prompt(msg, fn) {
stdin = stdin || process.openStdin();
sys[msg[msg.length - 1] == ' ' ? 'print' : 'puts'](msg);
stdin.setEncoding('ascii');
stdin.addListener('data', function(data){
fn(data);
stdin.removeListener('data', arguments.callee);
});
}
/**
* Mkdir -p.
*
* @param {String} path
* @param {Function} fn
*/
function mkdir(path, fn) {
childProcess.exec('mkdir -p ' + path, function(err){
if (err) throw err;
sys.puts(' create : ' + path);
fn && fn();
});
}
/**
* Exit with the given `str`.
*
* @param {String} str
*/
function abort(str) {
sys.error(str);
process.exit(1);
}
Jump to Line
Something went wrong with that request. Please try again.