@@ -6,6 +6,8 @@ import * as fs from 'node:fs'
6
6
import * as path from 'node:path'
7
7
import process from 'node:process'
8
8
import { config } from './config'
9
+ import { createShims } from './install-helpers'
10
+ import { logUniqueMessage } from './logging'
9
11
10
12
export interface BinaryInfo {
11
13
filename : string
@@ -509,17 +511,51 @@ Thanks for helping us make Launchpad better! 🙏
509
511
const progressPercent = Math . floor ( progress / 5 ) * 5 // Round to nearest 5%
510
512
511
513
if ( now - lastProgressUpdate > 100 || progress >= 100 || downloadedBytes === value . length ) {
512
- if ( config . verbose ) {
513
- const progressMsg = `⬇️ ${ downloadedBytes } /${ totalBytes } bytes (${ progressPercent } %) - PHP ${ binary . php_version } `
514
+ const progressMsg = config . verbose
515
+ ? `⬇️ ${ downloadedBytes } /${ totalBytes } bytes (${ progressPercent } %) - php.net v${ binary . php_version } `
516
+ : `⬇️ ${ downloadedBytes } /${ totalBytes } bytes (${ progressPercent } %)`
517
+
518
+ if ( process . env . LAUNCHPAD_SHELL_INTEGRATION === '1' ) {
519
+ process . stderr . write ( `\r${ progressMsg } ` )
520
+ if ( process . stderr . isTTY ) {
521
+ try {
522
+ fs . writeSync ( process . stderr . fd , '' )
523
+ }
524
+ catch { /* ignore */ }
525
+ }
526
+ }
527
+ else {
514
528
process . stdout . write ( `\r${ progressMsg } ` )
529
+ if ( process . stdout . isTTY ) {
530
+ try {
531
+ fs . writeSync ( process . stdout . fd , '' )
532
+ }
533
+ catch { /* ignore */ }
534
+ }
515
535
}
516
536
lastProgressUpdate = now
517
537
}
518
538
}
519
539
}
520
540
521
- if ( config . verbose ) {
522
- process . stdout . write ( '\r\x1B[K' ) // Clear the progress line
541
+ // Clear the progress line
542
+ if ( process . env . LAUNCHPAD_SHELL_INTEGRATION === '1' ) {
543
+ process . stderr . write ( '\r\x1B[K' )
544
+ if ( process . stderr . isTTY ) {
545
+ try {
546
+ fs . writeSync ( process . stderr . fd , '' )
547
+ }
548
+ catch { /* ignore */ }
549
+ }
550
+ }
551
+ else {
552
+ process . stdout . write ( '\r\x1B[K' )
553
+ if ( process . stdout . isTTY ) {
554
+ try {
555
+ fs . writeSync ( process . stdout . fd , '' )
556
+ }
557
+ catch { /* ignore */ }
558
+ }
523
559
}
524
560
525
561
// Combine all chunks
@@ -534,9 +570,52 @@ Thanks for helping us make Launchpad better! 🙏
534
570
await fs . promises . writeFile ( cachedPath , buffer )
535
571
}
536
572
else {
537
- // Fallback for unknown content length
573
+ // Fallback for unknown content length - show simple download indicator
574
+ const downloadMsg = config . verbose
575
+ ? `⬇️ Downloading php.net v${ binary . php_version } (size unknown)...`
576
+ : `⬇️ Downloading php.net v${ binary . php_version } ...`
577
+
578
+ if ( process . env . LAUNCHPAD_SHELL_INTEGRATION === '1' ) {
579
+ process . stderr . write ( `\r${ downloadMsg } ` )
580
+ if ( process . stderr . isTTY ) {
581
+ try {
582
+ fs . writeSync ( process . stderr . fd , '' )
583
+ }
584
+ catch { /* ignore */ }
585
+ }
586
+ }
587
+ else {
588
+ process . stdout . write ( `\r${ downloadMsg } ` )
589
+ if ( process . stdout . isTTY ) {
590
+ try {
591
+ fs . writeSync ( process . stdout . fd , '' )
592
+ }
593
+ catch { /* ignore */ }
594
+ }
595
+ }
596
+
538
597
const buffer = await response . arrayBuffer ( )
539
598
await fs . promises . writeFile ( cachedPath , Buffer . from ( buffer ) )
599
+
600
+ // Clear the download message
601
+ if ( process . env . LAUNCHPAD_SHELL_INTEGRATION === '1' ) {
602
+ process . stderr . write ( '\r\x1B[K' )
603
+ if ( process . stderr . isTTY ) {
604
+ try {
605
+ fs . writeSync ( process . stderr . fd , '' )
606
+ }
607
+ catch { /* ignore */ }
608
+ }
609
+ }
610
+ else {
611
+ process . stdout . write ( '\r\x1B[K' )
612
+ if ( process . stdout . isTTY ) {
613
+ try {
614
+ fs . writeSync ( process . stdout . fd , '' )
615
+ }
616
+ catch { /* ignore */ }
617
+ }
618
+ }
540
619
}
541
620
542
621
if ( config . verbose ) {
@@ -1027,15 +1106,26 @@ export async function downloadPhpBinary(installPath: string, requestedVersion?:
1027
1106
throw new Error ( `Failed to install PHP binary: ${ result . error } ` )
1028
1107
}
1029
1108
1030
- // Show clean success message (non-verbose) or detailed info (verbose)
1031
- if ( config . verbose ) {
1032
- console . log ( `🎉 PHP ${ result . version } (${ result . configuration } ) installed successfully!` )
1033
- console . log ( `📁 Location: ${ result . packageDir } ` )
1034
- console . log ( `🔌 Extensions: ${ result . extensions . length } loaded` )
1109
+ // Create shims in installPath/bin and sbin so php is available on PATH
1110
+ try {
1111
+ const installedBinaries = await createShims ( result . packageDir , installPath , 'php.net' , result . version )
1112
+ // Optionally report number of binaries installed in verbose
1113
+ if ( config . verbose ) {
1114
+ console . log ( `🎉 Successfully installed php.net (${ installedBinaries . length } ${ installedBinaries . length === 1 ? 'binary' : 'binaries' } )` )
1115
+ console . log ( `📁 Location: ${ result . packageDir } ` )
1116
+ console . log ( `🔌 Extensions: ${ result . extensions . length } loaded` )
1117
+ }
1035
1118
}
1036
- else {
1037
- console . log ( `✅ php.net (v${ result . version } )` )
1119
+ catch ( error ) {
1120
+ // Don't fail installation if shim creation has issues, but report in verbose
1121
+ if ( config . verbose ) {
1122
+ console . warn ( `⚠️ Failed to create php shims: ${ error instanceof Error ? error . message : String ( error ) } ` )
1123
+ }
1038
1124
}
1039
1125
1126
+ // Show standardized success message
1127
+ logUniqueMessage ( `✅ php.net \x1B[2m\x1B[3m(v${ result . version } )\x1B[0m` )
1128
+
1129
+ // Keep return shape for compatibility
1040
1130
return [ result . packageDir ]
1041
1131
}
0 commit comments