├── .github └── workflows │ └── nodejs.yml ├── .gitignore ├── .npmignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── appveyor.yml ├── bin ├── m.docopt ├── m.js └── mongodb-version-manager.js ├── index.js ├── lib ├── activate.js ├── config.js ├── download.js ├── model.js └── resolve.js ├── package.json └── test ├── index.test.js └── mocha.opts /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | 3 | name: CI 4 | 5 | jobs: 6 | test: 7 | name: Test 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | os: [ubuntu-latest] 12 | node-version: [12.x, 14.x] 13 | runs-on: ${{matrix.os}} 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v2 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: Install Dependencies 21 | run: npm install 22 | - name: Test 23 | run: npm test 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | .dist/ 4 | .build/ 5 | npm-debug.log 6 | coverage/ 7 | 8 | .idea/ 9 | *.iml 10 | .lone/ 11 | test/.versions 12 | package-lock.json -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .jshintrc 2 | .travis.yml 3 | test/ 4 | .lone 5 | CONTRIBUTING.md 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Great to have you here. These are a few ways you can help make this project better: 4 | 5 | - scratch an itch and implement a new feature using our [workflow](#workflow) 6 | - add an example to README.md 7 | - avoid sending pull requests related to "style" or whitespace as we have 8 | tools in our workflow to do this already 9 | - [creating a new issue](http://github.com/imlucas/mongodb-version-manager/issues) 10 | if there is something you need this project to do that it currently doesn't. 11 | We're always more than happy to chat about other projects. 12 | 13 | ## Workflow 14 | 15 | 1. Fork the repository on GitHub 16 | 1. Clone the repository to your local machine 17 | 1. Create a branch with a name that briefly describes your feature 18 | 1. Install dependencies `npm install` 19 | 1. Implement your feature or bug fix 20 | 1. Add new cases to `./tests.js` that verify your bug fix or make sure no one 21 | unintentionally breaks your feature in the future and run them with `npm test` 22 | 1. Add comments around your new code that explain what's happening 23 | 1. Commit and push your changes to your branch then submit a pull request 24 | 25 | Don’t get discouraged! We estimate that the response time from the 26 | maintainers is less than 24 hours. 27 | 28 | ## Bugs 29 | 30 | It would be extremely helpful, if you have the time, to 31 | look at existing bugs and help us understand if: 32 | 33 | * The bug is reproducible? 34 | * Is it reproducible in other environments (browsers)? 35 | * If they weren't included originally, what are the steps to reproduce? 36 | 37 | You can report new bugs by 38 | [creating a new issue](http://github.com/imlucas/mongodb-version-manager/issues). 39 | Please include as much information as possible about your environment 40 | ("I am using node.js v 0.10.28 on OSX Mavericks"). Actual code is always 41 | more valuable than an explanation, so please include a link to a GitHub 42 | gist or include a snippet directly in your issue description. 43 | 44 | ## Versioning 45 | 46 | This library aims to adhere to [Semantic Versioning 2.0.0](http://semver.org/). 47 | Violations of this scheme should be reported as bugs. Specifically, if a 48 | minor or patch version is released that breaks backward compatibility, 49 | that version should be immediately yanked and/or a new version should be 50 | immediately released that restores compatibility. 51 | 52 | ## Pro 53 | 54 | If you've been doing JS for awhile, thanks for checking this out. The quick 55 | version of the house rules are: 56 | 57 | - Indent 2 spaces 58 | - Single quotes > double quotes 59 | - Don't use ASI 60 | - Maximum line length is 80 61 | - Don't check in `dist` files 62 | - Avoid mutation 63 | - Write tests that make sense 64 | - Test must always be green 65 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mongodb-version-manager [![travis][travis_img]][travis_url] [![npm][npm_img]][npm_url] [![appveyor][appveyor_img]][appveyor_url] 2 | 3 | > Install and manage multiple versions of MongoDB. 4 | 5 | ## Install 6 | 7 | ```sh 8 | npm install -g mongodb-version-manager 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```sh 14 | $ m 15 | Usage: 16 | m use [--branch= --distro= --enterprise] 17 | m url [--branch= --distro= --enterprise] 18 | m available [--stable --unstable --rc --pokemon] 19 | m path 20 | ``` 21 | 22 | Once you've installed your first version of mongo with the `m use` command, update your `~/.bashrc` file: 23 | 24 | ```sh 25 | export PATH=~/.mongodb/versions/mongodb-current/bin:$PATH 26 | ``` 27 | 28 | When installed globally, each version of MongoDB you've installed are stored under `~/.mongodb/versions`: 29 | 30 | ``` 31 | ├── mongodb-3.0.7-osx-64 32 | ├── mongodb-3.2.0-osx-64 33 | ├── mongodb-3.3.8-osx-64-enterprise 34 | ├── mongodb-3.4.0-rc2-osx-64 35 | ├── mongodb-3.4.4-osx-64 36 | ├── mongodb-3.4.5-osx-64-enterprise 37 | ├── mongodb-3.5.1-osx-64 38 | ├── mongodb-3.6.3-osx-64 39 | ├── mongodb-3.6.4-osx-64 40 | ├── mongodb-3.7.3-osx-64 41 | └── mongodb-current -> ~/.mongodb/versions/mongodb-3.6.4-osx-64 42 | ``` 43 | 44 | The contents of each directory under `~/.mongodb/versions/mongodb-*` are: 45 | 46 | ``` 47 | ├── GNU-AGPL-3.0 48 | ├── MPL-2 49 | ├── README 50 | ├── THIRD-PARTY-NOTICES 51 | └── bin 52 | ├── bsondump 53 | ├── install_compass 54 | ├── mongo 55 | ├── mongod 56 | ├── mongodump 57 | ├── mongoexport 58 | ├── mongofiles 59 | ├── mongoimport 60 | ├── mongoperf 61 | ├── mongoreplay 62 | ├── mongorestore 63 | ├── mongos 64 | ├── mongostat 65 | └── mongotop 66 | ``` 67 | 68 | ## Related 69 | 70 | * [`mongodb-runner`](https://github.com/mongodb-js/runner) Easily control MongoDB for testing. 71 | 72 | ## License 73 | 74 | Apache 2.0 75 | 76 | [travis_img]: https://img.shields.io/travis/mongodb-js/version-manager.svg 77 | [travis_url]: https://secure.travis-ci.org/mongodb-js/version-manager 78 | [appveyor_img]: https://ci.appveyor.com/api/projects/status/s3xm8f9eqiakqusn?svg=true 79 | [appveyor_url]: https://ci.appveyor.com/project/imlucas/mongodb-version-manager 80 | [npm_img]: https://img.shields.io/npm/v/mongodb-version-manager.svg 81 | [npm_url]: https://npmjs.org/package/mongodb-version-manager 82 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # appveyor file 2 | # http://www.appveyor.com/docs/appveyor-yml 3 | 4 | # branches to build 5 | branches: 6 | # whitelist 7 | only: 8 | - master 9 | 10 | # build version format 11 | version: "{build}" 12 | 13 | # what combinations to test 14 | environment: 15 | matrix: 16 | - nodejs_version: 6 17 | 18 | # Get the stable version of node 19 | install: 20 | - ps: Install-Product node $env:nodejs_version 21 | - npm install 22 | 23 | build: off 24 | 25 | test_script: 26 | # Output useful info for debugging. 27 | - node --version && npm --version 28 | - ps: "npm test # PowerShell" # Pass comment to PS for easier debugging 29 | - cmd: npm test 30 | 31 | matrix: 32 | fast_finish: true 33 | 34 | cache: 35 | - C:\Users\appveyor\AppData\Roaming\npm\node_modules -> package.json # global npm modules 36 | - C:\Users\appveyor\AppData\Roaming\npm-cache -> package.json # npm cache 37 | - node_modules -> package.json # local npm modules 38 | -------------------------------------------------------------------------------- /bin/m.docopt: -------------------------------------------------------------------------------- 1 | m 2 | 3 | The MongoDB version manager. 4 | 5 | Usage: 6 | m use [--branch= --distro= --enterprise] 7 | m url [--branch= --distro= --enterprise] 8 | m available [--stable --unstable --rc --pokemon] 9 | m available 10 | m list 11 | m path 12 | 13 | Examples: 14 | m use # Install or activate MongoDB 15 | m use latest # Install or activate latest MongoDB release 16 | m use stable # Install or activate most recent stable MongoDB release 17 | m path # Print the absolute path to the current MongoDB version 18 | m available # List all available versions 19 | m available 3.5.x # List available versions matching any semver range 20 | m list # List all locally installed versions 21 | m url stable # Print download URL for the latest stable version 22 | m url 2ce51c8e0d4bf84589bffa87e59f2401578c2572 23 | # Download URL for mci artifact at a specific commit 24 | 25 | Options: 26 | -h --help Show this screen. 27 | --version Show version. 28 | --debug Show debugging messages. 29 | --url Print download URL and exit. 30 | --stable Only list available stable versions. 31 | --unstable Only list available unstable versions. 32 | --rc Include release candidates in available versions. 33 | --pokemon Show all available versions you do not have installed, 34 | so you can collect all the MongoDB's. 35 | --enterprise Use MongoDB enterprise. 36 | -------------------------------------------------------------------------------- /bin/m.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* eslint no-sync:0, no-console:0, no-octal-escape:0, no-path-concat:0 */ 4 | var fs = require('fs'); 5 | var docopt = require('docopt').docopt; 6 | var pkg = require('../package.json'); 7 | var path = require('path'); 8 | 9 | var docoptString = fs.readFileSync(path.join(__dirname, 'm.docopt'), 'utf-8'); 10 | docoptString = docoptString.replace(/[\r]/g, ''); 11 | var argv = docopt(docoptString, { 12 | version: pkg.version 13 | }); 14 | 15 | if (argv['--debug']) { 16 | process.env.DEBUG = '*'; 17 | } 18 | 19 | var mvm = require('../'); 20 | var difference = require('lodash.difference'); 21 | var chalk = require('chalk'); 22 | var figures = require('figures'); 23 | var debug = require('debug')('mongodb-version-manager'); 24 | var cmd; 25 | 26 | function printVersions(versions, fn) { 27 | mvm.current(function(err, current) { 28 | if (err) return fn(err); 29 | 30 | console.log( 31 | versions 32 | .map(function(v) { 33 | if (v === current) { 34 | return ' \033[32mο ' + v + '\033[0m \033[90m \033[0m'; 35 | } 36 | return ' ' + v + '\033[90m \033[0m'; 37 | }) 38 | .join('\n') 39 | ); 40 | 41 | fn(); 42 | }); 43 | } 44 | 45 | var abortIfError = function(err) { 46 | if (err) { 47 | console.error( 48 | chalk.bold.red(figures.cross), 49 | ' Error:', 50 | chalk.bold.red(err.message) 51 | ); 52 | 53 | console.error('We apologize for this issue and welcome your bug reports.'); 54 | console.error( 55 | 'Please visit: https://github.com/mongodb-js/version-manager/issues' 56 | ); 57 | console.error(); 58 | console.error('Try running your command again with debugging on:'); 59 | console.error(' m ' + cmd + ' --debug'); 60 | console.error(); 61 | if (typeof err.stack !== 'undefined') { 62 | console.error(chalk.bold('Stack Trace')); 63 | err.stack.split('\n').map(function(line) { 64 | console.error(' ', chalk.gray(line)); 65 | }); 66 | } 67 | return process.exit(1); 68 | } 69 | }; 70 | 71 | var commands = { 72 | available: function() { 73 | var title = ''; 74 | if (!argv['--rc'] && !argv['--stable'] && !argv['--unstable']) { 75 | argv['--all'] = true; 76 | } 77 | if (argv['--all']) { 78 | argv['--stable'] = true; 79 | argv['--unstable'] = true; 80 | argv['--rc'] = true; 81 | title = 'All'; 82 | } else { 83 | var includes = []; 84 | if (argv['--stable']) { 85 | includes.push('Stable'); 86 | } 87 | if (argv['--unstable']) { 88 | includes.push('Unstable'); 89 | } 90 | if (argv['--rc']) { 91 | includes.push('Release Candidates'); 92 | } 93 | title = includes.join('|'); 94 | } 95 | 96 | if (argv['']) { 97 | title = 'All versions matching ' + argv['']; 98 | } 99 | 100 | var opts = { 101 | stable: argv['--stable'], 102 | unstable: argv['--unstable'], 103 | rc: argv['--rc'], 104 | pokemon: argv['--pokemon'], 105 | range: argv[''] 106 | }; 107 | 108 | mvm.installed(function(err, installed) { 109 | /* eslint no-shadow:0 */ 110 | abortIfError(err); 111 | 112 | mvm.available(opts, function(err, versions) { 113 | abortIfError(err); 114 | 115 | if (!versions || versions.length === 0) { 116 | return abortIfError(new Error('No available versions?')); 117 | } 118 | 119 | if (opts.pokemon) { 120 | console.log(title + " versions you haven't installed yet:"); 121 | versions = difference(versions, installed); 122 | } 123 | printVersions(versions, function(err) { 124 | abortIfError(err); 125 | }); 126 | }); 127 | }); 128 | }, 129 | path: function() { 130 | mvm.path(function(err, p) { 131 | abortIfError(err); 132 | console.log(p); 133 | }); 134 | }, 135 | use: function(opts) { 136 | mvm.use(opts, function(err) { 137 | abortIfError(err); 138 | mvm.current(function(err, v) { 139 | abortIfError(err); 140 | console.log('switched to ' + v); 141 | }); 142 | }); 143 | }, 144 | list: function() { 145 | mvm.installed(function(err, versions) { 146 | abortIfError(err); 147 | 148 | if (versions.length > 0) { 149 | return printVersions(versions, function(err) { 150 | if (err) return console.log(err) && process.exit(1); 151 | }); 152 | } 153 | 154 | console.log('0 versions installed. Run one of:'); 155 | 156 | mvm.resolve( 157 | [ 158 | { 159 | version: 'unstable' 160 | }, 161 | { 162 | version: 'stable' 163 | } 164 | ], 165 | function(err, data) { 166 | abortIfError(err); 167 | 168 | if (!data || !data.stable || data.unstable) { 169 | return abortIfError(new Error('Unknown error')); 170 | } 171 | 172 | console.log( 173 | ' m use stable; # installs MongoDB v' + data.stable.version 174 | ); 175 | console.log( 176 | ' m use unstable; # installs MongoDB v' + data.unstable.version 177 | ); 178 | } 179 | ); 180 | }); 181 | } 182 | }; 183 | 184 | var opts = { 185 | version: argv[''], 186 | branch: argv['--branch'], 187 | distro: argv['--distro'], 188 | enterprise: argv['--enterprise'], 189 | range: argv[''] 190 | }; 191 | 192 | cmd = Object.keys(commands).filter(function(name) { 193 | return argv[name] === true; 194 | })[0]; 195 | 196 | if (!cmd) { 197 | cmd = argv[''] ? 'use' : 'list'; 198 | } 199 | 200 | debug('cmd is `%s` with opts `%j`', cmd, opts); 201 | 202 | commands[cmd](opts); 203 | -------------------------------------------------------------------------------- /bin/mongodb-version-manager.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('./m.js'); 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var async = require('async'); 2 | var fs = require('fs-extra'); 3 | var path = require('path'); 4 | var versions = require('mongodb-version-list'); 5 | var semver = require('semver'); 6 | var defaults = require('lodash.defaults'); 7 | var config = require('./lib/config'); 8 | var activate = require('./lib/activate'); 9 | var download = require('./lib/download'); 10 | var Model = require('./lib/model'); 11 | var resolve = require('./lib/resolve'); 12 | 13 | // var VERSION = /[0-9]+\.[0-9]+\.[0-9]+([-_\.][a-zA-Z0-9]+)?/; 14 | 15 | activate.addToPath(config.CURRENT_BIN_DIRECTORY); 16 | 17 | module.exports = exports = function(opts, fn) { 18 | if (typeof opts === 'function') { 19 | fn = opts; 20 | opts = {}; 21 | } else if (typeof opts === 'string') { 22 | opts = { 23 | version: opts 24 | }; 25 | } 26 | opts.version = opts.version || process.env.MONGODB_VERSION; 27 | 28 | exports.use(opts, fn); 29 | }; 30 | 31 | exports.resolve = function(opts, done) { 32 | resolve(opts, function(err, res) { 33 | if (err) return done(err); 34 | 35 | done(null, new Model(res)); 36 | }); 37 | }; 38 | 39 | var getVersion = require('get-mongodb-version'); 40 | exports.current = function(done) { 41 | var mongod = path.join(config.CURRENT_BIN_DIRECTORY, 'mongod'); 42 | fs.exists(mongod, function(exists) { 43 | if (!exists) return done(null, null); 44 | 45 | getVersion({path: mongod}, done); 46 | }); 47 | }; 48 | exports.config = config; 49 | exports.path = function(fn) { 50 | fn(null, config.CURRENT_BIN_DIRECTORY); 51 | }; 52 | 53 | exports.installed = function(fn) { 54 | fs.readdir(config.ROOT_DIRECTORY, function(err, files) { 55 | files = files || []; 56 | if (err) return fn(null, files); 57 | 58 | fn(null, files); 59 | }); 60 | }; 61 | 62 | exports.available = function(opts, fn) { 63 | opts = defaults(opts || {}, { 64 | stable: false, 65 | unstable: false, 66 | rc: false, 67 | range: undefined 68 | }); 69 | 70 | versions(function(err, res) { 71 | if (err) return fn(err); 72 | res = res.map(function(v) { 73 | return semver.parse(v); 74 | }) 75 | .filter(function(v) { 76 | if (opts.range) { 77 | return semver.satisfies(v.version, opts.range); 78 | } 79 | 80 | v.stable = v.minor % 2 === 0; 81 | v.unstable = !v.stable; 82 | v.rc = v.prerelease.length > 0; 83 | 84 | if (!opts.rc && v.rc) return false; 85 | if (!opts.stable && v.stable) return false; 86 | if (!opts.unstable && v.unstable) return false; 87 | return true; 88 | }) 89 | .map(function(v) { 90 | return v.version; 91 | }); 92 | fn(null, res); 93 | }); 94 | }; 95 | 96 | exports.is = function(s, done) { 97 | exports.current(function(err, v) { 98 | if (err) return done(err); 99 | 100 | done(null, semver.satisfies(v, s)); 101 | }); 102 | }; 103 | 104 | exports.install = function(version, done) { 105 | resolve({ 106 | version: version 107 | }, function(err, model) { 108 | if (err) return done(err); 109 | 110 | download(model, done); 111 | }); 112 | }; 113 | 114 | exports.use = function(opts, done) { 115 | /* eslint no-shadow:0 */ 116 | resolve(opts, function(err, model) { 117 | if (err) return done(err); 118 | 119 | // @todo (imlucas) Current needs to take into account 120 | // enterprise, debug, platform, bits, etc. 121 | // exports.current(function(err, v) { 122 | // if (err) return done(err); 123 | // 124 | // if (model.version === v) { 125 | // debug('already using ' + v); 126 | // return done(null, model); 127 | // } 128 | 129 | async.series([ 130 | download.bind(null, model), 131 | activate.bind(null, model) 132 | ], function(err) { 133 | if (err) return done(err); 134 | return done(null, model); 135 | }); 136 | }); 137 | }; 138 | -------------------------------------------------------------------------------- /lib/activate.js: -------------------------------------------------------------------------------- 1 | var config = require('./config'); 2 | var fs = require('fs-extra'); 3 | var async = require('async'); 4 | var delimiter = require('path').delimiter; 5 | var debug = require('debug')('mongodb-version-manager:activate'); 6 | 7 | /** 8 | * Make sure the bin directory for the current version 9 | * is in `$PATH`. 10 | * @param {String} directory 11 | * 12 | * @todo (imlucas): :axe: env helper from `mongodb-js/mj` 13 | * and use it here. 14 | */ 15 | function addToPath(directory) { 16 | var srcs = process.env.PATH.split(delimiter); 17 | if (srcs.indexOf(directory) === -1) { 18 | srcs.unshift(directory); 19 | process.env.PATH = srcs.join(delimiter); 20 | debug('added `%s` to $PATH and its now `%s`', 21 | directory, process.env.PATH); 22 | } 23 | } 24 | 25 | module.exports = function(model, done) { 26 | async.series([function(cb) { 27 | debug('removing old symlink if it exists...'); 28 | fs.remove(config.CURRENT_DIRECTORY, function() { 29 | cb(); 30 | }); 31 | }, function(cb) { 32 | debug('symlinking `%s` -> `%s`...', model.root_directory, config.CURRENT_DIRECTORY); 33 | fs.symlink(model.root_directory, config.CURRENT_DIRECTORY, cb); 34 | } 35 | ], done); 36 | }; 37 | 38 | module.exports.addToPath = addToPath; 39 | -------------------------------------------------------------------------------- /lib/config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var fs = require('fs-extra'); 3 | var untildify = require('untildify'); 4 | 5 | exports = {}; 6 | 7 | var dest; 8 | var modulePath = path.join(process.cwd(), 'node_modules', 'mongodb-version-manager'); 9 | if (process.env.MONGODB_VERSIONS) { 10 | dest = untildify(process.env.MONGODB_VERSIONS); 11 | } else { 12 | try { 13 | /* eslint no-sync:0 */ 14 | var isLocal = fs.statSync(modulePath).isDirectory(); 15 | if (isLocal) { 16 | dest = path.join(modulePath, '.mongodb'); 17 | } else { 18 | dest = untildify('~/.mongodb/versions'); 19 | } 20 | } catch (err) { 21 | dest = untildify('~/.mongodb/versions'); 22 | } 23 | } 24 | fs.mkdirsSync(dest); 25 | 26 | exports.cache = path.resolve(dest); 27 | 28 | // expire versions cache page every hour 29 | exports.expire = 60 * 60 * 1000; 30 | 31 | exports.ROOT_DIRECTORY = path.join(exports.cache); 32 | exports.CURRENT_DIRECTORY = path.join(exports.ROOT_DIRECTORY, 'mongodb-current'); 33 | exports.CURRENT_BIN_DIRECTORY = path.join(exports.CURRENT_DIRECTORY, 'bin'); 34 | 35 | module.exports = exports; 36 | -------------------------------------------------------------------------------- /lib/download.js: -------------------------------------------------------------------------------- 1 | var async = require('async'); 2 | var chalk = require('chalk'); 3 | var fs = require('fs-extra'); 4 | var tildify = require('tildify'); 5 | var figures = require('figures'); 6 | var dl = require('download'); 7 | var debug = require('debug')('mongodb-version-manager:download'); 8 | 9 | function download(model, done) { 10 | debug('downloading artifact from `%s` to `%s`...', 11 | model.url, tildify(model.directory)); 12 | 13 | var quiet = process.env.silent; 14 | var options = { 15 | extract: true, 16 | strip: 1, 17 | retries: 3 18 | // filename: model.filename, 19 | // output: model.directory 20 | 21 | }; 22 | debug(model.url, model.root_directory, options); 23 | dl(model.url, model.root_directory, options).then(function() { 24 | debug('successfully downloaded MongoDB version v%s to %s', 25 | model.version, model.root_directory); 26 | if (!quiet) { 27 | console.log(chalk.bold.green(figures.tick), 28 | ' Downloaded MongoDB', model.version); 29 | } 30 | done(); 31 | }) 32 | .catch(function(err) { 33 | debug('error downloading!', err); 34 | console.error(err); 35 | done(err); 36 | 37 | // debug('removing incomplete artifact from `%s`', 38 | // model.root_directory); 39 | // 40 | // fs.unlink(model.root_directory, function() { 41 | // done(err); 42 | // }); 43 | }); 44 | } 45 | 46 | module.exports = function(model, done) { 47 | debug('downloading', model.serialize({ 48 | props: true, 49 | derived: true 50 | })); 51 | async.series([ 52 | function(cb) { 53 | fs.stat(model.bin_directory, function(err) { 54 | if (err) { 55 | cb(); 56 | } else { 57 | cb(new Error('already exists')); 58 | } 59 | }); 60 | }, 61 | download.bind(null, model) 62 | ], function(err, results) { 63 | if (err && err.message === 'already exists') { 64 | debug('already have artifact at `%s`', model.bin_directory); 65 | return done(); 66 | } 67 | if (err) { 68 | return done(err); 69 | } 70 | done(); 71 | }); 72 | }; 73 | -------------------------------------------------------------------------------- /lib/model.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var config = require('./config'); 3 | var AmpersandState = require('ampersand-state'); 4 | 5 | var Model = AmpersandState.extend({ 6 | props: { 7 | name: { 8 | type: 'string', 9 | default: 'mongodb' 10 | }, 11 | platform: { 12 | type: 'string' 13 | }, 14 | version: { 15 | type: 'string' 16 | }, 17 | filename: { 18 | type: 'string' 19 | }, 20 | url: { 21 | type: 'string' 22 | }, 23 | debug: { 24 | type: 'boolean', 25 | default: false 26 | }, 27 | enterprise: { 28 | type: 'boolean', 29 | default: false 30 | }, 31 | distro: { 32 | type: 'string' 33 | }, 34 | bits: { 35 | type: 'string' 36 | }, 37 | directory: { 38 | type: 'string' 39 | } 40 | }, 41 | derived: { 42 | download_directory: { 43 | deps: ['directory'], 44 | fn: function() { 45 | if (!this.directory) { 46 | return undefined; 47 | } 48 | return path.join(this.directory, 'downloads'); 49 | } 50 | }, 51 | download_path: { 52 | deps: ['download_directory', 'filename'], 53 | fn: function() { 54 | if (!this.download_directory) { 55 | return undefined; 56 | } 57 | return path.join(this.download_directory, this.filename); 58 | } 59 | }, 60 | root_directory: { 61 | deps: ['directory', 'name', 'version', 'platform', 'bits', 'enterprise', 'debug'], 62 | fn: function() { 63 | if (!this.directory) { 64 | return undefined; 65 | } 66 | // * is not allowed in paths on windows 67 | var version = this.version === '*' ? 'latest' : this.version; 68 | var dir = [this.name, version, this.platform, this.bits].join('-'); 69 | if (this.enterprise) { 70 | dir += '-enterprise'; 71 | } 72 | if (this.debug) { 73 | dir += '-debug'; 74 | } 75 | return path.join(this.directory, dir); 76 | } 77 | }, 78 | bin_directory: { 79 | deps: ['root_directory'], 80 | fn: function() { 81 | if (!this.root_directory) { 82 | return undefined; 83 | } 84 | return path.join(this.root_directory, 'bin'); 85 | } 86 | } 87 | }, 88 | initialize: function(attrs) { 89 | attrs = attrs || {}; 90 | if (attrs.artifact) { 91 | this.filename = attrs.filename = attrs.artifact; 92 | } 93 | this.directory = attrs.directory = config.ROOT_DIRECTORY; 94 | if (attrs.platform === 'win32') { 95 | this.platform = attrs.platform = 'windows'; 96 | } 97 | } 98 | }); 99 | 100 | module.exports = Model; 101 | -------------------------------------------------------------------------------- /lib/resolve.js: -------------------------------------------------------------------------------- 1 | var resolve = require('mongodb-download-url').getDownloadURL; 2 | var Model = require('./model'); 3 | var debug = require('debug')('mongodb-version-manager:resolve'); 4 | 5 | module.exports = function(opts, done) { 6 | var platform = opts.platform || process.platform; 7 | resolve(opts).then(function(res) { 8 | res.platform = platform; 9 | var model = new Model(res); 10 | debug('resolved', model.serialize({ 11 | props: true, 12 | derived: true 13 | })); 14 | done(null, model); 15 | }, function(err) { done(err); }); 16 | }; 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongodb-version-manager", 3 | "version": "1.5.0", 4 | "description": "Install and manage multiple versions of MongoDB", 5 | "repository": { 6 | "type": "git", 7 | "url": "git://github.com/mongodb-js/version-manager.git" 8 | }, 9 | "homepage": "https://github.com/mongodb-js/version-manager", 10 | "bin": { 11 | "mongodb-version-manager": "bin/mongodb-version-manager.js", 12 | "m": "bin/m.js" 13 | }, 14 | "scripts": { 15 | "test": "cross-env DEBUG=mon* mocha" 16 | }, 17 | "devDependencies": { 18 | "cross-env": "^7.0.0", 19 | "mocha": "^5.2.0", 20 | "which": "^1.2.0" 21 | }, 22 | "dependencies": { 23 | "ampersand-state": "^5.0.3", 24 | "async": "^3.1.0", 25 | "chalk": "^2.1.0", 26 | "debug": ">= 2.6.9 < 3.0.0 || >= ^3.1.0", 27 | "docopt": "^0.6.2", 28 | "download": "^6.2.5", 29 | "figures": "^3.2.0", 30 | "fs-extra": "^8.1.0", 31 | "get-mongodb-version": "^2.0.1", 32 | "lodash.defaults": "^4.2.0", 33 | "lodash.difference": "^4.1.1", 34 | "mongodb-download-url": "^1.0.0", 35 | "mongodb-version-list": "^1.0.0", 36 | "semver": "^5.3.0", 37 | "tildify": "^2.0.0", 38 | "untildify": "^4.0.0" 39 | }, 40 | "license": "Apache-2.0" 41 | } 42 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | /* eslint no-sync: 0 */ 2 | process.env.silent = '1'; 3 | 4 | var assert = require('assert'); 5 | var execFile = require('child_process').execFile; 6 | var path = require('path'); 7 | var which = require('which'); 8 | var fs = require('fs-extra'); 9 | var debug = require('debug')('mongodb-version-manager:test'); 10 | 11 | process.env.MONGODB_VERSIONS = path.join(__dirname, '.versions'); 12 | 13 | var mvm = require('../'); 14 | 15 | var M = path.resolve(__dirname, '../bin/m.js'); 16 | var NODE = which.sync('node'); 17 | 18 | debug('path to m bin is %s', M); 19 | debug('path to node bin is %s', NODE); 20 | 21 | var skipIfNotLinux = function(runner) { 22 | if (process.platform !== 'linux') { 23 | runner.skip(); 24 | return; 25 | } 26 | }; 27 | 28 | var run = function(command, done) { 29 | /* eslint no-sync:0 no-console:0 */ 30 | if (typeof command === 'function') { 31 | done = command; 32 | command = ''; 33 | } 34 | 35 | var args = [M, command]; 36 | var debugCmd = '"' + NODE + '" ' + args; 37 | debug('running `%s`', debugCmd); 38 | assert(fs.existsSync(M), M + ' does not exist'); 39 | assert(fs.existsSync(NODE), NODE + ' does not exist'); 40 | 41 | execFile(NODE, args, function(err, stdout, stderr) { 42 | debug('result of `%s`', debugCmd, JSON.stringify({ 43 | stdout: stdout.toString('utf-8'), 44 | stderr: stderr.toString('utf-8') 45 | }, null, 2)); 46 | 47 | if (err) { 48 | debug('failed to run `%s`', debugCmd); 49 | console.error('exec failed: ', err); 50 | return done(err); 51 | } 52 | debug('completed successfully `%s`', debugCmd); 53 | done(); 54 | }); 55 | }; 56 | 57 | describe('mongodb-version-manager', function() { 58 | describe('bin', function() { 59 | it('should return 1 and print usage if i run `m`', function(done) { 60 | var expectStdout = [ 61 | 'Usage:', 62 | ' m use [--branch= --distro= --enterprise]', 63 | ' m url [--branch= --distro= --enterprise]', 64 | ' m available [--stable --unstable --rc --pokemon]', 65 | ' m available ', 66 | ' m list', 67 | ' m path', 68 | '' 69 | ].join('\n'); 70 | execFile(NODE, [M], function(err, stdout, stderr) { 71 | // DocOpt returns 1 instead of 0, so allow this as it's only useful 72 | // in that it prints the Usage message like `m --help` 73 | assert.strictEqual(err.code, 1); 74 | assert.strictEqual(stdout.toString('utf-8'), expectStdout); 75 | 76 | // Printing the error stack trace suggests something is wrong to a 77 | // new user, when nothing is, so we shouldn't see anything on stderr 78 | assert.strictEqual(stderr.toString('utf-8'), ''); 79 | }); 80 | done(); 81 | }); 82 | it('should limit stdout to 80 characters for `m --help`', function(done) { 83 | execFile(NODE, [M, '--help'], function(err, stdout, stderr) { 84 | assert.strictEqual(err, null); 85 | stdout.toString('utf-8').split('\n').forEach(function(line) { 86 | assert(line.length <= 80); 87 | }); 88 | assert.strictEqual(stderr.toString('utf-8'), ''); 89 | }); 90 | done(); 91 | }); 92 | 93 | // This command doesn't work anymore because it relies on the page layout of 94 | // the mongodb downloads page 95 | it.skip('should work if i run `m available`', function(done) { 96 | run('available', done); 97 | }); 98 | 99 | it('should work if i run `m path`', function(done) { 100 | run('path', done); 101 | }); 102 | }); 103 | describe('current', function() { 104 | it('should provide the current version', function(done) { 105 | mvm.current(function(err) { 106 | done(err); 107 | }); 108 | }); 109 | }); 110 | describe('available', function() { 111 | it('should list stable versions', function(done) { 112 | mvm.available({ 113 | stable: true 114 | }, function(err, versions) { 115 | assert.ifError(err); 116 | var unstable = versions.filter(function(v) { 117 | return parseInt(v.split('.')[1], 10) % 2 > 0; 118 | }); 119 | assert.equal(unstable.length, 0); 120 | done(); 121 | }); 122 | }); 123 | it('should list unstable versions', function(done) { 124 | mvm.available({ 125 | unstable: true 126 | }, function(err, versions) { 127 | assert.ifError(err); 128 | var stable = versions.filter(function(v) { 129 | return parseInt(v.split('.')[1], 10) % 2 === 0; 130 | }); 131 | assert.equal(stable.length, 0); 132 | done(); 133 | }); 134 | }); 135 | it('should list rc versions', function(done) { 136 | mvm.available({ 137 | rc: true 138 | }, function(err, versions) { 139 | assert.ifError(err); 140 | var stable = versions.filter(function(v) { 141 | return v.indexOf('rc') === -1; 142 | }); 143 | assert.equal(stable.length, 0); 144 | done(); 145 | }); 146 | }); 147 | }); 148 | describe('config', function() { 149 | it('should use the right directory', function() { 150 | assert.equal(mvm.config.cache, path.join(__dirname, '.versions')); 151 | }); 152 | }); 153 | describe('functional', function() { 154 | function bin(name, platform) { 155 | if (platform !== 'windows') { 156 | return name; 157 | } 158 | return name + '.exe'; 159 | } 160 | var downloadedSuccessfully = function(version, platform, done) { 161 | var dest = path.join( 162 | mvm.config.cache, 163 | ['mongodb', version, platform, '64'].join('-'), 164 | 'bin', 165 | bin('mongod', platform) 166 | ); 167 | 168 | fs.exists(dest, function(exists) { 169 | assert(exists, dest + ' does not exist'); 170 | done(); 171 | }); 172 | }; 173 | 174 | var use = function(version, platform, done) { 175 | mvm.use({ 176 | version: version, 177 | platform: platform 178 | }, function(err) { 179 | if (err) { 180 | return done(err); 181 | } 182 | downloadedSuccessfully(version, platform, done); 183 | }); 184 | }; 185 | 186 | var inPATH = function() { 187 | var dest = mvm.config.CURRENT_BIN_DIRECTORY; 188 | if (process.env.PATH.split(path.delimiter).indexOf(dest) === -1) { 189 | console.log('`%s` not in PATH: ', dest, JSON.stringify(process.env.PATH.split(path.delimiter), null, 2)); 190 | } 191 | assert(process.env.PATH.split(path.delimiter).indexOf(dest) !== -1); 192 | }; 193 | 194 | var shouldHaveCurrent = function(version, platform, done) { 195 | if (platform === 'windows') { 196 | process.env.PATHEXT = '.exe'; 197 | } 198 | mvm.current(function(err, v) { 199 | if (platform === 'windows') { 200 | process.env.PATHEXT = undefined; 201 | } 202 | if (err) { 203 | return done(err); 204 | } 205 | assert.equal(version, v); 206 | done(); 207 | }); 208 | }; 209 | 210 | var shouldHaveExecutable = function(name, version, platform, done) { 211 | var dest = path.join( 212 | mvm.config.cache, 213 | ['mongodb', version, platform, '64'].join('-'), 214 | 'bin', 215 | bin(name, platform) 216 | ); 217 | 218 | fs.exists(dest, function(exists) { 219 | if (!exists) { 220 | return done(new Error('File does not exist at ' + dest)); 221 | } 222 | done(); 223 | // @todo (imlucas): Ensure `which` returns the right path. 224 | // var symlink = path.join( 225 | // mvm.config.cache, 226 | // ['mongodb', 'current'].join('-'), 227 | // 'bin', 228 | // bin(name, platform) 229 | // ); 230 | // if (platform === 'windows') { 231 | // process.env.PATHEXT = '.exe'; 232 | // } 233 | // 234 | // which(name, { 235 | // all: true 236 | // }, function(_err, res) { 237 | // if (platform === 'windows') { 238 | // process.env.PATHEXT = undefined; 239 | // } 240 | // if (_err) return done(_err); 241 | // 242 | // assert.equal(res[0], symlink); 243 | // done(); 244 | // }); 245 | }); 246 | }; 247 | 248 | // afterEach(function(done) { 249 | // fs.remove(mvm.config.cache, done); 250 | // }); 251 | describe('osx', function() { 252 | it('should install 2.6.11 #slow', function(done) { 253 | this.slow(25000); 254 | use('2.6.11', 'osx', done); 255 | }); 256 | it('should have current symlink in $PATH', function() { 257 | inPATH('current', 'osx'); 258 | }); 259 | it('should symlink 2.6.11 as current', function(done) { 260 | if (process.platform !== 'darwin') { 261 | this.skip(); 262 | return; 263 | } 264 | shouldHaveCurrent('2.6.11', 'osx', done); 265 | }); 266 | it('should have an executable shell binary', function(done) { 267 | shouldHaveExecutable('mongo', '2.6.11', 'osx', done); 268 | }); 269 | it('should have an executable store binary', function(done) { 270 | shouldHaveExecutable('mongod', '2.6.11', 'osx', done); 271 | }); 272 | it('should have an executable router binary', function(done) { 273 | shouldHaveExecutable('mongos', '2.6.11', 'osx', done); 274 | }); 275 | }); 276 | describe('linux', function() { 277 | it('should install 2.6.11 #slow', function(done) { 278 | skipIfNotLinux(this); 279 | this.slow(25000); 280 | use('2.6.11', 'linux', done); 281 | }); 282 | it('should have current symlink in $PATH', function() { 283 | skipIfNotLinux(this); 284 | inPATH('current', 'linux'); 285 | }); 286 | it('should symlink 2.6.11 as current', function(done) { 287 | skipIfNotLinux(this); 288 | shouldHaveCurrent('2.6.11', 'linux', done); 289 | }); 290 | it('should have an executable shell binary', function(done) { 291 | skipIfNotLinux(this); 292 | shouldHaveExecutable('mongo', '2.6.11', 'linux', done); 293 | }); 294 | it('should have an executable store binary', function(done) { 295 | skipIfNotLinux(this); 296 | shouldHaveExecutable('mongod', '2.6.11', 'linux', done); 297 | }); 298 | it('should have an executable router binary', function(done) { 299 | skipIfNotLinux(this); 300 | shouldHaveExecutable('mongos', '2.6.11', 'linux', done); 301 | }); 302 | }); 303 | describe('windows', function() { 304 | it('should install 2.6.11 [#15] #slow', function(done) { 305 | this.slow(25000); 306 | use('2.6.11', 'windows', done); 307 | }); 308 | it('should have current symlink in $PATH', function() { 309 | inPATH('current', 'windows'); 310 | }); 311 | it.skip('should symlink 2.6.11 as current', function(done) { 312 | if (process.platform !== 'win32') { 313 | this.skip(); 314 | return; 315 | } 316 | shouldHaveCurrent('2.6.11', 'windows', done); 317 | }); 318 | it('should have an executable shell binary', function(done) { 319 | shouldHaveExecutable('mongo', '2.6.11', 'windows', done); 320 | }); 321 | it('should have an executable store binary', function(done) { 322 | shouldHaveExecutable('mongod', '2.6.11', 'windows', done); 323 | }); 324 | it('should have an executable router binary', function(done) { 325 | shouldHaveExecutable('mongos', '2.6.11', 'windows', done); 326 | }); 327 | }); 328 | 329 | describe('enterprise', function() { 330 | it('should install 2.6.11 enterprise'); 331 | it('should install have 2.6.11 and a separate 2.6.11 enterprise'); 332 | }); 333 | describe('debug', function() { 334 | it('should install 2.6.11 debug'); 335 | it('should install have 2.6.11 and a separate 2.6.11 debug'); 336 | }); 337 | }); 338 | }); 339 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | -R spec 2 | --timeout 1200000 3 | --slow 1000 4 | --------------------------------------------------------------------------------