33import fs from "node:fs" ;
44import os from "node:os" ;
55import path from "node:path" ;
6- import { execFileSync , spawnSync } from "node:child_process" ;
6+ import { spawnSync } from "node:child_process" ;
77
88const ROOT = process . cwd ( ) ;
99const DEFAULT_REMOTE = "https://github.com/vanityurls/code.git" ;
1010const DEFAULT_REF = "main" ;
1111const DEFAULT_PATHS = [ "defaults" , "scripts" , "package.json" , "package-lock.json" , "LICENSE" ] ;
1212const PROTECTED_PATHS = [ "custom" , "wrangler.toml" , ".dev.vars" , "README.md" ] ;
13+ const GENERATED_PATHS = [ "build" , "functions" , "src" ] ;
1314
1415function parseArgs ( argv ) {
1516 const args = {
@@ -95,7 +96,7 @@ Options:
9596 --paths <a,b> Product-owned paths to replace. Default: ${ DEFAULT_PATHS . join ( "," ) }
9697 --path <path> Add one product-owned path to replace
9798 --dry-run Show what would happen without changing files
98- --no-check Skip npm run check after syncing
99+ --no-check Skip upgrade verification after syncing
99100 --no-clean Skip npm run clean before syncing
100101 --allow-dirty Allow a dirty worktree before upgrade
101102` ) ;
@@ -113,13 +114,18 @@ function run(command, args, options = {}) {
113114 } ) ;
114115
115116 if ( result . status !== 0 ) {
116- const stderr = result . stderr ? `\n${ result . stderr . trim ( ) } ` : "" ;
117- throw new Error ( `${ command } ${ args . join ( " " ) } failed${ stderr } ` ) ;
117+ throw commandError ( command , args , result ) ;
118118 }
119119
120120 return result . stdout || "" ;
121121}
122122
123+ function commandError ( command , args , result ) {
124+ const stdout = result . stdout ? `\nstdout:\n${ result . stdout . trim ( ) } ` : "" ;
125+ const stderr = result . stderr ? `\nstderr:\n${ result . stderr . trim ( ) } ` : "" ;
126+ return new Error ( `${ command } ${ args . join ( " " ) } failed${ stdout } ${ stderr } ` ) ;
127+ }
128+
123129function git ( args , options ) {
124130 return run ( "git" , args , options ) ;
125131}
@@ -162,21 +168,52 @@ function resolveSource(args) {
162168 return "HEAD" ;
163169 }
164170
165- git ( [ "fetch" , "--depth=1" , remote , args . ref ] ) ;
171+ console . log ( `[fetch] ${ remoteLabel ( remote ) } ${ args . ref } ` ) ;
172+ git ( [ "fetch" , "--depth=1" , remote , args . ref ] , { capture : true } ) ;
166173 return "FETCH_HEAD" ;
167174}
168175
169176function clean ( args ) {
170177 if ( ! args . clean ) return ;
171178 if ( args . dryRun ) {
172- console . log ( " [dry-run] would run npm run clean" ) ;
179+ console . log ( ` [dry-run] would remove ${ GENERATED_PATHS . map ( ( entry ) => ` ${ entry } /` ) . join ( ", " ) } ` ) ;
173180 return ;
174181 }
175182
176- execFileSync ( "npm" , [ "run" , "clean" ] , {
183+ for ( const relativePath of GENERATED_PATHS ) {
184+ fs . rmSync ( path . join ( ROOT , relativePath ) , {
185+ recursive : true ,
186+ force : true
187+ } ) ;
188+ }
189+ console . log ( `[clean] Removed ${ GENERATED_PATHS . map ( ( entry ) => `${ entry } /` ) . join ( ", " ) } ` ) ;
190+ }
191+
192+ function remoteLabel ( remote ) {
193+ const cleanRemote = String ( remote || "" ) . replace ( / \. g i t $ / i, "" ) ;
194+ const githubHttps = cleanRemote . match ( / ^ h t t p s ? : \/ \/ g i t h u b \. c o m \/ ( .+ ) $ / i) ;
195+ if ( githubHttps ) return `github.com/${ githubHttps [ 1 ] } ` ;
196+ const githubSsh = cleanRemote . match ( / ^ g i t @ g i t h u b \. c o m : ( .+ ) $ / i) ;
197+ if ( githubSsh ) return `github.com/${ githubSsh [ 1 ] } ` ;
198+ return remote ;
199+ }
200+
201+ function runQuiet ( command , args ) {
202+ const result = spawnSync ( command , args , {
177203 cwd : ROOT ,
178- stdio : "inherit"
204+ encoding : "utf8" ,
205+ env : {
206+ ...process . env ,
207+ LC_ALL : "C"
208+ } ,
209+ stdio : "pipe"
179210 } ) ;
211+
212+ if ( result . status !== 0 ) {
213+ throw commandError ( command , args , result ) ;
214+ }
215+
216+ return result . stdout || "" ;
180217}
181218
182219function extractSource ( source , paths ) {
@@ -228,28 +265,29 @@ function syncPaths(args, source) {
228265function runCheck ( args ) {
229266 if ( ! args . check ) return ;
230267 if ( args . dryRun ) {
231- console . log ( "[dry-run] would run npm run check " ) ;
268+ console . log ( "[dry-run] would run upgrade verification " ) ;
232269 return ;
233270 }
234271
235- execFileSync ( "npm" , [ "run" , "check" ] , {
236- cwd : ROOT ,
237- stdio : "inherit"
238- } ) ;
272+ const buildOutput = runQuiet ( "npm" , [ "run" , "build" ] , "build" ) ;
273+ const linkCount = buildOutput . match ( / W r o t e b u i l d \/ v 8 s \. j s o n w i t h ( \d + ) l i n k s / ) ?. [ 1 ] || "unknown" ;
274+ console . log ( `[build] Built v8s-blocklist.json and v8s.json with ${ linkCount } links` ) ;
275+
276+ runQuiet ( process . execPath , [ "scripts/registry.test.mjs" ] , "registry tests" ) ;
277+ console . log ( "[test] registry tests ok" ) ;
278+ runQuiet ( process . execPath , [ "scripts/install.test.mjs" ] , "install tests" ) ;
279+ console . log ( "[test] install tests ok" ) ;
280+ runQuiet ( process . execPath , [ "scripts/maintenance.test.mjs" ] , "maintenance tests" ) ;
281+ console . log ( "[test] maintenance tests ok" ) ;
239282}
240283
241284function printSummary ( args , source , result ) {
242- console . log ( "\nUpgrade summary" ) ;
243- console . log ( `Source: ${ source } ` ) ;
244- console . log ( `Synced: ${ result . synced . length ? result . synced . join ( ", " ) : "none" } ` ) ;
245- if ( result . missing . length ) console . log ( `Missing upstream paths: ${ result . missing . join ( ", " ) } ` ) ;
285+ console . log ( `Summary: Synced ${ result . synced . length ? result . synced . join ( ", " ) : "none" } ` ) ;
286+ if ( result . missing . length ) console . log ( `Summary: Missing upstream paths: ${ result . missing . join ( ", " ) } ` ) ;
246287
247288 if ( ! args . dryRun ) {
248289 const status = worktreeStatus ( ) ;
249- console . log ( "\nReview with:" ) ;
250- console . log ( " git status --short" ) ;
251- console . log ( " git diff" ) ;
252- if ( status ) console . log ( "\nCommit after review and successful checks." ) ;
290+ if ( status ) console . log ( "Review with git status --short and git diff, then commit and push." ) ;
253291 }
254292}
255293
@@ -262,6 +300,10 @@ async function main() {
262300
263301 const source = resolveSource ( args ) ;
264302 const result = syncPaths ( args , source ) ;
303+ if ( ! args . dryRun ) {
304+ console . log ( `[sync] Synced ${ result . synced . length ? result . synced . join ( ", " ) : "none" } ` ) ;
305+ if ( result . missing . length ) console . log ( `[sync] Missing upstream paths: ${ result . missing . join ( ", " ) } ` ) ;
306+ }
265307
266308 runCheck ( args ) ;
267309 printSummary ( args , source , result ) ;
0 commit comments