@@ -129,4 +129,46 @@ describe('BaseInstallManager Test', () => {
129129 ) ;
130130 }
131131 } ) ;
132+
133+ it ( 'usePnpmPreferFrozenLockfileForRushUpdate should not add --prefer-frozen-lockfile when onlyShrinkwrap is true' , ( ) => {
134+ const rushJsonFile : string = path . resolve ( __dirname , 'ignoreCompatibilityDb/rush3.json' ) ;
135+ const rushConfiguration : RushConfiguration = RushConfiguration . loadFromConfigurationFile ( rushJsonFile ) ;
136+ const purgeManager : typeof PurgeManager . prototype = new PurgeManager ( rushConfiguration , rushGlobalFolder ) ;
137+
138+ // Enable the usePnpmPreferFrozenLockfileForRushUpdate experiment
139+ Object . defineProperty ( rushConfiguration . experimentsConfiguration , 'configuration' , {
140+ value : { usePnpmPreferFrozenLockfileForRushUpdate : true } ,
141+ writable : false ,
142+ configurable : true
143+ } ) ;
144+
145+ const fakeBaseInstallManager : FakeBaseInstallManager = new FakeBaseInstallManager (
146+ rushConfiguration ,
147+ rushGlobalFolder ,
148+ purgeManager ,
149+ { subspace : rushConfiguration . defaultSubspace } as IInstallManagerOptions
150+ ) ;
151+
152+ // When onlyShrinkwrap is true (Phase 1 of two-phase install), --prefer-frozen-lockfile must NOT be added.
153+ // pnpm v10 omits packages:/snapshots: sections when --prefer-frozen-lockfile and --lockfile-only are
154+ // combined, producing a broken lockfile that fails the subsequent --frozen-lockfile install phase.
155+ const argsWithOnlyShrinkwrap : string [ ] = [ ] ;
156+ fakeBaseInstallManager . pushConfigurationArgs (
157+ argsWithOnlyShrinkwrap ,
158+ { onlyShrinkwrap : true , pnpmFilterArgumentValues : [ ] } as unknown as IInstallManagerOptions ,
159+ rushConfiguration . defaultSubspace
160+ ) ;
161+ expect ( argsWithOnlyShrinkwrap ) . not . toContain ( '--prefer-frozen-lockfile' ) ;
162+ expect ( argsWithOnlyShrinkwrap ) . toContain ( '--lockfile-only' ) ;
163+
164+ // When onlyShrinkwrap is false (single-phase or Phase 2), --prefer-frozen-lockfile should be added.
165+ const argsWithoutOnlyShrinkwrap : string [ ] = [ ] ;
166+ fakeBaseInstallManager . pushConfigurationArgs (
167+ argsWithoutOnlyShrinkwrap ,
168+ { onlyShrinkwrap : false , pnpmFilterArgumentValues : [ ] } as unknown as IInstallManagerOptions ,
169+ rushConfiguration . defaultSubspace
170+ ) ;
171+ expect ( argsWithoutOnlyShrinkwrap ) . toContain ( '--prefer-frozen-lockfile' ) ;
172+ expect ( argsWithoutOnlyShrinkwrap ) . not . toContain ( '--lockfile-only' ) ;
173+ } ) ;
132174} ) ;
0 commit comments