Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Feat: repo owner changed option #621

Merged
merged 16 commits into from
Aug 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ $ ncu "/^(?!gulp-).*$/" # windows
semver.
-n, --newest DEPRECATED. Renamed to "--target newest".
-p, --packageManager <name> npm, yarn (default: "npm")
-o, --ownerChanged Check if the package owner changed between
current and upgraded version.
--packageData Include stringified package file (you can also
send to stdin).
--packageFile <path> Package file location (default: ./package.json).
Expand Down
4 changes: 4 additions & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ const cliOptions = [
description: 'npm, yarn',
default: 'npm'
},
{
name: '-o, --ownerChanged',
description: 'Check if the package owner changed between current and upgraded version.',
},
{
name: '--packageData',
description: 'Include stringified package file (you can also send to stdin).'
Expand Down
14 changes: 11 additions & 3 deletions lib/logging.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ function createDependencyTable() {
* @param args
* @param args.from
* @param args.to
* @param args.ownersChangedDeps
* @returns
*/
function toDependencyTable(args) {
Expand All @@ -77,8 +78,13 @@ function toDependencyTable(args) {
const to = isGithubUrl(toRaw) ? getGithubUrlTag(toRaw)
: isNpmAlias(toRaw) ? parseNpmAlias(toRaw)[1]
: toRaw
const ownerChanged = args.ownersChangedDeps
? dep in args.ownersChangedDeps
? args.ownersChangedDeps[dep] ? '*owner changed*' : ''
: '*unknown*'
: ''
const toColorized = colorizeDiff(from, to)
return [dep, from, '→', toColorized]
return [dep, from, '→', toColorized, ownerChanged]
})
rows.forEach(row => table.push(row)) // eslint-disable-line fp/no-mutating-methods
return table
Expand All @@ -91,8 +97,9 @@ function toDependencyTable(args) {
* @param args.upgraded - The packages that should be upgraded.
* @param args.numUpgraded - The number of upgraded packages
* @param args.total - The total number of all possible upgrades
* @param args.ownersChangedDeps - Boolean flag per dependency which announces if package owner changed.
*/
function printUpgrades(options, { current, upgraded, numUpgraded, total }) {
function printUpgrades(options, { current, upgraded, numUpgraded, total, ownersChangedDeps }) {
print(options, '')

// print everything is up-to-date
Expand All @@ -116,7 +123,8 @@ function printUpgrades(options, { current, upgraded, numUpgraded, total }) {
if (numUpgraded > 0) {
const table = toDependencyTable({
from: current,
to: upgraded
to: upgraded,
ownersChangedDeps
})
print(options, table.toString())
}
Expand Down
3 changes: 3 additions & 0 deletions lib/npm-check-updates.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ declare namespace ncu {
/** npm, yarn (default: "npm") */
packageManager?: string;

/** Check if the package owner changed between current and upgraded version. */
ownerChanged?: boolean;

/** Include stringified package file (you can also send to stdin). */
packageData?: boolean;

Expand Down
7 changes: 6 additions & 1 deletion lib/npm-check-updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ function analyzeProjectDependencies(options, pkgData, pkgFile) {
const filteredUpgraded = options.minimal ? cint.filterObject(selectedNewDependencies, dep => !isSatisfied(dep)) : selectedNewDependencies
const numUpgraded = Object.keys(filteredUpgraded).length

const ownersChangedDeps = options.ownerChanged
? await vm.getOwnerPerDependency(current, filteredUpgraded, options)
: null

// print
if (options.json) {
// use the selectedNewDependencies dependencies data to generate new package data
Expand All @@ -179,7 +183,8 @@ function analyzeProjectDependencies(options, pkgData, pkgFile) {
upgraded: filteredUpgraded,
latest,
numUpgraded,
total: Object.keys(upgraded).length
total: Object.keys(upgraded).length,
ownersChangedDeps
})
}

Expand Down
29 changes: 28 additions & 1 deletion lib/package-managers/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,32 @@ function parseJson(result, data) {
return json
}

/**
* Check if package author changed between current and upgraded version.
*
* @param packageName Name of the package
* @param currentVersion Current version declaration (may be range)
* @param upgradedVersion Upgraded version declaration (may be range)
* @returns A promise that fullfills with boolean value.
*/
async function packageAuthorChanged(packageName, currentVersion, upgradedVersion) {
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 upgraded = semver.maxSatisfying(pkgVersions, upgradedVersion)
if (current && upgraded && result.versions[current]._npmUser && result.versions[upgraded]._npmUser) {
const currentAuthor = result.versions[current]._npmUser.name
const latestAuthor = result.versions[upgraded]._npmUser.name
return !_.isEqual(currentAuthor, latestAuthor)
}
}

return null
}

/**
* Returns the value of one of the properties retrieved by npm view.
*
Expand Down Expand Up @@ -334,5 +360,6 @@ module.exports = {
)
},

defaultPrefix
defaultPrefix,
packageAuthorChanged
}
24 changes: 23 additions & 1 deletion lib/versionmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,27 @@ function filterAndReject(filter, reject) {
)
}

/**
* Return a promise which resolves to object storing package owner changed status for each dependency.
*
* @param fromVersion current packages version.
* @param toVersion target packages version.
* @param options
* @returns
*/
async function getOwnerPerDependency(fromVersion, toVersion, options) {
const packageManager = getPackageManager(options.packageManager)
return await Object.keys(toVersion).reduce(async (accum, dep) => {
const from = fromVersion[dep] || null
const to = toVersion[dep] || null
const ownerChanged = await packageManager.packageAuthorChanged(dep, from, to)
return {
...accum,
[dep]: ownerChanged,
}
}, {})
}

/**
* Returns an 2-tuple of upgradedDependencies and their latest versions.
*
Expand Down Expand Up @@ -582,12 +603,13 @@ module.exports = {
isSatisfied,
upgradePackageData,
upgradePackageDefinitions,
getOwnerPerDependency,

// exposed for testing
getPreferredWildcard,
isUpgradeable,
queryVersions,
upgradeDependencies,
upgradeDependencyDeclaration,
getPackageManager
getPackageManager,
}
6 changes: 6 additions & 0 deletions test/package-managers/npm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@ describe('npm', function () {
await packageManagers.npm.greatest('ncu-test-greatest-not-newest', null, { cwd: __dirname })
.should.eventually.equal('2.0.0-beta')
)

it('ownerChanged', async () => {
await packageManagers.npm.packageAuthorChanged('mocha', '^7.1.0', '8.0.1').should.eventually.equal(true)
await packageManagers.npm.packageAuthorChanged('htmlparser2', '^3.10.1', '^4.0.0').should.eventually.equal(false)
await packageManagers.npm.packageAuthorChanged('ncu-test-v2', '^1.0.0', '2.2.0').should.eventually.be.null
})
})