├── .gitignore ├── LICENSE.md ├── README.md ├── SECURITY.md ├── assets ├── di.png └── whoami.png ├── bin └── di ├── di.js ├── jsdoc.json ├── lib ├── alias.js ├── commands.js ├── commands │ └── install.js ├── completion.js ├── config.js ├── plugins │ ├── deployr-cli-server │ │ ├── commands.js │ │ └── index.js │ ├── deployr-cli-users │ │ ├── commands.js │ │ └── index.js │ └── inquirer.js ├── usage.js └── util │ ├── brand.js │ ├── clear.js │ ├── lang-type.js │ └── spawn-command.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore doc build 2 | deployr-cli-doc/ 3 | 4 | # Ignore extensions 5 | *.diff 6 | *.err 7 | *.log 8 | *.orig 9 | *.rej 10 | *.swo 11 | *.swp 12 | *.vi 13 | *.zip 14 | *~ 15 | 16 | # Ignore OS or Editor folders 17 | ._* 18 | .cache 19 | .DS_Store 20 | .project 21 | .settings 22 | .idea 23 | .tmproj 24 | *.esproj 25 | *.sublime-workspace 26 | *.sublime-project 27 | 28 | # Ignore node 29 | node_modules/ 30 | npm-debug.log 31 | 32 | # Ignore any examples 33 | java-example-fraud-score/ 34 | js-example-fraud-score/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010-2016, Microsoft Corporation 2 | 3 | This program is licensed to you under the terms of Version 2.0 of the Apache 4 | License. This program is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, 5 | INCLUDING THOSE OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 6 | PURPOSE. Please refer to the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) for more details. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deployr-cli 2 | 3 | > The [DeployR](http://go.microsoft.com/fwlink/?LinkID=692163) command line interface. 4 | 5 | 6 | 7 | ## Overview 8 | 9 | DeployR CLI is a [Command Line Tool (CLI)](http://en.wikipedia.org/wiki/Command-line_interface) for running useful 10 | [DeployR](http://go.microsoft.com/fwlink/?LinkID=692163) utilities. Although the 11 | current feature set is minimal, many more CLI commands will be added going 12 | forward. 13 | 14 | ## Prerequisites 15 | 16 | - Install the latest stable version of [Node.js](http://nodejs.org/) (version 0.10.x). 17 | - A running [DeployR](https://msdn.microsoft.com/en-us/microsoft-r/deployr-installation) server to connect to. 18 | 19 | **Note** to Windows users that have the [Microsoft HPC Pack](https://msdn.microsoft.com/en-us/library/cc853440%28v=vs.85%29.aspx). 20 | 21 | If your environment has the Microsoft HPC Pack, the `node.exe` from Node.js can 22 | conflict with the `node.exe` from the Microsoft HPC Pack (same name). You can 23 | view the [open issue](https://github.com/joyent/node/issues/7773) here. 24 | 25 | The current solution is to manually reorder the paths in the `PATH` environment 26 | variable giving Node.js's path a higher priority after installation. 27 | 28 | ## Installation 29 | 30 | The DeployR CLI is installed and managed via [npm](http://npmjs.org), the [Node.js](http://nodejs.org/) package manager. 31 | 32 | To get started, you will want to install the DeployR command line interface (CLI) 33 | globally. You may need to use sudo for (OSX, *nix, BSD, etc). If you are using 34 | Windows, run your command shell as Administrator. 35 | 36 | One-line install using [npm](http://npmjs.org): 37 | 38 | ``` 39 | npm install -g deployr-cli 40 | ``` 41 | 42 | This will put the `di` command in your system path allowing it to be run from 43 | any location. 44 | 45 | ## Usage 46 | 47 | DeployR CLI is self documenting and the best way to become familiar with the tool is to 48 | try it out from your command line: 49 | 50 | ``` 51 | di ... 52 | ``` 53 | 54 | ### Commands 55 | 56 | Command | Purpose 57 | :------------------------------------------ | :------- 58 | `di` | Displays the 'Main menu' User Interface. 59 | `di help` | Prints out a list of available commands. 60 | `di help ` | Prints out the _help_ text associated with the command. 61 | `di endpoint` | Set the DeployR server endpoint. 62 | `di login` | Log into DeployR. 63 | `di logout` | Log out of DeployR. 64 | `di whoami` | Displays the current logged in user to DeployR. 65 | `di install example` | Install a pre-built example. 66 | `di install example ` | Install a pre-built example by example name. 67 | `di about` | Displays DeployR server information based on the set server `endpoint`. 68 | `di config` | Allow you to edit your local `di` [configuration](#diconf-file) file. 69 | `di config list` | Lists all configuration values currently set in the configuration file. 70 | `di config set ` | Sets the specified pair in the `di` configuration. 71 | `di config get ` | Gets the value for the specified in the `di` configuration. 72 | `di config delete ` | Deletes the specified in the `di` configuration. 73 | 74 | ## Help 75 | 76 | All commands have corresponding _help_ text associated with it. To read the help 77 | text for a `di` command, type: 78 | 79 | ``` 80 | di help 81 | ``` 82 | 83 | For example, to display the help text for the `whoami` command: 84 | 85 | 86 | 87 | ## .diconf file 88 | 89 | All configuration data for your local DeployR CLI install is located in the *.diconf* 90 | file in your home directory. Directly modifying this file is not advised. You 91 | should be able to make all configuration changes from the _main menu_ UI or via: 92 | 93 | ``` 94 | di config 95 | ``` 96 | 97 | Example: 98 | 99 | ``` 100 | di config set endpoint http://dhost:port # set the DeployR server endpoint 101 | ``` 102 | 103 | If you need to have multiple configuration files, use --diconf options. 104 | 105 | Example: 106 | 107 | ``` 108 | di --diconf /path/to/other/configuration/.diconf 109 | ``` 110 | 111 | ## Options 112 | 113 | di [commands] [options] 114 | 115 | --version prints DeployR version and exit 116 | --diconf [file] specify file to load configuration from 117 | --help prints cli help and exit 118 | 119 | ## Tab Completion 120 | 121 | **System Requirements** 122 | 123 | - bash 124 | 125 | Any other shell other than `bash` will simply ignore tab completions. The first 126 | time you run `$ di` from the command line it will add to your `.bashrc` or 127 | `.bash_profile` or .`profile` the necessary hooks. Upon sourcing these files, 128 | the next time you run `$ di ` the completions with appear. 129 | 130 | Example: 131 | 132 | ``` 133 | $ di lo 134 | 135 | login logout 136 | 137 | $ di w 138 | 139 | whoami 140 | ``` 141 | 142 | ## API Documentation 143 | 144 | For advance usage, see our [API documentation](http://microsoft.github.io/deployr-cli) 145 | 146 | ## Notes 147 | 148 | Inspired by the [nodejitsu](https://www.nodejitsu.com) CLI and others. 149 | 150 | ## License 151 | 152 | Copyright (C) 2010-2016, Microsoft Corporation 153 | 154 | This program is licensed to you under the terms of Version 2.0 of the Apache 155 | License. This program is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, 156 | INCLUDING THOSE OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 157 | PURPOSE. Please refer to the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) for more details. 158 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /assets/di.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/deployr-cli/00e311db1f9a85caee121b51ef5815245a4fa091/assets/di.png -------------------------------------------------------------------------------- /assets/whoami.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/deployr-cli/00e311db1f9a85caee121b51ef5815245a4fa091/assets/whoami.png -------------------------------------------------------------------------------- /bin/di: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /*! 4 | * Copyright (C) 2010-2016, Microsoft Corporation 5 | * 6 | * This program is licensed to you under the terms of Version 2.0 of the 7 | * Apache License. This program is distributed WITHOUT 8 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 9 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 10 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 11 | * details. 12 | */ 13 | 14 | require('../lib/completion'); 15 | 16 | process.title = 'di'; 17 | 18 | var di = require('../di'); 19 | 20 | di.start(function (err) { 21 | process.exit(err ? 1 : 0); 22 | }); -------------------------------------------------------------------------------- /di.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 13 | 'use strict'; 14 | 15 | /** 16 | * The DeployR command line interface, a tool for running useful DeployR 17 | * utilities. 18 | * @module deployr-cli 19 | */ 20 | 21 | var path = require('path'), 22 | opn = require('opn'), 23 | flatiron = require('flatiron'), 24 | clear = require('./lib/util/clear'); 25 | 26 | /** 27 | * @alias module:deployr-cli 28 | */ 29 | var di = module.exports = flatiron.app; 30 | 31 | /** 32 | * Expose the CLI name _di_. 33 | * @property {String} name - The CLI name. 34 | */ 35 | di.name = 'di'; 36 | 37 | // 38 | // Setup `di` to use `pkginfo` to expose version, 39 | // 40 | require('pkginfo')(module, 'name', 'version'); 41 | 42 | // 43 | // Configure `di` to use `flatiron.plugins.cli` 44 | // 45 | di.use(flatiron.plugins.cli, { 46 | version: true, 47 | usage: require('./lib/usage'), 48 | source: path.join(__dirname, 'lib', 'commands'), 49 | argv: { 50 | version: { 51 | alias: 'v', 52 | description: 'prints DeployR version and exit', 53 | string: true 54 | }, 55 | diconf: { 56 | alias: 'j', 57 | description: 'specify file to load configuration from', 58 | string: true 59 | }, 60 | help: { 61 | alias: 'h', 62 | description: 'prints cli help and exit', 63 | string: true 64 | } 65 | } 66 | }); 67 | 68 | // 69 | // Configure `di` to use `cli-inquirer` for more sophisticated prompts. 70 | // 71 | di.use(require('./lib/plugins/inquirer')); 72 | 73 | // 74 | // Setup `di` with: config, command aliases settings 75 | // 76 | di.chalk = require('chalk'); 77 | di._ = require('lodash'); 78 | di.brand = require('./lib/util/brand'); 79 | di.spawnCommand = require('./lib/util/spawn-command'); 80 | require('./lib/config'); 81 | require('./lib/alias'); 82 | require('./lib/commands'); 83 | 84 | // 85 | // Setup other di settings. 86 | // 87 | di.started = false; 88 | di.displayExit = true; 89 | di.noop = function() {}; 90 | 91 | /** 92 | * Starts the di CLI and runs the specified command. 93 | * 94 | * @param {Function} callback - Continuation to pass control to when complete. 95 | */ 96 | di.start = function(callback) { 97 | // 98 | // whoami command should not output anything but username 99 | // 100 | if (di.argv._[0] === 'whoami') { 101 | di.displayExit = false; 102 | console.log(di.config.get('username') || ''); 103 | return; 104 | } 105 | 106 | di.init(function(err) { 107 | 108 | if (err) { 109 | di.showError(di.argv._.join(' '), err); 110 | return callback(err); 111 | } 112 | 113 | // intercept `--help, -h` help options 114 | di.argv._ = di.argv.help ? ['help'] : di.argv._; 115 | 116 | // `di` with no command or options routes to `home` 117 | if (!di.argv._[0]) { 118 | di.home(); 119 | } else { 120 | return di.exec(di.argv._, callback); 121 | } 122 | }); 123 | }; 124 | 125 | /** 126 | * Runs the specified command in the `di` CLI. 127 | * 128 | * @param {String} command - Command to execute 129 | * @param {Function} callback - Continuation to pass control to when complete. 130 | */ 131 | di.exec = function(command, callback) { 132 | function execCommand(err) { 133 | 134 | if (err) { 135 | return callback(err); 136 | } 137 | 138 | di.displayExit = false; 139 | di.router.dispatch('on', command.join(' '), di.log, function(err, shallow) { 140 | 141 | if (err) { 142 | di.showError(command.join(' '), err, shallow); 143 | return callback(err); 144 | } 145 | 146 | callback(); 147 | }); 148 | } 149 | 150 | return !di.started ? di.setup(execCommand) : execCommand(); 151 | }; 152 | 153 | /** 154 | * Sets up the instances of the Resource clients for di. 155 | * there is no io here, yet this function is ASYNC. 156 | * 157 | * @param {Function} callback - continuation to pass control to when complete. 158 | */ 159 | di.setup = function(callback) { 160 | if (di.started === true) { 161 | return callback(); 162 | } 163 | 164 | di.started = true; 165 | 166 | // Hack - override the 'jitsu' refrence in `$di help config list` 167 | di.commands.config.list.usage = [ 168 | 'Lists all configuration values currently', 169 | 'set in the .diconf file', 170 | '', 171 | 'di config list' 172 | ]; 173 | 174 | callback(); 175 | }; 176 | 177 | /** 178 | * Displays the `err` to the user for the `command` supplied. 179 | * 180 | * @param {String} command - Command which has errored. 181 | * @param {Error} err - Error received for the command. 182 | * @param {Boolean} shallow - Indicate if a deep stack should be displayed 183 | */ 184 | di.showError = function(command, err, shallow) { 185 | di.log.error('Error running command ' + di.chalk.magenta(command)); 186 | 187 | if (err.stack && !shallow) { 188 | err.stack.split('\n').forEach(function(trace) { 189 | di.log.error(trace); 190 | }); 191 | } else if (err.deployr) { 192 | di.log.error('DeployR API error on call "' + err.get('call') + '"'); 193 | di.log.error('Error Code: ' + err.get('errorCode')); 194 | di.log.error('Error: ' + err.get('error')); 195 | } else { 196 | di.log.error(err); 197 | } 198 | }; 199 | 200 | /** 201 | * Menu selection to run commands. 202 | */ 203 | di.goto = function(command, callback) { 204 | var cmdStr = (command || []).join(' '); 205 | 206 | di.plugins.cli.executeCommand(command, function(err, shallow) { 207 | if (err) { 208 | di.showError(cmdStr, err, shallow); 209 | } 210 | 211 | di.displayExit = false; 212 | }); 213 | }; 214 | 215 | /** 216 | * Display the home `di` screen with the intial set of options. 217 | */ 218 | di.home = function() { 219 | var separator = di.prompt.separator, 220 | endpoint = di.config.get('endpoint'), 221 | name = di.config.get('username'), 222 | defaults = [{ 223 | name: 'Install an example', 224 | value: { 225 | method: 'goto', 226 | args: ['install', 'example'] 227 | } 228 | }, { 229 | name: 'Settings', 230 | value: { 231 | method: 'settings' 232 | } 233 | }, { 234 | name: 'Find some help', 235 | value: { 236 | method: 'findHelp' 237 | } 238 | }, { 239 | name: 'Get me out of here!', 240 | value: { 241 | method: 'noop' 242 | } 243 | }]; 244 | 245 | name = (name && endpoint ? ' ' + name + '@' + endpoint.replace(/^https?:\/\//, '') : ''); 246 | 247 | di.prompt.inquirer([{ 248 | name: 'whatNext', 249 | type: 'list', 250 | message: 'Welcome to DeployR CLI' + di.chalk.magenta(name) + '!', 251 | choices: this._.flatten([ 252 | separator('Choices'), 253 | separator(), 254 | defaults, 255 | separator() 256 | ]) 257 | }], function(answer) { 258 | this[answer.whatNext.method](answer.whatNext.args); 259 | }.bind(this)); 260 | }; 261 | 262 | /** 263 | * Prompts user with a few helpful resources, then opens it in their browser. 264 | */ 265 | di.findHelp = function() { 266 | di.prompt.inquirer([{ 267 | name: 'whereTo', 268 | type: 'list', 269 | message: 'Here are a few helpful resources.\n' + 270 | '\nI will open the link you select in your browser for you', 271 | choices: [{ 272 | name: 'Take me to the documentation', 273 | value: di.config.get('homepage') 274 | }, { 275 | name: 'File an issue on GitHub', 276 | value: di.config.get('git').cli + '/issues' 277 | }, { 278 | name: 'Take me back home!', 279 | value: { 280 | method: 'home' 281 | } 282 | }] 283 | }], function(answer) { 284 | if (this._.isFunction(this[answer.whereTo.method])) { 285 | this[answer.whereTo.method](answer.whereTo.args); 286 | } else { 287 | opn(answer.whereTo); 288 | } 289 | }.bind(this)); 290 | }; 291 | 292 | /** 293 | * Prompts user with setting options. 294 | */ 295 | di.settings = function() { 296 | var separator = di.prompt.separator, 297 | choices = [{ 298 | name: 'DeployR endpoint', 299 | value: { 300 | method: 'goto', 301 | args: ['endpoint'] 302 | } 303 | }, { 304 | name: 'About server', 305 | value: { 306 | method: 'goto', 307 | args: ['about'] 308 | } 309 | }, { 310 | name: 'Take me back home!', 311 | value: { 312 | method: 'home' 313 | } 314 | }]; 315 | 316 | di.prompt.inquirer([{ 317 | name: 'general', 318 | type: 'list', 319 | message: 'General settings', 320 | choices: this._.flatten([ 321 | separator('Choices'), 322 | separator(), 323 | choices, 324 | separator() 325 | ]) 326 | }], function(answer) { 327 | this[answer.general.method](answer.general.args, function() { 328 | di.home(); 329 | }); 330 | }.bind(di)); 331 | }; 332 | 333 | /** 334 | * Clears stdout and bring the cursor to postion 0. 335 | */ 336 | di.clearScreen = function() { 337 | clear(); 338 | }; 339 | 340 | /** 341 | * Ends the `di` process with the a common exit message. 342 | */ 343 | di.exit = function() { 344 | if (di.displayExit) { 345 | var newLine = '\n'; 346 | 347 | console.log( 348 | di.brand + 349 | newLine + 350 | 'Good Bye!' + 351 | newLine + 352 | newLine + 353 | 'The DeployR Team' + di.chalk.dim.yellow(' ♥ ') 354 | ); 355 | } 356 | }; 357 | 358 | process.once('exit', di.exit.bind(this)); -------------------------------------------------------------------------------- /jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": { 3 | "include": ["./package.json", "./di.js", "lib"], 4 | "exclude": [ "./lib/completion.js" ], 5 | "includePattern": ".+\\.js(doc)?$" 6 | }, 7 | "opts": { 8 | "recurse": true, 9 | "destination": "../deployr-cli-doc/" 10 | }, 11 | "plugins": [ 12 | "plugins/markdown" 13 | ] 14 | } -------------------------------------------------------------------------------- /lib/alias.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var di = require('../di'); 15 | 16 | // 17 | // Alias the appropriate commands for simplier CLI usage 18 | // 19 | di.alias('w', { resource: 'users', command: 'whoami' }); 20 | di.alias('e', { resource: 'server', command: 'endpoint' }); -------------------------------------------------------------------------------- /lib/commands.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var di = require('../di'); 15 | 16 | // 17 | // Configure `di` to use the `deployr-cli-server` plugin. 18 | // 19 | di.use(require('./plugins/deployr-cli-server'), { 20 | before: { 21 | endpoint: function(details, next) { 22 | next(); 23 | } 24 | }, 25 | after: { 26 | endpoint: function(details, next) { 27 | // 28 | // Retrieve server details and store them 29 | // 30 | if (details && details.endpoint) { 31 | di.config.set('endpoint', details.endpoint); 32 | di.config.save(); 33 | } 34 | 35 | return next(); 36 | }, 37 | 38 | about: function(details, next) { 39 | var info = details.info, 40 | yellow = di.chalk.dim.yellow, 41 | username = di.config.get('username'), 42 | endpoint = di.config.get('endpoint') 43 | 44 | console.log(di.brand); 45 | 46 | if (info) { 47 | di.log.info('Version: ' + yellow(info.version + ' DeployR "' + 48 | (info.enterprise ? 'Enterprise' : 'Open') + '"')); 49 | di.log.info('Server: ' + yellow(endpoint)); 50 | di.log.info('Build Date: ' + yellow(info.date)); 51 | } else { 52 | di.log.warn('There is no DeployR server endpoint set. ' + 53 | 'Run `di endpoint` first.'); 54 | } 55 | 56 | console.log(''); 57 | 58 | return next(); 59 | } 60 | } 61 | }); 62 | 63 | // 64 | // Configure `di` to use the `deployr-cli-users` plugin. 65 | // 66 | di.use(require('./plugins/deployr-cli-users'), { 67 | before: { 68 | login: function(details, next) { 69 | next(); 70 | }, 71 | logout: function(details, next) { 72 | next(); 73 | } 74 | }, 75 | after: { 76 | login: function(details, next) { 77 | // 78 | // Retrieve authentication details and store them 79 | // 80 | if (details && details.username) { 81 | di.config.clear('password'); 82 | di.config.set('username', details.username); 83 | di.config.set('cookie', details.cookie); 84 | di.config.save(); 85 | } 86 | 87 | return next(); 88 | }, 89 | logout: function(details, next) { 90 | di.config.clear('cookie'); 91 | di.config.save(); 92 | return next(); 93 | } 94 | } 95 | }); 96 | 97 | -------------------------------------------------------------------------------- /lib/commands/install.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var path = require('path'), 15 | fs = require('fs'), 16 | deployr = require('deployr'), 17 | request = require('request'), 18 | opn = require('opn'), 19 | shell = require('shelljs'), 20 | Download = require('download'), 21 | progress = require('download-status'), 22 | spinner = require('char-spinner'), 23 | LangType = require('../util/lang-type'), 24 | di = require('../../di'), 25 | conf = di.config, 26 | // --- color aliases --- 27 | ul = di.chalk.underline, 28 | dim = di.chalk.dim, 29 | red = di.chalk.red, 30 | gray = di.chalk.gray, 31 | green = di.chalk.green, 32 | yellow = di.chalk.yellow, 33 | magenta = di.chalk.magenta; 34 | 35 | /** 36 | * Commands for installing and deploying starter examples. 37 | * @mixin 38 | * @alias commands/install 39 | */ 40 | var install = exports; 41 | 42 | /** 43 | * Usage for the _di install *_ commands which allow you install and deploy 44 | * starter examples. 45 | * 46 | * - di install example 47 | * - di install example 48 | */ 49 | install.usage = [ 50 | 'The `di install` command installs pre-built DeployR examples locally', 51 | '', 52 | 'Example usages:', 53 | 'di install example', 54 | 'di install example ' 55 | ]; 56 | 57 | /** 58 | * Installs a starter example. 59 | * 60 | * @param {String} exName - The example to install. 61 | * @param {Function} callback - Continuation to pass control when complete. 62 | */ 63 | install.example = function(exName, callback) { 64 | var exConfig = {}; 65 | 66 | // 67 | // Allows arbitrary amount of arguments 68 | // 69 | if (arguments.length) { 70 | var args = Array.prototype.slice.call([arguments], 0)[0]; 71 | callback = args[arguments.length - 1]; 72 | exName = args[0] || null; 73 | } 74 | 75 | function listExamples(interval) { 76 | var separator = di.prompt.separator, 77 | jsList = [], 78 | javaList = [], 79 | dotNETList = [], 80 | choices = [], 81 | found = false; 82 | 83 | try { 84 | 85 | clearInterval(interval); 86 | 87 | conf.get('git').repos.forEach(function(name, i) { 88 | if (name.indexOf('example') > -1) { 89 | found = name === exName ? true : found; 90 | switch (LangType.parse(name)) { 91 | case LangType.JS: 92 | jsList.push({ name: ' ' + name }); 93 | break; 94 | 95 | case LangType.JAVA: 96 | javaList.push(' ' + name); 97 | break; 98 | 99 | case LangType.DOTNET: 100 | dotNETList.push(' ' + name); 101 | break; 102 | } 103 | } 104 | }); 105 | 106 | if (found) { 107 | console.log('Installing example ' + ul(exName) + '\n'); 108 | installExample(exName, di.noop); 109 | return; 110 | } 111 | 112 | if (jsList.length > 0) { 113 | choices.push(separator('JavaScript Examples ')); 114 | choices.push(jsList); 115 | } 116 | 117 | if (javaList.length > 0) { 118 | choices.push(separator()); 119 | choices.push(separator('Java Examples ')); 120 | choices.push(javaList); 121 | } 122 | 123 | if (dotNETList.length > 0) { 124 | choices.push(separator('.NET Examples ')); 125 | choices.push(dotNETList); 126 | } 127 | 128 | choices.push(separator()); 129 | choices.push({ 130 | name: 'Take me back home!', 131 | value: { 132 | method: 'home' 133 | } 134 | }); 135 | 136 | di.prompt.inquirer([{ 137 | name: 'example', 138 | type: 'list', 139 | message: 'What example would you like to install?', 140 | choices: di._.flatten(choices) 141 | }], function(answer) { 142 | if (!answer.example.method) { 143 | installExample(answer.example.trim(), di.noop); 144 | } else { 145 | di.home(); 146 | } 147 | }.bind(di)); 148 | } catch (err) { 149 | return callback(new Error(chalk.bold( 150 | 'A problem occurred installing the example from Github.' + 151 | '\nUnable to parse response: not valid JSON.' ))); 152 | } 153 | } 154 | 155 | function installExample(example) { 156 | var download = new Download({ 157 | extract: true, 158 | strip: 1, 159 | mode: '755' 160 | }) 161 | .get(conf.get('git').example.replace('{{example}}', example)) 162 | .dest(example) 163 | .use(progress()); 164 | 165 | download.run(function(err, files, stream) { 166 | if (err) { callback(new Error(err)); } 167 | 168 | console.log(green.bold('✓ download complete.\n')); 169 | console.log(ul(example)); 170 | 171 | var installer; 172 | 173 | switch (LangType.parse(example)) { 174 | case LangType.JS: 175 | installer = function(next) { 176 | console.log(yellow('\nResolving npm dependencies, this might take a while...\n')); 177 | di.spawnCommand('npm', ['install', '--production', '--silent']) 178 | .on('error', next) 179 | .on('exit', next); 180 | }; 181 | break; 182 | 183 | case LangType.JAVA: 184 | case LangType.DOTNET: 185 | installer = function(next) { next(); } 186 | break; 187 | } 188 | 189 | // be in the example dir for installation and running 190 | shell.cd(example); 191 | 192 | installer(function() { 193 | fs.exists(path.resolve('di-config.json'), function(exists) { 194 | if (exists) { 195 | agent(); 196 | 197 | deployr.io('/r/user/about') 198 | .error(function() { 199 | var end = !conf.get('endpoint') ? 200 | ' First identify your DeployR server endpoint.' : ''; 201 | console.log(yellow('\nAuthentication required to install.' + end + '\n')); 202 | 203 | di.commands.login(function(err) { 204 | if (err) { return callback(err); } 205 | 206 | installation(); 207 | }); 208 | }) 209 | .end(function() { installation(); }); 210 | } else { 211 | // no `di-config` file given, just the launch example 212 | console.log('no di-config.json'); 213 | run(); 214 | } 215 | }); 216 | }); 217 | }); 218 | 219 | function installation() { 220 | var config = require(path.resolve('di-config.json')) || {}, 221 | repos = (config['app-install'] || {}).repository || [], 222 | dirs = di._.uniq(repos, 'directory'), 223 | last = dirs.length, 224 | success = 0; 225 | 226 | exConfig = { 227 | example: example, 228 | repos: repos, 229 | auth: (config['app-run'] || {}).requireAuthentication || false, 230 | tutorial: (config['app-run'] || {}).tutorial || {} 231 | }; 232 | 233 | if (repos.length > 0) { 234 | console.log(yellow('\nInstalling example analytics dependencies onto DeployR...\n')); 235 | agent(); 236 | 237 | repos.forEach(function(item, index) { 238 | console.log((index + 1) + '. ' + 239 | ul(item.file.filename) + ' in directory ' + 240 | ul(item.file.directory || 'root')); 241 | }); 242 | console.log(''); 243 | 244 | // 245 | // create directories for the dependencies, when done start the 246 | // upload/install of the analytic dependencies into DeployR 247 | // 248 | dirs.forEach(function(item) { 249 | deployr.io('/r/repository/directory/create') 250 | .data({ directory: item.file.directory }) 251 | .end(function() { success++; }) 252 | .ensure(function() { 253 | if (success === last) { analytics(repos); } 254 | }); 255 | }); 256 | } else { // othwise no dependencies just run the example 257 | candidateToRun(); 258 | } 259 | } 260 | 261 | function analytics(repos) { 262 | var last = repos.length, 263 | success = 0, 264 | retry = []; 265 | 266 | repos.forEach(function(item) { 267 | var file = item.file, 268 | perm = item.permissions; 269 | 270 | deployr.io('/r/repository/file/upload') 271 | .data({ 272 | filename: file.filename, 273 | directory: file.directory || 'root', 274 | restricted: perm.restricted || null, 275 | shared: perm.shared || true, 276 | published: perm.published || true, 277 | newversion: true, 278 | newversionmsg: 'DeployR CLI (examples) upload.' 279 | }) 280 | .attach(path.resolve('analytics', file.filename)) 281 | .error(function(err) { callback(err); }) 282 | .end(function(res) { 283 | var file = res.get('repository').file; 284 | 285 | console.log(green.bold('✓ upload complete.\n')); 286 | console.log(ul(file.filename) + 287 | ' uploaded to directory ' + 288 | ul(file.directory) + 289 | ' for ' + dim(conf.get('username') + '@' + conf.get('endpoint')) + 290 | '\n'); 291 | success++; 292 | }) 293 | .ensure(function() { 294 | if (success === last) { 295 | console.log(green.bold('✓ installation complete.\n')); 296 | candidateToRun(); 297 | } 298 | }); 299 | }); // foreach 300 | } 301 | 302 | } // end installExample 303 | 304 | function candidateToRun() { 305 | di.prompt.inquirer([{ 306 | name: 'run', 307 | type: 'confirm', 308 | message: 'Would you like to run the example:' 309 | }], function(result) { 310 | if (result.run) { 311 | if (exConfig.auth) { 312 | console.log('\nThis example requires ' + 313 | magenta(conf.get('username')) + 314 | '\'s password to run.\n'); 315 | 316 | verifyPassword(targets); 317 | } else { 318 | targets(); 319 | } 320 | } 321 | }); 322 | } 323 | 324 | function verifyPassword(cb) { 325 | di.prompt.inquirer([{ 326 | name: 'password', 327 | type: 'password', 328 | message: 'Password:', 329 | validate: function(input) { 330 | return input.length > 0 || 'Please enter a valid password.'; 331 | } 332 | }], function(answer) { 333 | // confirm password 334 | di.prompt.inquirer([{ 335 | name: 'password', 336 | type: 'password', 337 | message: 'Verify Password:' 338 | }], function(confirm) { 339 | if (answer.password === confirm.password) { 340 | cb(confirm.password); 341 | } else { 342 | console.log(red('>>') + ' Passwords do not match.\n'); 343 | verifyPassword(cb); 344 | } 345 | }); 346 | }); 347 | } 348 | 349 | function targets(pw) { 350 | var separator = di.prompt.separator; 351 | 352 | di.clearScreen(); 353 | 354 | // tutorial type examples 355 | if (exConfig.tutorial.topics) { 356 | var choices = [separator()]; 357 | 358 | choices.push({ 359 | name: 'Example Documentation', 360 | value: { 361 | help: exConfig.tutorial.help, 362 | } 363 | }); 364 | 365 | exConfig.tutorial.topics.forEach(function(obj) { 366 | choices.push({ 367 | name: obj.topic, 368 | value: { 369 | menu: obj.menu 370 | } 371 | }); 372 | }); 373 | 374 | choices.push(separator()); 375 | 376 | choices.push({ 377 | name: 'Take me back home!', 378 | value: 'home' 379 | }); 380 | 381 | di.prompt.inquirer([{ 382 | name: 'topic', 383 | type: 'list', 384 | message: 'Examples', 385 | choices: choices 386 | }], function(answer) { 387 | if (answer.topic === 'home') { 388 | di.home(); 389 | } else if (answer.topic.help) { 390 | opn(answer.topic.help); 391 | targets(pw); 392 | } else { 393 | tutorialChoice(answer.topic.menu, pw); 394 | } 395 | }); 396 | } else { // standalone example apps 397 | run({ 398 | pw: pw 399 | }); 400 | } 401 | } 402 | 403 | function tutorialChoice(menu, pw) { 404 | var separator = di.prompt.separator, 405 | choices = [separator()].concat(menu.map(function(obj) { 406 | return { 407 | name: obj.item, 408 | value: { 409 | test: obj.args 410 | } 411 | }; 412 | })); 413 | 414 | di.prompt.inquirer([{ 415 | name: 'item', 416 | type: 'list', 417 | message: 'Examples to run?', 418 | choices: choices.concat([ 419 | separator(), { 420 | name: 'Take me back', 421 | value: 'back' 422 | } 423 | ]) 424 | }], function(answer) { 425 | if (answer.item === 'back') { 426 | return targets(pw); 427 | } 428 | run({ 429 | pw: pw, 430 | tutorial: { 431 | menu: menu, 432 | example: answer.item.test 433 | } 434 | }); 435 | }); 436 | } 437 | 438 | function run(optArgs) { 439 | var args = [], 440 | options = [], 441 | sep = dim(ul(' ')), 442 | cmd; 443 | 444 | optArgs = optArgs || {}; 445 | 446 | switch (LangType.parse(exConfig.example)) { 447 | case LangType.JS: 448 | cmd = 'npm'; 449 | args = ['start']; 450 | 451 | process.env.endpoint = conf.get('endpoint'); 452 | process.env.username = conf.get('username'); 453 | process.env.password = optArgs.pw || ''; 454 | process.env.testmod = (optArgs.tutorial || {}).example; 455 | options = { env: process.env }; 456 | 457 | break; 458 | 459 | case LangType.JAVA: 460 | cmd = (process.platform === 'win32' ? 'gradlew.bat' : './gradlew'); 461 | args = [ 462 | 'run', 463 | '-Pendpoint=' + conf.get('endpoint') + '/deployr', 464 | '-Pusername=' + conf.get('username'), 465 | '-Ppassword=' + optArgs.pw || '', 466 | '-DtestClass=' + (optArgs.tutorial || {}).example 467 | ]; 468 | 469 | break; 470 | 471 | case LangType.DOTNET: 472 | break; 473 | } 474 | 475 | di.clearScreen(); 476 | 477 | console.log(sep); 478 | 479 | di.spawnCommand(cmd, args, options) 480 | .on('error', function(err) { 481 | callback(err); 482 | }) 483 | .on('close', function(err) { 484 | console.log(sep + '\n'); 485 | di.prompt.inquirer([{ 486 | name: 'post', 487 | type: 'list', 488 | message: 'What do you want to do?', 489 | choices: [{ 490 | name: 'Take me back', 491 | value: 'back' 492 | }, { 493 | name: 'Run more examples', 494 | value: 'more' 495 | }] 496 | }], function(answer) { 497 | di.clearScreen(); 498 | 499 | if (answer.post === 'back') { 500 | if (!optArgs.tutorial) { // no sub-menus 501 | listExamples(spinner()); 502 | } else { 503 | tutorialChoice(optArgs.tutorial.menu, optArgs.pw); 504 | } 505 | 506 | } else { 507 | targets(optArgs.pw); 508 | } 509 | }); 510 | }); 511 | } 512 | 513 | // 514 | // Start to example installation workflow 515 | // 516 | var interval = spinner(); 517 | setTimeout(function() { listExamples(interval); }, 500); 518 | }; 519 | 520 | /** 521 | * Output usage information describing commands for installing and deploying 522 | * starter examples. 523 | */ 524 | install.example.usage = [ 525 | 'The `di install` command installs pre-built DeployR examples locally', 526 | '', 527 | 'Example usages:', 528 | 'di install example', 529 | 'di install example ' 530 | ]; 531 | 532 | function agent() { 533 | deployr.configure({ 534 | host: conf.get('endpoint'), 535 | cookies: ['JSESSIONID=' + conf.get('cookie')], 536 | sticky: true 537 | }); 538 | } -------------------------------------------------------------------------------- /lib/completion.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | if (process.platform === 'win32') { 15 | return; 16 | } 17 | 18 | var complete = require('complete'); 19 | 20 | /** 21 | * di install [] 22 | * di install example 23 | * di install example 24 | * 25 | * di server [] 26 | * di endpoint 27 | * di about 28 | * 29 | * di users [] 30 | * di users confirm 31 | * 32 | * di help [] 33 | * di help users 34 | * di help server 35 | * di help config 36 | * di help install 37 | * di help login 38 | * di help logout 39 | * di help whoami 40 | * di help endpoint 41 | * di help about 42 | * 43 | * di config 44 | * di login 45 | * di logout 46 | * di whoami 47 | * di endpoint 48 | * di about 49 | */ 50 | 51 | /** 52 | * Lazy Loading 53 | */ 54 | function di() { 55 | if (!di.module) { 56 | di.module = require('../di'); 57 | di.module.setup(function() {}); 58 | } 59 | 60 | return di.module; 61 | } 62 | 63 | var commands = { 64 | // resource 65 | 'users': { 66 | 'login': {}, 67 | 'logout': {}, 68 | 'whoami': {} 69 | }, 70 | 'server': { 71 | 'endpoint': {}, 72 | 'about': {} 73 | }, 74 | 'install': { 75 | 'example': {} 76 | }, 77 | 'config': { 78 | 'list': {}, 79 | 'set': {}, 80 | 'get': {}, 81 | 'delete': {} 82 | }, 83 | 'login': {}, 84 | 'logout': {}, 85 | 'whoami': {}, 86 | 'endpoint': {}, 87 | 'about': {}, 88 | 'help': { 89 | // resource 90 | 'users': { 91 | 'login': {}, 92 | 'logout': {}, 93 | 'whoami': {} 94 | }, 95 | 'server': { 96 | 'endpoint': {}, 97 | 'about': {} 98 | }, 99 | 'install': { 100 | 'example': {} 101 | }, 102 | 'config': { 103 | 'list': {}, 104 | 'set': {}, 105 | 'get': {}, 106 | 'delete': {} 107 | }, 108 | // commands under resource 109 | 'login': {}, 110 | 'logout': {}, 111 | 'whoami': {}, 112 | 'endpoint': {}, 113 | 'about': {} 114 | } 115 | }; 116 | 117 | var options = { 118 | '--version': {}, 119 | '-v': {}, 120 | '--diconf': {}, 121 | '-j': {}, 122 | '--help': {}, 123 | '-h': {} 124 | }; 125 | 126 | complete({ 127 | program: 'di', 128 | commands: commands, 129 | options: options 130 | }); 131 | -------------------------------------------------------------------------------- /lib/config.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var path = require('path'), 15 | di = require('../di'); 16 | 17 | // 18 | // Update env for Windows 19 | // 20 | if (process.platform == 'win32') { 21 | process.env.HOME = process.env.USERPROFILE; 22 | } 23 | 24 | // 25 | // Setup target file for `.diconf`. 26 | // 27 | try { 28 | di.config.env().file({ 29 | file: di.argv.diconf || di.argv.j || '.diconf', 30 | dir: process.env.HOME, 31 | search: true 32 | }); 33 | } catch (err) { 34 | console.log('Error parsing ' + di.chalk.magenta(di.config.stores.file.file)); 35 | console.log(err.message); 36 | console.log(''); 37 | console.log('Please check the .diconf file and try again'); 38 | console.log(''); 39 | process.exit(1); 40 | } 41 | 42 | var restricted = ['git']; 43 | 44 | // 45 | // Set defaults for `diconfig`. 46 | // 47 | di.config.defaults({ 48 | homepage: 'http://go.microsoft.com/fwlink/?LinkID=692163', 49 | git: { 50 | repos: [ 'java-example-client-basics', 51 | 'java-example-client-data-io', 52 | 'java-example-fraud-score', 53 | 'java-example-rbroker-basics', 54 | 'java-example-rbroker-data-io', 55 | 'js-example-fraud-score', 56 | 'js-example-fraud-score-basics' 57 | ], 58 | example: 'https://github.com/microsoft/{{example}}/archive/master.zip', 59 | cli: 'http://github.com/microsoft/deployr-cli' 60 | } 61 | }); 62 | 63 | // 64 | // Use the `flatiron-cli-config` plugin for `di config *` commands. 65 | // 66 | di.use(require('flatiron-cli-config'), { 67 | 68 | // 69 | // Name of the store in `di.config` to use for `config list`. 70 | // 71 | // 72 | store: 'file', 73 | 74 | // 75 | // Set of properties which cannot be deleted using `config delete ` 76 | // 77 | restricted: restricted, 78 | 79 | // 80 | // Set of functions which will execute before named commands: 81 | // get, set, list, delete 82 | // 83 | before: { 84 | set: function(key) { 85 | if (di._.contains(restricted, key)) { 86 | di.log.warn('Cannot set reserved key ' + key.yellow); 87 | return false; 88 | } else { 89 | return true; 90 | } 91 | }, 92 | 93 | list: function() { 94 | var username = di.config.get('username'), 95 | confFile = di.config.stores.file.file, 96 | display = [ 97 | 'Hello ' + di.chalk.green(username) + 98 | ' here is the ' + di.chalk.grey(confFile) + ' file:', 99 | 'To change a property type:', 100 | 'di config set ', 101 | ]; 102 | 103 | display.forEach(function(line) { 104 | di.log.help(line); 105 | }); 106 | 107 | return true; 108 | } 109 | } 110 | }); 111 | -------------------------------------------------------------------------------- /lib/plugins/deployr-cli-server/commands.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var cliServer = require('./index'), 15 | common = require('flatiron').common, 16 | async = common.async; 17 | 18 | /** 19 | * The CLI Commands related to managing the DeployR server. 20 | * 21 | * @mixin 22 | * @alias plugins/deployr-cli-server/commands 23 | */ 24 | var server = exports; 25 | 26 | /** 27 | * Usage for the _di server *_ commands which allow you to work with the DeployR 28 | * server. Supported commands: 29 | * 30 | * - di server endpoint 31 | * - di server about 32 | */ 33 | server.usage = [ 34 | '` server *` commands allow you to work with the DeployR server', 35 | '', 36 | ' server endpoint', 37 | ' server about', 38 | '', 39 | 'You will be prompted for additional user information', 40 | 'as required.' 41 | ]; 42 | 43 | /** 44 | * Attempts to set the DeployR server _endpoint_ location in the CLI. 45 | * @param {Function} callback - Continuation to pass control to when complete. 46 | */ 47 | server.endpoint = function() { 48 | var app = cliServer.app, 49 | callback = common.args(arguments).callback, 50 | server = {}; 51 | 52 | if (cliServer.before.setup) { 53 | cliServer.before.setup({ 54 | endpoint: app.config.get('endpoint') 55 | }); 56 | } 57 | 58 | // 59 | // Endpoint workflow including async hooks 60 | // 61 | async.series([ 62 | // 63 | // Before endpoint hook 64 | // 65 | function before(next) { 66 | if (cliServer.before.endpoint) { 67 | cliServer.before.endpoint({ 68 | endpoint: app.config.get('endpoint') 69 | }, next); 70 | } else { 71 | next(); 72 | } 73 | }, 74 | 75 | // 76 | // Set the endpoint 77 | // 78 | function set(next) { 79 | app.setEndpoint(function(res) { // success 80 | server = res; // server's meta-data 81 | app.config.save(function(err) { 82 | return err ? next(err) : next(); 83 | }); 84 | }); 85 | }, 86 | 87 | // 88 | // After endpoint hook 89 | // 90 | function after(next) { 91 | if (cliServer.after.endpoint) { 92 | cliServer.after.endpoint(server, next); 93 | } else { 94 | next(); 95 | } 96 | } 97 | ], 98 | 99 | // 100 | // Workflow end 101 | // 102 | function(err, result) { 103 | return err ? callback(err) : callback(); 104 | }); 105 | }; 106 | 107 | /** 108 | * Usage for _di endpoint_ command. 109 | * 110 | * - di server endpoint 111 | * - di endpoint 112 | */ 113 | server.endpoint.usage = [ 114 | 'Allows the user to set the DeployR server endpoint', 115 | '', 116 | ' endpoint' 117 | ]; 118 | 119 | /** 120 | * Displays information regarding the DeployR server at the set _endpoint_ 121 | * location. 122 | * 123 | * @param {Function} callback - Continuation to pass control to when complete. 124 | */ 125 | server.about = function() { 126 | var app = cliServer.app, 127 | callback = common.args(arguments).callback, 128 | server = {}; 129 | // 130 | // Endpoint workflow including async hooks 131 | // 132 | async.series([ 133 | // 134 | // Find information 'about' the DeployR server 135 | // 136 | function about(next) { 137 | app.about(function(res, err) { // success 138 | if (err) { callback(err); } 139 | 140 | server = res; // server's meta-data 141 | app.config.save(function(err) { 142 | return err ? next(err) : next(); 143 | }); 144 | }); 145 | }, 146 | 147 | // 148 | // After about hook 149 | // 150 | function after(next) { 151 | if (cliServer.after.about) { 152 | cliServer.after.about(server, next); 153 | } else { 154 | next(); 155 | } 156 | } 157 | ], 158 | 159 | // 160 | // Workflow end 161 | // 162 | function(err, result) { 163 | return err ? callback(err) : callback(); 164 | }); 165 | }; 166 | 167 | /** 168 | * Usage for _di about_ command. 169 | * 170 | * - di server about 171 | * - di about 172 | */ 173 | server.about.usage = [ 174 | 'Displays DeployR server information based on the set server `endpoint`', 175 | '', 176 | ' about' 177 | ]; -------------------------------------------------------------------------------- /lib/plugins/deployr-cli-server/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var deployr = require('deployr'), 15 | common = require('flatiron').common; 16 | 17 | /** 18 | * Top-level include for the `deployr-cli-server` module. 19 | * 20 | * @mixin 21 | * @alias plugins/deployr-cli-server 22 | */ 23 | var cliServer = exports; 24 | 25 | /** 26 | * Expose the plugin `commands`. 27 | */ 28 | cliServer.commands = require('./commands'); 29 | 30 | /** 31 | * Expose the plugin name _cli-server_. 32 | * @property {String} name - The plugin name. 33 | */ 34 | cliServer.name = 'cli-server'; 35 | 36 | /** 37 | * Attaches the `deployr-cli-server` behavior to the application. 38 | * @param {Object} options - The options object literal to use when attaching. 39 | */ 40 | cliServer.attach = function(options) { 41 | var app = this; 42 | options = options || {}; 43 | 44 | if (!app.plugins.cli) { 45 | throw new Error('`cli` plugin is required to use `deployr-cli-server`'); 46 | } else if (!app.config) { 47 | throw new Error('`app.config` must be set to use `deployr-cli-server`'); 48 | } 49 | 50 | /** 51 | * Setup state from the application attached to. 52 | * @property {Object} app - The application. 53 | */ 54 | cliServer.app = app; 55 | cliServer.after = options.after || {}; 56 | cliServer.before = options.before || {}; 57 | common.templateUsage(app, cliServer.commands); 58 | 59 | // 60 | // Add the necessary ` server *` commands 61 | // 62 | app.commands['server'] = app.commands['server'] || {}; 63 | app.commands['server'] = common.mixin(app.commands['server'], cliServer.commands); 64 | 65 | // 66 | // Setup aliases for ` server *` commands. 67 | // 68 | app.alias('about', { // $ di about 69 | resource: 'server', 70 | command: 'about' 71 | }); 72 | 73 | app.alias('endpoint', { // $ di endpoint 74 | resource: 'server', 75 | command: 'endpoint' 76 | }); 77 | 78 | app.home = this.home; 79 | 80 | /** 81 | * Attempts to retrieve information about the DeployR server at the 82 | * supplied endpoint. 83 | * 84 | * @protected 85 | * @param {Function} callback - Continuation to pass control to when 86 | * complete. 87 | */ 88 | app.about = function(callback) { 89 | var endpoint = app.config.get('endpoint') || null; 90 | 91 | if (endpoint) { 92 | deployr.configure({ host: endpoint }) 93 | .io('/r/server/info') 94 | .error(function(err) { callback(null, err); }) 95 | .end(function(res) { 96 | callback({ endpoint: endpoint, info: res.get('info') }); 97 | }); 98 | } else { 99 | callback({}); 100 | } 101 | }; 102 | 103 | /** 104 | * Attempts to set the DeployR server endpoint. 105 | * 106 | * @memberof plugins/deployr-cli-server 107 | * @protected 108 | * @param {Function} callback - Continuation to pass control to when 109 | * complete. 110 | */ 111 | app.setEndpoint = function(callback) { 112 | var server = {}, 113 | regx = new RegExp('^(http|https)://', 'i'), 114 | endpoint = app.config.get('endpoint') || null, 115 | errorMsg = ' Please enter a valid DeployR endpoint.', 116 | hostMsg = (!endpoint ? ' http(s)://dhost:port' : ''); 117 | 118 | app.prompt.inquirer([{ 119 | name: 'endpoint', 120 | type: 'input', 121 | default: endpoint, 122 | message: 'DeployR Server' + app.chalk.dim.yellow(hostMsg) + ':', 123 | validate: function(input) { 124 | var done = this.async(); 125 | if (input.length > 0) { 126 | // Be more forgiving on the entered DeployR 'endpoint': 127 | // - http(s)://dhost:port 128 | // - http(s)://dhost:port/deployr 129 | // - dhost:port 130 | // - dhost:port/deployr 131 | input = input.replace(/\/*$|\/*deployr\/*$/, ''); 132 | input = regx.test(input) ? input : 'http://' + input; 133 | 134 | deployr.configure({ host: input }) 135 | .io('/r/server/info') 136 | .error(function(err) { 137 | deployr.configure({ host: '' }); 138 | done(errorMsg); 139 | }) 140 | .end(function(res) { 141 | server = { endpoint: input, info: res.get('info') }; 142 | done(true); 143 | }); 144 | } else { 145 | done(errorMsg); 146 | } 147 | } 148 | }], function() { 149 | callback(server); 150 | }); 151 | }; 152 | }; 153 | 154 | /** 155 | * Detaches this plugin from the application. 156 | */ 157 | cliServer.detach = function() { 158 | var app = this; 159 | 160 | Object.keys(app.commands['server']).forEach(function(method) { 161 | if (cliServer.commands[method]) { 162 | delete app.commands['config'][method]; 163 | } 164 | 165 | cliServer.commands.app = null; 166 | }); 167 | }; 168 | -------------------------------------------------------------------------------- /lib/plugins/deployr-cli-users/commands.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var cliUsers = require('./index'), 15 | common = require('flatiron').common, 16 | async = common.async; 17 | 18 | /** 19 | * The CLI Commands related to managing users. 20 | * 21 | * @mixin 22 | * @alias plugins/deployr-cli-users/commands 23 | */ 24 | var users = exports; 25 | 26 | /** 27 | * Usage for the _di users *_ commands which allow you to work with existing 28 | * user accounts on DeployR. Supported commands: 29 | * 30 | * - di users login 31 | * - di users logout 32 | * - di users whoami 33 | */ 34 | users.usage = [ 35 | '` users *` commands allow you to work with existing user accounts', 36 | '', 37 | ' users login', 38 | ' users logout', 39 | ' users whoami', 40 | '', 41 | 'You will be prompted for additional user information', 42 | 'as required.' 43 | ]; 44 | 45 | /** 46 | * Attempts to login the user with the prompted credentials. Makes three 47 | * prompt attempts and then exists. 48 | * 49 | * @param {Function} vcallback - Continuation to pass control to when complete. 50 | */ 51 | users.login = function() { 52 | var app = cliUsers.app, 53 | args = common.args(arguments), 54 | callback = args.callback, 55 | cookie = '', 56 | username = ''; 57 | 58 | if (cliUsers.before.setup) { 59 | cliUsers.before.setup({ 60 | username: app.config.get('username') 61 | }); 62 | } 63 | 64 | // 65 | // Login workflow including async hooks 66 | // 67 | async.series([ 68 | // 69 | // Before login hook 70 | // 71 | function before(next) { 72 | if (cliUsers.before.login) { 73 | cliUsers.before.login({ 74 | username: app.config.get('username') 75 | }, next); 76 | } else { 77 | next(); 78 | } 79 | }, 80 | 81 | // 82 | // Login 83 | // 84 | tryAuth, 85 | 86 | // 87 | // After login hook 88 | // 89 | function after(next) { 90 | if (cliUsers.after.login) { 91 | cliUsers.after.login({ 92 | cookie: cookie, 93 | username: username 94 | }, next); 95 | } else { 96 | next(); 97 | } 98 | } 99 | ], 100 | // 101 | // Workflow end 102 | // 103 | function(err, result) { 104 | return err ? callback(err) : callback(); 105 | }); 106 | 107 | // 108 | // Helper function to attempt to authenticate as the current user. 109 | // 110 | function tryAuth(next) { 111 | function auth() { 112 | app.auth(function(err, res) { 113 | if (err) { return callback(err); } 114 | 115 | cookie = res.get('httpcookie'); 116 | username = res.get('username'); 117 | 118 | app.config.save(function(err) { 119 | return err ? next(err) : next(); 120 | }); 121 | }); 122 | } 123 | 124 | return app.setup ? app.setup(function () { auth(next); }) : auth(next); 125 | } 126 | }; 127 | 128 | /** 129 | * Usage for _di login_ command. 130 | * 131 | * - di users login 132 | * - di login 133 | */ 134 | users.login.usage = [ 135 | 'Allows the user to login DeployR', 136 | '', 137 | ' login' 138 | ]; 139 | 140 | /** 141 | * Attempts to logout current user by removing the name from application config 142 | * and calling _/r/user/logout_ on DeployR. 143 | * 144 | * @param {Function} vcallback - Continuation to pass control to when complete. 145 | */ 146 | users.logout = function(callback) { 147 | var app = cliUsers.app, 148 | username = app.config.get('username'); 149 | 150 | async.series([ 151 | // 152 | // Before hook 153 | // 154 | function before(next) { 155 | if (cliUsers.before.logout) { 156 | cliUsers.before.logout({ 157 | username: username 158 | }, next); 159 | } else { 160 | next(); 161 | } 162 | }, 163 | function logout(next) { 164 | app.unauth(function() { 165 | app.config.clear('username'); 166 | app.config.clear('password'); 167 | next(); 168 | }); 169 | }, 170 | // 171 | // After hook 172 | // 173 | function after(next) { 174 | if (cliUsers.after.logout) { 175 | cliUsers.after.logout({ 176 | username: username 177 | }, next); 178 | } else { 179 | next(); 180 | } 181 | } 182 | ], 183 | // 184 | // End workflow 185 | // 186 | function(err, details) { 187 | app.config.save(function(err) { 188 | if (err) { 189 | return callback(err, true); 190 | } 191 | 192 | app.log.info('User has been logged out'); 193 | callback(); 194 | }); 195 | }); 196 | }; 197 | 198 | /** 199 | * Usage for _di logout_ command. 200 | * 201 | * - di users logout 202 | * - di logout 203 | */ 204 | users.logout.usage = [ 205 | 'Logs out the current user from DeployR', 206 | '', 207 | ' logout' 208 | ]; 209 | 210 | /** 211 | * Retrieves the name of the current logged in user to DeployR. 212 | * 213 | * @param {Function} callback - Continuation to pass control to when complete. 214 | */ 215 | users.whoami = function(callback) { 216 | var app = cliUsers.app, 217 | username = app.config.get('username') || 'not logged in'; 218 | 219 | app.log.info('You are: ' + username.magenta); 220 | callback(); 221 | }; 222 | /** 223 | * Usage for _di whoami_ command. 224 | * 225 | * - di users whoami 226 | * - di whoami 227 | */ 228 | users.whoami.usage = [ 229 | 'Displays the current logged in user', 230 | '', 231 | ' whoami' 232 | ]; -------------------------------------------------------------------------------- /lib/plugins/deployr-cli-users/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var deployr = require('deployr'), 15 | common = require('flatiron').common; 16 | 17 | /** 18 | * Top-level include for the `deployr-cli-users` module. 19 | * 20 | * @mixin 21 | * @alias plugins/deployr-cli-users 22 | */ 23 | var cliUsers = exports; 24 | 25 | /** 26 | * Expose the plugin `commands`. 27 | */ 28 | cliUsers.commands = require('./commands'); 29 | 30 | /** 31 | * Expose the plugin name _cli-users_. 32 | * @property {String} name - The plugin name. 33 | */ 34 | cliUsers.name = 'cli-users'; 35 | 36 | /** 37 | * Attaches the `deployr-cli-users` behavior to the application. 38 | * @param {Object} options - The options object literal to use when attaching. 39 | */ 40 | cliUsers.attach = function(options) { 41 | var app = this; 42 | options = options || {}; 43 | 44 | if (!app.plugins.cli) { 45 | throw new Error('`inquirer` plugin is required to use `deployr-cli-users`'); 46 | } else if (!app.config) { 47 | throw new Error('`app.config` must be set to use `deployr-cli-users`'); 48 | } 49 | 50 | /** 51 | * Setup state from the application attached to. 52 | * @property {Object} app - The application. 53 | */ 54 | cliUsers.app = app; 55 | cliUsers.after = options.after || {}; 56 | cliUsers.before = options.before || {}; 57 | common.templateUsage(app, cliUsers.commands); 58 | 59 | // 60 | // Add the necessary ` users *` commands 61 | // 62 | app.commands['users'] = app.commands['users'] || {}; 63 | app.commands['users'] = common.mixin(app.commands['users'], cliUsers.commands); 64 | 65 | // 66 | // Setup aliases for ` users *` commands. 67 | // 68 | app.alias('login', { 69 | resource: 'users', 70 | command: 'login' 71 | }); 72 | app.alias('logout', { 73 | resource: 'users', 74 | command: 'logout' 75 | }); 76 | app.alias('whoami', { 77 | resource: 'users', 78 | command: 'whoami' 79 | }); 80 | 81 | /** 82 | * Attempts to authenicate the user in DeployR. 83 | * 84 | * @memberof plugins/deployr-cli-users 85 | * @protected 86 | * @param {Function} callback - Continuation to pass control to when 87 | * complete. 88 | */ 89 | app.auth = function(callback) { 90 | var response, error, username, attempts = 0; 91 | 92 | // assert there is a DeployR endpoint 93 | if (!app.config.get('endpoint')) { 94 | app.commands.endpoint(function(n) { 95 | app.auth(callback); 96 | }); 97 | return; 98 | } 99 | 100 | app.prompt.inquirer([{ 101 | name: 'username', 102 | type: 'input', 103 | message: 'Username:', 104 | default: app.config.get('username') || null, 105 | validate: function(input) { 106 | username = input; 107 | return input.length >= 3 || ' Please enter a valid username'; 108 | } 109 | }, { 110 | name: 'password', 111 | type: 'password', 112 | message: 'Password:', 113 | validate: function(input) { 114 | var done = this.async(); 115 | 116 | if (!input) { 117 | done('Permission denied, please try again.'); 118 | return; 119 | } 120 | 121 | deployr.configure({ host: app.config.get('endpoint') }) 122 | .io('/r/user/login') 123 | .data({ username: username, password: input }) 124 | .error(function(err) { 125 | error = err; 126 | 127 | // 128 | // - Connection errors 129 | // - 940 Authentication Error: username/password 130 | // credentials provided are invalid. 131 | // 132 | if (!err.deployr) { 133 | error = 'Cannot establish connection to "' + 134 | app.config.get('endpoint') + '"'; 135 | } else if (err.get('errorCode') === 940) { 136 | // 137 | // Attempt to get the password three times. 138 | // 139 | attempts += 1; 140 | 141 | if (attempts >= 3) { 142 | error = 'Three failed login attempts.'; 143 | } else { 144 | done('Permission denied, please try again.'); 145 | return; 146 | } 147 | } 148 | 149 | done(true); 150 | }) 151 | .end(function(res) { 152 | response = res; 153 | error = null; 154 | done(true); 155 | }); 156 | } 157 | }], function() { 158 | callback(error, response); 159 | }.bind(this)); 160 | }; 161 | 162 | /** 163 | * Attempts to unauthenticate the user from DeployR. 164 | * 165 | * @memberof plugins/deployr-cli-users 166 | * @protected 167 | * @param {Function} callback - Continuation to pass control to when 168 | * complete. 169 | */ 170 | app.unauth = function(callback) { 171 | var endpoint = app.config.get('endpoint'); 172 | 173 | if (endpoint) { 174 | deployr.configure({ 175 | host: endpoint, 176 | cookies: ['JSESSIONID=' + app.config.get('cookie')], 177 | sticky: true 178 | }) 179 | .io('/r/user/logout') 180 | .end() 181 | .ensure(function() { callback(); }); 182 | } else { 183 | callback(); 184 | } 185 | }; 186 | }; 187 | 188 | /** 189 | * Detaches this plugin from the application. 190 | */ 191 | cliUsers.detach = function() { 192 | var app = this; 193 | 194 | Object.keys(app.commands['users']).forEach(function(method) { 195 | if (cliUsers.commands[method]) { 196 | delete app.commands['config'][method]; 197 | } 198 | 199 | cliUsers.commands.app = null; 200 | }); 201 | }; -------------------------------------------------------------------------------- /lib/plugins/inquirer.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var inquirer = require('inquirer'); 15 | 16 | /** 17 | * Bring `inquirer` behavior into the CLI. 18 | * 19 | * @mixin 20 | * @alias plugins/inquirer 21 | */ 22 | var cliInquirer = exports; 23 | 24 | 25 | /** 26 | * Expose the plugin name _cli-inquirer_. 27 | * @property {String} name - The plugin name. 28 | */ 29 | cliInquirer.name = 'cli-inquirer'; 30 | 31 | /** 32 | * Attaches the `inquirer` behavior to the application. 33 | * @params {Object} options - Options to use when attaching. 34 | */ 35 | cliInquirer.attach = function(options) { 36 | var app = this; 37 | options = options || {}; 38 | 39 | app.prompt.separator = function(msg) { 40 | return new inquirer.Separator(msg); 41 | }; 42 | 43 | app.prompt.inquirer = function(choices, cb) { 44 | inquirer.prompt(choices, function(answers) { 45 | if (cb) { 46 | cb.call(this, answers); 47 | } 48 | }); 49 | }; 50 | }; 51 | 52 | /** 53 | * Detaches this plugin from the application. 54 | */ 55 | cliInquirer.detach = function () { 56 | /* noop */ 57 | }; -------------------------------------------------------------------------------- /lib/usage.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var chalk = require('chalk'), 15 | cyan = chalk.cyan, 16 | ul = cyan.bold.underline; 17 | 18 | module.exports = [ 19 | require('./util/brand'), 20 | 21 | 'The CLI for DeployR - Simple R analytics integration for application developers', 22 | 'open-source and fully customizable', 23 | 'https://github.com/microsoft/deployr-cli', 24 | 25 | '', 26 | 27 | ul('Usage:'), 28 | '', 29 | ' di ...', 30 | '', 31 | 32 | ul('Common Commands:'), 33 | 34 | '', 35 | 36 | cyan('Main menu'), 37 | ' di', 38 | '', 39 | 40 | cyan('To set the DeployR server endpoint'), 41 | ' di endpoint', 42 | '', 43 | 44 | cyan('To log into DeployR'), 45 | ' di login', 46 | '', 47 | 48 | cyan('To install a pre-built example'), 49 | ' di install example', 50 | '', 51 | 52 | ul('Additional Commands'), 53 | ' di whoami', 54 | ' di logout', 55 | ' di about', 56 | ' di config', 57 | ' di users', 58 | ' di server' 59 | ]; -------------------------------------------------------------------------------- /lib/util/brand.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var chalk = require('chalk'); 15 | 16 | /** 17 | * Welcome to the DeployR CLI `di` prompt intro. 18 | *
19 |  * ________                .__                __________ 
20 |  * \______ \   ____ ______ |  |   ____ ___.__.\______   \
21 |  * |    |  \_/ __ \\____ \|  |  /  _ <   |  | |       _/
22 |  * |    `   \  ___/|  |_> >  |_(  <_> )___  | |    |   \
23 |  * /_______  /\___  >   __/|____/\____// ____| |____|_  /
24 |  *       \/     \/|__|               \/             \/ 
25 |  * 
26 | * 27 | * @mixin util/brand 28 | */ 29 | module.exports = chalk.cyan([ 30 | '', 31 | '________ .__. __________ ', 32 | '\\______ \\ ____ ______ | | ____ ___.__.\\______ \\ ', 33 | ' | | \\_/ __ \\\\____ \\| | / _ < | | | _/ ', 34 | ' | ` \\ ___/| |_> > |_( <_> )___ | | | \\ ', 35 | '/_______ /\\___ > __/|____/\\____// ____| |____|_ / ', 36 | ' \\/ \\/|__| \\/ \\\/ ', 37 | '' 38 | ].join('\n')); -------------------------------------------------------------------------------- /lib/util/clear.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | /** 15 | * Clears stdout and bring the cursor to postion 0,0. 16 | * 17 | * @mixin 18 | * @alias util/clear 19 | */ 20 | module.exports = function clearScreen() { 21 | process.stdout.write("\u001b[2J\u001b[0;0H"); 22 | }; -------------------------------------------------------------------------------- /lib/util/lang-type.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var Enum = require('enum'), 15 | langEnum = new Enum(['JS', 'JAVA', 'DOTNET'], 'LangType'); 16 | 17 | /** 18 | * Defines the currently supported set of example `Languages`. 19 | * 20 | * @mixin 21 | * @alias util/lang-type 22 | */ 23 | module.exports = { 24 | /** 25 | * Javascript Language 26 | */ 27 | JS: langEnum.Javascript, 28 | 29 | /** 30 | * Java Language 31 | */ 32 | JAVA: langEnum.JAVA, 33 | 34 | /** 35 | * .NET Language 36 | */ 37 | DOTNET: langEnum.DOTNET, 38 | 39 | /** 40 | * Converts the string representation of the name to an equivalent 41 | * enumerated object. 42 | */ 43 | parse: function(name) { 44 | if (!name || typeof name !== 'string') { return null; } 45 | 46 | if (name.indexOf('js-') > -1) { 47 | return this.JS; 48 | } else if (name.indexOf('java-') > -1) { 49 | return this.JAVA; 50 | } else if (name.indexOf('dotnet-') > -1) { 51 | return this.DOTNET; 52 | } else { 53 | return null; 54 | } 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /lib/util/spawn-command.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (C) 2010-2016, Microsoft Corporation 3 | * 4 | * This program is licensed to you under the terms of Version 2.0 of the 5 | * Apache License. This program is distributed WITHOUT 6 | * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 7 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 8 | * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more 9 | * details. 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var _ = require('lodash'), 15 | spawn = require('cross-spawn'); 16 | 17 | /** 18 | * Normalize a command across operating systems and spawn it. 19 | * 20 | * @mixin 21 | * @alias util/spawn-command 22 | */ 23 | module.exports = function spawnCommand(command, args, opt) { 24 | return spawn(command, args, _.defaults({ stdio: 'inherit' }, opt || {})); 25 | }; 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deployr-cli", 3 | "version": "1.1.2", 4 | "description": "The DeployR command line interface, a tool for running useful DeployR utilities.", 5 | "private": false, 6 | "keywords": [ 7 | "cli", 8 | "deployr", 9 | "rbroker", 10 | "R", 11 | "rro", 12 | "mro", 13 | "mrs", 14 | "Microsoft", 15 | "statistics" 16 | ], 17 | "author": "DeployR - Microsoft Corporation", 18 | "contributors": [ 19 | "Sean Wells" 20 | ], 21 | "repository": { 22 | "type": "git", 23 | "url": "git://github.com/microsoft/deployr-cli.git" 24 | }, 25 | "homepage": "http://go.microsoft.com/fwlink/?LinkID=692163", 26 | "dependencies": { 27 | "chalk": "^1.0.0", 28 | "char-spinner": "^1.0.1", 29 | "complete": "0.3.1", 30 | "cross-spawn": "^0.2.3", 31 | "deployr": "^8.0.5", 32 | "download": "^4.4.3", 33 | "download-status": "^2.2.1", 34 | "enum": "^0.2.6", 35 | "flatiron": "0.3.8", 36 | "flatiron-cli-config": "0.1.4", 37 | "inquirer": "^0.8.0", 38 | "lodash": "^2.4.1", 39 | "opn": "^1.0.1", 40 | "pkginfo": "0.3.0", 41 | "request": "^2.40.0", 42 | "require-analyzer": "0.5.0", 43 | "shelljs": "^0.3.0" 44 | }, 45 | "devDependencies": { 46 | "jsdoc": "^3.3.0-alpha13", 47 | "jshint": "^2.5.11" 48 | }, 49 | "bin": { 50 | "di": "bin/di" 51 | }, 52 | "scripts": { 53 | "doc": "node_modules/.bin/jsdoc -c jsdoc.json README.md", 54 | "test": "echo \"Error: no test specified\" && exit 1" 55 | }, 56 | "main": "di.js", 57 | "engines": { 58 | "node": ">= 0.10.0" 59 | }, 60 | "license": "Apache-2.0", 61 | "bugs": { 62 | "url": "https://github.com/microsoft/deployr-cli/issues" 63 | } 64 | } 65 | --------------------------------------------------------------------------------