Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

1005 lines (849 sloc) 29.225 kB
// Load the basic Geddy toolkit
require('../lib/geddy')
// Dependencies
var cwd = process.cwd()
, fs = require('fs')
, path = require('path')
, utils = require('../lib/utils')
, Adapter = require('../lib/template/adapters')
, geddyPassport = 'geddy-passport@0.0.x'
, getRouterPath
, getRoutes
, addRoute
, mixinJSONData;
getRouterPath = function () {
var beginPath
, jsRouter = path.normalize('config/router.js')
, coffeeRouter = path.normalize('config/router.coffee')
, routerPath;
// Check if the router file exists
beginPath = path.join(cwd, 'config');
utils.file.searchParentPath(jsRouter, function (err) {
if (err) {
var jsErr = err;
// If jsEnvironment wasn't found, try finding coffee variant
utils.file.searchParentPath(coffeeRouter, beginPath, function (err) {
if (err) {
throw jsErr;
} else {
routerPath = coffeeRouter;
}
});
} else {
routerPath = jsRouter;
}
});
return routerPath;
};
getRoutes = function (resource) {
if (!resource) {
return geddy.router.toString();
}
var rts = []
, _rt
, i;
// If a full route name was given add it to the list(e,g,. users.index)
if (resource.match(/.+\..+/)) {
var res = resource.split('.')
, cont = res[0]
, action = res[1];
for (i in geddy.router.routes) {
_rt = geddy.router.routes[i];
if (_rt.params.controller.match(cont) &&
_rt.params.action.match(action)) {
rts.push(_rt);
}
}
}
else {
for (i in geddy.router.routes) {
_rt = geddy.router.routes[i];
if (_rt.params.controller.match(resource) ||
_rt.params.action.match(resource)) {
rts.push(_rt);
}
}
}
return rts.map(function (rt) {
return rt.toString();
}).join('\n');
};
addRoute = function (routerPath, newRoute) {
var text = fs.readFileSync(routerPath, 'utf8')
, routerArr;
// Don't add the same route over and over
if (text.indexOf(newRoute) == -1) {
// Add the new resource route just above the export
routerArr = text.split('exports.router');
routerArr[0] += newRoute + '\n';
text = routerArr.join('exports.router');
fs.writeFileSync(routerPath, text, 'utf8');
return true;
}
else {
return false;
}
};
mixinJSONData = function (file, obj) {
var data = obj || {};
if (utils.file.existsSync(file)) {
try {
var content = JSON.parse(fs.readFileSync(file, 'utf8'));
utils.object.merge(content, data);
fs.writeFileSync(file, JSON.stringify(content, null, 2));
}
catch (e) {
throw new Error("Could not parse " + file);
}
}
else {
console.log("There is no file " + file + " to add data to.");
}
};
namespace('env', function () {
task('init', function (environment) {
jake.addListener('complete', function (e) {
jake.Task['env:cleanup'].invoke();
});
geddy.config = require('../lib/config').readConfig({
environment: environment || 'development'
});
geddy.model = require('model');
require('../lib/init').init(geddy, function () {
complete();
});
}, {async: true});
task('cleanup', function () {
// Disconnect all the adapters
var adapters = geddy.model.loadedAdapters
, adapter;
for (var p in adapters) {
adapter = adapters[p];
if (typeof adapter.disconnect == 'function') {
adapter.disconnect();
}
}
});
});
namespace('console', function () {
task('start', ['env:init'], {async: true}, function (environment) {
var env = environment || 'development'
, t = jake.Task['env:init'];
t.addListener('complete', function () {
var repl = require('repl')
, rl;
rl = repl.start({
prompt: '>>> '
, input: process.stdin
, output: process.stdout
});
rl.on('close', function () {
console.log('Exiting...');
return complete();
})
rl.context.capture = function (err, data) {
return rl.context.results = {
err: err
, data: data
};
};
rl.context.echo = function (err, data) {
rl.context.capture(err, data);
if (err) {
console.log('Error: ', err);
}
if (data) {
if (data.length) {
for (var i in data) {
if (data[i] && data[i].toData) {
console.log(data[i].toData());
} else {
console.log(data[i]);
}
}
}
else {
if (data && data.toData) {
console.log(data.toData());
} else {
console.log(data);
}
}
} else {
console.log('No data');
}
};
rl.context.routes = function (resource) {
console.log(getRoutes(resource));
};
});
t.invoke(env);
});
});
namespace('routes', function () {
task('show', ['env:init'], {async: true}, function (resource) {
console.log('Showing route results for "' + resource + '"');
console.log(getRoutes(resource));
});
});
namespace('db', function () {
task('createTable', ['env:init'], function (name) {
var modelName
, createTable
, adapters
, adapter;
if (typeof name == 'string') {
if (name.indexOf('%') > -1) {
modelNames = name.split('%');
}
else {
modelNames = [name];
}
}
else {
modelNames = name;
}
createTable = function () {
if ((m = modelNames.shift())) {
// Make sure this is a correct model-name
m = utils.string.getInflections(m).constructor.singular;
if (!geddy.model[m]) {
throw new Error(m + ' is not a known model.');
}
adapter = geddy.model.adapters[m];
if (adapter) {
console.log('Creating table for ' + m);
adapter.createTable(m, function (err, data) {
if (err) { throw err }
createTable();
});
}
else {
createTable();
}
}
else {
complete();
}
};
// Defer until associations are set up
setTimeout(function () {
createTable();
}, 0);
}, {async: true});
task('init', ['env:init'], function () {
var modelNames = Object.keys(geddy.model.descriptionRegistry)
, createTask = jake.Task['db:createTable'];
createTask.once('complete', function () {
complete();
});
createTask.invoke(modelNames);
}, {async: true});
});
namespace('gen', function () {
var _writeTemplate = function (name, filename, dirname, opts) {
var options = opts || {}
, names = utils.string.getInflections(name)
, text = fs.readFileSync(path.join(__dirname, filename + '.ejs'), 'utf8').toString()
, bare = options.bare || false // Default to full controller
, adapter
, templContent
, fileDir
, filePath;
// Render with the right model name
adapter = new Adapter({engine: 'ejs', template: text});
templContent = adapter.render({names: names, bare: bare, properties: options.properties});
// Write file
fileDir = dirname;
if (!utils.file.existsSync(fileDir)) {
fs.mkdirSync(fileDir);
}
filePath = path.join(fileDir, names.filename[options.inflection] + '.js');
fs.writeFileSync(filePath, templContent, 'utf8');
console.log('[Added] ' + filePath);
};
var _formatModelProperties = function (properties) {
var obj = {default: {name: '', type: ''}};
if (!properties) {
return obj;
}
obj['default'].name = 'id';
obj['default'].type = 'string';
var itemsArr = properties.split('%')
, name
, type
, args
, i
, value;
i = -1;
while (++i < itemsArr.length) {
value = itemsArr[i];
name = utils.string.camelize(value.replace(/:.*/g, ''));
type = value.replace(/[a-zA-Z]*:?/, '');
args = type.replace(/[a-zA-Z]*:?/, '');
// Take off any args on the type
type = type.replace(/:.*/g, '');
// Defaults and aliases
if (!type) {
type = 'string';
}
if (args === 'def') {
args = 'default';
}
switch (type) {
case 'integer':
type = 'int';
break;
case 'bool':
type = 'boolean';
break;
case 'default':
case 'def':
type = 'string';
args = 'default';
break;
}
// Manage properties that deal with changing default properties
if (args === 'default') {
// Reset old default property to it's own property, only if it's not
// already the default
if (name !== obj['default'].name) {
// If the new default item already exists then delete it
if (obj[name]) {
delete obj[name];
}
obj[obj['default'].name] = obj[obj['default'].name] || obj['default'];
}
// Add new default property
obj['default'] = {name: name, type: type};
continue;
}
// If ID property is given and it matches the default
// then rewrite the default with the new ID property
if (name === 'id' && obj['default'].name === 'id') {
obj['default'] = {name: name, type: type};
continue;
}
// If the name is name or title then set them to default, otherwise add
// the property normally
if (name === 'name' || name === 'title') {
// Reset old default to it's own property
obj[obj['default'].name] = obj[obj['default'].name] || obj['default'];
// Add new default property
obj['default'] = {name: name, type: type};
} else {
obj[name] = {name: name, type: type};
}
}
return obj;
};
// Creates a new Geddy app scaffold
task('app', function (name, engine, realtime) {
var basePath = path.join(__dirname, 'base')
, mkdirs
, cps
, text
, adapter;
if (!name) {
throw new Error('No app name specified.');
}
if (!engine || engine == 'default') {
engine = 'ejs';
}
if (realtime == 'default') {
realtime = false;
}
mkdirs = [
''
, 'config'
, 'app/models'
, 'app/controllers'
, 'app/helpers'
, 'lib'
, 'log'
, 'node_modules'
, 'test'
];
cps = [
(realtime) ? ['realtime/views/' + engine, 'app/views'] : ['views/' + engine, 'app/views']
, ['public', '']
, ['router.js', 'config']
, ['init.js', 'config']
, (realtime) ? ['realtime/environment.js', 'config'] : ['environment.js', 'config']
, ['development.js', 'config']
, ['production.js', 'config']
, ['secrets.json', 'config']
, ['main.js', 'app/controllers']
, ['application.js', 'app/controllers']
, ['favicon.ico', 'public']
, ['gitignore.txt', '.gitignore']
];
mkdirs.forEach(function (dir) {
jake.mkdirP(path.join(name, dir));
});
cps.forEach(function (cp) {
jake.cpR(path.join(basePath, cp[0]), path.join(name, cp[1]), {silent: true});
});
// one offs
if (realtime) {
jake.cpR(path.join(__dirname, '..', 'node_modules', 'socket.io' ), path.join(name, 'node_modules'), {silent: true});
}
// Compile Jakefile
text = fs.readFileSync(path.join(basePath, 'Jakefile.ejs'), 'utf8').toString();
adapter = new Adapter({engine: 'ejs', template: text});
fs.writeFileSync(path.join(name, 'Jakefile'), adapter.render({appName: name}), 'utf8');
// Compile package.json
text = fs.readFileSync(path.join(basePath, 'package.json.ejs'), 'utf8').toString();
adapter = new Adapter({engine: 'ejs', template: text});
fs.writeFileSync(path.join(name, 'package.json'), adapter.render({appName: name}), 'utf8');
// Add engine to package.json if it's not EJS
if (engine !== 'ejs') {
// Change to handlebars as we use it behind the scenes
if (engine === 'mustache') {
engine = 'handlebars';
}
var data = {dependencies: {}};
data.dependencies[engine] = "*";
mixinJSONData(path.join(name, 'package.json'), data);
}
console.log('Created app ' + name + '.');
});
// Creates a resource with a model, controller and a resource route
task('resource', function (name, modelProperties) {
var names
, modelTask = jake.Task['gen:model'];
if (!name) {
throw new Error('No resource name specified.');
}
modelTask.on('complete', function () {
jake.Task['gen:controller'].invoke(name);
jake.Task['gen:route'].invoke(name);
names = utils.string.getInflections(name);
// Create views folder but not actions
jake.mkdirP(path.join('app', 'views', names.filename.plural));
console.log('[Added] ' + names.filename.plural + ' view directory');
complete();
});
modelTask.invoke(name, modelProperties);
}, {async: true});
// Creates a full scaffold with views, a model, controller and a resource route
task('scaffold', function (name, realtime, engine, modelProperties) {
var modelTask = jake.Task['gen:model'];
if (!name) {
throw new Error('No scaffold name specified.');
}
if (!engine || engine == 'default') {
engine = 'ejs';
}
if (!realtime || realtime == 'default') {
realtime = false;
}
modelTask.on('complete', function () {
jake.Task['gen:test'].invoke(name,
{properties: modelProperties});
jake.Task['gen:controllerScaffold'].invoke(name,
{properties: modelProperties});
jake.Task['gen:route'].invoke(name);
jake.Task['gen:viewsScaffold'].invoke(name,
{engine: engine, properties: modelProperties, realtime: realtime});
complete();
});
modelTask.invoke(name, modelProperties, 'scaffold');
}, {async: true});
task('model', function (name, properties, modelPath) {
var createTableTask;
if (!name) {
throw new Error('No model name specified.');
}
if (!modelPath) {
modelPath = 'resource';
}
modelPath += '/model';
_writeTemplate(name, modelPath, path.join('app', 'models'), {
inflection: 'singular'
, properties: _formatModelProperties(properties)
});
// Try to create a table -- should be a no-op if an
// appropriate DB adapter can't be found
createTableTask = jake.Task['db:createTable'];
createTableTask.on('complete', function () {
complete();
});
createTableTask.invoke(name);
}, {async: true});
task('controller', function (name) {
if (!name) {
throw new Error('No controller name specified.');
}
_writeTemplate(name, 'resource/controller', path.join('app', 'controllers'),
{inflection: 'plural', bare: false});
});
task('test', function (name) {
if (!name) {
throw new Error('No test name specified.');
}
_writeTemplate(name, 'resource/test', 'test',
{inflection: 'singular'});
});
task('controllerScaffold', function (name, options) {
if (!name) {
throw new Error('No controller name specified.');
}
options = options || {};
_writeTemplate(name, 'scaffold/controller', path.join('app', 'controllers'), {
inflection: 'plural'
, bare: false
, properties: _formatModelProperties(options.properties)
});
});
task('bareController', function (name, engine) {
if (!name) {
throw new Error('No controller name specified.');
}
if (!engine || engine == 'default') {
engine = 'ejs';
}
_writeTemplate(name, 'resource/controller', path.join('app', 'controllers'),
{inflection: 'plural', bare: true});
jake.Task['gen:route'].invoke(name, {bare: true});
jake.Task['gen:views'].invoke(name, {bare: true, engine: engine});
});
task('route', function (name, options) {
if (!name) {
throw new Error('No route name specified.');
}
options = options || {};
var names = utils.string.getInflections(name)
, routerPath = getRouterPath()
, routeType = options.bare ? 'Bare' : 'Resource'
, newRoute;
if (routerPath) {
if (routerPath.match('.coffee')) {
if (options.bare) {
newRoute = 'router.match(\'/' + names.filename.plural +
'\').to controller: \'' + names.constructor.plural +
'\', action: \'index\'';
} else {
newRoute = 'router.resource \'' + names.filename.plural + '\'';
}
} else if (routerPath.match('.js')) {
if (options.bare) {
newRoute = 'router.match(\'/' + names.filename.plural +
'\').to({controller: \'' + names.constructor.plural +
'\', action: \'index\'});';
} else {
newRoute = 'router.resource(\'' + names.filename.plural + '\');';
}
}
if (addRoute(routerPath, newRoute)) {
console.log('[Added] ' + routeType + ' ' + names.filename.plural +
' route added to ' + routerPath);
}
else {
console.log(routeType + ' ' + names.filename.plural + ' route already defined in ' +
routerPath);
}
}
else {
console.log('There is no router file to add routes too');
}
});
task('views', function (name, options) {
if (!name) {
throw new Error('No view name specified.');
}
options = options || {};
// Option defaults
options.engine = options.engine || 'ejs';
var names = utils.string.getInflections(name)
, engine = options.engine
, appViewDir = path.join('app', 'views', names.filename.plural)
, templateViewDir = path.join(__dirname, 'views', engine)
, cmds = []
, ext = '.html'
, appLayoutPath
, actions
, addActionView;
// Set extension based on engine option
switch (engine) {
case 'ejs':
ext += '.ejs';
break;
case 'jade':
ext += '.jade';
break;
case 'handlebars':
ext += '.hbs';
break;
case 'mustache':
ext += '.ms';
break;
}
// Set application layout path
appLayoutPath = path.join('app', 'views', 'layouts', 'application');
// Copy template view to application path
addActionView = function (action) {
jake.cpR(path.join(templateViewDir, action + ext + '.ejs'), appViewDir, {silent: true});
};
jake.mkdirP(appViewDir);
jake.mkdirP('app/views/layouts');
addActionView('index');
// Add views for the other CRUD actions when doing a full-on resource
if (!options.bare) {
['add', 'edit', 'show'].forEach(function (action) {
addActionView(action);
});
}
// Create default layout if one doesn't exist
// Hack: There should be a better way to detect if a application layout exists
if (!utils.file.existsSync(appLayoutPath + '.html.ejs') && !utils.file.existsSync(appLayoutPath + '.html.jade') &&
!utils.file.existsSync(appLayoutPath + '.html.hbs') && !utils.file.existsSync(appLayoutPath + '.html.ms')) {
// Copy template layout file to apps application layout file
jake.cpR(path.join(templateViewDir, 'layout' + ext + '.ejs'), appLayoutPath + ext, {silent: true});
}
// Add engine to package.json if it's not EJS
if (engine !== 'ejs') {
// Change to handlebars as we use it behind the scenes
if (engine === 'mustache') {
engine = 'handlebars';
}
var data = {dependencies: {}};
data.dependencies[engine] = "*";
mixinJSONData('package.json', data);
}
console.log('[Added] View templates');
});
task('viewsScaffold', function (name, options) {
if (!name) {
throw new Error('No view name specified.');
}
options = options || {};
// Option defaults
options.engine = options.engine || 'ejs';
var names = utils.string.getInflections(name)
, engine = options.engine
, appViewDir = path.join('app', 'views', names.filename.plural)
, templateViewDir
, cmds = []
, ext = '.html'
, appLayoutPath
, layoutViewPath
, actions
, addActionView
, viewPath
, text
, adapter
, templContent;
// Set extension based on engine option
switch (engine) {
case 'ejs':
ext += '.ejs';
break;
case 'jade':
ext += '.jade';
break;
case 'handlebars':
ext += '.hbs';
break;
case 'mustache':
ext += '.ms';
break;
}
// Get view path
templateViewDir = options.realtime ?
path.join(__dirname, 'scaffold', 'realtime', 'views', engine) :
path.join(__dirname, 'scaffold', 'views', engine);
// Set application layout path
appLayoutPath = path.join('app', 'views', 'layouts', 'application');
// Function to compile the template
addActionView = function (action) {
viewPath = path.join(templateViewDir, action + ext + '.ejs');
if (!utils.file.existsSync(viewPath)) {
return;
}
text = fs.readFileSync(viewPath).toString();
// Compile template text
adapter = new Adapter({engine: 'ejs', template: text});
templContent = adapter.render({names: names, properties: _formatModelProperties(options.properties)});
// Write file
fs.writeFileSync(path.join(appViewDir, action + ext),
templContent.replace(/<@/g, '<%').replace(/@>/g, '%>'), 'utf8');
};
jake.mkdirP(appViewDir);
jake.mkdirP('app/views/layouts');
// Add views for the other CRUD actions when doing a full-on resource
['index', 'add', 'show', 'edit', 'form'].forEach(function (action) {
addActionView(action);
});
// Create default layout if one doesn't exist
// Hack: There should be a better way to detect if a application layout exists
if (!utils.file.existsSync(appLayoutPath + '.html.ejs') && !utils.file.existsSync(appLayoutPath + '.html.jade') &&
!utils.file.existsSync(appLayoutPath + '.html.hbs') && !utils.file.existsSync(appLayoutPath + '.html.ms')) {
// Copy template layout file to apps application layout file
jake.cpR(path.join(templateViewDir, 'layout' + ext + '.ejs'), appLayoutPath + ext, {silent: true});
}
// Add engine to package.json if it's not EJS
if (engine !== 'ejs') {
// Change to handlebars as we use it behind the scenes
if (engine === 'mustache') {
engine = 'handlebars';
}
var data = {dependencies: {}};
data.dependencies[engine] = "*";
mixinJSONData('package.json', data);
}
console.log('[Added] View templates');
});
// Generate a new application secret in environment.js
task('secret', function () {
var secretsFile = path.join(cwd, 'config', 'secrets.json')
, secret = utils.string.uuid(128);
mixinJSONData(secretsFile, {secret: secret});
console.log('Added app-secret to config/secrets.json.\n' +
'DO NOT add this file into your revision control.\n' +
'DO make a backup of it, keep it someplace safe.');
});
});
namespace('auth', function () {
task('update', {async: true}, function () {
var updatePath = path.join('geddy-passport', 'app', 'helpers', 'passport')
, from
, to;
console.log('Updating passport helpers from', geddyPassport);
jake.exec('npm uninstall ' + geddyPassport +
' && npm install ' + geddyPassport, function () {
from = path.join(cwd, 'node_modules', updatePath);
to = path.join(cwd, 'app', 'helpers');
jake.rmRf(path.join(cwd, 'passport'), {silent: true});
jake.cpR(from, to, {silent: true});
console.log("\nCleaning up...");
jake.exec('npm uninstall ' + geddyPassport, function () {
complete();
});
}, {printStdout: true});
});
task('init', {async: true}, function (engine) {
var readline = require('readline')
, fromBase = path.join(cwd, 'node_modules', 'geddy-passport')
, install = false
, rl, installPackages, passportCopy;
if (!engine || engine == 'default') {
engine = 'ejs';
}
// Create and start the prompt
rl = readline.createInterface({
input: process.stdin
, output: process.stdout
});
rl.setPrompt("WARNING: This command will create/overwrite files in your app.\n" +
"Do you wish to continue?(yes|no)\n\n");
rl.prompt();
rl.on('line', function (line) {
if (line === 'yes' || line === 'y') {
install = true;
}
rl.close();
});
rl.on('close', function () {
if (!install) {
return;
}
console.log('Installing', geddyPassport);
jake.exec('npm uninstall ' + geddyPassport +
' && npm install ' + geddyPassport, installPackages, {printStdout: true});
});
// Gets the package versions from geddy-passport's package.json
// and installs them, then calls passportCopy
installPackages = function () {
var deps = require(path.join(fromBase, 'package')).dependencies
, packages = ''
, k;
mixinJSONData(path.join(cwd, 'package.json'), {dependencies: deps});
for (k in deps) {
packages += k + '@' + deps[k] + ' ';
}
console.log("\nInstalling", packages);
jake.exec('npm uninstall ' + packages +
' && npm install ' + packages, passportCopy, {printStdout: true});
};
// Copy the contents of geddy-passport into the application
passportCopy = function () {
var list = require(path.join(fromBase, 'file_list'))
, routerPath = getRouterPath()
, newRoute
, from
, to
, p
, i;
// Copy files to the application
for (i = 0; i < list.length; i++) {
item = list[i];
from = path.join(fromBase, item);
to = path.dirname(path.join(cwd, item));
if (item.match('/app/views')) {
// If the view is not for the given engine, skip it
if (!item.match(engine)) {
continue;
}
to = to.replace(engine, "");
}
jake.mkdirP(to);
console.log('Creating file:', path.join(to, path.basename(item)));
// Delete any existing interferring templates
if (item.match('/app/views')) {
['.jade', '.ejs', '.ms', '.mustache', '.hbs', '.handlebars'].forEach(function (ext) {
p = path.basename(item, path.extname(item)) + ext;
jake.rmRf(path.join(to, p), {silent: true});
});
}
jake.cpR(from, to, {silent: true});
}
// Add new routes to router
if (routerPath) {
// CoffeeScript routes
if (routerPath.match('.coffee')) {
newRoute = "router.get('/login').to 'Main.login'\n" +
"router.get('/logout').to 'Main.logout'\n" +
"router.post('/auth/local').to 'Auth.local'\n" +
"router.get('/auth/twitter').to 'Auth.twitter'\n" +
"router.get('/auth/twitter/callback').to 'Auth.twitterCallback'\n" +
"router.get('/auth/facebook').to 'Auth.facebook'\n" +
"router.get('/auth/facebook/callback').to 'Auth.facebookCallback'\n" +
"router.get('/auth/yammer').to 'Auth.yammer'\n" +
"router.get('/auth/yammer/callback').to 'Auth.yammerCallback'\n" +
"router.resource 'users'";
} else {
newRoute = "router.get('/login').to('Main.login');\n" +
"router.get('/logout').to('Main.logout');\n" +
"router.post('/auth/local').to('Auth.local');\n" +
"router.get('/auth/twitter').to('Auth.twitter');\n" +
"router.get('/auth/twitter/callback').to('Auth.twitterCallback');\n" +
"router.get('/auth/facebook').to('Auth.facebook');\n" +
"router.get('/auth/facebook/callback').to('Auth.facebookCallback');\n" +
"router.get('/auth/yammer').to('Auth.yammer');\n" +
"router.get('/auth/yammer/callback').to('Auth.yammerCallback');\n" +
"router.resource('users');";
}
if (addRoute(routerPath, "\n" + newRoute)) {
console.log('\nAdded authentication routes:\n' + newRoute);
} else {
console.log('\nAuthentication routes already defined in', routerPath);
}
}
else {
console.log('\nThere is no router file to add routes too.');
}
// Create secrets and copy the secrets template
console.log("\nCreating secrets.json file with stubbed-out Passport config.");
jake.cpR(path.join(fromBase, 'config', 'secrets.json.template'),
path.join(cwd, 'config', 'secrets.json'), {silent: true});
jake.Task['gen:secret'].invoke();
// Remove geddy-passport as it isn't needed anymore
console.log('\nCleaning up...');
jake.exec('npm uninstall geddy-passport', function () {
console.log('Please set up your Passport config in config/secrets.json');
complete();
});
};
});
});
Jump to Line
Something went wrong with that request. Please try again.