1- import { execSync } from 'child_process' ;
1+ import {
2+ spawnSync ,
3+ type SpawnSyncOptionsWithStringEncoding ,
4+ } from 'child_process' ;
25import { RootCommand } from '../src/t.js' ;
36
4- function debugLog ( ...args : any [ ] ) {
7+ function debugLog ( ...args : unknown [ ] ) {
58 if ( process . env . DEBUG ) {
69 console . error ( '[DEBUG]' , ...args ) ;
710 }
811}
912
13+ const completionSpawnOptions : SpawnSyncOptionsWithStringEncoding = {
14+ encoding : 'utf8' ,
15+ stdio : [ 'pipe' , 'pipe' , 'ignore' ] ,
16+ timeout : 1000 ,
17+ } ;
18+
19+ function runCompletionCommand (
20+ command : string ,
21+ leadingArgs : string [ ] ,
22+ completionArgs : string [ ]
23+ ) : string {
24+ const result = spawnSync (
25+ command ,
26+ [ ...leadingArgs , 'complete' , '--' , ...completionArgs ] ,
27+ completionSpawnOptions
28+ ) ;
29+
30+ if ( result . error ) {
31+ throw result . error ;
32+ }
33+
34+ if ( typeof result . status === 'number' && result . status !== 0 ) {
35+ throw new Error (
36+ `Completion command "${ command } " exited with code ${ result . status } `
37+ ) ;
38+ }
39+
40+ return ( result . stdout ?? '' ) . trim ( ) ;
41+ }
42+
1043async function checkCliHasCompletions (
1144 cliName : string ,
1245 packageManager : string
1346) : Promise < boolean > {
1447 try {
15- const result = execSync ( `${ cliName } complete --` , {
16- encoding : 'utf8' ,
17- stdio : [ 'pipe' , 'pipe' , 'ignore' ] ,
18- timeout : 1000 ,
19- } ) ;
20- if ( result . trim ( ) ) return true ;
48+ const result = runCompletionCommand ( cliName , [ ] , [ ] ) ;
49+ if ( result ) return true ;
2150 } catch { }
2251
2352 try {
24- const result = execSync ( `${ packageManager } ${ cliName } complete --` , {
25- encoding : 'utf8' ,
26- stdio : [ 'pipe' , 'pipe' , 'ignore' ] ,
27- timeout : 1000 ,
28- } ) ;
29- return ! ! result . trim ( ) ;
53+ const result = runCompletionCommand ( packageManager , [ cliName ] , [ ] ) ;
54+ return ! ! result ;
3055 } catch {
3156 return false ;
3257 }
@@ -37,34 +62,16 @@ async function getCliCompletions(
3762 packageManager : string ,
3863 args : string [ ]
3964) : Promise < string [ ] > {
40- const completeArgs = args . map ( ( arg ) =>
41- arg . includes ( ' ' ) ? `"${ arg } "` : arg
42- ) ;
43-
4465 try {
45- const result = execSync (
46- `${ cliName } complete -- ${ completeArgs . join ( ' ' ) } ` ,
47- {
48- encoding : 'utf8' ,
49- stdio : [ 'pipe' , 'pipe' , 'ignore' ] ,
50- timeout : 1000 ,
51- }
52- ) ;
53- if ( result . trim ( ) ) {
54- return result . trim ( ) . split ( '\n' ) . filter ( Boolean ) ;
66+ const result = runCompletionCommand ( cliName , [ ] , args ) ;
67+ if ( result ) {
68+ return result . split ( '\n' ) . filter ( Boolean ) ;
5569 }
5670 } catch { }
5771
5872 try {
59- const result = execSync (
60- `${ packageManager } ${ cliName } complete -- ${ completeArgs . join ( ' ' ) } ` ,
61- {
62- encoding : 'utf8' ,
63- stdio : [ 'pipe' , 'pipe' , 'ignore' ] ,
64- timeout : 1000 ,
65- }
66- ) ;
67- return result . trim ( ) . split ( '\n' ) . filter ( Boolean ) ;
73+ const result = runCompletionCommand ( packageManager , [ cliName ] , args ) ;
74+ return result . split ( '\n' ) . filter ( Boolean ) ;
6875 } catch {
6976 return [ ] ;
7077 }
0 commit comments