@@ -75,6 +75,8 @@ function parsePackageJSON(packageJSONContent: CorepackPackageJSON, localEnv?: Lo
7575 if ( ! version )
7676 throw new UsageError ( `Providing no version nor ranger for package manager is currently not supported` ) ;
7777
78+ debugUtils . log ( `devEngines defines that ${ packageManager . name } @${ version } is the local package manager` ) ;
79+
7880 const localEnvKey = `COREPACK_DEV_ENGINES_${ packageManager . name . toUpperCase ( ) } ` ;
7981 const localEnvVersion = localEnv ?. [ localEnvKey ] ;
8082 if ( localEnvVersion ) {
@@ -107,26 +109,43 @@ export async function setLocalPackageManager(cwd: string, info: PreparedPackageM
107109 const lookup = await loadSpec ( cwd ) ;
108110
109111 const content = lookup . type !== `NoProject`
110- ? await fs . promises . readFile ( lookup . target , `utf8` )
112+ ? await fs . promises . readFile ( ( lookup as FoundSpecResult ) . envFilePath ?? lookup . target , `utf8` )
111113 : `` ;
112114
113- const { data, indent} = nodeUtils . readPackageJson ( content ) ;
115+ let previousPackageManager : string ;
116+ let newContent : string ;
117+ if ( ( lookup as FoundSpecResult ) . envFilePath ) {
118+ const envKey = `COREPACK_DEV_ENGINES_${ ( lookup as FoundSpecResult ) . spec . name . toUpperCase ( ) } ` ;
119+ const index = content . lastIndexOf ( `\n${ envKey } =` ) + 1 ;
120+
121+ if ( index === 0 && ! content . startsWith ( `${ envKey } =` ) )
122+ throw new Error ( `INTERNAL ASSERTION ERROR: missing expected ${ envKey } in .corepack.env` ) ;
114123
115- const previousPackageManager = data . packageManager ?? `unknown` ;
116- data . packageManager = `${ info . locator . name } @${ info . locator . reference } ` ;
124+ const lineEndIndex = content . indexOf ( `\n` , index ) ;
117125
118- const newContent = nodeUtils . normalizeLineEndings ( content , `${ JSON . stringify ( data , null , indent ) } \n` ) ;
119- await fs . promises . writeFile ( lookup . target , newContent , `utf8` ) ;
126+ previousPackageManager = content . slice ( index , lineEndIndex === - 1 ? undefined : lineEndIndex ) ;
127+ newContent = nodeUtils . normalizeLineEndings ( content , `${ content . slice ( 0 , index ) } \n${ envKey } =${ info . locator . reference } \n${ lineEndIndex === - 1 ? `` : content . slice ( lineEndIndex ) } ` ) ;
128+ } else {
129+ const { data, indent} = nodeUtils . readPackageJson ( content ) ;
130+
131+ previousPackageManager = data . packageManager ?? `unknown` ;
132+ data . packageManager = `${ info . locator . name } @${ info . locator . reference } ` ;
133+
134+ newContent = nodeUtils . normalizeLineEndings ( content , `${ JSON . stringify ( data , null , indent ) } \n` ) ;
135+ }
136+
137+ await fs . promises . writeFile ( ( lookup as FoundSpecResult ) . envFilePath ?? lookup . target , newContent , `utf8` ) ;
120138
121139 return {
122140 previousPackageManager,
123141 } ;
124142}
125143
144+ type FoundSpecResult = { type : `Found`, target : string , spec : Descriptor , envFilePath ?: string } ;
126145export type LoadSpecResult =
127146 | { type : `NoProject`, target : string }
128147 | { type : `NoSpec`, target : string }
129- | { type : `Found` , target : string , spec : Descriptor } ;
148+ | FoundSpecResult ;
130149
131150export async function loadSpec ( initialCwd : string ) : Promise < LoadSpecResult > {
132151 let nextCwd = initialCwd ;
@@ -135,6 +154,7 @@ export async function loadSpec(initialCwd: string): Promise<LoadSpecResult> {
135154 let selection : {
136155 data : any ;
137156 manifestPath : string ;
157+ envFilePath ?: string ;
138158 localEnv ?: LocalEnvFile ;
139159 } | null = null ;
140160
@@ -175,7 +195,7 @@ export async function loadSpec(initialCwd: string): Promise<LoadSpecResult> {
175195 localEnv = process . env ;
176196 }
177197
178- selection = { data, manifestPath, localEnv} ;
198+ selection = { data, manifestPath, localEnv, envFilePath } ;
179199 }
180200
181201 if ( selection === null )
@@ -185,9 +205,12 @@ export async function loadSpec(initialCwd: string): Promise<LoadSpecResult> {
185205 if ( typeof rawPmSpec === `undefined` )
186206 return { type : `NoSpec` , target : selection . manifestPath } ;
187207
208+ debugUtils . log ( `${ selection . manifestPath } defines ${ rawPmSpec } as local package manager` ) ;
209+
188210 return {
189211 type : `Found` ,
190212 target : selection . manifestPath ,
213+ envFilePath : selection . localEnv !== process . env ? selection . envFilePath : undefined ,
191214 spec : parseSpec ( rawPmSpec , path . relative ( initialCwd , selection . manifestPath ) ) ,
192215 } ;
193216}
0 commit comments