fix(resolve-dependencies): not update git protocol dependency when add unrelated dependency (#7054)

close #7008
This commit is contained in:
await-ovo
2023-09-23 19:11:48 +08:00
committed by GitHub
parent ee328fd25e
commit f394cfccda
14 changed files with 511 additions and 366 deletions

View File

@@ -0,0 +1,9 @@
---
"@pnpm/resolve-dependencies": patch
"@pnpm/core": patch
"@pnpm/lockfile-utils": patch
"@pnpm/pick-fetcher": patch
"pnpm": patch
---
Don't update git-hosted dependencies when adding unrelated dependency [#7008](https://github.com/pnpm/pnpm/issues/7008).

View File

@@ -0,0 +1,6 @@
{
"name":"with-git-protocol-dep",
"dependencies": {
"is-negative": "github:kevva/is-negative#master"
}
}

View File

@@ -0,0 +1,26 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
is-negative:
specifier: github:kevva/is-negative#master
version: github.com/kevva/is-negative/219c424611ff4a2af15f7deeff4f93c62558c43d
packages:
/is-positive@3.1.0:
resolution: {integrity: sha512-8ND1j3y9/HP94TOvGzr69/FgbkX2ruOldhLEsTWwcJVfo4oRjwemJmJxt7RJkKYH8tz7vYBP9JcKQY8CLuJ90Q==}
engines: {node: '>=0.10.0'}
dev: false
github.com/kevva/is-negative/219c424611ff4a2af15f7deeff4f93c62558c43d:
resolution: {tarball: https://codeload.github.com/kevva/is-negative/tar.gz/219c424611ff4a2af15f7deeff4f93c62558c43d}
name: is-negative
version: 2.0.0
engines: {node: '>=0.10.0'}
dependencies:
is-positive: 3.1.0
dev: false

View File

@@ -23,7 +23,7 @@ export function pickFetcher (fetcherByHostingType: Partial<Fetchers>, resolution
return fetch
}
function isGitHostedPkgUrl (url: string) {
export function isGitHostedPkgUrl (url: string) {
return (
url.startsWith('https://codeload.github.com/') ||
url.startsWith('https://bitbucket.org/') ||

View File

@@ -41,6 +41,7 @@
"dependencies": {
"@pnpm/dependency-path": "workspace:*",
"@pnpm/lockfile-types": "workspace:*",
"@pnpm/pick-fetcher": "workspace:*",
"@pnpm/resolver-base": "workspace:*",
"@pnpm/types": "workspace:*",
"get-npm-tarball-url": "^2.0.3",

View File

@@ -4,6 +4,7 @@ import { type Resolution } from '@pnpm/resolver-base'
import { type Registries } from '@pnpm/types'
import * as dp from '@pnpm/dependency-path'
import getNpmTarballUrl from 'get-npm-tarball-url'
import { isGitHostedPkgUrl } from '@pnpm/pick-fetcher'
import { nameVerFromPkgSnapshot } from './nameVerFromPkgSnapshot'
export function pkgSnapshotToResolution (
@@ -13,7 +14,8 @@ export function pkgSnapshotToResolution (
): Resolution {
if (
Boolean((pkgSnapshot.resolution as TarballResolution).type) ||
(pkgSnapshot.resolution as TarballResolution).tarball?.startsWith('file:')
(pkgSnapshot.resolution as TarballResolution).tarball?.startsWith('file:') ||
isGitHostedPkgUrl((pkgSnapshot.resolution as TarballResolution).tarball ?? '')
) {
return pkgSnapshot.resolution as Resolution
}

View File

@@ -9,6 +9,9 @@
"../../__typings__/**/*.d.ts"
],
"references": [
{
"path": "../../fetching/pick-fetcher"
},
{
"path": "../../packages/dependency-path"
},

View File

@@ -6,12 +6,17 @@ import {
addDependenciesToPackage,
install,
} from '@pnpm/core'
import { fixtures } from '@pnpm/test-fixtures'
import { assertProject } from '@pnpm/assert-project'
import rimraf from '@zkochan/rimraf'
import { isCI } from 'ci-info'
import exists from 'path-exists'
import sinon from 'sinon'
import { testDefaults } from '../utils'
const f = fixtures(__dirname)
const withGitProtocolDepFixture = f.find('with-git-protocol-dep')
test('from a github repo', async () => {
const project = prepareEmpty()
@@ -278,3 +283,34 @@ test('re-adding a git repo with a different tag', async () => {
}
)
})
test('should not update when adding unrelated dependency', async () => {
process.chdir(withGitProtocolDepFixture)
fs.rmSync('./node_modules', {
recursive: true,
force: true,
})
let manifest = JSON.parse(fs.readFileSync('./package.json', 'utf8'))
await install(manifest, await testDefaults({ preferFrozenLockfile: false, dir: withGitProtocolDepFixture, lockfileDir: withGitProtocolDepFixture }))
expect(fs.existsSync('./node_modules/.pnpm/github.com+kevva+is-negative@219c424611ff4a2af15f7deeff4f93c62558c43d')).toBe(true)
manifest = await addDependenciesToPackage(manifest, ['is-number'], await testDefaults({ preferFrozenLockfile: false }))
expect(manifest.dependencies).toHaveProperty('is-number')
expect(manifest.dependencies['is-negative']).toBe('github:kevva/is-negative#master')
const project = assertProject(withGitProtocolDepFixture)
await project.has('is-number')
expect(fs.existsSync('./node_modules/.pnpm/github.com+kevva+is-negative@219c424611ff4a2af15f7deeff4f93c62558c43d')).toBe(true)
expect((await project.readLockfile()).dependencies).toEqual({
'is-negative': {
specifier: 'github:kevva/is-negative#master',
version: 'github.com/kevva/is-negative/219c424611ff4a2af15f7deeff4f93c62558c43d',
},
'is-number': {
specifier: '^7.0.0',
version: '7.0.0',
},
})
})

View File

@@ -35,7 +35,7 @@ test("don't override existing spec in package.json on named installation", async
expect(manifest.dependencies).toStrictEqual({
'is-negative': '^1.0.1',
'is-positive': '^2.0.0',
sec: 'github:sindresorhus/sec#main',
sec: 'sindresorhus/sec#main',
})
})

View File

@@ -38,6 +38,7 @@
"@pnpm/manifest-utils": "workspace:*",
"@pnpm/npm-resolver": "workspace:*",
"@pnpm/pick-registry-for-package": "workspace:*",
"@pnpm/pick-fetcher": "workspace:*",
"@pnpm/prune-lockfile": "workspace:*",
"@pnpm/read-package-json": "workspace:*",
"@pnpm/resolver-base": "workspace:*",

View File

@@ -920,6 +920,9 @@ function referenceSatisfiesWantedSpec (
return false
}
const { version } = nameVerFromPkgSnapshot(depPath, pkgSnapshot)
if (!semver.validRange(wantedDep.pref) && Object.values(opts.lockfile.importers).filter(importer => importer.specifiers[wantedDep.alias] === wantedDep.pref).length) {
return true
}
return semver.satisfies(version, wantedDep.pref, true)
}

View File

@@ -7,6 +7,8 @@ import {
} from '@pnpm/manifest-utils'
import versionSelectorType from 'version-selector-type'
import semver from 'semver'
import { isGitHostedPkgUrl } from '@pnpm/pick-fetcher'
import { type TarballResolution } from '@pnpm/resolver-base'
import { type ResolvedDirectDependency } from './resolveDependencyTree'
import { type ImporterToResolve } from '.'
@@ -25,7 +27,16 @@ export async function updateProjectManifest (
.filter((rdd, index) => importer.wantedDependencies[index]?.updateSpec)
.map((rdd, index) => {
const wantedDep = importer.wantedDependencies[index]!
return resolvedDirectDepToSpecObject({ ...rdd, isNew: wantedDep.isNew, specRaw: wantedDep.raw, preserveNonSemverVersionSpec: wantedDep.preserveNonSemverVersionSpec }, importer, {
return resolvedDirectDepToSpecObject({
...rdd,
isNew:
wantedDep.isNew,
specRaw: wantedDep.raw,
preserveNonSemverVersionSpec: wantedDep.preserveNonSemverVersionSpec,
// For git-protocol dependencies that are already installed locally, there is no normalizedPref unless do force resolve,
// so we use pref in wantedDependency here.
normalizedPref: rdd.normalizedPref ?? (isGitHostedPkgUrl((rdd.resolution as TarballResolution).tarball ?? '') ? wantedDep.pref : undefined),
}, importer, {
nodeExecPath: wantedDep.nodeExecPath,
pinnedVersion: wantedDep.pinnedVersion ?? importer.pinnedVersion ?? 'major',
preserveWorkspaceProtocol: opts.preserveWorkspaceProtocol,

View File

@@ -12,6 +12,9 @@
{
"path": "../../config/pick-registry-for-package"
},
{
"path": "../../fetching/pick-fetcher"
},
{
"path": "../../lockfile/lockfile-types"
},

768
pnpm-lock.yaml generated
View File

File diff suppressed because it is too large Load Diff