1+ import { spawnSync } from 'node:child_process' ;
12import { randomUUID } from 'node:crypto' ;
23import fs , { readFileSync } from 'node:fs' ;
34import fsPromises from 'node:fs/promises' ;
@@ -91,6 +92,48 @@ function selectShard<T>(items: T[], index: number, total: number): T[] {
9192}
9293
9394const NPM_GLOBAL_PREFIX_DIR = 'npm-global-lib-for-snap-tests' ;
95+ const vpBinaryName = process . platform === 'win32' ? 'vp.exe' : 'vp' ;
96+
97+ function setupLocalGlobalShims ( vitePlusHome : string , sourceBinDir : string ) : string {
98+ const resolvedSourceBinDir = path . resolve ( expandHome ( sourceBinDir ) ) ;
99+ const sourceVpPath = path . join ( resolvedSourceBinDir , vpBinaryName ) ;
100+ if ( ! fs . existsSync ( sourceVpPath ) ) {
101+ throw new Error ( `Missing local vp binary for snap tests: ${ sourceVpPath } ` ) ;
102+ }
103+
104+ const currentBinDir = path . join ( vitePlusHome , 'current' , 'bin' ) ;
105+ fs . mkdirSync ( currentBinDir , { recursive : true } ) ;
106+
107+ const localVpPath = path . join ( currentBinDir , vpBinaryName ) ;
108+ if ( process . platform === 'win32' ) {
109+ fs . copyFileSync ( sourceVpPath , localVpPath ) ;
110+
111+ const sourceShimPath = path . join ( resolvedSourceBinDir , 'vp-shim.exe' ) ;
112+ if ( ! fs . existsSync ( sourceShimPath ) ) {
113+ throw new Error ( `Missing local vp trampoline for snap tests: ${ sourceShimPath } ` ) ;
114+ }
115+ fs . copyFileSync ( sourceShimPath , path . join ( currentBinDir , 'vp-shim.exe' ) ) ;
116+ } else {
117+ fs . symlinkSync ( sourceVpPath , localVpPath ) ;
118+ }
119+
120+ const result = spawnSync ( localVpPath , [ 'env' , 'setup' , '--refresh' ] , {
121+ env : {
122+ ...process . env ,
123+ VP_HOME : vitePlusHome ,
124+ } ,
125+ encoding : 'utf-8' ,
126+ } ) ;
127+
128+ if ( ! result . error && result . status === 0 ) {
129+ return path . join ( vitePlusHome , 'bin' ) ;
130+ }
131+
132+ const output = [ result . stdout , result . stderr ] . filter ( Boolean ) . join ( '\n' ) . trim ( ) ;
133+ throw new Error (
134+ `Failed to prepare local global shims for snap tests.${ output ? `\n${ output } ` : '' } ` ,
135+ ) ;
136+ }
94137
95138export async function snapTest ( ) {
96139 const { positionals, values } = parseArgs ( {
@@ -99,6 +142,7 @@ export async function snapTest() {
99142 options : {
100143 dir : { type : 'string' } ,
101144 'bin-dir' : { type : 'string' } ,
145+ 'local-vp-bin-dir' : { type : 'string' } ,
102146 shard : { type : 'string' } ,
103147 } ,
104148 } ) ;
@@ -129,6 +173,9 @@ export async function snapTest() {
129173
130174 const vitePlusHome = path . join ( tempTmpDir , 'vite-plus-home' ) ;
131175 fs . mkdirSync ( vitePlusHome , { recursive : true } ) ;
176+ const effectiveBinDir = values [ 'local-vp-bin-dir' ]
177+ ? setupLocalGlobalShims ( vitePlusHome , values [ 'local-vp-bin-dir' ] )
178+ : values [ 'bin-dir' ] ;
132179
133180 // Remove .previous-version so command-upgrade-rollback snap test is stable
134181 const previousVersionPath = path . join ( vitePlusHome , '.previous-version' ) ;
@@ -210,8 +257,7 @@ export async function snapTest() {
210257 for ( const caseName of selectedCases ) {
211258 const stepsPath = path . join ( casesDir , caseName , 'steps.json' ) ;
212259 const steps : Steps = JSON . parse ( readFileSync ( stepsPath , 'utf-8' ) ) ;
213- const task = ( ) =>
214- runTestCase ( caseName , tempTmpDir , casesDir , vitePlusHome , values [ 'bin-dir' ] ) ;
260+ const task = ( ) => runTestCase ( caseName , tempTmpDir , casesDir , vitePlusHome , effectiveBinDir ) ;
215261 if ( steps . serial ) {
216262 serialTasks . push ( task ) ;
217263 } else {
0 commit comments