-
Notifications
You must be signed in to change notification settings - Fork 3k
Add new subcommand npm doctor
#14582
Conversation
|
Does this add any new deps? |
lib/doctor.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be 'npm@' + npmV?
|
@watilde I owe you a response! I'll try to get to it today! The summary is this looks fantastic, but we need to talk a lil more about the functionality everybody wants. |
|
Current comments:
|
|
@legodude17 Yes, that's a good point. Before that, I'm thinking about a way to make the test having a fixture in test. @othiym23 Sure thing! Let's continue the discussion at #6756 |
1b49329 to
6333bc7
Compare
npm doctornpm doctor
|
@watilde is this still |
|
@legodude17 It's fixed technically for the original plan, but the code potentially will be changed depending on what kind of request comes from the issue thread. Then the status doesn't matter anymore :) |
|
One suggestion from #6756 is to offer to fix it like |
othiym23
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@watilde, my apologies for the lengthy delay. It's been a bruiser of a month.
Here, in no particular order, are my thoughts:
-
I'm not in love with the idea of prescribing that users nuke their caches every time they run
npm doctor. It makes installs (potentially much) slower until the cache rewarms, and in cases in which the user is on a flaky internet connection, can actually make installs even flakier. If at all possible, I'd like to move to advising people to onlynpm cache cleanindividual broken dependencies.It's probably out of scope for this initial spike, but something that validates that the cache is in good shape (and maybe went ahead and cleaned up any shasum mismatches automatically) would be a super useful alternative.
-
Something that validates that
$HOME/.npmand all its children is owned and writable by$USERwould be very helpful for diagnostic purposes. -
Similarly, something that checks whether
join(npm.config.globalPrefix, 'lib', 'node_modules')is writable and tells the user whether they need to usesudoto run global installs would be very helpful. -
It would be very helpful to verify that Git is installed and available, especially for Windows users.
-
This is another thing that doesn't have to be added yet, but something that builds a very simple canned native module with
node-gypwould be extremely helpful for Windows users unsure whether they have their toolchain correctly installed. -
Finally, and longest-term, it would be fantastic to have some way for npm to verify its own integrity, which probably requires that some kind of install manifest be generated for it. While it would be useful to have this functionality for npm packages in general, it's especially important for npm, because of the Node.js installer's bad habit of just copying the new npm right over the top of the old one, which causes a bunch of the stranger
module not foundbugs that show up on the issue tracker. Being able to catch this automatically would be hugely useful.
This is basically my wishlist, though. What you've got is a fantastic start, and when you get the above comments addressed, I'll ship what you've got so far. Thank you so much for putting this together!
lib/doctor.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're going to want to use a semver range comparator here, because something weird will happen as soon as Node 10 is released. 👍 on the check for LTS, though – that's exactly what I was looking for.
doc/cli/npm-doctor.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be expanded to explain all of the questions and answers, as well as the team's consensus about rationales for the recommendations.
doc/cli/npm-doctor.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be cool if npm doctor produced output in a format similar enough to Markdown that the output could just be cut and pasted directly into a new issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the best way to do that would be to template it, but I am not sure about what anyone's thoughts are about including a template engine with npm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's absolutly good idea, and I'd like to have the feature in npm report command which have been proposaling at #5214. I'm planning to use the ISSUE_TEMPLATE.md as a acutual template, but let's separete the reporting part from this diagnosis part to make the initial scope clear and simple.
lib/doctor.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of these aren't really questions, so I suggest something like Check, Value, and Recommendation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point @othiym23.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True! I've updated :)
test/tap/doctor.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this use the url initialized above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's right! I've updated.
test/tap/doctor.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test should verify that npm doctor is producing sensible output, and should also start up a mock registry that allows the test to control which version of npm is returned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it should be since npm doctor ask the things to the registry through npm ping and fetchPackageMetadata. I've added npm-registry-mock into this test and verifying all of the output!
lib/doctor.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer this to pull d['dist-tags'].latest instead, so that npm doctor always recommends latest instead of next.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So cb(er, d['dist-tags'].latest)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated with npm@latest check.
lib/doctor.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...but this is part of why we need to be matching against npm doctor actually returns in the tests, because it seems very possible to me that changes made to the configuration code could break this command without anyone noticing otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added it to the test! Once the structure of default properties are changed, the test makes an error.
|
@othiym23 Hey Forrest, thanks for your thoughtful wish list! I'd like to separate examination processes and auto-fix features and let me reply to every wish-item of yours.
Additionally, I've added one more permission check for
Let me ping you when they're ready. |
|
Some random ideas for things to add:
Keep up the great work @watilde! |
fe36ada to
86b0824
Compare
|
@othiym23 I've added some check items that I wrote down at #14582 (comment), and also written up the detailed documentation for the (๑˃̵ᴗ˂̵)و let me cc to you as well @zkat |
This command will diagnose user's environment and let the user know some recommended solutions if they potentially have any problems related to npm.
c9002da to
d8b1b45
Compare
|
I think this will be ready in time to include in this week's release, which might end up being the last release of the CLI in 2016! I only have a few further comments:
This is really great! I can't wait to get it out into people's hands. Thank you so much for your patience and careful work, Daijiro! |
lib/doctor.js
Outdated
| var nodeLTS = p[2].replace('v', '') | ||
| var whichGit = p[3] || 'not installed' | ||
| var readbleCaches = p[4] ? 'ok' : 'notOk' | ||
| var executableGlobalModules = p[4] ? 'ok' : 'notOk' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't these from this line down be 5, 6 & 7?
lib/doctor/checksum-cached-files.js
Outdated
| if (!/.tgz$/.test(file)) return | ||
| var tgz = fs.readFileSync(file) | ||
| try { | ||
| var pkgJSON = fs.readFileSync(path.join(file, '../package/package.json')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what's wanted here is: path.join(path.dirname(file), 'package/package.json')
Alternatively, I think: path.resolve(file, '../package/package.json')
Would have worked, but it's sufficiently weird that I prefer the former.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also turns out that it's entirely ok for the package.json to be missing, in which case we ought to skip trying to verify the shasum.
lib/doctor/checksum-cached-files.js
Outdated
| var tgz = fs.readFileSync(file) | ||
| try { | ||
| var pkgJSON = fs.readFileSync(path.join(file, '../package/package.json')) | ||
| var shasum = JSON.parse(pkgJSON).dist.shasum |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dist is added by the registry and won't be present for modules installed from other sources. _shasum should be available however.
lib/doctor/check-files-permission.js
Outdated
|
|
||
| function checkFilesPermission (root, mask, cb) { | ||
| var accessible = true | ||
| if (process.platform === 'win32') return cb(null, !accessible) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be calling back with true shouldn't it? We don't want it to mark windows as always failing right?
lib/doctor/check-files-permission.js
Outdated
| files.some(function (f) { | ||
| if (!accessible) return true | ||
| var file = path.join(root, f) | ||
| fs.stat(file, function (e, stat) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fs.stat is async and files.some is sync, they can't be used together.
| var getUid = require('uid-number') | ||
| var npm = require('../npm.js') | ||
|
|
||
| function checkFilesPermission (root, mask, cb) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mask isn't being used like a umask which I think is the cause of an issue in how this function is being called…
lib/doctor.js
Outdated
| [getLatestNpmVersion], | ||
| [getLatestNodejsVersion, args['node-url']], | ||
| [which, 'git'], | ||
| [checkFilesPermission, npm.cache, 4], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filemode & 0400 would be true for files you have read access to. Should this be rewrite instead? (6)
lib/doctor.js
Outdated
| [getLatestNodejsVersion, args['node-url']], | ||
| [which, 'git'], | ||
| [checkFilesPermission, npm.cache, 4], | ||
| [checkFilesPermission, globalNodeModules, 1], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filemode & 0100 is true if you have execute access to. I'm assuming that this is supposed to be checking for read access? (4)
|
I put together a little patch that fixes the bugs that I encountered and reworks things to allow progress bars. You can see that here: |
|
@iarna Thanks for your comments, and your patch seems so brilliant.. Let me do cherry-pick it into this PR, or you also can handle the commits to be suited for next-release. |
|
Thanks again for this! It was merged and released in 4.1.0. |
From here #6756 (comment)
this screenshot was updated with current progress at 4th December 2016

ToDo:
getLatestNodejsVersionwith a fixturable way