@@ -11,6 +11,12 @@ import cspawn = require('cross-spawn');
1111import path = require( 'path' ) ;
1212import StreamZip = require( 'node-stream-zip' ) ;
1313import { CUSTOM_CONFIG } from '../../Constants' ;
14+ import * as fs from "node:fs" ;
15+
16+ // Note that we don't want to call npx retire from this file since we don't want to accidentally have npx pick up
17+ // another version on the users machine. Instead, we want to call the command directly from the node_modules/.bin
18+ // folder (which always shows up when you install the retire dependency).
19+ const RETIRE_JS_COMMAND = findCommand ( 'retire' ) ;
1420
1521// Unlike the other engines we use, RetireJS doesn't really have "rules" per se. So we sorta have to synthesize a
1622// "catalog" out of RetireJS's normal behavior and its permutations.
@@ -199,7 +205,7 @@ export class RetireJsEngine extends AbstractRuleEngine {
199205
200206 private async executeRetireJs ( invocation : RetireJsInvocation , verboseViolations : boolean ) : Promise < RuleResult [ ] > {
201207 return new Promise < RuleResult [ ] > ( ( res , rej ) => {
202- const cp = cspawn ( 'npx' , [ 'retire' ] . concat ( invocation . args ) ) ;
208+ const cp = cspawn ( RETIRE_JS_COMMAND , invocation . args ) ;
203209
204210 // Initialize both stdout and stderr as empty strings to which we can append data as we receive it.
205211 let stdout = '' ;
@@ -543,3 +549,17 @@ export class RetireJsEngine extends AbstractRuleEngine {
543549 ) ;
544550 }
545551}
552+
553+
554+ /**
555+ * Finds the command location (symlink) for a command that is pulled in from this package's dependencies.
556+ * We need to look up the location since the node_modules or .bin can change locations in various scenarios.
557+ */
558+ export function findCommand ( commandName : string ) : string {
559+ for ( let dir = __dirname ; dir !== path . resolve ( dir , '..' ) ; dir = path . resolve ( dir , '..' ) ) {
560+ const commandPath = path . join ( dir , 'node_modules' , '.bin' , commandName ) ;
561+ if ( fs . existsSync ( commandPath ) ) return commandPath ;
562+ }
563+ /* istanbul ignore next */
564+ throw new Error ( `Could not find file for command: ${ commandName } ` ) ;
565+ }
0 commit comments