From 0978630bbe6b335f8072f529fe5b93830790a3ab Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Tue, 28 Jul 2015 15:41:00 -0700 Subject: [PATCH] Remove strongops and its dependencies --- Makefile | 52 --- README.md | 4 - docs.json | 16 - lib/commands/strongops.js | 836 -------------------------------------- man/slc.txt | 4 - man/strongops.txt | 55 --- package.json | 5 - test/config.js | 27 -- test/strongops.js | 109 ----- 9 files changed, 1108 deletions(-) delete mode 100644 Makefile delete mode 100644 docs.json delete mode 100644 lib/commands/strongops.js delete mode 100644 man/strongops.txt delete mode 100644 test/config.js delete mode 100644 test/strongops.js diff --git a/Makefile b/Makefile deleted file mode 100644 index c988ae1..0000000 --- a/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -.PHONY: test - -# Pre-conditions: -# ruby 1.9.3 -# gem install cucumber rspec - -.PHONY: test-cucumber -test-cucumber: check_cucumber - export PATH=${PATH}:${PWD}/bin;export testFolder=/tmp;cd node_modules/automation/strongnode && cucumber -f pretty features/cli_slc* - -test: test-cucumber - -check_cucumber: - gem list cucumber - gem list rspec - -.PHONY: test-mocha -test-mocha: - JENKINS_HOME=true ./node_modules/.bin/mocha - -test: test-mocha - -.PHONY: test-cli -test-cli: - cd cli-test/cmd_strongops && node drv_strongops_test.js - cd cli-test/prompt && node drv_prompt_test.js - -test: test-cli - -.PHONY: build -build: man - -MKD = $(wildcard man/*.md) -TXT = $(MKD:.md=) - -.PHONY: man -man: check-ronn $(TXT) - -man/%.md2: man/%.md - perl -pes'/^#//' < $< > $@ - -man/%.roff: man/%.md2 $(RONN) - ronn --pipe -r $< > $@ - -man/%: man/%.roff - groff -Tascii -mandoc -c $< | uniq > $@ - -check-ronn: -ifeq ($(shell which ronn),) - $(error Cannot find `ronn` executable. \ - Install it by running `gem install ronn` or `apt-get install ruby-ronn`) -endif diff --git a/README.md b/README.md index b5d28eb..4025f54 100644 --- a/README.md +++ b/README.md @@ -82,10 +82,6 @@ Commands: Datadog, Statsd, etc.). To experiment locally with the manager without installing, see the `pm` command. - strongops: save StrongOps API key into strongloop.json - - A key is required to publish metrics to the StrongOps hosted service. - These commands are used internally, and may be useful when building custom tooling and integrations with StrongLoop features: diff --git a/docs.json b/docs.json deleted file mode 100644 index 4d4627a..0000000 --- a/docs.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "content": [ - "README.md", - "man/slc.md", - "man/clusterctl.md", - "man/create.md", - "man/debug.md", - "man/env.md", - "man/help.md", - "man/lb.md", - "man/npm.md", - "man/run.md", - "man/strongops.md", - "man/version.md" - ] -} diff --git a/lib/commands/strongops.js b/lib/commands/strongops.js deleted file mode 100644 index 8ace0a5..0000000 --- a/lib/commands/strongops.js +++ /dev/null @@ -1,836 +0,0 @@ -'use strict'; - -// This code is radically different in style, and intended to be deleted soon. -/* eslint-disable */ - -var strongopsReg = require('nodefly-register'); -var colors = require('colors'); -var ini = require('ini'); -var fs = require('fs'); -var path = require('path'); -var util = require('util'); -var prompt = require('prompt'); -var async = require('async'); -var is = require('is2'); -var jsonFile = require('json-file-plus'); - -var timesSaved; -var whereSaved = ''; -var errCode; -var useColors = false; - -module.exports = exports = strongops; // for slc's loader.js to run -exports.test = {}; // for testing - -/** - * The strongops command provides a means for developers to register for a - * strongops account. The command prompts users for the name, email and - * password with defaults coming from the ~/.gitconfig and ~/.npmrc. - * Additionally, the command take switches to skip prompting, e.g.: $ slc - * strongops --name "Edmond Meinfelder" --email "elm@stdarg.com" --password - * "12345678" - * @param {Object} argv The command line command. - * @param {Object} options The command line options via optimist. - */ -function strongops(argv, options, loader) { - if (options.help || options.h) { - return loader.printUsage('strongops'); - } - - options = addDefaultOptions(options); - errCode = 0; - timesSaved = 0; - var defaults = getDefaults(); - var overrides = getCmdLineOverrides(options); - - if (options && options.nocolors) - useColors = false; - - if (options && options.colors) - useColors = true; - - doUserLogin(overrides, defaults, options, handleResponseCb); - - function handleResponseCb(err, userEnteredData) { - if (err) { - displayError(getErrorForUser(err)); - process.exit(1); - } else{ - // success - return finished(userEnteredData); - } - } - - function finished(userData) { - if (!is.nonEmptyObj(userData)) { - displayError('Authenticated, but user data is invalid: '+ - util.inspect(userData)); - } - saveCredentials(userData, options); - } -} -exports.test.cmd = strongops; - -/** - * A convenience function to format strongops error messages into nice, user - * error messages. - * @param {String} err An error string message. - */ -function getErrorForUser(err) { - // Do not like the inconsistency - var ERR_INVALID_CREDENTIALS = '[Error: Invalid Credentials]'; - var ERR_USER_EXISTS = 'Error: user exists'; - - if (err == ERR_USER_EXISTS) - return 'Error: A user with that email already exists.'; - - if (err == ERR_INVALID_CREDENTIALS) - return 'Error: Either the user is not registered or has a different password.'; - - return util.format('Error:', err); -} - -/** - * Adds default option of --local, if no save options are present. - * @param {Object} options Object with command line options. - */ -function addDefaultOptions(options) { - if (!is.obj(options)) - options = {}; - - // if no options for saving are specified, make the cmd save locally to the - // ./strongloop.json file. - if (!options.nosave && !options.package && !options.global && - !options.saveall) { - options.local = true; - } - - return options; -} - -/** - * Prompt users to see if they want to login again or register - * @param {Function} cb A callback function(err, bool) - */ -function promptToLoginOrRegister(cb) { - - console.log('\nWould you like to:'); - prompt.message = '(l)ogin with different credentials or (q)uit?'; - - var schema = { - properties: { - answer: { - pattern: /^[lqLQ]$/, - message: 'Response can be either \'l\' or \'q\'.', - default: 'l', - required: true - }, - } - }; - prompt.colors = useColors; - prompt.start(); - prompt.get(schema, function (err, result) { - cb(undefined, result.answer); - }); -} - -/** - * handles the user registration flow - * @param {Object} overrides Object cmd lines overrides for values - * @param {Object} defaults Object with default values for prompts. - * @param {Object} options Object with command line options. - */ -function doUserReg(overrides, defaults, options, cb) { - // avoid prompt, if user has submitted all the overrides - if (!is.obj(overrides) || Object.keys(overrides).length < 3) - console.log('Please answer the following to register with StrongOps:\n'); - - // get the registration information from the user, if we don't already - // have it - promptUserForReg(overrides, defaults, function(err, userEnteredData) { - // if we get an invalid response, asume users want to exit - if (!userEnteredData) { - console.log(''); - process.exit(13); - } - strongOpsRegister(userEnteredData, options, function(err, userData) { - if (err) return cb(err); - console.log( - '\nYou are now registered. Welcome to StrongOps!\n' + - '\n' + - 'Thanks for creating your temporary StrongOps login, good for 24 hrs.\n' + - 'Check your inbox tomorrow to verify your email address and create a\n' + - 'permanent account.\n' + - '\n' + - 'You are now ready to view your dashboard. Let\'s have a look: ' + - 'https://strongops.strongloop.com' + - '\n' - ); - cb(undefined, userData); - }); - }); -} - -function doUserLogin(overrides, defaults, options, cb) { - if (options.license) { - try { - var license = require('strong-agent/lib/license')(options.license); - console.log('Skipping login, checking pre-defined license key.'); - console.log(['License details:', - ' email: %s', - ' product: %s', - ' features: %s', - ' activation: %s', - ' expiration: %s'].join('\n'), - license.details.email, license.details.product, - license.details.features.join(', '), - license.details.activationDate, - license.details.expirationDate); - if (!license.covers('agent')) { - return cb('Invalid license, please contact sales@strongloop.com'); - } - if (!license.covers(false, false, new Date())) { - return cb('Expired license, please contact sales@strongloop.com'); - } - return cb(null, { agent_license: options.license }); - } catch (e) { - return cb('Error validating license: ' + e); - } - } - // get the name and email only for login - promptUserForLogin(overrides, defaults, function(err, userEnteredData) { - // if we get an invalid response, asume users want to exit - if (!userEnteredData) { - console.log(''); - process.exit(13); - } - strongOpsLogin(userEnteredData, options, function(err, userData) { - if (err) return cb(err); - if (userData && is.nonEmptyStr(userData.name)) - console.log('You are now logged in. Welcome back, %s.', userData.name); - cb(undefined, userData); - }); - }); -} - -/** - * Handles persisting the user credentials, if specified by the options. - * @param {Object} userData Object describing the user and auth. - * @param {Object} options Object with command line options. - */ -function saveCredentials(userData, options) { - var errCode = 0; - handleCredentials(userData, options, function(err) { - if (err) { - displayError('There was an error saving your credentials: '+err); - errCode = 2; - } - // if we have not saved the strongops credentials, echo them out to - // stdout if they have been saved, inform the user where. - if (timesSaved === 0) - displayCredentials(userData); - else if (timesSaved > 0) - console.log('Your StrongOps credentials were written to: %s', - whereSaved); - }); -} -exports.test.saveCredentials = saveCredentials; - -/** - * strongOpsLogin does what you'd expect, given user data with a - * name, email and password, registers the user with the strongops - * platform. - * @param {Object} userEnteredData An object containing the following string - * properties: name, email, password. - */ -function strongOpsLogin(userEnteredData, options, cb) { - strongopsReg.login(userEnteredData, function(err, userData) { - if (err) return cb(util.inspect(err)); - - if (!is.obj(userData)) - return cb('Error on strongops login',userData); - - if (Object.keys(userData).length === 1 && is.nonEmptyStr(userData.message)) - return cb('There was an error on login: '+ - JSON.stringify(userData.message)); - - // remove loggedIn property - it's not needed - if (userData && userData.hasOwnProperty('loggedIn')) - delete userData.loggedIn; - if (userData && userData.hasOwnProperty('apps')) - delete userData.apps; - - if (!is.nonEmptyObj(userData) || !is.nonEmptyStr(userData.userKey)) - return cb('There was an error. The server failed to return the user ' + - 'key.\nThe data returned: '+JSON.stringify(userData)); - cb(undefined, userData); - }); -} -exports.test.strongOpsLogin = strongOpsLogin; - -/** - * strongOpsRegister does what you'd expect, given user data with a - * name, email and password, registers the user with the strongops - * platform. - * @param {Object} userEnteredData An object containing the following string - * properties: name, email, password. - */ -function strongOpsRegister(userEnteredData, options, cb) { - strongopsReg.register(userEnteredData, function(err, userData) { - if (err) return cb(err); - - if (!is.obj(userData)) - return cb('Error on StrongOps registration',userData); - - if (Object.keys(userData).length === 1 && is.nonEmptyStr(userData.message)) - return cb(userData.message); - - // remove loggedIn property - it's not needed - if (userData && userData.hasOwnProperty('loggedIn')) - delete userData.loggedIn; - if (userData && userData.hasOwnProperty('apps')) - delete userData.apps; - if (!is.nonEmptyObj(userData) || !is.nonEmptyStr(userData.userKey)) - return cb('Bad response: '+JSON.stringify(userData)); - - cb(undefined, userData); - }); -} -exports.test.strongOpsRegister = strongOpsRegister; - -/** - * handleCredentials checks the options and unless, options.nosave exists with - * a truthy value, persists the user data depending on one fo teh following - * options: global, local or package. - * @param {Object} userData an object from the StrongOps platform with the user - * data including the API key. - * @param {Object} options An object containing the command line argument - * options - */ -function handleCredentials(userData, options, cb) { - // if the user does not want to persist the strongops credentials, - // we are done - if (options && options.nosave) return cb(); - - // Errors are displayed previous, just left the CB in case it is needed later. - persistUserData(userData, options, function(err) { - // if we never saved the credentials, at least show them to the user once - cb(err); - }); -} -exports.test.handleCredentials = handleCredentials; - -/** - * We display credentials in two places and I like to stay DRY. - * @param {Object} userData An object with the StrongOps userData. - */ -function displayCredentials(userData) { - console.log('\nAs your StrongOps credentials were not saved, here they are:'); - console.log(JSON.stringify(userData)); -} -exports.test.displayCredentials = displayCredentials; - -/** - * If the file does not exist, create an empty JSON file. - * @param {String} file The file with path. - * @param {Function} cb The callback function. - */ -function createEmptyJsonFileIfNone(file, cb) { - if (!is.nonEmptyStr(file)) - return cb('createEmptyJsonFile expected a filename, received: '+ - JSON.stringify(file)); - - if (fs.existsSync(file)) return cb(); - - fs.open(file, 'w', function(err, fd) { - if (err) return cb(err); - var buff = '{\n}'; - - fs.write(fd, new Buffer(buff), 0, buff.length, 0, function(err) { - if (err) return cb(err); - fs.close(fd); - cb(); - }); - }); -} -exports.test.createEmptyJsonFileIfNone = createEmptyJsonFileIfNone; - -/** - * A wrapper around the writes to persist the strongops credentials - * to simplify the async.parallel code, which can get tedious to read. - * We display errors here, but do not pass them on. If we can't write - * to a file, there's not much we can do other than display the error. - * @param {String} file The file name with path to write to. - * @param {Object} userData The data to write to a file. - * @param {Boolean} createIfNotThere True, if we should create the file - * if missing and false otherwise. - * @param {Function} cb The callback. - */ -function writeTo(file, userData, createIfNotThere, cb) { - - // for ./strongloop.json and ~/strongloop.json files - if (createIfNotThere) { - // create if it does not exist - createEmptyJsonFileIfNone(file, function(err) { - if (err) return cb('Error creating "'+file+'": '+JSON.stringify(err)); - - saveCredentialsToFile(userData, file, function(err) { - if (err) { - return cb('Error writing to "'+file+'": '+JSON.stringify(err)); - } else { - whereSaved += ((whereSaved.length === 0) ? '' : ', ') + file; - timesSaved++; - } - return cb(); - }); - }); - } else { - // case for package.json - saveCredentialsToFile({strongloop: userData}, file, function(err) { - if (err) - displayError(util.format('Error writing to \'%s\':', file, err)); - else { - whereSaved += ((whereSaved.length === 0) ? '' : ', ') + file; - timesSaved++; - } - return cb(); - }); - } -} -exports.test.writeTo = writeTo; - -/** - * Using async.parallel, persists the user data in one of three places - * according to the options. - * @param {Object} userData The user data to save to disk. - * @param {Object} options The command line user options from optimist - * @param {Function} cb The callback function. - */ -function persistUserData(userData, options, cb) { - - // if we are not saving anything exit - if (!options.saveall && !options.local && !options.package && !options.global) - return cb(); - - var localfile = './strongloop.json'; - var packagefile = './package.json'; - var globalfile = getUserHome() + '/strongloop.json'; - var createMissingFile = true; - var dontCreateMissingFile = false; - - async.parallel( - [ - // write to local file - function(cb) { - if (!options.saveall && !options.local) - return cb(); - writeTo(localfile, userData, createMissingFile, cb); - }, - - // update to the local package file, if present - function(cb) { - if (!options.saveall && !options.package) - return cb(); - writeTo(packagefile, userData, dontCreateMissingFile, cb); - }, - - // write to the global file - function(cb) { - if (!options.saveall && !options.global) - return cb(); - writeTo(globalfile, userData, createMissingFile, cb); - } - ], - - // error handler, and finished handler too - function(err) { cb(err); } - ); -} -exports.test.persistUserData = persistUserData; - -/** - * Save the user credentials to a file - * @param {Object} data The user data to save to a file. - * @param {String} file The file with path. - * @param {Function} cb The callback function. - */ -function saveCredentialsToFile(data, file, cb) { - if (!fs.existsSync(file)) { - displayError('The file'+file+'does not exist.'); - return cb('The file '+file+' does not exist.'); - } - jsonFile(file, function (err, fileObj) { - if (err) return cb(util.format('read failed (%s)', err.message || err)); - - fileObj.set(data); - fileObj.save(function(err) { - return cb(err); - }); - }); -} -exports.test.saveCredentialsToFile = saveCredentialsToFile; - -/** - * Using the prompt module, interactively query users for name, email and a - * password to use as credentials for the strongops platform. - * @param {Object} data A set of defaults, if any (from .gitconfig or .npmrc) - * @param {Function} cb A callback, because prompt is asynchronous. - */ -function promptUserForLogin(overrides, defaults, cb) { - console.log([ - 'Generating strongops configuration requires a registered email and', - 'password.', - 'Visit http://strongloop.com/register if you have not already.', - '' - ].join('\n')); - - prompt.colors = useColors; - prompt.override = overrides; - prompt.message = 'Please enter your'; - - // overwrite defaults with overrides - for (var prop in overrides) - defaults[prop] = overrides[prop]; - - // The prompt schema describes the data we need the user to enter. - var promptSchema = getLoginPromptSchema(defaults); - var result; // storage from prompt results, so different parts of - // asynch.whilst can use - - // do whilst performs the function and then the test and repeats so long - // as the test function returns true - async.doWhilst( - // function to execute repeatedly until test is false - function(cb) { - prompt.start(); // create event to start the prompting - // Get 2 properties from the user: email, & password - prompt.get(promptSchema, function (err, resultObj) { - result = resultObj; // store results in outter function scope - cb(err, result); // we're done, go to last function in async.whilst() - }); - }, - - // the test to decide if we need to continue - function() { - // handle edgecase where command line can be a number - // when we need a string - if (is.number(result.password)) - result.password = result.password.toString(); - - if (!is.nonEmptyStr(result.name) || !is.nonEmptyStr(result.password)) - return false; - - return true; - }, - - // error handler, also triggers when test condition is false - // we do the handling in the calling function's callback, though - function(err) { - cb(err, result); - } - ); -} -exports.test.promptUserForLogin = promptUserForLogin; - -/** - * Using the prompt module, interactively query users for email and a - * password to use as credentials for login to the strongops platform. - * @param {Object} data A set of defaults, if any (from .gitconfig or .npmrc) - * @param {Function} cb A callback, because prompt is asynchronous. - */ -function promptUserForReg(overrides, defaults, cb) { - prompt.colors = useColors; - prompt.override = overrides; - prompt.message = 'Please enter your'; - - // overwrite defaults with overrides - for (var prop in overrides) - defaults[prop] = overrides[prop]; - - // The prompt schema describes the data we need the user to enter. - var promptSchema = getPromptSchema(defaults); - var result; // storage from prompt results, so different parts of - // asynch.whilst can use - var count = 0; // limit the number of re-tries for entering a password to 3 - - // do whilst performs the function and then the test and repeats so long - // as the test function returns true - async.doWhilst( - // function to execute repeatedly until test is false - function(cb) { - prompt.start(); // create event to start the prompting - // Get 3 properties from the user: email, password, and user name - prompt.get(promptSchema, function (err, resultObj) { - result = resultObj; // store results in outter function scope - cb(err, result); // we're done, go to last function in async.whilst() - }); - }, - - // the test to decide if we need to continue - function() { - // handle edgecase where command line can be a number - // when we need a string - if (is.number(result.password)) - result.password = result.password.toString(); - if (is.number(result.password2)) - result.password2 = result.password2.toString(); - - // do the password and its confirmation match? - if (result.password !== result.password2) { - // if the user can't get it in 3 tries, give up - if (++count > 3) { - displayError('Giving up after 3 re-tries to enter a password and '+ - 'matching confirmation.'); - return false; - } - if (result.password) delete result.password; - if (result.password2) delete result.password2; - prompt.override = result; - displayError('The password does not match its confirmation. '+ - 'Please try again.'); - return true; - } - return false; - }, - - // error handler, also triggers when test condition is false - // we do the handling in the calling function's callback, though - function(err) { - // remove the 2nd password - it's only for confirmation - if (result && result.password2) delete result.password2; - cb(err, result); - } - ); -} -exports.test.promptUserForReg = promptUserForReg; - -/** - * Get the command lines options for user name, email and password from the - * command line and place them in an overrides structure. - */ -function getCmdLineOverrides(options) { - if (!is.nonEmptyObject(options)) - return {}; - - var overrides = {}; - if (is.nonEmptyStr(options.name)) - overrides.name = options.name; - - if (is.nonEmptyStr(options.email)) - overrides.email = options.email; - - // the only way to get a default email is on the command line - if (options && options.password) { - overrides.password = options.password; - overrides.password2 = options.password; - } - - return overrides; -} -exports.test.getCmdLineOverrides = getCmdLineOverrides; - -/** - * Using argv options from optimist and the gitconfig & npm rc files, gather - * up default options. Note password can only be set on the command line. - * @returns {Object} conatining defaults for the user, name and password. - */ -function getDefaults() { - - var git = getGitConfigInfo(); // get git config info - var npmEmail = getNpmEmail(); // get email from npmrc - var defaults = {}; - - // user data on command trumps data in gitconfig - if (is.nonEmptyObj(git) && is.nonEmptyStr(git.name)) - defaults.name = git.name; - - // email entry on command trumps data in gitconfig - // and gitconfig email trump npmrc email - if (is.nonEmptyObj(git) && is.nonEmptyStr(git.email)) - defaults.email = git.email; - else if (is.nonEmptyStr(npmEmail)) - defaults.email = npmEmail; - - return defaults; -} -exports.test.getDefaults = getDefaults; - -exports.userHome = process.env[ - (process.platform === 'win32') ? 'USERPROFILE' : 'HOME' -]; - -/** - * Get the path to the user's home directory in a platform independent way. - * @returns {String} The path to the user's home directory. - */ -function getUserHome() { - return exports.userHome; -} - - -/** - * Get user name and email from .gitconfig, if possible. - * @returns {Object} An object with the name and email from .gitconfig if - * possible if nothing is found an empty object is returned. - */ -function getGitConfigInfo() { - var gitConfigPath = path.resolve(getUserHome(), '.gitconfig'); - var gitconfig = false; - var data = getFileSync(gitConfigPath); - - if (data !== false) gitconfig = ini.parse(data); - - var obj = {}; - if (gitconfig && gitconfig.user && typeof gitconfig.user.name === 'string') - obj.name = gitconfig.user.name; - if (gitconfig && gitconfig.user && typeof gitconfig.user.email === 'string') - obj.email = gitconfig.user.email; - - return obj; -} -exports.test.gitConfig = getGitConfigInfo; - -/** - * Get email from ~/.npmrc if possible. - * @returns {String|Undefined} The email address from .npmrc or undefined, if - * none - */ -function getNpmEmail() { - var npmrcPath = path.resolve(getUserHome(), '.npmrc'); - var data = getFileSync(npmrcPath); - if (!data) return undefined; - var npmrc = ini.parse(data); - if (npmrc && npmrc.email) - return npmrc.email; - return undefined; -} -exports.test.npmEmail = getNpmEmail; - -/** - * A convenience function to return the schema for the prompt data. - * @param {Object} defaults An object containing default values for prompts - * @returns {Object} A schema describing the data that we need from the user. - */ -function getPromptSchema(defaults) { - - // The prompt schema describes the data we need the user to enter. - var promptSchema = { - properties: { - name: { - description: 'full name ', - type: 'string', - default: defaults.name, - pattern: /^[a-zA-Z\s\-\.]+$/, - message: 'A name may only have letters, spaces, periods and dashes.', - required: true - }, - email: { - description: 'email address', - type: 'string', - default: defaults.email, - pattern: /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/, - message: 'An email must be a valid address, qualified with a domain.', - required: true - }, - password: { - description: 'password', - pattern: /^[A-Za-z0-9!@#%&\/(){}\[\]=?+*^~\-_\.:,;]{8,64}$/, - message: 'A password must be at least 8 characters.', - hidden: true, - required: true - }, - password2: { - description: 'password again for confirmation', - pattern: /^[A-Za-z0-9!@#%&\/(){}\[\]=?+*^~\-_\.:,;]{8,64}$/, - message: 'A password must be at least 8 characters.', - hidden: true, - required: true - } - } - }; - - if (useColors) { - promptSchema.properties.name.description = - promptSchema.properties.name.description.inverse.white; - promptSchema.properties.email.description = - promptSchema.properties.email.description.inverse.white; - promptSchema.properties.password.description = - promptSchema.properties.password.description.inverse.white; - promptSchema.properties.password2.description = - promptSchema.properties.password2.description.inverse.white; - } - - return promptSchema; -} -exports.test.getPromptSchema = getPromptSchema; - -/** - * A convenience function to return the schema for the prompt data. - * @param {Object} defaults An object containing default values for prompts - * @returns {Object} A schema describing the data that we need from the user. - */ -function getLoginPromptSchema(defaults) { - - // The prompt schema describes the data we need the user to enter. - var promptSchema = { - properties: { - email: { - description: 'email address', - type: 'string', - default: defaults.email, - pattern: /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/, - message: 'An email must be a valid address, qualified with a domain.', - required: true - }, - password: { - description: 'password', - pattern: /^.+$/, - message: 'A password must be at least 1 character.', - hidden: true, - required: true - } - } - }; - - if (useColors) { - promptSchema.properties.email.description = - promptSchema.properties.email.description.inverse.white; - promptSchema.properties.password.description = - promptSchema.properties.password.description.inverse.white; - } - - return promptSchema; -} -exports.test.getLoginPromptSchema = getLoginPromptSchema; - -/** - * Read a file into a buffer using fs.readFileSync will catch in eth case the - * file does not exist and returns false when there is no file (or it can't be - * read) and a string with the file contents otherwise. - * @param {String} filename a file name with path information. - * @returns {Boolean|String} false if the file can't be read or a buffer with - * the file contents otherwise - */ -function getFileSync(filename) { - var data = false; - - // readFileSync throws, we must catch. :( - try { - data = fs.readFileSync(filename, 'utf-8'); - } catch (err) { - } - - return data; -} -exports.test.getFileSync = getFileSync; - -/** - * Convenience function to display an error. - * @param {String} str A string to display to stderr. - */ -function displayError(str) { - if (is.func(str) || !is.nonEmptyStr(str)) return; - var outStr = useColors ? str.red : str; - console.log(outStr); -} - diff --git a/man/slc.txt b/man/slc.txt index d9f0df2..cf398d4 100644 --- a/man/slc.txt +++ b/man/slc.txt @@ -51,10 +51,6 @@ Commands: Datadog, Statsd, etc.). To experiment locally with the manager without installing, see the `pm` command. - strongops: save StrongOps API key into strongloop.json - - A key is required to publish metrics to the StrongOps hosted service. - These commands are used internally, and may be useful when building custom tooling and integrations with StrongLoop features: diff --git a/man/strongops.txt b/man/strongops.txt deleted file mode 100644 index e32d1f3..0000000 --- a/man/strongops.txt +++ /dev/null @@ -1,55 +0,0 @@ -usage: slc strongops [options] - -Generate the configuration files to profile with StrongOps. - -Prompts for the email address and password of your StrongOps account, and saves -the credentials in the specified configuration file. - -There are no interactive prompts for data specified on the command line. - -Options: - - --email: Specify the email address, e.g.: `--email someone@strongloop.com`. - The address found in your `~/.gitconfig` or `~/.npmrc` is offered as the - default. - - --password: Specify your StrongOps password, e.g.: `--password 12345678` - - --license: Write the specified strong-agent license key instead of - authenticating with the StrongOps servers and storing a StrongOps agent API - key. If both types of keys are required, `slc strongops` can be run again - without the `--license` option and the file will be updated with additional - credentials. - - e.g.: `--license XXXXXYYYYYYZZZZZZ`. - - --nosave: Prevent saving of StrongOps account credentials, this overrides any - save option. - - --local: Saves StrongOps account credentials in a `./strongloop.json` file. - This is set by default, if no other save options exist. - - --package: Saves StrongOps account credentials in `./package.json` file, if - the file exists. - - --global: Saves StrongOps account credentials in a `~/strongloop.json` file. - -See http://docs.strongloop.com/ for a description of the format of the -`package.json` and `strongloop.json` properties that StrongOps uses. - -Examples: - -- The following will have strongops prompt for the email and password. The - credentials are saved in the `./strongloop.json` file: - - $ slc strongops - -- Use the `--email` and `--password` options for non-interactive registration - with no prompts: - - $ slc strongops --email "bw@example.com" --password "12345678" - -- To decode and view the details of a strong-agent license without modifying - any files, where XXYYZZ is your license key: - - $ slc strongops --nosave --license XXYYZZ diff --git a/package.json b/package.json index 8d80d93..9ca1352 100644 --- a/package.json +++ b/package.json @@ -80,18 +80,13 @@ }, "dependencies": { "async": "^0.9.0", - "colors": "^1.0.3", "debug": "^2.1.0", "generator-loopback": "1.x", - "ini": "^1.3.2", - "is2": "~0.0.3", - "json-file-plus": "^3.0.0", "loopback-sdk-angular-cli": "1.x", "node-inspector": "~0.7.0", "nodefly-register": "~0.3.2", "nopt": "~3.0.1", "optimist": "^0.6.1", - "prompt": "~0.2.11", "read": "~1.0.5", "strong-agent": "^1.5.0", "strong-arc": "^1.2.0", diff --git a/test/config.js b/test/config.js deleted file mode 100644 index 2a06a55..0000000 --- a/test/config.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @fileOverview - * config.js holds answers to tests, we could later switch on an environment - * variable which config we load for targeted tests. - */ - -var path = require('path'); - -// This is a duplication of the same code in the module under test (i.e. -// stronops.js) It's questionable whether such test brings any benefit -var home = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME']; - -/** - * Configuration options as set in test gitconfig and npmrc - */ -exports.strongops = { - npmEmail: 'npmrc@example.com', - gitConfig: { - name: 'GitConfig Name', - email: 'gitconfig@example.com' - }, - userHome: home, - anExistingFile: path.resolve(__dirname, '.gitconfig') -}; - -exports.strongops.getDefaults = exports.strongops.gitConfig; - diff --git a/test/strongops.js b/test/strongops.js deleted file mode 100644 index 2d20d40..0000000 --- a/test/strongops.js +++ /dev/null @@ -1,109 +0,0 @@ -var assert = require('assert'); -var path = require('path'); -var is = require('is2'); -var strops = require('../lib/commands/strongops'); -var test = require('./config').strongops; - -var originalUserHome = strops.userHome; - -beforeEach(function() { strops.userHome = originalUserHome; }); - -describe('getNpmEmail', function() { - it('Should return the email string from ~/.npmrc', function() { - givenUserHomeInTestFolder(); - assert.equal(test.npmEmail, strops.test.npmEmail()); - }); -}); - -describe('getGitConfigInfo', function() { - it('Should return the user name and email string from ~/.gitconfig', function() { - givenUserHomeInTestFolder(); - var git = strops.test.gitConfig(); - assert.deepEqual(git, strops.test.gitConfig()); - }); -}); - -describe('getUserHome', function() { - it('Should return the home directory for the user', function() { - assert.equal(test.userHome, strops.userHome); - }); -}); - -// FIXME: make another test with a config, to test .npmrc email retrieval -describe('getDefaults', function() { - it('Should get the defaults from ~/.gitconfig and possibly ~/.npmrc', function() { - givenUserHomeInTestFolder(); - assert.deepEqual(test.getDefaults, strops.test.getDefaults()); - }); -}); - -describe('getCmdLineOverrides', function() { - it('Given an empty options object, should an empty object', function() { - givenUserHomeInTestFolder(); - assert.deepEqual({}, strops.test.getCmdLineOverrides()); - }); -}); - -describe('getCmdLineOverrides', function() { - it('Given an options with a name property, should an object with a name property', function() { - var options = { name: 'E. Meinfelder' }; - assert.deepEqual({ name: 'E. Meinfelder' }, strops.test.getCmdLineOverrides(options)); - }); -}); - -describe('getCmdLineOverrides', function() { - it('Given options with an email property, should an object with an email property', function() { - var options = { email: 'e@e.com' }; - assert.deepEqual({ email: 'e@e.com' }, strops.test.getCmdLineOverrides(options)); - }); -}); - -describe('getCmdLineOverrides', function() { - it('Given options with a password property, should an object with a password and password2 properties', function() { - var options = { password: '12345678' }; - var expected = { password: '12345678', password2: '12345678' }; - assert.deepEqual(expected, strops.test.getCmdLineOverrides(options)); - }); -}); - -describe('getCmdLineOverrides', function() { - it('Given options with a name, email & password, should an object with name, email, password and password2 properties', function() { - var options = { - name: 'Monkey', - email: 'monkey@monkey.com', - password: '12345678' - }; - var expected = { - name: 'Monkey', - email: 'monkey@monkey.com', - password: '12345678', - password2: '12345678' - }; - assert.deepEqual(expected, strops.test.getCmdLineOverrides(options)); - }); -}); - -describe('getCmdLineOverrides', function() { - it('Given options with an email property, should an object with an email property', function() { - var options = { email: 'e@e.com' }; - assert.deepEqual({ email: 'e@e.com' }, strops.test.getCmdLineOverrides(options)); - }); -}); - -describe('getFileSync', function() { - it('Should return false when getting a file that is not present.', function() { - assert.ok(strops.test.getFileSync('./dhsjdhjhdjdww78783') === false); - }); -}); - -describe('getFileSync', function() { - it('Should return the contents of a file when file is present.', function() { - //console.log('getFileSync:', test.getFileSync); - assert.ok(is.nonEmptyStr(strops.test.getFileSync(test.anExistingFile)) === true); - }); -}); - -function givenUserHomeInTestFolder() { - strops.userHome = path.resolve(__dirname); -} -