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