11import * as fs from 'fs-extra' ;
2+ import * as glob from 'glob-promise' ;
23import * as jsonc from 'jsonc-parser' ;
34import { Shrinkwrap , ShrinkwrapPackage } from './pnpm' ;
45import * as path from 'path' ;
@@ -22,10 +23,30 @@ const peerDependencyVersionPattern = /^\/((?:@(?:[^\/]+)\/)?[^\/]+)\/([^\/]+)\//
2223export class RushContext {
2324 private shrinkwrap ?: Shrinkwrap ;
2425 private shrinkwrapPackages ?: Map < string , ShrinkwrapPackage > ;
25- private packageRepository : string ;
26+ private readonly packageStore : string ;
2627
2728 constructor ( public readonly rushConfig : RushConfiguration ) {
28- this . packageRepository = path . join ( rushConfig . pnpmStoreFolder , '2/registry.npmjs.org' ) ;
29+ this . packageStore = path . join ( rushConfig . pnpmStoreFolder , '2' ) ;
30+ }
31+
32+ private async findPackageInRepository ( name : string , version : string ) : Promise < string > {
33+ // Packages may be pulled from multiple registries, each of which has its own directory in the
34+ // pnpm store. Search for the package name in any of these directories. We use `*.*` to match
35+ // the directory name to avoid searching the `local` directory, which does not represent a
36+ // package registry.
37+ const results = await glob ( `*.*/${ name } /${ version } /package` , {
38+ absolute : true ,
39+ cwd : this . packageStore
40+ } ) ;
41+ if ( results . length === 0 ) {
42+ throw new Error ( `Package '${ name } :${ version } ' not found in package repository.` ) ;
43+ }
44+ else if ( results . length > 1 ) {
45+ throw new Error ( `Multiple copies of package '${ name } :${ version } ' found in package repository.` ) ;
46+ }
47+ else {
48+ return results [ 0 ] ;
49+ }
2950 }
3051
3152 private getRushProjectPath ( name : string ) : string | undefined {
@@ -86,10 +107,7 @@ export class RushContext {
86107 pkg = await this . getShrinkwrapPackage ( name , version ) ;
87108 // Ensure a proper version number. pnpm uses syntax like 3.4.0_glob@7.1.6 for peer dependencies
88109 version = version . split ( '_' ) [ 0 ] ;
89- packagePath = path . join ( this . packageRepository , name , version , 'package' ) ;
90- if ( ! await fs . pathExists ( packagePath ) ) {
91- throw new Error ( `Package '${ name } :${ version } ' not found in package repository.` ) ;
92- }
110+ packagePath = await this . findPackageInRepository ( name , version ) ;
93111 packagePath = await fs . realpath ( packagePath ) ;
94112 config = jsonc . parse ( await fs . readFile ( path . join ( packagePath , 'package.json' ) , 'utf8' ) ) ;
95113 }
0 commit comments