@@ -81,6 +81,8 @@ import {
8181} from '@socketsecurity/build-infra/lib/build-helpers'
8282import { printError , printHeader , printWarning } from '@socketsecurity/build-infra/lib/build-output'
8383import {
84+ analyzePatchContent ,
85+ checkPatchConflicts ,
8486 testPatchApplication ,
8587 validatePatch ,
8688} from '@socketsecurity/build-infra/lib/patch-validator'
@@ -161,7 +163,7 @@ async function copyBuildAdditions() {
161163 logger . log (
162164 `✅ Copied ${ ADDITIONS_DIR . replace ( `${ ROOT_DIR } /` , '' ) } / → ${ NODE_DIR } /` ,
163165 )
164- logger . log ( )
166+ logger . log ( '' )
165167}
166168
167169/**
@@ -194,7 +196,7 @@ async function copySocketSecurityBootstrap() {
194196 logger . log (
195197 ` ${ ( stats . size / 1024 ) . toFixed ( 1 ) } KB (will be brotli encoded with lib/ files)` ,
196198 )
197- logger . log ( )
199+ logger . log ( '' )
198200}
199201
200202const CPU_COUNT = cpus ( ) . length
@@ -237,7 +239,7 @@ async function resetNodeSource() {
237239 await exec ( 'git' , [ 'reset' , '--hard' , NODE_VERSION ] , { cwd : NODE_DIR } )
238240 await exec ( 'git' , [ 'clean' , '-fdx' ] , { cwd : NODE_DIR } )
239241 logger . log ( '✅ Node.js source reset to clean state' )
240- logger . log ( )
242+ logger . log ( '' )
241243}
242244
243245/**
@@ -574,7 +576,7 @@ async function _compressNodeJsWithBrotli() {
574576 }
575577
576578 logger . log ( 'Minifying and compressing JavaScript files...' )
577- logger . log ( )
579+ logger . log ( '' )
578580
579581 const libDir = join ( NODE_DIR , 'lib' )
580582
@@ -653,7 +655,7 @@ async function _compressNodeJsWithBrotli() {
653655 }
654656 }
655657
656- logger . log ( )
658+ logger . log ( '' )
657659 logger . log ( `✅ Processed ${ filesCompressed } files` )
658660 logger . log (
659661 ` Original: ${ ( totalOriginalSize / 1024 / 1024 ) . toFixed ( 2 ) } MB` ,
@@ -667,7 +669,7 @@ async function _compressNodeJsWithBrotli() {
667669 logger . log (
668670 ` Final savings: ${ ( ( totalOriginalSize - totalCompressedSize ) / 1024 / 1024 ) . toFixed ( 2 ) } MB` ,
669671 )
670- logger . log ( )
672+ logger . log ( '' )
671673
672674 // Create decompression bootstrap hook.
673675 await createBrotliBootstrapHook ( )
@@ -787,7 +789,7 @@ async function createBrotliBootstrapHook() {
787789 }
788790
789791 logger . log ( '✅ Brotli bootstrap hook created' )
790- logger . log ( )
792+ logger . log ( '' )
791793}
792794
793795/**
@@ -837,7 +839,7 @@ async function main() {
837839 throw new Error ( 'Invalid Node.js version' )
838840 }
839841 logger . log ( `✅ ${ NODE_VERSION } exists in Node.js repository` )
840- logger . log ( )
842+ logger . log ( '' )
841843
842844 // Clone or reset Node.js repository.
843845 if ( ! existsSync ( NODE_DIR ) || CLEAN_BUILD ) {
@@ -848,24 +850,24 @@ async function main() {
848850 await rm ( NODE_DIR , { recursive : true , force : true } )
849851 await cleanCheckpoint ( BUILD_DIR )
850852 logger . log ( '✅ Cleaned build directory' )
851- logger . log ( )
853+ logger . log ( '' )
852854 }
853855
854856 printHeader ( 'Cloning Node.js Source' )
855857 logger . log ( `Version: ${ NODE_VERSION } ` )
856858 logger . log ( 'Repository: https://github.com/nodejs/node.git' )
857- logger . log ( )
859+ logger . log ( '' )
858860 logger . log ( '⏱️ This will download ~200-300 MB (shallow clone)...' )
859861 logger . log ( 'Retry: Up to 3 attempts if clone fails' )
860- logger . log ( )
862+ logger . log ( '' )
861863
862864 // Git clone with retry (network can fail during long downloads).
863865 let cloneSuccess = false
864866 for ( let attempt = 1 ; attempt <= 3 ; attempt ++ ) {
865867 try {
866868 if ( attempt > 1 ) {
867869 logger . log ( `Retry attempt ${ attempt } /3...` )
868- logger . log ( )
870+ logger . log ( '' )
869871 }
870872
871873 await exec (
@@ -912,15 +914,15 @@ async function main() {
912914 // Wait before retry.
913915 const waitTime = 2000 * attempt
914916 logger . log ( `⏱️ Waiting ${ waitTime } ms before retry...` )
915- logger . log ( )
917+ logger . log ( '' )
916918 await new Promise ( resolve => setTimeout ( resolve , waitTime ) )
917919 }
918920 }
919921
920922 if ( cloneSuccess ) {
921923 logger . log ( '✅ Node.js source cloned successfully' )
922924 await createCheckpoint ( BUILD_DIR , 'cloned' )
923- logger . log ( )
925+ logger . log ( '' )
924926 }
925927 } else {
926928 printHeader ( 'Using Existing Node.js Source' )
@@ -940,12 +942,12 @@ async function main() {
940942
941943 // Wait 5 seconds before proceeding.
942944 await new Promise ( resolve => setTimeout ( resolve , 5000 ) )
943- logger . log ( )
945+ logger . log ( '' )
944946 } else if ( isDirty && AUTO_YES ) {
945947 logger . log (
946948 '⚠️ Node.js source has uncommitted changes (auto-resetting with --yes)' ,
947949 )
948- logger . log ( )
950+ logger . log ( '' )
949951 }
950952
951953 await resetNodeSource ( )
@@ -965,7 +967,7 @@ async function main() {
965967 printHeader ( 'Validating Socket Patches' )
966968 logger . log ( `Found ${ socketPatches . length } patch(es) for ${ NODE_VERSION } ` )
967969 logger . log ( 'Checking integrity, compatibility, and conflicts...' )
968- logger . log ( )
970+ logger . log ( '' )
969971
970972 const patchData = [ ]
971973 let allValid = true
@@ -981,19 +983,28 @@ async function main() {
981983 continue
982984 }
983985
986+ const content = await readFile ( patchPath , 'utf8' )
984987 const metadata = validation . metadata
988+ const analysis = analyzePatchContent ( content )
985989
986990 patchData . push ( {
987991 name : patchFile ,
988992 path : patchPath ,
989993 metadata,
994+ analysis,
990995 } )
991996
992997 if ( metadata ?. description ) {
993998 logger . log ( ` 📝 ${ metadata . description } ` )
994999 }
1000+ if ( analysis . modifiesV8Includes ) {
1001+ logger . log ( ' ⚠️ Modifies V8 includes' )
1002+ }
1003+ if ( analysis . modifiesSEA ) {
1004+ logger . log ( ' ✓ Modifies SEA detection' )
1005+ }
9951006 logger . log ( ' ✅ Valid' )
996- logger . log ( )
1007+ logger . log ( '' )
9971008 }
9981009
9991010 if ( ! allValid ) {
@@ -1011,16 +1022,50 @@ async function main() {
10111022 ' 3. Check build/patches/README.md for patch creation guide' ,
10121023 )
10131024 }
1014- // Note: Advanced patch conflict detection is not yet implemented.
1015- // TODO: Implement analyzePatchContent and checkPatchConflicts in build-infra package.
1016- logger . log ( '✅ All Socket patches validated successfully' )
1017- logger . log ( )
1025+ // Check for conflicts between patches.
1026+ const conflicts = checkPatchConflicts ( patchData , NODE_VERSION )
1027+ if ( conflicts . length > 0 ) {
1028+ logger . warn ( '⚠️ Patch Conflicts Detected:' )
1029+ logger . warn ( )
1030+ for ( const conflict of conflicts ) {
1031+ if ( conflict . severity === 'error' ) {
1032+ logger . error ( ` ❌ ERROR: ${ conflict . message } ` )
1033+ allValid = false
1034+ } else {
1035+ logger . warn ( ` ⚠️ WARNING: ${ conflict . message } ` )
1036+ }
1037+ }
1038+ logger . warn ( )
1039+
1040+ if ( ! allValid ) {
1041+ throw new Error (
1042+ 'Critical patch conflicts detected.\n\n' +
1043+ `Socket patches have conflicts and cannot be applied to Node.js ${ NODE_VERSION } .\n\n` +
1044+ 'Conflicts found:\n' +
1045+ conflicts
1046+ . filter ( c => c . severity === 'error' )
1047+ . map ( c => ` - ${ c . message } ` )
1048+ . join ( '\n' ) +
1049+ '\n\n' +
1050+ 'To fix:\n' +
1051+ ' 1. Remove conflicting patches\n' +
1052+ ` 2. Use version-specific patches for ${ NODE_VERSION } \n` +
1053+ ' 3. Regenerate patches:\n' +
1054+ ` node scripts/regenerate-node-patches.mjs --version=${ NODE_VERSION } \n` +
1055+ ' 4. See build/patches/socket/README.md for guidance' ,
1056+ )
1057+ }
1058+ } else {
1059+ logger . log ( '✅ All Socket patches validated successfully' )
1060+ logger . log ( '✅ No conflicts detected' )
1061+ logger . log ( '' )
1062+ }
10181063
10191064 // Test Socket patches (dry-run) before applying.
10201065 if ( allValid ) {
10211066 printHeader ( 'Testing Socket Patch Application' )
10221067 logger . log ( 'Running dry-run to ensure patches will apply cleanly...' )
1023- logger . log ( )
1068+ logger . log ( '' )
10241069
10251070 for ( const { name, path : patchPath } of patchData ) {
10261071 logger . log ( `Testing ${ name } ...` )
@@ -1035,7 +1080,7 @@ async function main() {
10351080 logger . log ( ' ✅ Will apply cleanly' )
10361081 }
10371082 }
1038- logger . log ( )
1083+ logger . log ( '' )
10391084
10401085 if ( ! allValid ) {
10411086 throw new Error (
@@ -1089,7 +1134,7 @@ async function main() {
10891134 }
10901135 }
10911136 logger . log ( '✅ All Socket patches applied successfully' )
1092- logger . log ( )
1137+ logger . log ( '' )
10931138 }
10941139 } else {
10951140 throw new Error (
@@ -1125,17 +1170,17 @@ async function main() {
11251170 logger . log (
11261171 ' 💾 OPTIMIZATIONS: no-snapshot, no-code-cache, no-object-print, no-SEA, V8 Lite' ,
11271172 )
1128- logger . log ( )
1173+ logger . log ( '' )
11291174 logger . log (
11301175 ' ⚠️ V8 LITE MODE: JavaScript runs 5-10x slower (CPU-bound code)' ,
11311176 )
11321177 logger . log ( ' ✅ WASM: Full speed (uses Liftoff compiler, unaffected)' )
11331178 logger . log ( ' ✅ I/O: No impact (network, file operations)' )
1134- logger . log ( )
1179+ logger . log ( '' )
11351180 logger . log (
11361181 'Expected binary size: ~60MB (before stripping), ~23-27MB (after)' ,
11371182 )
1138- logger . log ( )
1183+ logger . log ( '' )
11391184
11401185 const configureFlags = [
11411186 '--with-intl=none' , // -6-8 MB: No ICU/Intl support (use polyfill instead)
@@ -1164,7 +1209,7 @@ async function main() {
11641209
11651210 await exec ( './configure' , configureFlags , { cwd : NODE_DIR } )
11661211 logger . log ( '✅ Configuration complete' )
1167- logger . log ( )
1212+ logger . log ( '' )
11681213
11691214 // Build Node.js.
11701215 printHeader ( 'Building Node.js' )
@@ -1174,16 +1219,16 @@ async function main() {
11741219 `⏱️ Estimated time: ${ timeEstimate . estimatedMinutes } minutes (${ timeEstimate . minMinutes } -${ timeEstimate . maxMinutes } min range)` ,
11751220 )
11761221 logger . log ( `🚀 Using ${ CPU_COUNT } CPU cores for parallel compilation` )
1177- logger . log ( )
1222+ logger . log ( '' )
11781223 logger . log ( 'You can:' )
11791224 logger . log ( ' • Grab coffee ☕' )
11801225 logger . log ( ' • Work on other tasks' )
11811226 logger . log ( ' • Watch progress in this terminal' )
1182- logger . log ( )
1227+ logger . log ( '' )
11831228 logger . log ( `Build log: ${ getBuildLogPath ( BUILD_DIR ) } ` )
1184- logger . log ( )
1229+ logger . log ( '' )
11851230 logger . log ( 'Starting build...' )
1186- logger . log ( )
1231+ logger . log ( '' )
11871232
11881233 const buildStart = Date . now ( )
11891234
@@ -1218,17 +1263,17 @@ async function main() {
12181263 const buildDuration = Date . now ( ) - buildStart
12191264 const buildTime = formatDuration ( buildDuration )
12201265
1221- logger . log ( )
1266+ logger . log ( '' )
12221267 logger . log ( `✅ Build completed in ${ buildTime } ` )
12231268 await createCheckpoint ( BUILD_DIR , 'built' )
1224- logger . log ( )
1269+ logger . log ( '' )
12251270
12261271 // Test the binary.
12271272 printHeader ( 'Testing Binary' )
12281273 const nodeBinary = join ( NODE_DIR , 'out' , 'Release' , 'node' )
12291274
12301275 logger . log ( 'Running basic functionality tests...' )
1231- logger . log ( )
1276+ logger . log ( '' )
12321277
12331278 await exec ( nodeBinary , [ '--version' ] , {
12341279 env : { ...process . env , PKG_EXECPATH : 'PKG_INVOKE_NODEJS' } ,
@@ -1242,9 +1287,9 @@ async function main() {
12421287 } ,
12431288 )
12441289
1245- logger . log ( )
1290+ logger . log ( '' )
12461291 logger . log ( '✅ Binary is functional' )
1247- logger . log ( )
1292+ logger . log ( '' )
12481293
12491294 // Copy unmodified binary to build/out/Release.
12501295 printHeader ( 'Copying to Build Output (Release)' )
@@ -1267,7 +1312,7 @@ async function main() {
12671312 const sizeBeforeStrip = await getFileSize ( nodeBinary )
12681313 logger . log ( `Size before stripping: ${ sizeBeforeStrip } ` )
12691314 logger . log ( 'Removing debug symbols and unnecessary sections...' )
1270- logger . log ( )
1315+ logger . log ( '' )
12711316 await exec ( 'strip' , [ '--strip-all' , nodeBinary ] )
12721317 const sizeAfterStrip = await getFileSize ( nodeBinary )
12731318 logger . log ( `Size after stripping: ${ sizeAfterStrip } ` )
@@ -1302,7 +1347,7 @@ async function main() {
13021347 }
13031348 }
13041349
1305- logger . log ( )
1350+ logger . log ( '' )
13061351
13071352 // Smoke test binary after stripping (ensure strip didn't corrupt it).
13081353 logger . log ( 'Testing binary after stripping...' )
@@ -1325,7 +1370,7 @@ async function main() {
13251370 }
13261371
13271372 logger . log ( '✅ Binary functional after stripping' )
1328- logger . log ( )
1373+ logger . log ( '' )
13291374
13301375 // Copy stripped binary to build/out/Stripped.
13311376 printHeader ( 'Copying to Build Output (Stripped)' )
@@ -1443,12 +1488,12 @@ async function main() {
14431488 }
14441489
14451490 logger . log ( '✅ Binary installed to pkg cache successfully' )
1446- logger . log ( )
1491+ logger . log ( '' )
14471492
14481493 // Verify the cached binary works.
14491494 printHeader ( 'Verifying Cached Binary' )
14501495 logger . log ( 'Testing that pkg can use the installed binary...' )
1451- logger . log ( )
1496+ logger . log ( '' )
14521497
14531498 const cacheTest = await smokeTestBinary ( targetPath , {
14541499 ...process . env ,
@@ -1471,7 +1516,7 @@ async function main() {
14711516
14721517 logger . log ( '✅ Cached binary passed smoke test' )
14731518 logger . log ( '✅ pkg can use this binary' )
1474- logger . log ( )
1519+ logger . log ( '' )
14751520
14761521 // Copy final binary to build/out/Distribution.
14771522 printHeader ( 'Copying Final Binary to build/out/Distribution' )
0 commit comments