Skip to content

Commit

Permalink
Merge pull request #934 from forcedotcom/dev
Browse files Browse the repository at this point in the history
RELEASE: @W-12278374@: Merging dev to release for 3.8.0
  • Loading branch information
rmohan20 authored Jan 4, 2023
2 parents 6b140a3 + b8bfc92 commit 4b09d60
Show file tree
Hide file tree
Showing 99 changed files with 5,945 additions and 1,520 deletions.
3 changes: 3 additions & 0 deletions messages/DefaultRuleManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ module.exports = {
"targetSkipped": "The specified target wasn't processed by any engines. Use the --engine parameter to select a different engine or specify a different target. Specified target: %s.",
"targetsSkipped": "The specified targets weren't processed by any engines: %s. Review your target and engine combinations and try again.",
"pathsDoubleProcessed": "One or more files were processed by eslint and eslint-lwc simultaneously. To remove possible duplicate violations, customize the targetPatterns property for eslint and eslint-lwc engines in %s on these files: %s.",
},
"error": {
"cannotRunDfaAndNonDfaConcurrently": "DFA engines %s cannot be run concurrently with non-DFA engines %s"
}
}
9 changes: 9 additions & 0 deletions messages/RunOutputProcessor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
"output": {
"engineSummaryTemplate": "Executed %s, found %s violation(s) across %s file(s).",
"noViolationsDetected": "Executed engines: %s. No rule violations found.",
"sevThresholdSummary": "Rule violations of severity %s or more severe were detected.",
"writtenToConsole": "Rule violations were logged to the console.",
"writtenToOutFile": "Rule violations were written to %s."
}
}
9 changes: 7 additions & 2 deletions messages/SfgeEngine.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
module.exports = {
"spinnerStart": "Analyzing with Salesforce Graph Engine. See %s for details.",
"pleaseWait": "Please wait"
"messages": {
"pleaseWait": "Please wait",
"spinnerStart": "Analyzing with Salesforce Graph Engine. See %s for details."
},
"errors": {
"failedWithoutProjectDir": `The --projectdir|-p flag is missing. Rerun your command with --projectdir|-p to allow Graph Engine to run, or with --engine|-e to exclude Graph Engine from execution.`
}
};
23 changes: 23 additions & 0 deletions messages/run-common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
"flags": {
"formatDescription": "specify results output format",
"formatDescriptionLong": "Specifies results output format written directly to the console.",
"normalizesevDescription": "return normalized severity 1 (high), 2 (moderate), and 3 (low), and the engine-specific severity",
"normalizesevDescriptionLong": "Returns normalized severity 1 (high), 2 (moderate), and 3 (low), and the engine-specific severity. For the html option, the normalized severity is displayed instead of the engine severity.",
"outfileDescription": "write output to a file",
"outfileDescriptionLong": "Writes output to a file.",
"projectdirDescription": "provide root directory of project",
"projectdirDescriptionLong": "Provides the relative or absolute root project directory used to set the context for Graph Engine's analysis. Project directory must be a path, not a glob. Specify multiple values as a comma-separated list.",
"sevthresholdDescription": "throw an error when a violation threshold is reached, the --normalize-severity is invoked, and severity levels are reset to the baseline",
"sevthresholdDescriptionLong": "Throws an error when violations are found with equal or greater severity than the provided value. Values are 1 (high), 2 (moderate), and 3 (low). Exit code is the most severe violation. Using this flag also invokes the --normalize-severity flag."
},
"validations": {
"cannotWriteTableToFile": "Format 'table' can't be written to a file. Specify a different format.",
"outfileFormatMismatch": "The selected output format doesn't match the output file type. Output format: %s. Output file type: %s.",
"outfileMustBeValid": "--outfile must be a well-formed filepath.",
"outfileMustBeSupportedType": "--outfile must be of a supported type: .csv; .xml; .json; .html; .sarif.",
"projectdirCannotBeGlob": "--projectdir cannot specify globs",
"projectdirMustBeDir": "--projectdir must specify directories",
"projectdirMustExist": "--projectdir must specify existing paths"
}
}
16 changes: 2 additions & 14 deletions messages/run-dfa.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,12 @@ module.exports = {
"commandDescriptionLong": `Scans codebase with all DFA rules by default.
Specify the format of output and print results directly or as contents of a file that you provide with --outfile flag.`,
"flags": {
"formatDescription": "specify results output format",
"formatDescriptionLong": "Specifies results output format written directly to the console.",
"normalizesevDescription": "return normalized severity in addition to the engine-specific severity",
"normalizesevDescriptionLong": "Returns normalized severity 1 (high), 2 (moderate), and 3 (low) and the engine-specific severity. For the html option, normalized severity is displayed instead of the engine severity.",
"outfileDescription": "write output to a file",
"outfileDescriptionLong": "Writes output to a file.",
"projectdirDescription": "provide root directory of project",
"projectdirDescriptionLong": "Provides the relative or absolute root project directory used to set the context for Graph Engine's analysis. Project directory must be a path, not a glob. Specify multiple values as a comma-separated list.",
"ruledisablewarningviolationDescription": "disable warning violations from Salesforce Graph Engine. Alternatively, set value using environment variable `SFGE_RULE_DISABLE_WARNING_VIOLATION`",
"ruledisablewarningviolationDescriptionLong": "Disables warning violations, such as those on StripInaccessible READ access, to get only high-severity violations (default: false). Inherits value from SFGE_RULE_DISABLE_WARNING_VIOLATION env-var if set.",
"rulethreadcountDescription": "specify number of threads that evaluate DFA rules. Alternatively, set value using environment variable `SFGE_RULE_THREAD_COUNT`. Default is 4",
"rulethreadcountDescriptionLong": "Specifies number of rule evaluation threads, or how many entrypoints can be evaluated concurrently. Inherits value from SFGE_RULE_THREAD_COUNT env-var, if set. Default is 4.",
"rulethreadtimeoutDescription": "specify timeout for individual rule threads in milliseconds. Alternatively, set the timeout value using environment variable `SFGE_RULE_THREAD_TIMEOUT`. Default: 90000 ms",
"rulethreadtimeoutDescriptionLong": "Specifies time limit for evaluating a single entrypoint in milliseconds. Inherits value from SFGE_RULE_THREAD_TIMEOUT env-var if set. Default is 900,000 ms, or 15 minutes.",
"sevthresholdDescription": "throw an error when violations of specific or higher severity are detected, and invoke --normalize-severity",
"sevthresholdDescriptionLong": "Throws an error when violations are found with equal or greater severity than provided value. Values are 1 (high), 2 (moderate), and 3 (low). Exit code is the most severe violation. Using this flag also invokes the --normalize-severity flag.",
"sfgejvmargsDescription": "specify Java Virtual Machine (JVM) arguments to optimize Salesforce Graph Engine execution to your system (optional)",
"sfgejvmargsDescriptionLong": "Specifies Java Virtual Machine arguments to override system defaults while executing Salesforce Graph Engine. For multiple arguments, add them to the same string separated by space.",
"targetDescription": "return location of source code",
Expand All @@ -27,12 +17,10 @@ module.exports = {
"validations": {
"methodLevelTargetCannotBeGlob": "Method-level targets supplied to --target cannot be globs",
"methodLevelTargetMustBeRealFile": "Method-level target %s must be a real file",
"projectdirCannotBeGlob": "--projectdir cannot specify globs",
"projectdirMustBeDir": "--projectdir must specify directories",
"projectdirMustExist": "--projectdir must specify existing paths"
"projectdirIsRequired": "--projectdir is required for this command.",
},
"examples": `The paths specified for --projectdir must contain all files specified through --target cumulatively.
$ sfdx sacnner:run:dfa --target "./myproject/main/default/classes/*.cls" --projectdir "./myproject/"
$ sfdx scanner:run:dfa --target "./myproject/main/default/classes/*.cls" --projectdir "./myproject/"
$ sfdx scanner:run:dfa --target "./**/*.cls" --projectdir "./"
$ sfdx scanner:run:dfa --target "./dir1/file1.cls,./dir2/file2.cls" --projectdir "./dir1/,./dir2/"
This example fails because the set of files included in --target is larger than that contained in --projectdir:
Expand Down
28 changes: 9 additions & 19 deletions messages/run.js → messages/run-pathless.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,26 @@ module.exports = {
"rulesetDescriptionLong": "[deprecated] One or more rulesets to run. Specify multiple values as a comma-separated list.",
"targetDescription": "source code location",
"targetDescriptionLong": "Source code location. May use glob patterns. Specify multiple values as a comma-separated list.",
"formatDescription": "specify results output format",
"formatDescriptionLong": "Specifies output format with results written directly to the console.",
"outfileDescription": "write output to a file",
"outfileDescriptionLong": "Writes output to a file.",
"envDescription": "[deprecated] override ESLint's default environment variables, in JSON-formatted string",
"envDescriptionLong": "[deprecated] Overrides ESLint's default environmental variables, in JSON-formatted string.",
"envParamDeprecationWarning": "--env parameter is being deprecated, and will be removed in a future release.",
"tsconfigDescription": "location of tsconfig.json file",
"tsconfigDescriptionLong": "Location of tsconfig.json file used by eslint-typescript engine.",
"stDescription": "throw an error when a violation threshold is reached, the --normalize-severity is invoked, and severity levels are reset to the baseline",
"stDescriptionLong": "Throws an error when violations are found with equal or greater severity than the provided value. --normalize-severity is invoked and severity levels are reset to the baseline. Normalized severity values are: 1 (high), 2 (moderate), and 3 (low). Exit code is the most severe violation.",
"nsDescription": "return normalized severity 1 (high), 2 (moderate), and 3 (low), and the engine-specific severity",
"nsDescriptionLong": "Returns normalized severity 1 (high), 2 (moderate), and 3 (low), and the engine-specific severity. For the html option, the normalized severity is displayed instead of the engine severity.",
'engineDescription': "specify which engines to run",
'engineDescriptionLong': "Specifies one or more engines to run. Submit multiple values as a comma-separated list.",
'eslintConfigDescription': 'specify the location of eslintrc config to customize eslint engine',
'eslintConfigDescriptionLong': 'Specifies the location of eslintrc config to customize eslint engine.',
'pmdConfigDescription': 'specify location of PMD rule reference XML file to customize rule selection',
'pmdConfigDescriptionLong': 'Specifies the location of PMD rule reference XML file to customize rule selection.',
"verboseViolationsDescription": "return retire-js violation message details",
"verboseViolationsDescriptionLong": "Returns retire-js violation messages details about each vulnerability, including summary, Common Vulnerabilities and Exposures (CVE), and URLs."
"verboseViolationsDescriptionLong": "Returns retire-js violation messages details about each vulnerability, including summary, Common Vulnerabilities and Exposures (CVE), and URLs."
},
"validations": {
"methodLevelTargetingDisallowed": "The target '%s' is invalid because method-level targeting isn't supported with this command.",
"outfileFormatMismatch": "The selected output format doesn't match the output file type. Output format: %s. Output file type: %s.",
"outfileMustBeValid": "--outfile must be a well-formed filepath.",
"outfileMustBeSupportedType": "--outfile must be of a supported type: .csv; .xml; .json; .html; .sarif.",
"cannotWriteTableToFile": "Format 'table' can't be written to a file. Specify a different format.",
"tsConfigEslintConfigExclusive": "A --tsconfig flag can't be specified with an --eslintconfig flag. Review your tsconfig path in the eslint config file under 'parseOptions.project'.",
},
"output": {
"noViolationsDetected": "Executed engines: %s. No rule violations found.",
"invalidEnvJson": "--env parameter must be a well-formed JSON.",
"engineSummaryTemplate": "Executed %s, found %s violation(s) across %s file(s).",
"writtenToOutFile": "Rule violations were written to %s.",
"writtenToConsole": "Rule violations were logged to the console.",
"sevThresholdSummary": "Rule violations of severity %s or more severe were detected.",
"pleaseSeeAbove": "Review the logs.",
"filtersIgnoredCustom": "Rule filters will be ignored by engines that are run with custom config using --pmdconfig or --eslintconfig flags. Modify your config file to include your filters."
},
"rulesetDeprecation": "The 'ruleset' command parameter is deprecated. Use 'category' instead.",
Expand Down Expand Up @@ -96,5 +78,13 @@ This example uses --normalize-severity to output normalized severity and engine-
This example uses --severity-threshold to throw a non-zero exit code when rule violations of normalized severity 2 or greater are found. If any violations with the specified severity (or greater) are found, the exit code equals the severity of the most severe violation.
$ sfdx scanner:run --target "/some-project/" --severity-threshold 2
The paths specified for --projectdir must contain all files specified through --target cumulatively.
$ sfdx scanner:run --target "./myproject/main/default/classes/*.cls" --projectdir "./myproject/"
$ sfdx scanner:run --target "./**/*.cls" --projectdir "./"
$ sfdx scanner:run --target "./dir1/file1.cls,./dir2/file2.cls" --projectdir "./dir1/,./dir2/"
This example fails because the set of files included in --target is larger than that contained in --projectdir:
$ sfdx scanner:run --target "./**/*.cls" --projectdir "./myproject/"
`
};
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@salesforce/sfdx-scanner",
"description": "Static code scanner that applies quality and security rules to Apex code, and provides feedback.",
"version": "3.7.1",
"version": "3.8.0",
"author": "ISV SWAT",
"bugs": "https://github.com/forcedotcom/sfdx-scanner/issues",
"dependencies": {
Expand All @@ -22,7 +22,7 @@
"eslint": "^8.10.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^26.1.1",
"find-java-home": "1.1.0",
"find-java-home": "1.2.2",
"globby": "^11.0.0",
"html-escaper": "^3.0.0",
"is-zip": "^1.0.0",
Expand Down
47 changes: 24 additions & 23 deletions sfge/src/main/java/com/salesforce/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import com.salesforce.rules.AbstractRule;
import com.salesforce.rules.AbstractRuleRunner;
import com.salesforce.rules.RuleRunner;
import com.salesforce.rules.RuleUtil;
import com.salesforce.rules.Violation;
import com.salesforce.rules.ops.ProgressListenerProvider;
import java.util.Arrays;
Expand All @@ -28,30 +27,28 @@
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;

/**
* The main class, invoked by sfdx-scanner. `catalog` flow lists all of the available rules in a
* standardized format.
*
* <p>The `execute` flow accepts as a parameter the name of a file whose contents are a JSON with
* the following structure:
* The main class, invoked by sfdx-scanner. The first arg should be either `catalog` or `execute`,
* and determines which flow runs. <br>
* For `catalog`, the second arg should be either `pathless` or `dfa`. Enabled rules matching that
* type will be logged as a JSON. No meaningful environment variables exist for this flow. Exit code
* 0 means success. Any other exit code means failure. <br>
* For `execute`, the second arg should be the path to a JSON file whose contents are structured as:
*
* <ol>
* <li>rulesToRun: An array of rule names.
* <li>projectDirs: An array of directories from which the graph should be built.
* <li>targets: An array of objects with a `targetFile` property indicating the file to be
* analyzed and a `targetMethods` property indicating individual methods.
* <li>rulesToRun: an array of rule names.
* <li>projectDirs: an array of directories from which the graph should be built.
* <li>targets: an array of objects with a `targetFile` property indicating the file to be
* analyzed and a `targetMethods` property that may optionally indicate individual methods
* within that file.
* </ol>
*
* <p>Exit codes:
*
* <ul>
* <li>Negative numbers indicate an internal error.
* <li>0 indicates a successful run with * no violations.
* <li>Positive numbers indicate a successful run with exit-code-many violations.
* </ul>
* The following exit codes are possible:
*
* <p>Usage: mvn exec:java -Dexec.mainClass=com.salesforce.Main -Dexec.args="catalog" OR mvn
* exec:java -Dexec.mainClass=com.salesforce.Main -Dexec.args="execute [path to file listing
* targets] [path to file listing sources] [comma-separated rules]"
* <ol>
* <li>0: Successful run without violations.
* <li>1: Internal error with no violations.
* <li>4: Successful run with violations.5: Internal error with some violations.>
* </ol>
*/
@SuppressWarnings(
"PMD.SystemPrintln") // Since println is currently used to communicate to outer layer
Expand Down Expand Up @@ -97,19 +94,22 @@ int process(String... args) {

switch (action) {
case CATALOG:
return catalog();
return catalog(args);
case EXECUTE:
return execute(args);
default:
throw new ProgrammingException("Unhandled action: " + action);
}
}

private int catalog() {
/** Expectations for args documented in class header above. */
private int catalog(String... args) {
LOGGER.info("Invoked CATALOG flow");
CliArgParser.CatalogArgParser cap = new CliArgParser.CatalogArgParser();
List<AbstractRule> rules;
try {
rules = RuleUtil.getEnabledRules();
cap.parseArgs(args);
rules = cap.getSelectedRules();
} catch (SfgeException | SfgeRuntimeException ex) {
dependencies.printError(ex.getMessage());
return EXIT_WITH_INTERNAL_ERROR_NO_VIOLATIONS;
Expand All @@ -119,6 +119,7 @@ private int catalog() {
return EXIT_GOOD_RUN_NO_VIOLATIONS;
}

/** Expectations for args documented in class header above. */
private int execute(String... args) {
LOGGER.info("Invoked EXECUTE flow");
// Parse the arguments with our delegate class.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import apex.jorje.semantic.ast.expression.ReferenceExpression;
import apex.jorje.semantic.ast.expression.SoqlExpression;
import apex.jorje.semantic.ast.expression.SoslExpression;
import apex.jorje.semantic.ast.expression.SuperMethodCallExpression;
import apex.jorje.semantic.ast.expression.ThisMethodCallExpression;
import apex.jorje.semantic.ast.expression.ThisVariableExpression;
import apex.jorje.semantic.ast.expression.TriggerVariableExpression;
Expand Down Expand Up @@ -145,6 +146,8 @@ public static String getVertexLabel(Class<? extends AstNode> clazz) {
public static final String REFERENCE_EXPRESSION = getVertexLabel(ReferenceExpression.class);
public static final String RETURN_STATEMENT = getVertexLabel(ReturnStatement.class);
public static final String STANDARD_CONDITION = getVertexLabel(StandardCondition.class);
public static final String SUPER_METHOD_CALL_EXPRESSION =
getVertexLabel(SuperMethodCallExpression.class);
public static final String THIS_METHOD_CALL_EXPRESSION =
getVertexLabel(ThisMethodCallExpression.class);
public static final String THIS_VARIABLE_EXPRESSION =
Expand Down
Loading

0 comments on commit 4b09d60

Please sign in to comment.