forcedotcom / sfdx-scanner

MIT License
207 stars 49 forks source link

[BUG] Error (1): RetireJS: sh: line 1: retire: command not found (when linking instead of installing plugin) #1507

Closed YodaDaCoda closed 3 weeks ago

YodaDaCoda commented 3 weeks ago

Have you tried to resolve this issue yourself first?

Yes

Bug Description

Sf scanner fails to run due to apparently inability to resolve correct path of the retire executable.

Output / Logs

$ .ci/lint.sh
+ sf scanner run --pmdconfig .ci/pmd.xml --format junit --target force-app/main --outfile ./build/sf-scanner-results.xml
Warning: We're continually improving Salesforce Code Analyzer. Tell us what you think! Give feedback at https://research.net/r/SalesforceCA
About to run PMD with custom config in .ci/pmd.xml. Please make sure that any custom rule references have already been added to the plugin through scanner:rule:add command.
Error (1): RetireJS: sh: line 1: retire: command not found

Steps To Reproduce

  1. npm install and link plugin npm install --save @salesforce/sfdx-scanner@4.2.0 sf plugins link --no-install "node_modules/@salesforce/sfdx-scanner"
  2. Attempt to scan project using sf scanner run (via script file) sf scanner run --pmdconfig .ci/pmd.xml --format junit --target force-app/main --outfile ./build/sf-scanner-results.xml or just sf scanner run --target force-app/main
  3. Observe the error

Expected Behavior

SF Scanner should run, including the retirejs engine, without error.

Operating System

Ubuntu 23.04 / Manjaro

Salesforce CLI Version

@salesforce/cli/2.46.5 linux-x64 node-v20.14.0

Code Analyzer Plugin (@salesforce/sfdx-scanner) Version

@salesforce/sfdx-scanner 4.2.0 (link)

Additional Context (Screenshots, Files, etc)

I suspect the root cause is the use of npx to launch the retire executable. This fails because retire is not a direct dependency of my project, so it isn't in my project's node_modules/.bin folder.

https://github.com/forcedotcom/sfdx-scanner/blob/a90943099c29a7c37dfe6e67c9d08547f2f604fe/src/lib/retire-js/RetireJsEngine.ts#L202

Dynamically resolving the path to the executable allows me to run sf scanner without error.

- const cp = cspawn('npx', ['retire'].concat(invocation.args));
+ const retirePackagePath = require.resolve('retire/package.json');
+ const retireBinPath = path.join(path.dirname(retirePackagePath), require(retirePackagePath).bin.retire);
+ const cp = cspawn(retireBinPath, invocation.args);

Workaround

No response

Urgency

Low

stephen-carter-at-sf commented 3 weeks ago

Hello @YodaDaCoda . This is interesting. I would have thought the npx would look under the node_modules of the location of where the @salesforce/sfdx-scanner plugin is installed (which can be found via sf plugins inspect @salesforce/sfdx-scanner) automatically even if you had your own node_modules folder for your project. Can you first confirm that you have a node_modules folder that contains the retire executables in this @salesforce/sfdx-scanner plugin install directory?

Meanwhile, I'm going to try to reproduce. I'll report back here soon.

stephen-carter-at-sf commented 3 weeks ago

Oh I see you are doing a link to the plugin instead of just installing the plugin through sf.

Is there a reason you are doing the following:

npm install --save @salesforce/sfdx-scanner@4.2.0
sf plugins link --no-install "node_modules/@salesforce/sfdx-scanner"

instead of

sf plugins install @salesforce/sfdx-scanner@4.2.0

?

Note: I was able to reproduce by linking instead of installing as you are doing. So the workaround is to install instead of linking the plugin.

What is your use case?

git2gus[bot] commented 3 weeks ago

This issue has been linked to a new work item: W-16007479