Skip to content
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

Feat: repo owner changed option #621

Merged
merged 16 commits into from
Aug 29, 2020

Conversation

KingDarBoja
Copy link
Contributor

Fixes #465. Thanks @stoically for helping me with the packument stuff.

Unfortunately, I don't have any screenshot at the moment to showcase the new owner changed column, as I have no idea which npm package got author changed.

To test it out, I had to tweak this library and use verdaccio for local publish in order to check the behaviour of the packument author data between two versions.

const to = versionUtil.colorizeDiff(mappedArgs.from[dep], mappedArgs.to[dep] || '');
let owner = '';
if (options.ownerChanged) {
owner = mappedArgs.owner && mappedArgs.owner[dep] ? '*owner changed*' : '';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it might make sense to list the actual changed owners? Otherwise looking that up manually could be hard.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How could that be displayed on the table? 🤔

Copy link
Owner

@raineorshine raineorshine Jan 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I somewhat prefer *owner changed*. Listing the actual changed owners would make sense in --loglevel verbose if we were to expand results beyond a single line.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, that might make the whole thing noisy. Maybe additionally a "some owners changed while checking for updates, execute with --loglevel verbose to see the full list" at the end of the listing in case something changed?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, since currently getting the owner changed information is already opt-in, wouldn't that be enough intent to actually get the owner information as well?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option that I think would be reasonable would be to add something like --full which would be expected to break the single-line formatting and would allow room for additional information to be added in the future, as suggested.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That could get interesting if multiple owners get added and removed (long line). Also there might be a problem with accessibility (color blind) if owners are only added or removed (no arrow, or arrow pointing to / originating from nothing).

But

htmlparser2              ^3.10.1  →   ^4.0.0

                       Owner added:  foo, bar, baz
                           removed:  baz, bar, foo

              License changed from:  MIT
                                to:  GPL

moment                   ^2.22.2  →  ^2.24.0
react-click-n-hold        ^1.0.6  →   ^1.0.7

isn't exactly pretty 😬

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option that I think would be reasonable would be to add something like --full

So, leaving *owner changed* as is and showing more information with the --full flag?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't exactly pretty 😬

That's not so bad for the full view.

So, leaving owner changed as is and showing more information with the --full flag?

That's what I'm leaning towards.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stoically I'm going to get this PR merged as-is, but I'm open to enhanced functionality in a separate PR!

lib/npm-check-updates.js Outdated Show resolved Hide resolved
lib/package-managers/npm.js Outdated Show resolved Hide resolved
lib/package-managers/pacotetest.js Outdated Show resolved Hide resolved
lib/versionmanager.js Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
const to = versionUtil.colorizeDiff(mappedArgs.from[dep], mappedArgs.to[dep] || '');
let owner = '';
if (options.ownerChanged) {
owner = mappedArgs.owner && mappedArgs.owner[dep] ? '*owner changed*' : '';
Copy link
Owner

@raineorshine raineorshine Jan 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I somewhat prefer *owner changed*. Listing the actual changed owners would make sense in --loglevel verbose if we were to expand results beyond a single line.

lib/npm-check-updates.js Outdated Show resolved Hide resolved
lib/npm-check-updates.js Outdated Show resolved Hide resolved
lib/npm-check-updates.js Outdated Show resolved Hide resolved
lib/npm-check-updates.js Outdated Show resolved Hide resolved
lib/npm-check-updates.js Outdated Show resolved Hide resolved
lib/package-managers/npm.js Outdated Show resolved Hide resolved
lib/npm-check-updates.js Outdated Show resolved Hide resolved
Copy link
Owner

@raineorshine raineorshine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments

lib/package-managers/npm.js Outdated Show resolved Hide resolved
const result = await pacote.packument(packageName, npmConfig);
if (result.versions) {
let pkgVersions = Object.keys(result.versions);
const current = semver.maxSatisfying(pkgVersions, currentVersion);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want to use currentVersion as-is rather than getting maxSatisfying. If the owner changed on a patch version in between currentVersion and current, it would not detect the owner change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about the bug after removing the maxSatisfying, I tested the counterpart function (minSatisfying) and I think it does what I wanted for both current and latest version:

Return the lowest version in the list that satisfies the range, or null if none of them do.

So if Mocha current is ^7.0.1, the minimum version will be 7.0.1 whereas if latest is 8.0.0 or ^8.0.0, it will return 8.0.0. For cases where the version doesn't exist, i.e. current being 8.2.1/ ^8.2.1 and latest being 9.0.0, it will fail as minSatisfying will be unable to find a version to match these.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One image is better than 1000 words.

ncu-owner-check

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can confirm that currentVersion is a range, not an exact version as I suggested in my initial comment.

I changed it to use minSatisfying on currentVersion and maxSatisfying on upgradedVersion. This ensures that the broadest change is covered in case the owner changed anywhere between the two.

bin/ncu Outdated Show resolved Hide resolved
lib/npm-check-updates.js Outdated Show resolved Hide resolved
Copy link
Owner

@raineorshine raineorshine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am currently getting the following error with some packages. You can run ncu -o on npm-check-updates itself or try mocha as an example.

Question is, why is _npmUser not defined on some packages? If it is not guaranteed, how reliable will this feature be? We might have to print something like *unknown* to avoid a false positive.

$ ncu -o
Checking /Users/raine/projects/npm-check-updates/package.json
[====================] 34/34 100%
/Users/raine/projects/npm-check-updates/lib/npm-check-updates.js:437
  throw err
  ^

TypeError: Cannot read property '_npmUser' of undefined
    at Object.packageAuthorChanged (/Users/raine/projects/npm-check-updates/lib/package-managers/npm.js:68:54)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async /Users/raine/projects/npm-check-updates/lib/versionmanager.js:274:28
    at async Promise.all (index 0)
    at async Object.getOwnerPerDependency (/Users/raine/projects/npm-check-updates/lib/versionmanager.js:270:3)
    at async /Users/raine/projects/npm-check-updates/lib/npm-check-updates.js:239:16
    at async getAnalysis (/Users/raine/projects/npm-check-updates/lib/npm-check-updates.js:486:24)

lib/package-managers/npm.js Outdated Show resolved Hide resolved
@KingDarBoja
Copy link
Contributor Author

KingDarBoja commented Jul 18, 2020

Tested against mocha with current version being ^7.2.0 and latest being 8.0.1 and checked all version list _npmUser to see what is going on. Noticed that Mocha has _npmUser on any version until now, so the owner in theory never changed but the issue is caused by current having a wildcard.

@raineorshine
Copy link
Owner

I'm sort of following. Do you need assistance or do you have a solution? I can try to understand better if you are in need of support.

@KingDarBoja
Copy link
Contributor Author

I'm sort of following. Do you need assistance or do you have a solution? I can try to understand better if you are in need of support.

Kinda both, I explained it on one of the above comments what I think should be done:

async function packageAuthorChanged(packageName, currentVersion, latestVersion) {
  npmConfig.fullMetadata = true

  const result = await pacote.packument(packageName, npmConfig)
  if (result.versions) {
    const pkgVersions = Object.keys(result.versions)
    const current = semver.minSatisfying(pkgVersions, currentVersion)
    const latest = semver.minSatisfying(pkgVersions, latestVersion)
    if (current && latest) {
      if (result.versions[current]._npmUser && result.versions[latest]._npmUser) {
        const currentAuthor = result.versions[current]._npmUser.name
        const latestAuthor = result.versions[latest]._npmUser.name
        return !_.isEqual(currentAuthor, latestAuthor)
      }
    }
  }
  return null
}

Replace at the previous replit code and see what happens with Mocha.

@raineorshine
Copy link
Owner

That should work. Do you think we should print something like *unknown* in those cases where no comparison can be made? Otherwise it might be possible to have a false positive.

@KingDarBoja
Copy link
Contributor Author

KingDarBoja commented Jul 20, 2020

That should work. Do you think we should print something like *unknown* in those cases where no comparison can be made? Otherwise it might be possible to have a false positive.

Of course, that's why I am returning null, to check if it is null before displaying at the table. If it is null, then show unknown :) that's atleast what I have in mind.

Also, I would add some testing to cover this feature so we don't end up with some edge cases.

@raineorshine
Copy link
Owner

raineorshine commented Jul 20, 2020

Great, that sounds good.

Note that you will also need to check result.versions[current] && result.versions[latest] otherwise we get the Cannot read property '_npmUser' of undefined error.

@KingDarBoja
Copy link
Contributor Author

Great, that sounds good.

Note that you will also need to check result.versions[current] && result.versions[latest] otherwise we get the Cannot read property '_npmUser' of undefined error.

Too bad we can't use the optional chaining operator here 😢

@KingDarBoja
Copy link
Contributor Author

@raineorshine Sorry for the delay, been busy with some real life stuff but managed to update the branch and provide three basic test for this feature, I will be pushing in a few minutes these changes.

Cheers!

@raineorshine
Copy link
Owner

Thanks! I will review this week.

@raineorshine
Copy link
Owner

Okay, I believe it's ready to merge!

I just made some small changes in 7f08648:

  • Only print ownerChanged status when --ownerChanged is specified
  • Fix issue with getOwnerPerDependency that was not returning the correct object
  • Minor refactor, renames, convert to functional style

@raineorshine raineorshine removed the request for review from stoically August 29, 2020 01:52
@KingDarBoja
Copy link
Contributor Author

Finally! After few months and some lazyness from me, this will be merged 🎉

@raineorshine raineorshine merged commit 8851b6b into raineorshine:master Aug 29, 2020
@KingDarBoja KingDarBoja deleted the feat/repo-owner-column branch August 29, 2020 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Issue a warning when repository owner is changed
3 participants