@@ -8,6 +8,7 @@ import { access, appendFile, copyFile, type FileHandle, open } from 'node:fs/pro
88import path from 'node:path' ;
99import readline from 'node:readline' ;
1010import { promisify as toPromise } from 'node:util' ;
11+ import { phpCommand } from './php' ;
1112
1213// Create an awaitable version of execFile that won't block the main process,
1314// which would produce a disconcerting beach ball on macOS.
@@ -25,7 +26,7 @@ async function createProject (win?: WebContents): Promise<void>
2526 // @todo Remove EventEmitter from the intersection type when Node's type
2627 // definitions are updated to reflect the documentation.
2728 // @see https://nodejs.org/docs/latest/api/fs.html#class-filehandle
28- log = await open ( installLog , 'w ' ) as FileHandle & EventEmitter ;
29+ log = await open ( installLog , 'a ' ) as FileHandle & EventEmitter ;
2930
3031 // Invalidate the handle when the file is closed, so we don't try to write to
3132 // it accidentally.
@@ -37,33 +38,32 @@ async function createProject (win?: WebContents): Promise<void>
3738 log = null ;
3839 }
3940
40- const runComposer = ( command : string [ ] ) => {
41- log ?. write ( '\n>>> ' + command . join ( ' ' ) + '\n' ) ;
41+ // Always invoke Composer directly through the PHP interpreter, with a known set
42+ // of options.
43+ const _phpCommand = [
44+ ...await phpCommand ( ) ,
45+ // We use an unpacked version of Composer because the phar file has a shebang
46+ // line that breaks us, due to GUI-launched Electron apps not inheriting the
47+ // parent environment in macOS and Linux.
48+ path . join ( 'composer' , 'bin' , 'composer' ) ,
49+ // Disable ANSI output (i.e., colors) so the log is readable.
50+ '--no-ansi' ,
51+ // We don't want Composer to ask us any questions, since we have no way for
52+ // the user to answer them.
53+ '--no-interaction' ,
54+ ] ;
4255
56+ const runComposer = ( command : string [ ] ) => {
4357 // Always direct Composer to the created project root, unless we're about to
4458 // create it initially.
4559 if ( command [ 0 ] !== 'create-project' ) {
4660 command . push ( `--working-dir=${ projectRoot } ` ) ;
4761 }
48- command . push (
49- // Disable ANSI output (i.e., colors) so the log is readable.
50- '--no-ansi' ,
51- // We don't want Composer to ask us any questions, since we have no way for
52- // the user to answer them.
53- '--no-interaction' ,
54- ) ;
55- command . unshift (
56- // Explicitly pass the cURL CA bundle so that HTTPS requests from Composer can
57- // succeed on Windows.
58- '-d' ,
59- 'curl.cainfo=' + path . join ( bin , 'cacert.pem' ) ,
60- // We use an unpacked version of Composer because the phar file has a shebang
61- // line that breaks us, due to GUI-launched Electron apps not inheriting the
62- // parent environment in macOS and Linux.
63- path . join ( 'composer' , 'bin' , 'composer' ) ,
64- ) ;
62+ command . unshift ( ..._phpCommand ) ;
63+ // For forensic purposes, log the complete command we're about to execute.
64+ log ?. write ( '\n>>> ' + command . join ( ' ' ) + '\n' ) ;
6565
66- const task = execFileAsPromise ( path . join ( bin , 'php' ) , command , {
66+ const task = execFileAsPromise ( command [ 0 ] , command . slice ( 1 ) , {
6767 // Run from the `bin` directory so we can use a relative path to Composer.
6868 cwd : bin ,
6969 // Send a customized copy of the current environment variables to Composer.
0 commit comments