1 | # next-update
|
2 |
|
3 | > Tests if module's dependencies can be updated to the newer version without breaking the tests
|
4 |
|
5 | [![NPM][next-update-icon] ][next-update-url]
|
6 |
|
7 | [![Build status][next-update-ci-image] ][next-update-ci-url]
|
8 | [![Circle CI][circle-ci-image] ][circle-ci-url]
|
9 | [![Coverage Status][next-update-coverage-image] ][next-update-coverage-url]
|
10 | [![semantic-release][semantic-image] ][semantic-url]
|
11 | [![Known Vulnerabilities](https://snyk.io/test/github/bahmutov/next-update/230d136b5c68dadb1fd5459619df8f7678d28429/badge.svg)](https://snyk.io/test/github/bahmutov/next-update/230d136b5c68dadb1fd5459619df8f7678d28429)
|
12 |
|
13 | [next-update-icon]: https://nodei.co/npm/next-update.svg?downloads=true
|
14 | [next-update-url]: https://npmjs.org/package/next-update
|
15 | [next-update-ci-image]: https://travis-ci.org/bahmutov/next-update.svg?branch=master
|
16 | [next-update-ci-url]: https://travis-ci.org/bahmutov/next-update
|
17 | [next-update-coverage-image]: https://coveralls.io/repos/bahmutov/next-update/badge.svg
|
18 | [next-update-coverage-url]: https://coveralls.io/r/bahmutov/next-update
|
19 | [circle-ci-image]: https://circleci.com/gh/bahmutov/next-update.svg?style=svg
|
20 | [circle-ci-url]: https://circleci.com/gh/bahmutov/next-update
|
21 | [semantic-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
|
22 | [semantic-url]: https://github.com/semantic-release/semantic-release
|
23 |
|
24 |
|
25 |
|
26 | **Note** I no longer maintain Node 0.12/4 compatibility. Please switch to
|
27 | Node 6.
|
28 |
|
29 | [![asciicast](https://asciinema.org/a/21645.png)](https://asciinema.org/a/21645)
|
30 |
|
31 | Also check out:
|
32 |
|
33 | * [next-updater](https://github.com/bahmutov/next-updater) can update all your repos
|
34 | * [dont-break](https://github.com/bahmutov/dont-break)
|
35 | that checks if your code is going to break everyone who depends on it.
|
36 | * [changed-log](https://github.com/bahmutov/changed-log) returns commit messages for
|
37 | the given NPM package or Github repo between two tags.
|
38 |
|
39 | ### Example
|
40 |
|
41 | Imagine your nodejs module *foo* has the following dependencies listed in *package.json*
|
42 |
|
43 | "dependencies": {
|
44 | "lodash": "~1.2.0",
|
45 | "async": "~0.2.5"
|
46 | }
|
47 |
|
48 | You would like to update lodash and async to latest versions, to not sure if
|
49 | this would break anything. With *next-update* it is easy: run command `next-update`
|
50 | in the folder with module *foo*. Here is the example output:
|
51 |
|
52 | next updates:
|
53 | lodash
|
54 | 1.2.1 PASS
|
55 | async
|
56 | 0.2.6 PASS
|
57 | 0.2.7 PASS
|
58 | 0.2.8 PASS
|
59 |
|
60 |
|
61 | Both *package.json* file and *node_modules* folder are left unchanged,
|
62 | and now you know that you can safely upgrade both libraries to later versions.
|
63 |
|
64 | #### It even tells you the install command ;)
|
65 |
|
66 | Use the following command to install working versions
|
67 | npm install --save lodash@2.1.0
|
68 |
|
69 | This might not appear like a big deal for a single module that is using
|
70 | popular 3rd party libraries with stable apis only. *next-update* is most useful
|
71 | in the larger development context, where multiple modules are being developed
|
72 | side by side, often by different teams. In such situations, checking if an upgrade
|
73 | is possible could be part of the continuous build pipeline.
|
74 |
|
75 | You can see if your dependencies are out of date by using
|
76 | [david](https://david-dm.org),
|
77 | it even has badges you can add to your README files.
|
78 |
|
79 | *next-update* reports the probability of success for a given dependency update using
|
80 | anonymous global statistics from [next-update](http://next-update.herokuapp.com/) server
|
81 |
|
82 | ```
|
83 | available updates:
|
84 | package available from version average success % successful updates failed updates
|
85 | -------------------- --------- ------------ ----------------- ------------------ --------------
|
86 | grunt-contrib-jshint 0.8.0 0.7.2 100% 34 0
|
87 | grunt-bump 0.0.13 0.0.12 100% 4 0
|
88 | ```
|
89 |
|
90 | ### Install
|
91 |
|
92 | You can install this tool globally
|
93 |
|
94 | npm install -g next-update // installs module globally
|
95 | next-update --help // shows command line options
|
96 |
|
97 | Then run inside any package folder
|
98 |
|
99 | /git/my-awesome-module
|
100 | $ next-update
|
101 |
|
102 | Or you can use this module as a devDependency and a script command
|
103 |
|
104 | npm install --save-dev next-update
|
105 |
|
106 | ```json
|
107 | {
|
108 | "scripts": {
|
109 | "next-update": "next-update -k true --tldr"
|
110 | }
|
111 | }
|
112 | ```
|
113 |
|
114 | This command will keep the successfuly version upgrades in the package.json file,
|
115 | but will not be very verbose when run.
|
116 |
|
117 | ### Anonymous usage collection
|
118 |
|
119 | After testing each module A upgrade from version X to Y, *next-update* sends
|
120 | anonymous result to [next-update.herokuapp.com/](http://next-update.herokuapp.com/).
|
121 | The only information transmitted is:
|
122 |
|
123 | ```json
|
124 | {
|
125 | "name": "lodash",
|
126 | "from": "1.0.0",
|
127 | "to": "2.0.0",
|
128 | "success": true
|
129 | }
|
130 | ```
|
131 |
|
132 | This information is used to answer the following questions later:
|
133 | what is the probability module A can be upgraded from X to Y?
|
134 | Thus even if you do not have tests covering this particular module,
|
135 | you can judge how compatible version X and Y really are over the entire
|
136 | internet.
|
137 |
|
138 | You can inspect data send in
|
139 | [stats.js](https://github.com/bahmutov/next-update/blob/master/src/stats.js).
|
140 |
|
141 | If the dependency module has been upgraded by anyone else, its statistics
|
142 | will be displayed with each test.
|
143 |
|
144 | ```sh
|
145 | stats: deps-ok 0.0.7 -> 0.0.8 success probability 44.44% 8 success(es) 10 failure(s)
|
146 | ```
|
147 |
|
148 | A lot of NPM modules [do not have tests](http://npmt.abru.pt/), but
|
149 | at least you can judge if someone else has success going from verion X to version Y
|
150 | of a dependency.
|
151 |
|
152 | ### Use
|
153 |
|
154 | Make sure the target module has unit / integration tests,
|
155 | and the tests can be run using `npm test` command.
|
156 |
|
157 | Run `next-update` from the command line in the same folder as
|
158 | the target module. In general this tool does the following:
|
159 |
|
160 | 1. Reads the module's dependencies (including dev) and their versions
|
161 | 2. Queries npm registry to see if there are newer versions
|
162 | 3. For each dependency that has newer versions available:
|
163 | 1. Installs each version
|
164 | 2. Runs command `npm test` to determine if the new version breaks the tests
|
165 | 3. Installs back the current version.
|
166 | 4. Reports results
|
167 |
|
168 | ### Ignoring or skipping some modules
|
169 |
|
170 | Some modules are hard to unit test, thus the automatic upgrades are not appropriate.
|
171 | For example [benv](https://npmjs.org/package/benv) upgrade brings a new
|
172 | [jsdom](https://npmjs.org/package/jsdom) version, which does not work on Node 0.12
|
173 | Similarly, upgrading [Q](https://npmjs.org/package/q) from 1.x.x to 2.x.x is usually
|
174 | a breaking change.
|
175 |
|
176 | You can skip a list of modules by name using `config` property in the `package.json`
|
177 |
|
178 | ```json
|
179 | "config": {
|
180 | "next-update": {
|
181 | "skip": ["benv", "q"]
|
182 | }
|
183 | }
|
184 | ```
|
185 |
|
186 | ### Misc
|
187 |
|
188 | * To see what has changed in the latest version of any module,
|
189 | use my companion tool [changed](https://npmjs.org/package/changed)
|
190 | like this `changed foo` (*foo* is package name)
|
191 | * When comparing versions, keywords *latest* and *** are both assumed to equal to "0.0.0".
|
192 | * A good workflow using *next-update*
|
193 | * see available new versions `next-update --available`
|
194 | * check latest version of each module using `next-update --latest`
|
195 | * install new versions of the desired modules using standard `npm i dependency@version --save`
|
196 | * You can use custom test command, for example `next-update -t "grunt test"`
|
197 | * `npm test` is used by default.
|
198 | * You can keep each working version in package.json by using `--keep` flag.
|
199 |
|
200 |
|
201 |
|
202 | ## API
|
203 |
|
204 | You can use `next-update` as a module. See file
|
205 | [src/next-update-as-module](./src/next-update-as-module) for all options.
|
206 |
|
207 | ```js
|
208 | const nextUpdate = require('next-update')
|
209 | nextUpdate({
|
210 | module: ['foo', 'bar']
|
211 | }).then(results => {
|
212 | console.log(results)
|
213 | })
|
214 | /*
|
215 | prints something like
|
216 | [[
|
217 | {
|
218 | "name": "foo",
|
219 | "version": "0.2.0",
|
220 | "from": "0.2.1",
|
221 | "works": true
|
222 | },
|
223 | {
|
224 | "name": "foo",
|
225 | "version": "0.2.0",
|
226 | "from": "0.3.0",
|
227 | "works": false
|
228 | }
|
229 | ], [
|
230 | {
|
231 | "name": "bar",
|
232 | "version": "1.5.1",
|
233 | "from": "2.0.0",
|
234 | "works": true
|
235 | }
|
236 | }}
|
237 | */
|
238 | ```
|
239 |
|
240 |
|
241 |
|
242 | ## Development
|
243 |
|
244 | Edit source, run unit tests, run end to end tests and release
|
245 | new version commands:
|
246 |
|
247 | ```sh
|
248 | npm test
|
249 | npm run e2e
|
250 | grunt release
|
251 | npm publish
|
252 | ```
|
253 |
|
254 |
|
255 | ### Related
|
256 |
|
257 | * [Painless modular development](http://glebbahmutov.com/blog/modular-development-using-nodejs/)
|
258 | * [Really painless modular development](http://glebbahmutov.com/blog/really-painless-modular-development/)
|
259 |
|
260 |
|
261 |
|
262 | ### 3<sup>rd</sup> party libraries
|
263 |
|
264 | * [lazy-ass](https://github.com/bahmutov/lazy-ass) and
|
265 | [check-more-types](https://github.com/kensho/check-more-types) are used to
|
266 | [defend against runtime errors](http://glebbahmutov.com/blog/lazy-and-async-assertions/).
|
267 | * [lo-dash](https://github.com/bestiejs/lodash) is used to deal with collections / iterators.
|
268 | * [check-types](https://github.com/philbooth/check-types.js) is used to verify arguments through out the code.
|
269 | * [optimist](https://github.com/substack/node-optimist) is used to process command line arguments.
|
270 | * [request](https://npmjs.org/package/request) is used to fetch NPM registry information.
|
271 | * [semver](https://npmjs.org/package/semver) is used to compare module version numbers.
|
272 | * [q](https://npmjs.org/package/q) library is used to handle promises. While developing this tool,
|
273 | I quickly ran into problems managing the asynchronous nature of fetching information, installing multiple modules,
|
274 | testing, etc. At first I used [async](https://npmjs.org/package/async), but it was still too complex.
|
275 | Using promises allowed to cut the program's code and the complexity to very manageable level.
|
276 | * [cli-color](https://npmjs.org/package/cli-color) prints colored text to the terminal.
|
277 |
|
278 |
|
279 |
|
280 | ### Small print
|
281 |
|
282 | Author: Gleb Bahmutov © 2014
|
283 |
|
284 | * [@bahmutov](https://twitter.com/bahmutov)
|
285 | * [glebbahmutov.com](https://glebbahmutov.com)
|
286 | * [blog](https://glebbahmutov.com/blog)
|
287 |
|
288 | License: MIT - do anything with the code, but don't blame me if it does not work.
|
289 |
|
290 | Spread the word: tweet, star on github, etc.
|
291 |
|
292 | Support: if you find any problems with this module, email / tweet /
|
293 | [open issue](https://github.com/bahmutov/next-update/issues?state=open) on Github
|
294 |
|
295 |
|
296 |
|
297 | ## MIT License
|
298 |
|
299 | Copyright (c) 2014 Gleb Bahmutov
|
300 |
|
301 | Permission is hereby granted, free of charge, to any person
|
302 | obtaining a copy of this software and associated documentation
|
303 | files (the "Software"), to deal in the Software without
|
304 | restriction, including without limitation the rights to use,
|
305 | copy, modify, merge, publish, distribute, sublicense, and/or sell
|
306 | copies of the Software, and to permit persons to whom the
|
307 | Software is furnished to do so, subject to the following
|
308 | conditions:
|
309 |
|
310 | The above copyright notice and this permission notice shall be
|
311 | included in all copies or substantial portions of the Software.
|
312 |
|
313 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
314 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
315 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
316 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
317 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
318 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
319 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
320 | OTHER DEALINGS IN THE SOFTWARE.
|
321 |
|
322 |
|