-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Add check to pkg command to deal with empty values #6902
Conversation
I think there's a bad assumption being made here (i.e. the original code) where if only one item was returned then only one item was asked for. The "length" check is more intended for the use case of "I asked for one attribute but the value of it is an array", e.g. $ npm pkg get dependencies
{
"@npmcli/promise-spawn": "^6.0.0",
"lru-cache": "^10.0.1",
"npm-pick-manifest": "^9.0.0",
"proc-log": "^3.0.0",
"promise-inflight": "^1.0.1",
"promise-retry": "^2.0.1",
"semver": "^7.3.5",
"which": "^3.0.0"
} I would think that if I asked for multiple attributes, I will always get back the long form, even if some of them are empty.
~/D/n/c/b/main (latest|✔) $ npm pkg get name foo
undefined
~/D/n/c/b/main (latest|✔) $ npm view npm name foo
npm
~/D/n/c/b/main (latest|✔) $ npm pkg get name version
{
"name": "npm",
"version": "10.2.0"
}
~/D/n/c/b/main (latest|✔) $ npm view npm name version
name = 'npm'
version = '10.2.0'
You'll see both exhibiting this bug. Both of them use if (!_data[k]) {
return undefined
} Perhaps that should be a Then we can also make sure that if the user asked for more than one attribute, we always return the long form. |
Very good points @wraithgar. I was conflicted whether or not it should return the empty string or not, but I should have searched deeper for the core issue. I'll take a look and adjust the code/PR. |
@wraithgar I've made some modifications and added a test for the view command. I had to generate snapshots for Tap, do I need to commit the files it generates? I've never used the snapshot stuff before so wasn't sure. Edit: |
lib/utils/queryable.js
Outdated
@@ -113,12 +113,14 @@ const getter = ({ data, key }) => { | |||
} else { | |||
// if can't find any more values, it means it's just over | |||
// and there's nothing to return | |||
if (!_data[k]) { | |||
if (Object.hasOwn(_data, k) && !_data[k]) { |
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 falsey check here was a bad idea in the first place. What if the value of node-gyp
is false
? Shouldn't I get that back?
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.
Yes when you run As I commented inline, the entire premise of doing a falsey check here is wrong, I think. Do you agree? |
lib/utils/queryable.js
Outdated
const value = _data[k] | ||
if (typeof value === 'boolean' || (value === '' && Object.hasOwn(_data, k))) { | ||
_data = value | ||
} else if (value === undefined) { |
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.
if value === undefined
and value = _data[k]
then returning _data[k]
would return undefined anyways. Not sure what this check gains us.
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 right, I did overcomplicate that. The undefined check is needed since other functionality/tests expect it to be returned and not just set to _data
.
I simplified it so now it only returns undefined, else just sets up _data = value
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 undefined check is needed since other functionality/tests expect it to be returned and not just set to _data.
Can you show me where this is happening? That still seems very counterintuitive.
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.
oooooh I see it now. we're not returning otherwise. My bad!
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.
OK I think we're getting somewhere. I think this check should be JUST a hasOwn
, and if that's false we return undefined. Otherwise we let it fall through.
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 works, change has been made
It looks like the early return has to do w/ the accumulator that keeps a running tab of what Unpacking that is a larger issue than this PR imo. |
The two failing tests are flaky, not related to this PR |
Ah ok, I was trying to replicate locally but the tests would all pass so was a little confused. |
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 new pkg
test outlines the fix perfectly.
This will go out w/ the next npm release. If you need this in npm 9 you can cherry pick 35c92fe and make a new PR to the release/v9 branch |
If your package.json contains an empty value such as:
Executing,
npm pkg get name author
will returnundefined
. You'd expect it to return"foo"
.This is because the args is being used as an index when returning a single value. This patch fixes this and adds two new tests to the pkg command.