Skip to content

Commit

Permalink
feat: lockfile v6
Browse files Browse the repository at this point in the history
  • Loading branch information
zkochan committed Jan 6, 2023
1 parent 044cfe5 commit 3c6620a
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 10 deletions.
1 change: 1 addition & 0 deletions config/config/src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export interface Config {
registrySupportsTimeField?: boolean
failedToLoadBuiltInConfig: boolean
resolvePeersFromWorkspaceRoot?: boolean
useLockfileV6?: boolean

// proxy
httpProxy?: string
Expand Down
1 change: 1 addition & 0 deletions config/config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export const types = Object.assign({
'strict-peer-dependencies': Boolean,
'use-beta-cli': Boolean,
'use-inline-specifiers-lockfile-format': Boolean,
'use-lockfile-v6': Boolean,
'use-node-version': String,
'use-running-store-server': Boolean,
'use-store-server': Boolean,
Expand Down
32 changes: 25 additions & 7 deletions packages/dependency-path/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export function tryGetPackageId (registries: Registries, relDepPath: string) {
if (relDepPath[0] !== '/') {
return null
}
const sepIndex = relDepPath.indexOf('(', relDepPath.lastIndexOf('/'))
if (sepIndex !== -1) {
return resolve(registries, relDepPath.slice(0, sepIndex))
}
const underscoreIndex = relDepPath.indexOf('_', relDepPath.lastIndexOf('/'))
if (underscoreIndex !== -1) {
return resolve(registries, relDepPath.slice(0, underscoreIndex))
Expand All @@ -45,7 +49,7 @@ export function refToAbsolute (
if (reference.startsWith('link:')) {
return null
}
if (!reference.includes('/')) {
if (!reference.includes('/') || !reference.replace(/(\([^)]+\))+$/, '').includes('/')) {
const registryName = encodeRegistry(getRegistryByPackageName(registries, pkgName))
return `${registryName}/${pkgName}/${reference}`
}
Expand Down Expand Up @@ -83,7 +87,7 @@ export function refToRelative (
if (reference.startsWith('file:')) {
return reference
}
if (!reference.includes('/')) {
if (!reference.includes('/') || !reference.replace(/(\([^)]+\))+$/, '').includes('/')) {
return `/${pkgName}/${reference}`
}
return reference
Expand All @@ -104,13 +108,22 @@ export function parse (dependencyPath: string) {
const name = parts[0].startsWith('@')
? `${parts.shift()}/${parts.shift()}` // eslint-disable-line @typescript-eslint/restrict-template-expressions
: parts.shift()
let version = parts.shift()
let version = parts.join('/')
if (version) {
const underscoreIndex = version.indexOf('_')
let peerSepIndex!: number
let peersSuffix: string | undefined
if (underscoreIndex !== -1) {
peersSuffix = version.substring(underscoreIndex + 1)
version = version.substring(0, underscoreIndex)
if (version.includes('(') && version.endsWith(')')) {
peerSepIndex = version.indexOf('(')
if (peerSepIndex !== -1) {
peersSuffix = version.substring(peerSepIndex)
version = version.substring(0, peerSepIndex)
}
} else {
peerSepIndex = version.indexOf('_')
if (peerSepIndex !== -1) {
peersSuffix = version.substring(peerSepIndex + 1)
version = version.substring(0, peerSepIndex)
}
}
if (semver.valid(version)) {
return {
Expand Down Expand Up @@ -148,6 +161,11 @@ function depPathToFilenameUnescaped (depPath: string) {
return depPath.replace(':', '+')
}

export function createPeersFolderSuffixNewFormat (peers: Array<{ name: string, version: string }>): string {
const folderName = peers.map(({ name, version }) => `${name}@${version}`).sort().join(')(')
return `(${folderName})`
}

export function createPeersFolderSuffix (peers: Array<{ name: string, version: string }>): string {
const folderName = peers.map(({ name, version }) => `${name.replace('/', '+')}@${version}`).sort().join('+')

Expand Down
17 changes: 17 additions & 0 deletions packages/dependency-path/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,22 @@ test('parse()', () => {
version: '1.0.0',
})

expect(parse('example.com/foo/1.0.0(bar@2.0.0)')).toStrictEqual({
host: 'example.com',
isAbsolute: true,
name: 'foo',
peersSuffix: '(bar@2.0.0)',
version: '1.0.0',
})

expect(parse('/foo/1.0.0(@types/babel__core@7.1.14)(foo@1.0.0)')).toStrictEqual({
host: undefined,
isAbsolute: false,
name: 'foo',
peersSuffix: '(@types/babel__core@7.1.14)(foo@1.0.0)',
version: '1.0.0',
})

expect(() => parse('/foo/bar')).toThrow(/\/foo\/bar is an invalid relative dependency path/)
})

Expand Down Expand Up @@ -143,4 +159,5 @@ test('depPathToFilename()', () => {

test('tryGetPackageId', () => {
expect(tryGetPackageId({ default: 'https://registry.npmjs.org/' }, '/foo/1.0.0_@types+babel__core@7.1.14')).toEqual('registry.npmjs.org/foo/1.0.0')
expect(tryGetPackageId({ default: 'https://registry.npmjs.org/' }, '/foo/1.0.0(@types+babel__core@7.1.14)')).toEqual('registry.npmjs.org/foo/1.0.0')
})
2 changes: 2 additions & 0 deletions pkg-manager/core/src/install/extendInstallOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export interface StrictInstallOptions {
allProjects: ProjectOptions[]
resolveSymlinksInInjectedDirs: boolean
dedupeDirectDeps: boolean
useLockfileV6: boolean
}

export type InstallOptions =
Expand Down Expand Up @@ -206,6 +207,7 @@ const defaults = async (opts: InstallOptions) => {
resolveSymlinksInInjectedDirs: false,
dedupeDirectDeps: false,
resolvePeersFromWorkspaceRoot: false,
useLockfileV6: false,
} as StrictInstallOptions
}

Expand Down
1 change: 1 addition & 0 deletions pkg-manager/core/src/install/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
patchedDependencies: opts.patchedDependencies,
lockfileIncludeTarballUrl: opts.lockfileIncludeTarballUrl,
resolvePeersFromWorkspaceRoot: opts.resolvePeersFromWorkspaceRoot,
useLockfileV6: opts.useLockfileV6,
}
)
if (!opts.include.optionalDependencies || !opts.include.devDependencies || !opts.include.dependencies) {
Expand Down
2 changes: 1 addition & 1 deletion pkg-manager/resolve-dependencies/src/depPathToRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function depPathToRef (
}
if (depPath[0] === '/' && opts.alias === opts.realName) {
const ref = depPath.replace(`/${opts.realName}/`, '')
if (!ref.includes('/')) return ref
if (!ref.includes('/') || !ref.replace(/(\([^)]+\))+$/, '').includes('/')) return ref
}
return depPath
}
1 change: 1 addition & 0 deletions pkg-manager/resolve-dependencies/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export async function resolveDependencies (
projects: projectsToLink,
virtualStoreDir: opts.virtualStoreDir,
resolvePeersFromWorkspaceRoot: Boolean(opts.resolvePeersFromWorkspaceRoot),
useLockfileV6: Boolean(opts.useLockfileV6),
})

for (const { id, manifest } of projectsToLink) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export interface ResolveDependenciesOptions {
virtualStoreDir: string
wantedLockfile: Lockfile
workspacePackages: WorkspacePackages
useLockfileV6?: boolean
}

export async function resolveDependencyTree<T> (
Expand Down
8 changes: 6 additions & 2 deletions pkg-manager/resolve-dependencies/src/resolvePeers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
PeerDependencyIssues,
PeerDependencyIssuesByProjects,
} from '@pnpm/types'
import { depPathToFilename, createPeersFolderSuffix } from '@pnpm/dependency-path'
import { depPathToFilename, createPeersFolderSuffix, createPeersFolderSuffixNewFormat } from '@pnpm/dependency-path'
import { KeyValuePair } from 'ramda'
import isEmpty from 'ramda/src/isEmpty'
import mapValues from 'ramda/src/map'
Expand Down Expand Up @@ -62,6 +62,7 @@ export function resolvePeers<T extends PartialResolvedPackage> (
virtualStoreDir: string
lockfileDir: string
resolvePeersFromWorkspaceRoot?: boolean
useLockfileV6: boolean
}
): {
dependenciesGraph: GenericDependenciesGraph<T>
Expand Down Expand Up @@ -91,6 +92,7 @@ export function resolvePeers<T extends PartialResolvedPackage> (
purePkgs: new Set(),
rootDir,
virtualStoreDir: opts.virtualStoreDir,
useLockfileV6: opts.useLockfileV6,
})
if (!isEmpty(peerDependencyIssues.bad) || !isEmpty(peerDependencyIssues.missing)) {
peerDependencyIssuesByProjects[id] = {
Expand Down Expand Up @@ -176,6 +178,7 @@ function resolvePeersOfNode<T extends PartialResolvedPackage> (
purePkgs: Set<string> // pure packages are those that don't rely on externally resolved peers
rootDir: string
lockfileDir: string
useLockfileV6: boolean
}
): PeersResolution {
const node = ctx.dependenciesTree[nodeId]
Expand Down Expand Up @@ -256,7 +259,7 @@ function resolvePeersOfNode<T extends PartialResolvedPackage> (
if (isEmpty(allResolvedPeers)) {
depPath = resolvedPackage.depPath
} else {
const peersFolderSuffix = createPeersFolderSuffix(
const peersFolderSuffix = (ctx.useLockfileV6 ? createPeersFolderSuffixNewFormat : createPeersFolderSuffix)(
Object.entries(allResolvedPeers)
.map(([alias, nodeId]) => {
if (nodeId.startsWith('link:')) {
Expand Down Expand Up @@ -372,6 +375,7 @@ function resolvePeersOfChildren<T extends PartialResolvedPackage> (
dependenciesTree: DependenciesTree<T>
rootDir: string
lockfileDir: string
useLockfileV6: boolean
}
): PeersResolution {
const allResolvedPeers: Record<string, string> = {}
Expand Down

0 comments on commit 3c6620a

Please sign in to comment.