mirror of
https://github.com/zhigang1992/firebase-tools.git
synced 2026-04-28 11:55:43 +08:00
Implements the "use" command, deprecates "firebase" key
This commit is contained in:
@@ -37,7 +37,7 @@ logger.add(winston.transports.Console, {
|
||||
});
|
||||
|
||||
var debugging = false;
|
||||
if (_.contains(args, '--debug')) {
|
||||
if (_.includes(args, '--debug')) {
|
||||
logger.transports.console.level = 'debug';
|
||||
debugging = true;
|
||||
}
|
||||
|
||||
@@ -36,5 +36,7 @@ module.exports = function(client) {
|
||||
client.functions = {};
|
||||
client.functions.log = loadCommand('functions-log');
|
||||
|
||||
client.use = loadCommand('use');
|
||||
|
||||
return client;
|
||||
};
|
||||
|
||||
@@ -55,9 +55,9 @@ module.exports = new Command('init')
|
||||
{
|
||||
type: 'list',
|
||||
name: 'project',
|
||||
message: 'What Firebase do you want to use?',
|
||||
message: 'What Firebase project do you want to use?',
|
||||
validate: function(answer) {
|
||||
if (!_.contains(nameOptions, answer)) {
|
||||
if (!_.includes(nameOptions, answer)) {
|
||||
return 'Must specify a Firebase to which you have access';
|
||||
}
|
||||
return true;
|
||||
|
||||
156
commands/use.js
Normal file
156
commands/use.js
Normal file
@@ -0,0 +1,156 @@
|
||||
'use strict';
|
||||
|
||||
var Command = require('../lib/command');
|
||||
var logger = require('../lib/logger');
|
||||
var configstore = require('../lib/configstore');
|
||||
var requireAuth = require('../lib/requireAuth');
|
||||
var api = require('../lib/api');
|
||||
var chalk = require('chalk');
|
||||
var utils = require('../lib/utils');
|
||||
var _ = require('lodash');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var prompt = require('../lib/prompt');
|
||||
|
||||
var makeActive = function(projectDir, newActive) {
|
||||
var activeProjects = configstore.get('activeProjects') || {};
|
||||
if (newActive) {
|
||||
activeProjects[projectDir] = newActive;
|
||||
} else {
|
||||
_.unset(activeProjects, projectDir);
|
||||
}
|
||||
|
||||
configstore.set('activeProjects', activeProjects);
|
||||
};
|
||||
|
||||
var writeAlias = function(projectDir, rc, alias, projectId) {
|
||||
if (projectId) {
|
||||
_.set(rc, ['projects', alias], projectId);
|
||||
} else {
|
||||
_.unset(rc, ['projects', alias], projectId);
|
||||
}
|
||||
fs.writeFileSync(path.resolve(projectDir, './.firebaserc'), JSON.stringify(rc, null, 2));
|
||||
};
|
||||
|
||||
var listAliases = function(options) {
|
||||
if (_.size(options.rc, 'projects') > 0) {
|
||||
logger.info('Project aliases for', chalk.bold(options.projectRoot) + ':');
|
||||
logger.info();
|
||||
_.forEach(options.rc.projects, function(projectId, alias) {
|
||||
var listing = alias + ' (' + projectId + ')';
|
||||
if (options.project === projectId || options.projectAlias === alias) {
|
||||
logger.info(chalk.cyan.bold('* ' + listing));
|
||||
} else {
|
||||
logger.info(' ' + listing);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logger.info('Run', chalk.bold('firebase use --add'), 'to define a new project alias.');
|
||||
}
|
||||
};
|
||||
|
||||
var verifyMessage = function(name) {
|
||||
return 'please verify project ' + chalk.bold(name) + ' exists and you have access.';
|
||||
};
|
||||
|
||||
module.exports = new Command('use [alias_or_project_id]')
|
||||
.description('set an active Firebase project for your working directory')
|
||||
.option('--add', 'create a new project alias interactively')
|
||||
.option('--alias <name>', 'create a new alias for the provided project id')
|
||||
.option('--unalias <name>', 'remove an already created project alias')
|
||||
.option('--clear', 'clear the active project selection')
|
||||
.before(requireAuth)
|
||||
.action(function(newActive, options) {
|
||||
// HACK: Commander.js silently swallows an option called alias >_<
|
||||
var aliasOpt;
|
||||
var i = process.argv.indexOf('--alias');
|
||||
if (i >= 0 && process.argv.length > i + 1) {
|
||||
aliasOpt = process.argv[i + 1];
|
||||
}
|
||||
|
||||
if (!options.projectRoot) { // not in project directory
|
||||
return utils.reject(chalk.bold('firebase use') + ' must be run from a Firebase project directory.\n\nRun ' + chalk.bold('firebase init') + ' to start a project directory in the current folder.');
|
||||
}
|
||||
|
||||
if (newActive) { // firebase use [alias_or_project]
|
||||
var aliasedProject = _.get(options.rc, ['projects', newActive]);
|
||||
return api.getProjects().then(function(projects) {
|
||||
if (aliasOpt) { // firebase use [project] --alias [alias]
|
||||
if (!projects[newActive]) {
|
||||
return utils.reject('Cannot create alias ' + chalk.bold(aliasOpt) + ', ' + verifyMessage(newActive));
|
||||
}
|
||||
writeAlias(options.projectRoot, options.rc, aliasOpt, newActive);
|
||||
aliasedProject = newActive;
|
||||
logger.info('Created alias', chalk.bold(aliasOpt), 'for', aliasedProject + '.');
|
||||
}
|
||||
|
||||
if (aliasedProject) { // found alias
|
||||
if (!projects[aliasedProject]) { // found alias, but not in project list
|
||||
return utils.reject('Unable to use alias ' + chalk.bold(newActive) + ', ' + verifyMessage(aliasedProject));
|
||||
}
|
||||
|
||||
makeActive(options.projectRoot, newActive);
|
||||
logger.info('Now using alias', chalk.bold(newActive), '(' + aliasedProject + ')');
|
||||
} else if (projects[newActive]) { // exact project id specified
|
||||
makeActive(options.projectRoot, newActive);
|
||||
logger.info('Now using project', chalk.bold(newActive));
|
||||
} else { // no alias or project recognized
|
||||
return utils.reject('Invalid project selection, ' + verifyMessage(newActive));
|
||||
}
|
||||
});
|
||||
} else if (options.unalias) { // firebase use --unalias [alias]
|
||||
if (_.has(options.rc, ['projects', options.unalias])) {
|
||||
writeAlias(options.projectRoot, options.rc, options.unalias, null);
|
||||
logger.info('Removed alias', chalk.bold(options.unalias));
|
||||
logger.info();
|
||||
listAliases(options);
|
||||
}
|
||||
} else if (options.add) { // firebase use --add
|
||||
if (options.nonInteractive) {
|
||||
return utils.reject('Cannot run ' + chalk.bold('firebase use --add') + ' in non-interactive mode. Use ' + chalk.bold('firebase use <project_id> --alias <alias>') + ' instead.');
|
||||
}
|
||||
return api.getProjects().then(function(projects) {
|
||||
var results = {};
|
||||
return prompt(results, [
|
||||
{
|
||||
type: 'list',
|
||||
name: 'project',
|
||||
message: 'Which project do you want to add?',
|
||||
choices: Object.keys(projects).sort()
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'alias',
|
||||
message: 'What alias do you want to use for this project? (e.g. staging)'
|
||||
}
|
||||
]).then(function() {
|
||||
writeAlias(options.projectRoot, options.rc, results.alias, results.project);
|
||||
makeActive(options.projectRoot, results.alias);
|
||||
logger.info();
|
||||
logger.info('Created alias', chalk.bold(results.alias), 'for', results.project + '.');
|
||||
logger.info('Now using alias', chalk.bold(results.alias) + ' (' + results.project + ')');
|
||||
});
|
||||
});
|
||||
} else if (options.clear) { // firebase use --clear
|
||||
makeActive(options.projectRoot, null);
|
||||
options.projectAlias = null;
|
||||
options.project = null;
|
||||
logger.info('Cleared active project.');
|
||||
logger.info();
|
||||
listAliases(options);
|
||||
} else { // fireabase use
|
||||
if (options.projectAlias) {
|
||||
logger.info('Active Project:', chalk.bold.cyan(options.projectAlias + ' (' + options.project + ')'));
|
||||
} else if (options.project) {
|
||||
logger.info('Active Project:', chalk.bold.cyan(options.project));
|
||||
} else {
|
||||
var msg = 'No project is currently active';
|
||||
if (_.size(options.rc.projects === 0)) {
|
||||
msg += ', and no aliases have been created.';
|
||||
}
|
||||
logger.info(msg + '.');
|
||||
}
|
||||
logger.info();
|
||||
listAliases(options);
|
||||
}
|
||||
});
|
||||
@@ -58,7 +58,7 @@ var _request = function(options) {
|
||||
|
||||
var _appendQueryData = function(path, data) {
|
||||
if (data && _.size(data) > 0) {
|
||||
path += _.contains(path, '?') ? '&' : '?';
|
||||
path += _.includes(path, '?') ? '&' : '?';
|
||||
path += querystring.stringify(data);
|
||||
}
|
||||
return path;
|
||||
|
||||
@@ -8,8 +8,10 @@ var utils = require('./utils');
|
||||
var FirebaseError = require('./error');
|
||||
var chalk = require('chalk');
|
||||
var getProjectId = require('./getProjectId');
|
||||
var loadRCFiles = require('./loadRCFiles');
|
||||
var loadRCFile = require('./loadRCFile');
|
||||
var Config = require('./config');
|
||||
var detectProjectRoot = require('./detectProjectRoot');
|
||||
var configstore = require('../lib/configstore');
|
||||
|
||||
var Command = function(cmd) {
|
||||
this._cmd = cmd;
|
||||
@@ -120,19 +122,28 @@ Command.prototype._prepare = function(options) {
|
||||
options.configError = e;
|
||||
}
|
||||
|
||||
this.applyPrefs(options);
|
||||
options.projectRoot = detectProjectRoot(options.cwd);
|
||||
this.applyRC(options);
|
||||
return RSVP.resolve();
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply configuration from .firebaserc files in the working directory tree.
|
||||
*/
|
||||
Command.prototype.applyPrefs = function(options) {
|
||||
var prefs = loadRCFiles(options.cwd);
|
||||
Command.prototype.applyRC = function(options) {
|
||||
var rc = loadRCFile(options.cwd);
|
||||
options.rc = rc;
|
||||
|
||||
var prefsProject = _.get(prefs, ['project', options.project || 'default']);
|
||||
if (prefsProject) {
|
||||
options.project = prefsProject;
|
||||
options.project = options.project || (configstore.get('activeProjects') || {})[options.projectRoot];
|
||||
// support deprecated "firebase" key in firebase.json
|
||||
if (options.config && !options.project) {
|
||||
options.project = options.config.defaults.project;
|
||||
}
|
||||
|
||||
var rcProject = _.get(rc, ['projects', options.project]);
|
||||
if (rcProject) {
|
||||
options.projectAlias = options.project;
|
||||
options.project = rcProject;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ var parseBoltRules = require('./parseBoltRules');
|
||||
var triggerRulesGenerator = require('./triggerRulesGenerator');
|
||||
var detectProjectRoot = require('./detectProjectRoot');
|
||||
var chalk = require('chalk');
|
||||
|
||||
var utils = require('./utils');
|
||||
var Config = function(src, options) {
|
||||
this.options = options || {};
|
||||
this.projectDir = detectProjectRoot(options.cwd);
|
||||
@@ -23,6 +23,7 @@ var Config = function(src, options) {
|
||||
|
||||
if (this._src.firebase) {
|
||||
this.defaults.project = this._src.firebase;
|
||||
utils.logWarning(chalk.bold('"firebase"') + ' key in firebase.json is deprecated. Run ' + chalk.bold('firebase use --add') + ' instead');
|
||||
}
|
||||
|
||||
Config.TARGETS.forEach(function(target) {
|
||||
@@ -131,7 +132,7 @@ Config.prototype.has = function(key) {
|
||||
|
||||
Config.prototype.path = function(pathName) {
|
||||
var outPath = path.normalize(path.join(this.projectDir, pathName));
|
||||
if (_.contains(path.relative(this.projectDir, outPath), '..')) {
|
||||
if (_.includes(path.relative(this.projectDir, outPath), '..')) {
|
||||
throw new FirebaseError(chalk.bold(pathName) + ' is outside of project directory', {exit: 1});
|
||||
}
|
||||
return outPath;
|
||||
|
||||
@@ -36,8 +36,8 @@ var deploy = function(targetNames, options) {
|
||||
var projectId = getProjectId(options);
|
||||
|
||||
// --- TEMPORARY CHECKS FOR FUNCTION RULE COMPILATION
|
||||
var deployingFunctions = _.contains(targetNames, 'functions');
|
||||
var deployingRules = _.contains(targetNames, 'rules');
|
||||
var deployingFunctions = _.includes(targetNames, 'functions');
|
||||
var deployingRules = _.includes(targetNames, 'rules');
|
||||
var warnText = chalk.yellow.bold('\n>--- ALPHA WARNING! ---<\n');
|
||||
if (deployingFunctions && !deployingRules) {
|
||||
console.log(warnText);
|
||||
@@ -103,7 +103,7 @@ var deploy = function(targetNames, options) {
|
||||
logger.info();
|
||||
utils.logSuccess(chalk.underline.bold('Deploy complete!'));
|
||||
logger.info();
|
||||
var deployedHosting = _.contains(targetNames, 'hosting');
|
||||
var deployedHosting = _.includes(targetNames, 'hosting');
|
||||
if (deployedHosting) {
|
||||
logger.info(chalk.bold('URL:'), utils.addSubdomain(api.hostingOrigin, projectId));
|
||||
}
|
||||
|
||||
31
lib/loadRCFile.js
Normal file
31
lib/loadRCFile.js
Normal file
@@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
var fsutils = require('./fsutils');
|
||||
var path = require('path');
|
||||
var cjson = require('cjson');
|
||||
var utils = require('./utils');
|
||||
var chalk = require('chalk');
|
||||
var detectProjectRoot = require('./detectProjectRoot');
|
||||
|
||||
/**
|
||||
* .firebaserc should always be a sibling of firebase.json. If it doesn't parse,
|
||||
* it's considered a warning, not an error.
|
||||
*/
|
||||
module.exports = function(cwd) {
|
||||
var out = {};
|
||||
var dir = detectProjectRoot(cwd || process.cwd());
|
||||
if (!dir) {
|
||||
return out;
|
||||
}
|
||||
|
||||
var potential = path.resolve(dir, './.firebaserc');
|
||||
if (fsutils.fileExistsSync(potential)) {
|
||||
try {
|
||||
out = cjson.load(potential);
|
||||
} catch (e) {
|
||||
// a malformed .firebaserc is a warning, not an error
|
||||
utils.logWarning('JSON parsing error while trying to load ' + chalk.bold(potential));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var fsutils = require('./fsutils');
|
||||
var path = require('path');
|
||||
var cjson = require('cjson');
|
||||
var utils = require('./utils');
|
||||
var _ = require('lodash');
|
||||
|
||||
/**
|
||||
* Detect all .firebaserc files traversing up from the current directory and
|
||||
* merge them together (with closest to working dir winning conflicts).
|
||||
*/
|
||||
module.exports = function(cwd) {
|
||||
var cur = cwd || process.cwd();
|
||||
var out = [];
|
||||
var prev;
|
||||
while (cur !== prev) {
|
||||
var potential = path.resolve(cur, './.firebaserc');
|
||||
if (fsutils.fileExistsSync(potential)) {
|
||||
try {
|
||||
out.push(cjson.load(potential));
|
||||
} catch (e) {
|
||||
// a malformed .firebaserc is a warning, not an error
|
||||
utils.logWarning('JSON parsing error while trying to load ' + potential);
|
||||
}
|
||||
}
|
||||
|
||||
prev = cur;
|
||||
cur = path.dirname(cur);
|
||||
}
|
||||
return _.merge.apply(null, out.reverse());
|
||||
};
|
||||
@@ -57,10 +57,10 @@
|
||||
"fs-extra": "^0.23.1",
|
||||
"fstream-ignore": "^1.0.2",
|
||||
"googleapis": "^2.1.7",
|
||||
"inquirer": "^0.8.5",
|
||||
"inquirer": "^0.12.0",
|
||||
"jsonschema": "^1.0.2",
|
||||
"jsonwebtoken": "^5.4.0",
|
||||
"lodash": "^3.10.0",
|
||||
"lodash": "^4.6.1",
|
||||
"node-uuid": "^1.4.3",
|
||||
"open": "^0.0.5",
|
||||
"portfinder": "^0.4.0",
|
||||
|
||||
Reference in New Issue
Block a user