diff --git a/.eslintrc.json b/.eslintrc.json index 6e1f214f9..28a3ed529 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,7 +3,8 @@ "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking" + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:sf-plugin/migration" ], "parserOptions": { "sourceType": "module", diff --git a/.github/ISSUE_TEMPLATE/0scanner_run_bug.md b/.github/ISSUE_TEMPLATE/0scanner_run_bug.md index ca38c0d9d..a0b7c0eb7 100644 --- a/.github/ISSUE_TEMPLATE/0scanner_run_bug.md +++ b/.github/ISSUE_TEMPLATE/0scanner_run_bug.md @@ -1,14 +1,14 @@ --- -name: Report a Bug with scanner:run -about: Report an issue with the scanner:run command. +name: Report a Bug with scanner run +about: Report an issue with the scanner run command. title: "[BUG]" labels: '' assignees: '' --- -### `scanner:run` Issue Template +### `scanner run` Issue Template Fill out this template to submit your Code Analyzer issue. diff --git a/.github/ISSUE_TEMPLATE/1scanner_run_dfa_bug.md b/.github/ISSUE_TEMPLATE/1scanner_run_dfa_bug.md index c4e3ef63f..372672598 100644 --- a/.github/ISSUE_TEMPLATE/1scanner_run_dfa_bug.md +++ b/.github/ISSUE_TEMPLATE/1scanner_run_dfa_bug.md @@ -1,14 +1,14 @@ --- -name: Report a Bug with scanner:run:dfa -about: Report an issue with the scanner:run:dfa command. +name: Report a Bug with scanner run dfa +about: Report an issue with the scanner run dfa command. title: "[BUG]" labels: '' assignees: '' --- -### `scanner:run:dfa` Issue Template +### `scanner run dfa` Issue Template Fill out this template to submit your Code Analyzer issue. diff --git a/.github/ISSUE_TEMPLATE/2scanner_run_false_result.md b/.github/ISSUE_TEMPLATE/2scanner_run_false_result.md index da0b573c5..2a5fa431a 100644 --- a/.github/ISSUE_TEMPLATE/2scanner_run_false_result.md +++ b/.github/ISSUE_TEMPLATE/2scanner_run_false_result.md @@ -1,6 +1,6 @@ --- -name: Report a scanner:run False Result -about: Report false results in scanner:run scan reports. If you’re submitting your managed package for AppExchange security review, include documentation of your false results with your submission. +name: Report a scanner run False Result +about: Report false results in scanner run scan reports. If you’re submitting your managed package for AppExchange security review, include documentation of your false results with your submission. title: "[False Result]" labels: '' assignees: '' diff --git a/.github/ISSUE_TEMPLATE/3scanner_run_dfa_false_result.md b/.github/ISSUE_TEMPLATE/3scanner_run_dfa_false_result.md index 44ebe1bcd..11d2c5604 100644 --- a/.github/ISSUE_TEMPLATE/3scanner_run_dfa_false_result.md +++ b/.github/ISSUE_TEMPLATE/3scanner_run_dfa_false_result.md @@ -1,11 +1,11 @@ --- -name: Report a scanner:run:dfa False Result -about: Report false results returned in scanner:run:dfa scan reports. If you’re submitting for AppExchange security review, include documentation of your false results with your submission. +name: Report a scanner run dfa False Result +about: Report false results returned in scanner run dfa scan reports. If you’re submitting for AppExchange security review, include documentation of your false results with your submission. title: "[False Result]" labels: '' assignees: '' --- -### `scanner:run:dfa` False Positives Template +### `scanner run dfa` False Positives Template **Description:** diff --git a/.github/ISSUE_TEMPLATE/4feature_request.md b/.github/ISSUE_TEMPLATE/4feature_request.md index 9ecf7264a..3593534ec 100644 --- a/.github/ISSUE_TEMPLATE/4feature_request.md +++ b/.github/ISSUE_TEMPLATE/4feature_request.md @@ -7,7 +7,7 @@ assignees: '' --- **Is your feature request related to an issue that you encountered with Salesforce Code Analyzer?** - + **Describe the solution that you want:** diff --git a/.github/workflows/production-heartbeat.yml b/.github/workflows/production-heartbeat.yml index 42b2ed91b..49dde51e5 100644 --- a/.github/workflows/production-heartbeat.yml +++ b/.github/workflows/production-heartbeat.yml @@ -37,7 +37,7 @@ jobs: # In the following script, the use of the `echo "name=value" >> $GITHUB_ENV` structure is used to set/update # environment variables. Such updates are visible to all subsequent steps. # - # If the CLI_VERSION repo secret is set, we want to install that version of sfdx-cli, so we set an environment + # If the CLI_VERSION repo secret is set, we want to install that version ofsf-cli, so we set an environment # variable. Otherwise, we leave the environment variable unset, so it implicitly defaults to `latest`. # Note: This can be used to intentionally fail the GHA by providing an invalid version number. if [[ -n "${{ secrets.CLI_VERSION }}" ]]; then @@ -58,34 +58,34 @@ jobs: fi - # === Make three attempts to install sfdx through npm === - - name: Install SFDX - id: sfdx_install + # === Make three attempts to install SF through npm === + - name: Install SF + id: sf_install # If the first attempt fails, wait a minute and try again. After a second failure, wait 5 minutes then try again. Then give up. # Set an output parameter, `retry_count`, indicating the number of retry attempts that were made. run: | - (echo "::set-output name=retry_count::0" && npm install -g sfdx-cli${{ env.CLI_VERSION }}) || - (echo "::set-output name=retry_count::1" && sleep 60 && npm install -g sfdx-cli${{ env.CLI_VERSION }}) || - (echo "::set-output name=retry_count::2" && sleep 300 && npm install -g sfdx-cli${{ env.CLI_VERSION }}) + (echo "::set-output name=retry_count::0" && npm install -g @salesforce/cli${{ env.CLI_VERSION }}) || + (echo "::set-output name=retry_count::1" && sleep 60 && npm install -g @salesforce/cli${{ env.CLI_VERSION }}) || + (echo "::set-output name=retry_count::2" && sleep 300 && npm install -g @salesforce/cli${{ env.CLI_VERSION }}) - # === Make three attempts to install the scanner plugin through sfdx === + # === Make three attempts to install the scanner plugin through sf === - name: Install Scanner Plugin id: scanner_install # If the first attempt fails, wait a minute and try again. After a second failure, wait 5 minutes then try again. Then give up. # Set an output parameter, `retry_count`, indicating the number of retry attempts that were made. run: | - (echo "::set-output name=retry_count::0" && sfdx plugins:install @salesforce/sfdx-scanner${{ env.SCANNER_VERSION }}) || - (echo "::set-output name=retry_count::1" && sleep 60 && sfdx plugins:install @salesforce/sfdx-scanner${{ env.SCANNER_VERSION }}) || - (echo "::set-output name=retry_count::2" && sleep 300 && sfdx plugins:install @salesforce/sfdx-scanner${{ env.SCANNER_VERSION }}) + (echo "::set-output name=retry_count::0" && sf plugins install @salesforce/sfdx-scanner${{ env.SCANNER_VERSION }}) || + (echo "::set-output name=retry_count::1" && sleep 60 && sf plugins install @salesforce/sfdx-scanner${{ env.SCANNER_VERSION }}) || + (echo "::set-output name=retry_count::2" && sleep 300 && sf plugins install @salesforce/sfdx-scanner${{ env.SCANNER_VERSION }}) # === Log the installed plugins for easier debugging === - name: Log plugins - run: sfdx plugins + run: sf plugins # === Attempt to execute the smoke tests === - name: Run smoke tests id: smoke_tests - run: smoke-tests/smoke-test${{ matrix.os.exe }} sfdx + run: smoke-tests/smoke-test${{ matrix.os.exe }} sf # === Upload the smoke-test-results folder as an artifact === - name: Upload smoke-test-results folder as artifact @@ -109,7 +109,7 @@ jobs: IS_CRITICAL: ${{ contains(join(steps.*.outcome), 'failure') || contains(join(steps.*.outcome), 'skipped') }} # Build the status strings for each step as environment variables to save space later. Null retry_count values # will be replaced with `n/a` to maintain readability in the alert. - CLI_INSTALL_STATUS: ${{ steps.sfdx_install.outcome }} after ${{ steps.sfdx_install.outputs.retry_count || 'n/a' }} retries + CLI_INSTALL_STATUS: ${{ steps.sf_install.outcome }} after ${{ steps.sf_install.outputs.retry_count || 'n/a' }} retries SCANNER_INSTALL_STATUS: ${{ steps.scanner_install.outcome }} after ${{ steps.scanner_install.outputs.retry_count || 'n/a' }} retries SMOKE_TESTS_STATUS: ${{ steps.smoke_tests.outcome }} # A link to this run, so the PagerDuty assignee can quickly get here. @@ -126,13 +126,13 @@ jobs: # Define a helper function to create our POST request's data, to sidestep issues with nested quotations. generate_post_data() { # This is known as a HereDoc, and it lets us declare multi-line input ending when the specified limit string, - # in this case EOF, is encoutered. + # in this case EOF, is encountered. cat < { const oclif = await import('@oclif/core') diff --git a/bin/run.js b/bin/run.js index a1ac68f39..9287772cd 100755 --- a/bin/run.js +++ b/bin/run.js @@ -3,5 +3,5 @@ // eslint-disable-next-line unicorn/prefer-top-level-await (async () => { const oclif = await import('@oclif/core') - await oclif.execute({development: true, dir: __dirname}) + await oclif.execute({dir: __dirname}) })() diff --git a/cli-messaging/build.gradle.kts b/cli-messaging/build.gradle.kts index 5062ba8ac..48a495006 100644 --- a/cli-messaging/build.gradle.kts +++ b/cli-messaging/build.gradle.kts @@ -1,5 +1,8 @@ +import java.awt.Desktop + plugins { java + jacoco } version = "1.0" @@ -16,16 +19,45 @@ dependencies { } implementation("com.google.code.gson:gson:2.10.1") implementation("com.google.guava:guava:31.1-jre") + testImplementation("org.hamcrest:hamcrest:2.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2") testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.2") testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.2") } -tasks.getByName("test") { +tasks.test { + // Use JUnit 5 useJUnitPlatform() testLogging { events("passed", "skipped", "failed") } + // Run tests in multiple threads + maxParallelForks = Runtime.getRuntime().availableProcessors()/2 + 1 + + // Report is always generated after test runs + finalizedBy(tasks.jacocoTestReport) +} + +tasks.jacocoTestReport { + dependsOn(tasks.test) +} + +tasks.register("showCoverageReport") { + group = "verification" + dependsOn(tasks.jacocoTestReport) + doLast { + Desktop.getDesktop().browse(File("$buildDir/reports/jacoco/test/html/index.html").toURI()) + } +} + +tasks.jacocoTestCoverageVerification { + violationRules { + rule { + limit { + minimum = BigDecimal("0.70") // TODO: We should aim to increase this + } + } + } } diff --git a/cli-messaging/src/main/java/com/salesforce/messaging/CliMessager.java b/cli-messaging/src/main/java/com/salesforce/messaging/CliMessager.java index b96a53aec..60f14f7b4 100644 --- a/cli-messaging/src/main/java/com/salesforce/messaging/CliMessager.java +++ b/cli-messaging/src/main/java/com/salesforce/messaging/CliMessager.java @@ -9,9 +9,9 @@ public class CliMessager { // The START string gives us something to scan for when we're processing output. - private static final String START = "SFDX-START"; + private static final String START = "SF-START"; // The END string lets us know when a message stops, which should prevent bugs involving multi-line output. - private static final String END = "SFDX-END"; + private static final String END = "SF-END"; private static final String REALTIME_START = "SFCA-REALTIME-START"; private static final String REALTIME_END = "SFCA-REALTIME-END"; diff --git a/cli-messaging/src/main/java/com/salesforce/messaging/EventKey.java b/cli-messaging/src/main/java/com/salesforce/messaging/EventKey.java index 17c045be4..bbe108910 100644 --- a/cli-messaging/src/main/java/com/salesforce/messaging/EventKey.java +++ b/cli-messaging/src/main/java/com/salesforce/messaging/EventKey.java @@ -2,7 +2,7 @@ import static com.salesforce.messaging.Message.*; public enum EventKey { - // MAKE SURE `messageKey` OF EVERY VALUE ADDED HERE HAS AN ENTRY IN 'messages/EventKeyTemplates.js'! + // MAKE SURE `messageKey` OF EVERY VALUE ADDED HERE HAS AN ENTRY IN 'messages/EventKeyTemplates.md'! /** PMD-CATALOGER RELATED **/ INFO_GENERAL_INTERNAL_LOG("info.generalInternalLog", 1, MessageType.INFO, MessageHandler.INTERNAL, true), diff --git a/cli-messaging/src/test/java/com/salesforce/messaging/EventKeyTest.java b/cli-messaging/src/test/java/com/salesforce/messaging/EventKeyTest.java index dd3ffe8cf..a30af6a24 100644 --- a/cli-messaging/src/test/java/com/salesforce/messaging/EventKeyTest.java +++ b/cli-messaging/src/test/java/com/salesforce/messaging/EventKeyTest.java @@ -1,27 +1,28 @@ package com.salesforce.messaging; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import static com.salesforce.messaging.Message.*; -import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.*; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; import java.util.stream.Stream; /** - * Parses messages/EventKeyTemplates.json and confirms that enums defined in EventKey + * Parses messages/EventKeyTemplates.md and confirms that enums defined in EventKey * are valid */ public class EventKeyTest { @@ -31,41 +32,31 @@ public class EventKeyTest { private static final String ERROR_INTERNAL_PREFIX = "error.internal"; // Current path is sfdx-scanner/pmd-cataloger - private static final String MESSAGES_FILE = "../messages/EventKeyTemplates.js"; + private static final String MESSAGES_FILE = "../messages/EventKeyTemplates.md"; - JSONObject jsonObject = null; + /** + * This list will hold the keys that reside in {@code /messages/EventKeyTemplates.md}. + */ + Set eventKeyTemplatesMdKeys = null; @BeforeEach - public void extractMessagesJson() throws IOException, ParseException { + public void extractMessageKeysFromTemplateFile() throws IOException, ParseException { final Path path = Paths.get(MESSAGES_FILE); assertThat("Invalid test setup. File does not exist: " + MESSAGES_FILE, Files.exists(path), is(true)); - final String fileContent = new String(Files.readAllBytes(path)); - final String[] fileSplit = fileContent.split("="); - final int fileParts = fileSplit.length; - assertThat("Invalid test setup. File has more than one '=', which caused confusion in picking JSON content. Please revisit messages in " + MESSAGES_FILE, fileParts, is(2)); - final String jsonContent = fileSplit[1]; - jsonObject = (JSONObject) new JSONParser().parse(jsonContent); - assertThat("Invalid test setup. Messages json has not been parsed correctly. Please check validity of " + MESSAGES_FILE, jsonObject, is(notNullValue())); + final List fileLines = Files.readAllLines(path); + eventKeyTemplatesMdKeys = fileLines.stream().filter(s -> s.startsWith("#")).map(s -> s.substring(1).trim()).collect(Collectors.toSet()); } + /** + * Verifies that every {@link EventKey}'s {@link EventKey#getMessageKey()} result corresponds + * to an entry in {@code ./messages/EventKeyTemplates.md}. + * @param eventKey + */ @ParameterizedTest(name = "eventKey={0}") @MethodSource("getAllEventKeyValues") - public void verifyKeyInJson(EventKey eventKey) { - // Split messageKey into levels + public void verifyKeysMatchTemplateFile(EventKey eventKey) { final String messageKey = eventKey.getMessageKey(); - final String[] levels = messageKey.split("\\."); - - // Loop through JSON to verify presence of each level - int idx = 0; - JSONObject currentJsonContent = this.jsonObject; - while (idx < levels.length - 1) { - currentJsonContent = (JSONObject) currentJsonContent.get(levels[idx]); - assertThat("Level " + levels[idx] + " not found. Recheck value of messageKey " + messageKey + " in EventKey." + eventKey, currentJsonContent, is(notNullValue())); - idx++; - } - final Object lastLevel = currentJsonContent.get(levels[levels.length - 1]); - assertThat("messageKey " + messageKey + " does not exist. Recheck EventKey." + eventKey, lastLevel, is(notNullValue())); - assertThat("Message value should be a String for messageKey " + messageKey + " in EventKey." + eventKey, lastLevel instanceof String, is(true)); + assertThat("EventKey." + eventKey.name() + "'s messageKey property is missing from `./messages/EventKeyTemplates.md.", messageKey, is(in(eventKeyTemplatesMdKeys))); } @ParameterizedTest(name = "eventKey={0}") diff --git a/messages/Config.js b/messages/Config.js deleted file mode 100644 index db09bbe8d..000000000 --- a/messages/Config.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - "GeneratingConfigFromPilot": "Generating config file by copying pilot config file. If this is undesirable, delete or rename `%s`.", - "InvalidStringArrayValue": "Specify a valid property for '%s' in %s for %s. Supply an array of strings: %s.", - "InvalidBooleanValue": "Specify a valid property for '%s' in %s for %s. Supply a boolean: %s.", - "InvalidNumberValue": "Specify a valid property for '%s' in %s for %s. Supply a number: %s.", - "UpgradeFailureTroubleshooting": `%s -The upgrade wasn't successful and the original config was saved to %s. Try again. If the upgrade continues to fail, delete %s.` -}; diff --git a/messages/Config.md b/messages/Config.md new file mode 100644 index 000000000..6fb4e2614 --- /dev/null +++ b/messages/Config.md @@ -0,0 +1,20 @@ +# GeneratingConfigFromPilot + +Generating config file by copying pilot config file. If this is undesirable, delete or rename `%s`. + +# InvalidStringArrayValue + +Specify a valid property for '%s' in %s for %s. Supply an array of strings: %s. + +# InvalidBooleanValue + +Specify a valid property for '%s' in %s for %s. Supply a boolean: %s. + +# InvalidNumberValue + +Specify a valid property for '%s' in %s for %s. Supply a number: %s. + +# UpgradeFailureTroubleshooting + +%s +The upgrade wasn't successful and the original config was saved to %s. Try again. If the upgrade continues to fail, delete %s. \ No newline at end of file diff --git a/messages/Controller.js b/messages/Controller.js deleted file mode 100644 index 177a45cb4..000000000 --- a/messages/Controller.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - "NoEnabledEnginesFound": "You must enable at least one engine. Your currently disabled engines are: %s.", - "NoFilteredEnginesFound": "The filter doesn't match any engines. Filter '%s'. Engines: %s." -} diff --git a/messages/Controller.md b/messages/Controller.md new file mode 100644 index 000000000..86aec2739 --- /dev/null +++ b/messages/Controller.md @@ -0,0 +1,7 @@ +# NoEnabledEnginesFound + +You must enable at least one engine. Your currently disabled engines are: %s. + +# NoFilteredEnginesFound + +The filter doesn't match any engines. Filter '%s'. Engines: %s. \ No newline at end of file diff --git a/messages/CpdEngine.js b/messages/CpdEngine.js deleted file mode 100644 index 0e855f49d..000000000 --- a/messages/CpdEngine.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - "CpdViolationMessage": "ID %s: number %s of %s duplicated segments. %s line(s), %s tokens. To refactor your code, create a method that Code Analyzer can reference." -}; diff --git a/messages/CpdEngine.md b/messages/CpdEngine.md new file mode 100644 index 000000000..c1e6d615d --- /dev/null +++ b/messages/CpdEngine.md @@ -0,0 +1,3 @@ +# CpdViolationMessage + +ID %s: number %s of %s duplicated segments. %s line(s), %s tokens. To refactor your code, create a method that Code Analyzer can reference. \ No newline at end of file diff --git a/messages/CustomEslintEngine.js b/messages/CustomEslintEngine.js deleted file mode 100644 index fd50ebf3c..000000000 --- a/messages/CustomEslintEngine.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - "ConfigFileDoesNotExist": "The specified ESLint config file doesn't exist: %s.", - "InvalidJson": "Something in the ESLint config JSON is invalid. Check ESLint's JSON specifications: %s.", -} diff --git a/messages/CustomEslintEngine.md b/messages/CustomEslintEngine.md new file mode 100644 index 000000000..da280e58b --- /dev/null +++ b/messages/CustomEslintEngine.md @@ -0,0 +1,7 @@ +# ConfigFileDoesNotExist + +The specified ESLint config file doesn't exist: %s. + +# InvalidJson + +Something in the ESLint config JSON is invalid. Check ESLint's JSON specifications: %s %s. \ No newline at end of file diff --git a/messages/CustomRulePathManager.js b/messages/CustomRulePathManager.js deleted file mode 100644 index 707bfd4f6..000000000 --- a/messages/CustomRulePathManager.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - "errors": { - "invalidFilePath": "We couldn't find a file or directory with path: %s.", - "readCustomRulePathFileFailed": "We couldn't read the custom rule path file: %s.", - "writeCustomRulePathFileFailed": "We couldn't write to the custom rule path file: %s.", - } -}; diff --git a/messages/CustomRulePathManager.md b/messages/CustomRulePathManager.md new file mode 100644 index 000000000..6fb568f53 --- /dev/null +++ b/messages/CustomRulePathManager.md @@ -0,0 +1,11 @@ +# errors.invalidFilePath + +We couldn't find a file or directory with path: %s. + +# errors.readCustomRulePathFileFailed + +We couldn't read the custom rule path file: %s. + +# errors.writeCustomRulePathFileFailed + +We couldn't write to the custom rule path file: %s. \ No newline at end of file diff --git a/messages/DefaultRuleManager.js b/messages/DefaultRuleManager.js deleted file mode 100644 index aed6fcb9f..000000000 --- a/messages/DefaultRuleManager.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - "warning": { - "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" - } -} diff --git a/messages/DefaultRuleManager.md b/messages/DefaultRuleManager.md new file mode 100644 index 000000000..7af6a0151 --- /dev/null +++ b/messages/DefaultRuleManager.md @@ -0,0 +1,15 @@ +# warning.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. + +# warning.targetsSkipped + +The specified targets weren't processed by any engines: %s. Review your target and engine combinations and try again. + +# warning.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 \ No newline at end of file diff --git a/messages/EventKeyTemplates.js b/messages/EventKeyTemplates.js deleted file mode 100644 index 3868b22dd..000000000 --- a/messages/EventKeyTemplates.js +++ /dev/null @@ -1,59 +0,0 @@ -module.exports = { - "info": { - "categoryImplicitlyRun": "Implicitly including %s rules from category '%s'", - "jarAndXmlProcessed": "Cataloger: XML files collected from JAR [%s]: %s", - "usingEngineConfigFile": "Using engine configuration file at %s", - "generalInternalLog": "Log from Java: %s", - "customEslintHeadsUp": "About to run Eslint with custom config in %s. Please make sure your current directory has all the required NPM dependencies.", - "customPmdHeadsUp": "About to run PMD with custom config in %s. Please make sure that any custom rule references have already been added to the plugin through scanner:rule:add command.", - "pmdRuleSkipped": "Omitting results for PMD rule \"%s\". Reason: %s.", - "unmatchedPathExtensionCpd": "Path extensions for the following files will not be processed by CPD: %s", - "sfgeInfoLog": "%s", - "sfgeMetaInfoCollected": "Loaded %s: [ %s ]", - "sfgeFinishedCompilingFiles": "Compiled %s files.", - "sfgeStartedBuildingGraph": "Building graph.", - "sfgeFinishedBuildingGraph": "Added all compilation units to graph.", - "sfgePathEntryPointsIdentified": "Identified %s path entry point(s).", - "sfgeViolationsInPathProgress": "Detected %s violation(s) from %s path(s) on %s/%s entry point(s).", - "sfgeCompletedPathAnalysis": "Overall, analyzed %s path(s) from %s entry point(s). Detected %s violation(s).", - "telemetry": "This message is unused." - }, - "warning": { - "pmd7IncompatibleRule": "PMD rule [%s] isn't compatible with PMD 7.0: %s. Resolve these issues to future-proof your rule. If you need help, log an issue on github.com/forcedotcom/sfdx-scanner", - "invalidCategorySkipped": "Cataloger: Skipping invalid PMD Category file '%s'.", - "invalidRulesetSkipped": "Cataloger: Skipping invalid PMD Ruleset file '%s'.", - "xmlDropped": "Cataloger: Dropping XML file [%s] since its path does not conform to Rulesets or Category.", - "langMarkedForDeprecation": "Future releases will not include PMD support for %s. If this would cause you hardship, please log an issue on github.com/forcedotcom/sfdx-scanner", - "customRuleFileNotFound": "Custom rule file path [%s] for language [%s] was not found.", - "pmdSkippedFile": "PMD failed to evaluate against file '%s'. Message: %s", - "pmdSuppressedViolation": "PMD suppressed violation against file '%s'. Message: %s. Suppression Type: %s. User Message: %s", - "unexpectedPmdNodeType": "Encountered unexpected PMD node of type '%s'", - "multipleMethodTargetMatches": "Total of %s methods in file %s matched name #%s", - "noMethodTargetMatches": "No methods in file %s matched name #%s()", - "pmdConfigError": "PMD failed to evaluate rule '%s'. Message: %s", - "sfgeWarnLog": "%s" - }, - "error": { - "internal": { - "unexpectedError": "INTERNAL ERROR: Unexpected error occurred while cataloging rules: %s. Please log an issue with us at github.com/forcedotcom/sfdx-scanner.", - "mainInvalidArgument": "INTERNAL ERROR: Invalid arguments passed to Main. Details: %s. Please log an issue with us at github.com/forcedotcom/sfdx-scanner.", - "jsonWriteFailed": "INTERNAL ERROR: Failed to write JSON to file: %s. Please log an issue with us at github.com/forcedotcom/sfdx-scanner.", - "classpathDoesNotExist": "INTERNAL ERROR: Path does not exist: %s. Please log an issue with us at github.com/forcedotcom/sfdx-scanner.", - "xmlMissingInClasspath": "INTERNAL ERROR: XML resource [%s] found in jar, but not in Classpath. Please log an issue with us at github.com/forcedotcom/sfdx-scanner." - }, - "external": { - "errorMessageAbove": "Please see error details displayed above.", - "genericErrorMessage": "ERROR: An unexpected error occurred. Please log an issue on github.com/forcedotcom/sfdx-scanner.", - "jarNotReadable": "ERROR: Unable to read resource JAR: %s", - "dirNotReadable": "ERROR: Unable to walk directory: %s", - "multipleRuleDesc": "ERROR: PMD Rule [%s] has %s 'description' elements. Please reduce this number to 1.", - "recursionLimitReached": "ERROR: PMD Ruleset [%s] references rule [%s] through 10 or more layers of indirection. Please reduce this number.", - "xmlNotReadable": "ERROR: Error occurred while reading file [%s]: %s", - "xmlNotParsable": "ERROR: Could not parse XML file [%s]: %s", - "duplicateXmlPath": "ERROR: XML path [%s] defined in jar [%s] collides with previously defined path in jar [%s]. You will need to remove one of the jars by executing the following command 'sfdx scanner:rule:remove --force --path '", - "sfgeIncompleteAnalysis": "ERROR: Salesforce Graph Engine encountered an error and couldn't complete analysis: %s", - "sfgeErrorLog": "%s" - } - } - -} diff --git a/messages/EventKeyTemplates.md b/messages/EventKeyTemplates.md new file mode 100644 index 000000000..fa9230d9b --- /dev/null +++ b/messages/EventKeyTemplates.md @@ -0,0 +1,183 @@ +# info.categoryImplicitlyRun + +Implicitly including %s rules from category '%s' + +# info.jarAndXmlProcessed + +Cataloger: XML files collected from JAR [%s]: %s + +# info.usingEngineConfigFile + +Using engine configuration file at %s + +# info.generalInternalLog + +Log from Java: %s + +# info.customEslintHeadsUp + +About to run Eslint with custom config in %s. Please make sure your current directory has all the required NPM dependencies. + +# info.customPmdHeadsUp + +About to run PMD with custom config in %s. Please make sure that any custom rule references have already been added to the plugin through scanner:rule:add command. + +# info.pmdRuleSkipped + +Omitting results for PMD rule "%s". Reason: %s. + +# info.unmatchedPathExtensionCpd + +Path extensions for the following files will not be processed by CPD: %s + +# info.sfgeInfoLog + +%s + +# info.sfgeMetaInfoCollected + +Loaded %s: [ %s ] + +# info.sfgeFinishedCompilingFiles + +Compiled %s files. + +# info.sfgeStartedBuildingGraph + +Building graph. + +# info.sfgeFinishedBuildingGraph + +Added all compilation units to graph. + +# info.sfgePathEntryPointsIdentified + +Identified %s path entry point(s). + +# info.sfgeViolationsInPathProgress + +Detected %s violation(s) from %s path(s) on %s/%s entry point(s). + +# info.sfgeCompletedPathAnalysis + +Overall, analyzed %s path(s) from %s entry point(s). Detected %s violation(s). + +# info.telemetry + +This message is unused. + +# warning.pmd7IncompatibleRule + +PMD rule [%s] isn't compatible with PMD 7.0: %s. Resolve these issues to future-proof your rule. If you need help, log an issue on github.com/forcedotcom/sfdx-scanner + +# warning.invalidCategorySkipped + +Cataloger: Skipping invalid PMD Category file '%s'. + +# warning.invalidRulesetSkipped + +Cataloger: Skipping invalid PMD Ruleset file '%s'. + +# warning.xmlDropped + +Cataloger: Dropping XML file [%s] since its path does not conform to Rulesets or Category. + +# warning.langMarkedForDeprecation + +Future releases will not include PMD support for %s. If this would cause you hardship, please log an issue on github.com/forcedotcom/sfdx-scanner + +# warning.customRuleFileNotFound + +Custom rule file path [%s] for language [%s] was not found. + +# warning.pmdSkippedFile + +PMD failed to evaluate against file '%s'. Message: %s + +# warning.pmdSuppressedViolation + +PMD suppressed violation against file '%s'. Message: %s. Suppression Type: %s. User Message: %s + +# warning.unexpectedPmdNodeType + +Encountered unexpected PMD node of type '%s' + +# warning.multipleMethodTargetMatches + +Total of %s methods in file %s matched name #%s + +# warning.noMethodTargetMatches + +No methods in file %s matched name #%s() + +# warning.pmdConfigError + +PMD failed to evaluate rule '%s'. Message: %s + +# warning.sfgeWarnLog + +%s + +# error.internal.unexpectedError + +INTERNAL ERROR: Unexpected error occurred while cataloging rules: %s. Please log an issue with us at github.com/forcedotcom/sfdx-scanner. + +# error.internal.mainInvalidArgument + +INTERNAL ERROR: Invalid arguments passed to Main. Details: %s. Please log an issue with us at github.com/forcedotcom/sfdx-scanner. + +# error.internal.jsonWriteFailed + +INTERNAL ERROR: Failed to write JSON to file: %s. Please log an issue with us at github.com/forcedotcom/sfdx-scanner. + +# error.internal.classpathDoesNotExist + +INTERNAL ERROR: Path does not exist: %s. Please log an issue with us at github.com/forcedotcom/sfdx-scanner. + +# error.internal.xmlMissingInClasspath + +INTERNAL ERROR: XML resource [%s] found in jar, but not in Classpath. Please log an issue with us at github.com/forcedotcom/sfdx-scanner. + +# error.external.errorMessageAbove + +Please see error details displayed above. + +# error.external.genericErrorMessage + +ERROR: An unexpected error occurred. Please log an issue on github.com/forcedotcom/sfdx-scanner. + +# error.external.jarNotReadable + +ERROR: Unable to read resource JAR: %s + +# error.external.dirNotReadable + +ERROR: Unable to walk directory: %s + +# error.external.multipleRuleDesc + +ERROR: PMD Rule [%s] has %s 'description' elements. Please reduce this number to 1. + +# error.external.recursionLimitReached + +ERROR: PMD Ruleset [%s] references rule [%s] through 10 or more layers of indirection. Please reduce this number. + +# error.external.xmlNotReadable + +ERROR: Error occurred while reading file [%s]: %s + +# error.external.xmlNotParsable + +ERROR: Could not parse XML file [%s]: %s + +# error.external.duplicateXmlPath + +ERROR: XML path [%s] defined in jar [%s] collides with previously defined path in jar [%s]. You will need to remove one of the jars by executing the following command '<%= config.bin %> scanner rule remove --force --path ' + +# error.external.sfgeIncompleteAnalysis + +ERROR: Salesforce Graph Engine encountered an error and couldn't complete analysis: %s + +# error.external.sfgeErrorLog + +%s diff --git a/messages/Exceptions.js b/messages/Exceptions.js deleted file mode 100644 index edad3f111..000000000 --- a/messages/Exceptions.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - "RuleFilter" : { - "PositiveOnly": "The filter %s doesn't support exclusion. Edit the filter and try again.", - "MixedTypes": "Inclusive and exclusive values cannot be combined in %s filter. Edit the filter and try again.", - } -} diff --git a/messages/Exceptions.md b/messages/Exceptions.md new file mode 100644 index 000000000..e4d02675e --- /dev/null +++ b/messages/Exceptions.md @@ -0,0 +1,7 @@ +# RuleFilter.PositiveOnly + +The filter %s doesn't support exclusion. Edit the filter and try again. + +# RuleFilter.MixedTypes + +Inclusive and exclusive values cannot be combined in %s filter. Edit the filter and try again. \ No newline at end of file diff --git a/messages/PmdEngine.js b/messages/PmdEngine.js deleted file mode 100644 index b1963d84d..000000000 --- a/messages/PmdEngine.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - "ConfigNotFound": "The PMD config file %s couldn't be found.", - "errorTemplates": { - "rulesetNotFoundTemplate": "PMD couldn't find the source file %s for rule %s. Review the source and rule, and try again." - } -}; diff --git a/messages/PmdEngine.md b/messages/PmdEngine.md new file mode 100644 index 000000000..c59351a9e --- /dev/null +++ b/messages/PmdEngine.md @@ -0,0 +1,7 @@ +# ConfigNotFound + +The PMD config file %s couldn't be found. + +# errorTemplates.rulesetNotFoundTemplate + +PMD couldn't find the source file %s for rule %s. Review the source and rule, and try again. \ No newline at end of file diff --git a/messages/PmdLanguageManager.js b/messages/PmdLanguageManager.js deleted file mode 100644 index 88b1d0971..000000000 --- a/messages/PmdLanguageManager.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - "InvalidLanguageAlias": "The %s file contains invalid language: %s.", - "JavascriptNotSupported": "Javascript isn't supported by the PMD engine." -}; diff --git a/messages/PmdLanguageManager.md b/messages/PmdLanguageManager.md new file mode 100644 index 000000000..a1c46814b --- /dev/null +++ b/messages/PmdLanguageManager.md @@ -0,0 +1,7 @@ +# InvalidLanguageAlias + +The %s file contains invalid language: %s. + +# JavascriptNotSupported + +Javascript isn't supported by the PMD engine. \ No newline at end of file diff --git a/messages/RunOutputProcessor.js b/messages/RunOutputProcessor.js deleted file mode 100644 index 7340a2432..000000000 --- a/messages/RunOutputProcessor.js +++ /dev/null @@ -1,9 +0,0 @@ -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." - } -} diff --git a/messages/RunOutputProcessor.md b/messages/RunOutputProcessor.md new file mode 100644 index 000000000..e70effe4c --- /dev/null +++ b/messages/RunOutputProcessor.md @@ -0,0 +1,19 @@ +# output.engineSummaryTemplate + +Executed %s, found %s violation(s) across %s file(s). + +# output.noViolationsDetected + +Executed engines: %s. No rule violations found. + +# output.sevThresholdSummary + +Rule violations of severity %s or more severe were detected. + +# output.writtenToConsole + +Rule violations were logged to the console. + +# output.writtenToOutFile + +Rule violations were written to %s. \ No newline at end of file diff --git a/messages/SfgeEngine.js b/messages/SfgeEngine.js deleted file mode 100644 index 1b3cd6ba3..000000000 --- a/messages/SfgeEngine.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - "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.` - } -}; diff --git a/messages/SfgeEngine.md b/messages/SfgeEngine.md new file mode 100644 index 000000000..a60b487a9 --- /dev/null +++ b/messages/SfgeEngine.md @@ -0,0 +1,11 @@ +# messages.pleaseWait + +Please wait + +# messages.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. \ No newline at end of file diff --git a/messages/TypescriptEslintStrategy.js b/messages/TypescriptEslintStrategy.js deleted file mode 100644 index fd65784f9..000000000 --- a/messages/TypescriptEslintStrategy.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - "FileNotIncludedByTsConfig": "'%s' doesn't reside in a location that is included by your %s 'include' attribute.", - "MissingTsConfigFromCwd": "We couldn't find '%s' in the current directory '%s'. Switch to a directory that contains '%s' or specify the current directory with the --tsconfig flag.", - "InvalidNameTsConfigFromOptions": "The file '%s' specified by the --tsconfig flag must be named '%s'.", - "NotAFileTsConfigFromOptions": "We couldn't find the '%s' at location '%s' specified by the --tsconfig option." -} diff --git a/messages/TypescriptEslintStrategy.md b/messages/TypescriptEslintStrategy.md new file mode 100644 index 000000000..a220c4c96 --- /dev/null +++ b/messages/TypescriptEslintStrategy.md @@ -0,0 +1,15 @@ +# FileNotIncludedByTsConfig + +'%s' doesn't reside in a location that is included by your %s 'include' attribute. + +# MissingTsConfigFromCwd + +We couldn't find '%s' in the current directory '%s'. Switch to a directory that contains '%s' or specify the current directory with the --tsconfig flag. + +# InvalidNameTsConfigFromOptions + +The file '%s' specified by the --tsconfig flag must be named '%s'. + +# NotAFileTsConfigFromOptions + +We couldn't find the '%s' at location '%s' specified by the --tsconfig option. \ No newline at end of file diff --git a/messages/VersionUpgradeManager.js b/messages/VersionUpgradeManager.js deleted file mode 100644 index f3e87d8b9..000000000 --- a/messages/VersionUpgradeManager.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - "upgradeFailed": `The upgrade script for %s failed: %s. Back up your current config file and delete it. The next analysis run will attempt to reconstruct the config file.` -}; diff --git a/messages/VersionUpgradeManager.md b/messages/VersionUpgradeManager.md new file mode 100644 index 000000000..c32903687 --- /dev/null +++ b/messages/VersionUpgradeManager.md @@ -0,0 +1,3 @@ +# upgradeFailed + +The upgrade script for %s failed: %s. Back up your current config file and delete it. The next analysis run will attempt to reconstruct the config file. \ No newline at end of file diff --git a/messages/add.js b/messages/add.js deleted file mode 100644 index 2e6a75879..000000000 --- a/messages/add.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = { - "commandDescription": `add custom rules to Salesforce Code Analyzer's registry`, - "commandDescriptionLong": `Adds custom rules to Salesforce Code Analyzer's registry so that you can run them along with the built-in rules. Compile and test custom rules separately before adding them.`, - "flags": { - "languageDescription": "language that the custom rules are evaluated against", - "languageDescriptionLong": "Language that the custom rules are evaluated against.", - "pathDescription": "one or more paths (such as a directory or JAR file) to custom rule definitions", - "pathDescriptionLong": `One or more paths (such as a directory or JAR file) to custom rule definitions. Specify multiple values as a comma-separated list.` - }, - "validations": { - "languageCannotBeEmpty": "Specify a language", - "pathCannotBeEmpty": "Specify a path" - }, - "examples": `Bundle custom PMD rules in JAR files. Follow PMD conventions, such as defining the custom rules in XML files under a \`/category/\` directory. -See PMD's documentation for more information on writing rules. - -This example shows how to specify two JAR files directly. - $ sfdx scanner:rule:add --language apex --path "/Users/me/rules/Jar1.jar,/Users/me/rules/Jar2.jar" - Successfully added rules for apex. - 2 path(s) added: - /Users/me/rules/Jar1.jar,/Users/me/rules/Jar2.jar - -This example shows how to specify a directory containing one or more JARs, all of which are added to the registry. - $ sfdx scanner:rule:add --language apex --path "/Users/me/rules" - Successfully added rules for apex.` -}; diff --git a/messages/add.md b/messages/add.md new file mode 100644 index 000000000..4ce224067 --- /dev/null +++ b/messages/add.md @@ -0,0 +1,46 @@ +# commandSummary + +add custom rules to Salesforce Code Analyzer's registry + +# commandDescription + +Adds custom rules to Salesforce Code Analyzer's registry so that you can run them along with the built-in rules. Compile and test custom rules separately before adding them. + +# flags.languageSummary + +language that the custom rules are evaluated against + +# flags.languageDescription + +Language that the custom rules are evaluated against. + +# flags.pathSummary + +one or more paths (such as a directory or JAR file) to custom rule definitions + +# flags.pathDescription + +One or more paths (such as a directory or JAR file) to custom rule definitions. Specify multiple values as a comma-separated list. + +# validations.languageCannotBeEmpty + +Specify a language + +# validations.pathCannotBeEmpty + +Specify a path + +# examples + +Bundle custom PMD rules in JAR files. Follow PMD conventions, such as defining the custom rules in XML files under a `/category/` directory. +See PMD's documentation for more information on writing rules. + +This example shows how to specify two JAR files directly. + $ <%= config.bin %> <%= command.id %> --language apex --path "/Users/me/rules/Jar1.jar,/Users/me/rules/Jar2.jar" + Successfully added rules for apex. + 2 path(s) added: + /Users/me/rules/Jar1.jar,/Users/me/rules/Jar2.jar + +This example shows how to specify a directory containing one or more JARs, all of which are added to the registry. + $ <%= config.bin %> <%= command.id %> --language apex --path "/Users/me/rules" + Successfully added rules for apex. diff --git a/messages/common.js b/messages/common.js deleted file mode 100644 index ad0124953..000000000 --- a/messages/common.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - surveyRequestMessage: `We're continually improving Salesforce Code Analyzer. Tell us what you think! Give feedback at https://research.net/r/SalesforceCA` -}; diff --git a/messages/common.md b/messages/common.md new file mode 100644 index 000000000..1e028d00a --- /dev/null +++ b/messages/common.md @@ -0,0 +1,7 @@ +# flags.verboseSummary + +emit additional command output to stdout + +# surveyRequestMessage + +We're continually improving Salesforce Code Analyzer. Tell us what you think! Give feedback at https://research.net/r/SalesforceCA \ No newline at end of file diff --git a/messages/describe.js b/messages/describe.js deleted file mode 100644 index 1481a0a1f..000000000 --- a/messages/describe.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - "commandDescription": "provide detailed information about a rule", - "commandDescriptionLong": `Provides detailed information about a rule. Information includes the rule's language (such as Apex or Java), the violation it detects, and example code of the violation. The command output also includes the rule's categories and rulesets.`, - "flags": { - "rulenameDescription": "the name of the rule", - "rulenameDescriptionLong": "The name of the rule." - }, - "output": { - "noMatchingRules": "No rules were found with the name '%s'.", - "multipleMatchingRules": "%s rules with the name '%s' were found." - }, - "examples": { - // The example for when only one rule matches the provided name. - "normalExample": `$ sfdx scanner:rule:describe --rulename ExampleRule - name: AvoidWithStatement - categories: Best Practices - rulesets: Controversial Ecmascript - languages: javascript - description: Avoid using with - it's bad news - message: Avoid using with - it's bad news - ` - } -}; diff --git a/messages/describe.md b/messages/describe.md new file mode 100644 index 000000000..5226678da --- /dev/null +++ b/messages/describe.md @@ -0,0 +1,33 @@ +# commandSummary + +provide detailed information about a rule + +# commandDescription + +Provides detailed information about a rule. Information includes the rule's language (such as Apex or Java), the violation it detects, and example code of the violation. The command output also includes the rule's categories and rulesets. + +# flags.rulenameSummary + +the name of the rule + +# flags.rulenameDescription + +The name of the rule. + +# output.noMatchingRules + +No rules were found with the name '%s'. + +# output.multipleMatchingRules + +%s rules with the name '%s' were found. + +# examples.normalExample + +$ <%= config.bin %> <%= command.id %> --rulename ExampleRule + name: AvoidWithStatement + categories: Best Practices + rulesets: Controversial Ecmascript + languages: javascript + description: Avoid using with - it's bad news + message: Avoid using with - it's bad news diff --git a/messages/eslintEngine.js b/messages/eslintEngine.js deleted file mode 100644 index 3b123b7b9..000000000 --- a/messages/eslintEngine.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - "InvalidPath": "The path in the `overriddenConfigPath` property of Config.json is invalid. %s.", - "ConfigFileMissing": "We couldn't find %s with overridden path %s." -}; diff --git a/messages/eslintEngine.md b/messages/eslintEngine.md new file mode 100644 index 000000000..a600c2b36 --- /dev/null +++ b/messages/eslintEngine.md @@ -0,0 +1,7 @@ +# InvalidPath + +The path in the `overriddenConfigPath` property of Config.json is invalid. %s. + +# ConfigFileMissing + +We couldn't find %s with overridden path %s. \ No newline at end of file diff --git a/messages/jreSetupManager.js b/messages/jreSetupManager.js deleted file mode 100644 index ff86330b6..000000000 --- a/messages/jreSetupManager.js +++ /dev/null @@ -1,10 +0,0 @@ -const fixInstructions = - `Please verify that Java 1.8 or later is installed on your machine and try again. -If the problem persists, please manually add a 'javaHome' property to your Config.json file, referencing your Java home directory.`; - -module.exports = { - "NoJavaHomeFound": `We couldn't find Java Home.\n${fixInstructions}`, - "InvalidJavaHome": `The Java Home is invalid: %s. Error code: %s.\n${fixInstructions}`, - "VersionNotFound": `We couldn't find the Java version.\n${fixInstructions}`, - "InvalidVersion": "Java version %s isn't supported. Install Java 1.8 or later." -}; diff --git a/messages/jreSetupManager.md b/messages/jreSetupManager.md new file mode 100644 index 000000000..d0dd7a1b5 --- /dev/null +++ b/messages/jreSetupManager.md @@ -0,0 +1,21 @@ +# NoJavaHomeFound + +We couldn't find Java Home. +Please verify that Java 1.8 or later is installed on your machine and try again. +If the problem persists, please manually add a 'javaHome' property to your Config.json file, referencing your Java home directory. + +# InvalidJavaHome + +The Java Home is invalid: %s. Error code: %s. +Please verify that Java 1.8 or later is installed on your machine and try again. +If the problem persists, please manually add a 'javaHome' property to your Config.json file, referencing your Java home directory. + +# VersionNotFound + +We couldn't find the Java version. +Please verify that Java 1.8 or later is installed on your machine and try again. +If the problem persists, please manually add a 'javaHome' property to your Config.json file, referencing your Java home directory. + +# InvalidVersion + +Java version %s isn't supported. Install Java 1.8 or later. \ No newline at end of file diff --git a/messages/list.js b/messages/list.js deleted file mode 100644 index f040be98a..000000000 --- a/messages/list.js +++ /dev/null @@ -1,40 +0,0 @@ -module.exports = { - "commandDescription": "list basic information about all rules matching provided criteria", - "commandDescriptionLong": `Lists all the rules available in the catalog. You can filter the output to view a smaller set of rules. To get more information about a specific rule, use the \`scanner:rule:describe\` command.`, - "flags": { - "languageDescription": "select rules by language", - "languageDescriptionLong": "Selects rules by language. Enter multiple values as a comma-separated list.", - "categoryDescription": "select rules by category", - "categoryDescriptionLong": "Selects rules by category. Enter multiple values as a comma-separated list.", - "rulesetDescription": "[deprecated] select rules by ruleset", - "rulesetDescriptionLong": "[deprecated] Selects rules by ruleset. Enter multiple values as a comma-separated list.", - 'engineDescription': "select rules by engine", - 'engineDescriptionLong': "Selects rules by engine. Enter multiple engines as a comma-separated list." - }, - "rulesetDeprecation": "The 'ruleset' command parameter is deprecated. Use 'category' instead", - "columnNames": { - "name": "name", - "languages": "languages", - "categories": "categories", - "rulesets": "rulesets [dep]", - "is-dfa": "is dfa", - "is-pilot": "is pilot", - "engine": "engine" - }, - "yes": "Y", - "no": "N", - "examples": ` -This example invokes the command without filter criteria, which returns all rules. - $ sfdx scanner:rule:list - -This example returns all rules for Apex OR Javascript. Values supplied to a single filter are handled with a logical OR. - $ sfdx scanner:rule:list --language apex,javascript - -This example returns all rules except those in the Design or Best Practices categories. Exclude categories by specifying the negation operator and enclosing the values in single quotes. - $ sfdx scanner:rule:list --category '!Design,!Best Practices' - -This example returns all rules that target Apex OR Javascript, AND are members of the Braces OR Security rulesets. -The different filters are combined with a logical AND. - $ sfdx scanner:rule:list --language apex,javascript --ruleset Braces,Security -` -}; diff --git a/messages/list.md b/messages/list.md new file mode 100644 index 000000000..7fa8f2d50 --- /dev/null +++ b/messages/list.md @@ -0,0 +1,94 @@ +# commandSummary + +list basic information about all rules matching provided criteria + +# commandDescription + +Lists all the rules available in the catalog. You can filter the output to view a smaller set of rules. To get more information about a specific rule, use the `scanner rule describe` command. + +# flags.languageSummary + +select rules by language + +# flags.languageDescription + +Selects rules by language. Enter multiple values as a comma-separated list. + +# flags.categorySummary + +select rules by category + +# flags.categoryDescription + +Selects rules by category. Enter multiple values as a comma-separated list. + +# flags.rulesetSummary + +[deprecated] select rules by ruleset + +# flags.rulesetDescription + +[deprecated] Selects rules by ruleset. Enter multiple values as a comma-separated list. + +# flags.engineSummary + +select rules by engine + +# flags.engineDescription + +Selects rules by engine. Enter multiple engines as a comma-separated list. + +# rulesetDeprecation + +The 'ruleset' command parameter is deprecated. Use 'category' instead + +# columnNames.name + +name + +# columnNames.languages + +languages + +# columnNames.categories + +categories + +# columnNames.rulesets + +rulesets [dep] + +# columnNames.is-dfa + +is dfa + +# columnNames.is-pilot + +is pilot + +# columnNames.engine + +engine + +# yes + +Y + +# no + +N + +# examples + +This example invokes the command without filter criteria, which returns all rules. + $ <%= config.bin %> <%= command.id %> + +This example returns all rules for Apex OR Javascript. Values supplied to a single filter are handled with a logical OR. + $ <%= config.bin %> <%= command.id %> --language apex,javascript + +This example returns all rules except those in the Design or Best Practices categories. Exclude categories by specifying the negation operator and enclosing the values in single quotes. + $ <%= config.bin %> <%= command.id %> --category '!Design,!Best Practices' + +This example returns all rules that target Apex OR Javascript, AND are members of the Braces OR Security rulesets. +The different filters are combined with a logical AND. + $ <%= config.bin %> <%= command.id %> --language apex,javascript --ruleset Braces,Security diff --git a/messages/remove.js b/messages/remove.js deleted file mode 100644 index 376f317b9..000000000 --- a/messages/remove.js +++ /dev/null @@ -1,37 +0,0 @@ -module.exports = { - "commandDescription": "remove custom rules from the registry of available rules", - "commandDescriptionLong": `Removes custom rules from the registry of available rules. Use the \`-p|--path\` parameter to specify one or more paths to remove. If you don't specify any parameters, the command lists all valid custom paths but doesn't remove any.`, - "flags": { - "forceDescription": "bypass the confirmation prompt and immediately remove the rules", - "forceDescriptionLong": "Bypasses the confirmation prompt and immediately removes the rules.", - "pathDescription": "one or more paths to remove", - "pathDescriptionLong": "One or more paths to remove. Specify multiple values with a comma-separated list." - }, - "validations": { - "pathCannotBeEmpty": "Specify at least one path." - }, - "errors": { - "noMatchingPaths": "No registered custom rules match the provided paths." - }, - "output": { - "aborted": "The operation stopped.", - "dryRunReturnedNoRules": "No custom rules are registered.", - "dryRunOutput": "%i custom path(s) available for removal:\n%s", - // Use a bit of leading whitespace so the paths hang underneath the initial line. - "dryRunRuleTemplate": " %s", - // Use a bit of leading whitespace so the rules hang underneath the initial line. - "ruleTemplate": " '%s', defined in %s", - "deletionPrompt": "These rules will be unregistered:\n%s\nDo you wish to proceed? (y/n)", - "resultSummary": "Success. These rules were unregistered: %s.", - }, - "examples": `This example runs the command without arguments to see a list of registered custom paths. - $ sfdx scanner:rule:remove - -This example uses the --path parameter to deregister the rules defined in somerules.jar and any JARs/XMLs contained in the rules folder. - $ sfdx scanner:rule:remove --path "~/path/to/somerules.jar,~/path/to/folder/containing/rules" - -This example uses the --force flag to bypass the confirmation prompt, removing all rules defined in somerules.jar. -By default, a list of all rules that will be unregistered is displayed, and the action must be confirmed. To bypass that confirmation, use the --force flag. - $ sfdx scanner:rule:remove --force --path "~/path/to/somerules.jar" -` -}; diff --git a/messages/remove.md b/messages/remove.md new file mode 100644 index 000000000..deba35626 --- /dev/null +++ b/messages/remove.md @@ -0,0 +1,74 @@ +# commandSummary + +remove custom rules from the registry of available rules + +# commandDescription + +Removes custom rules from the registry of available rules. Use the `-p|--path` parameter to specify one or more paths to remove. If you don't specify any parameters, the command lists all valid custom paths but doesn't remove any. + +# flags.forceSummary + +bypass the confirmation prompt and immediately remove the rules + +# flags.forceDescription + +Bypasses the confirmation prompt and immediately removes the rules. + +# flags.pathSummary + +one or more paths to remove + +# flags.pathDescription + +One or more paths to remove. Specify multiple values with a comma-separated list. + +# validations.pathCannotBeEmpty + +Specify at least one path. + +# errors.noMatchingPaths + +No registered custom rules match the provided paths. + +# output.aborted + +The operation stopped. + +# output.dryRunReturnedNoRules + +No custom rules are registered. + +# output.dryRunOutput + +%i custom path(s) available for removal: +%s + +# output.dryRunRuleTemplate + +%s + +# output.ruleTemplate + +'%s', defined in %s + +# output.deletionPrompt + +These rules will be unregistered: +%s +Do you wish to proceed? (y/n) + +# output.resultSummary + +Success. These rules were unregistered: %s. + +# examples + +This example runs the command without arguments to see a list of registered custom paths. + $ <%= config.bin %> <%= command.id %> + +This example uses the --path parameter to deregister the rules defined in somerules.jar and any JARs/XMLs contained in the rules folder. + $ <%= config.bin %> <%= command.id %> --path "~/path/to/somerules.jar,~/path/to/folder/containing/rules" + +This example uses the --force flag to bypass the confirmation prompt, removing all rules defined in somerules.jar. +By default, a list of all rules that will be unregistered is displayed, and the action must be confirmed. To bypass that confirmation, use the --force flag. + $ <%= config.bin %> <%= command.id %> --force --path "~/path/to/somerules.jar" diff --git a/messages/run-common.js b/messages/run-common.js deleted file mode 100644 index 7a5c116f5..000000000 --- a/messages/run-common.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - "flags": { - "categoryDescription": "one or more categories of rules to run", - "categoryDescriptionLong": "One or more categories of rules to run. Specify multiple values as a comma-separated list.", - "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" - } -} diff --git a/messages/run-common.md b/messages/run-common.md new file mode 100644 index 000000000..807d9221b --- /dev/null +++ b/messages/run-common.md @@ -0,0 +1,83 @@ +# flags.categorySummary + +one or more categories of rules to run + +# flags.categoryDescription + +One or more categories of rules to run. Specify multiple values as a comma-separated list. + +# flags.formatSummary + +specify results output format + +# flags.formatDescription + +Specifies results output format written directly to the console. + +# flags.normalizesevSummary + +return normalized severity 1 (high), 2 (moderate), and 3 (low), and the engine-specific severity + +# flags.normalizesevDescription + +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. + +# flags.outfileSummary + +write output to a file + +# flags.outfileDescription + +Writes output to a file. + +# flags.projectdirSummary + +provide root directory of project + +# flags.projectdirDescription + +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. + +# flags.sevthresholdSummary + +throw an error when a violation threshold is reached, the --normalize-severity is invoked, and severity levels are reset to the baseline + +# flags.sevthresholdDescription + +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. + +# internal.outfileMustBeValid + +The %s environment variable must be a well-formed filepath. + +# internal.outfileMustBeSupportedType + +The %s environment variable must be of a supported type: .csv; .xml; .json; .html; .sarif. + +# validations.cannotWriteTableToFile + +Format 'table' can't be written to a file. Specify a different format. + +# validations.outfileFormatMismatch + +The selected output format doesn't match the output file type. Output format: %s. Output file type: %s. + +# validations.outfileMustBeValid + +--outfile must be a well-formed filepath. + +# validations.outfileMustBeSupportedType + +--outfile must be of a supported type: .csv; .xml; .json; .html; .sarif. + +# validations.projectdirCannotBeGlob + +--projectdir cannot specify globs + +# validations.projectdirMustBeDir + +--projectdir must specify directories + +# validations.projectdirMustExist + +--projectdir must specify existing paths diff --git a/messages/run-dfa.js b/messages/run-dfa.js deleted file mode 100644 index ab403046b..000000000 --- a/messages/run-dfa.js +++ /dev/null @@ -1,54 +0,0 @@ -module.exports = { - "commandDescription": "scan codebase with all DFA rules", - "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": { - "pathexplimitDescription": "specify a path expansion upper boundary to limit the complexity of code that Graph Engine analyzes. Alternatively, set the value using environment variable `SFGE_PATH_EXPANSION_LIMIT`", - "pathexplimitDescriptionLong": "Specifies a path expansion upper boundary to limit the complexity of code Graph Engine analyzes before failing fast. Set the value to -1 to remove any upper boundary. --pathexplimit inherits value from SFGE_PATH_EXPANSION_LIMIT env-var, if set. Its default value is derived from JVM heap space allocation.", - "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.", - "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", - "targetDescriptionLong": "Returns the source code location. Use glob patterns or specify individual methods with #-syntax. Multiple values are specified as a comma-separated list.", - "withpilotDescription": "allow pilot rules to execute", - "withpilotDescriptionLong": "Allows pilot rules to execute." - }, - "validations": { - "methodLevelTargetCannotBeGlob": "Method-level targets supplied to --target cannot be globs", - "methodLevelTargetMustBeRealFile": "Method-level target %s must be a real file", - "projectdirIsRequired": "--projectdir is required for this command.", - }, - "examples": `The paths specified for --projectdir must contain all files specified through --target cumulatively. - $ 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: - $ sfdx scanner:run:dfa --target "./**/*.cls" --projectdir "./myproject/" -Globs must be wrapped in quotes, as in these Windows and Unix examples, which evaluate rules against all .cls files in the current directory and subdirectories except for IgnoreMe.cls: -Unix example: - $ sfdx scanner:run:dfa --target "./**/*.cls,!./**/IgnoreMe.cls" ... -Windows example: - $ sfdx scanner:run:dfa --target ".\\**\\*.cls,!.\\**\\IgnoreMe.cls" ... -You can target individual methods within a file with a suffix hash (#) on the file's path, and with a semi-colon-delimited list of method names. This syntax is incompatible with globs and directories. This example evaluates rules against all methods named Method1 or Method2 in File1.cls, and all methods named Method3 in File2.cls: - $ sfdx scanner:run:dfa --target "./File1.cls#Method1;Method2,./File2.cls#Method3" ... -Use --normalize-severity to output a normalized severity across all engines, in addition to the engine-specific severity. Normalized severity is 1 (high), 2 (moderate), and 3 (low): - $ sfdx scanner:run:dfa --target "./some-project/" --projectdir "./some-project/" --format csv --normalize-severity -Use --severity-threshold to throw a non-zero exit code when rule violations of a specific normalized severity or greater are found. If there are any rule violations with a severity of 2 or 1, the exit code is equal to the severity of the most severe violation: - $ sfdx scanner:run:dfa --target "./some-project/" --projectdir "./some-project/" --severity-threshold 2 -use --rule-thread-count to allow more (or fewer) entrypoints to be evaluated concurrently: - $ sfdx scanner:run:dfa --rule-thread-count 6 ... -Use --rule-thread-timeout to increase or decrease the maximum runtime for a single entrypoint evaluation. This increases the timeout from the 15-minute default to 150 minutes: - $ sfdx scanner:run:dfa --rule-thread-timeout 9000000 ... -Use --sfgejvmargs to pass Java Virtual Machine args to override system defaults while executing Salesforce Graph Engine's rules. -The example overrides the system's default heap space allocation to 8 GB and decreases chances of encountering OutOfMemory error. - $ sfdx scanner:run:dfa --sfgejvmargs "-Xmx8g" ... -Use --with-pilot to allow execution of pilot rules: -This example allows pilot rules in the "Performance" category to execute. - $ sfdx scanner:run:dfa --category 'Performance' --with-pilot ... -` -}; diff --git a/messages/run-dfa.md b/messages/run-dfa.md new file mode 100644 index 000000000..0efcee1b1 --- /dev/null +++ b/messages/run-dfa.md @@ -0,0 +1,106 @@ +# commandSummary + +scan codebase with all DFA rules + +# commandDescription + +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.pathexplimitSummary + +specify a path expansion upper boundary to limit the complexity of code that Graph Engine analyzes. Alternatively, set the value using environment variable `SFGE_PATH_EXPANSION_LIMIT` + +# flags.pathexplimitDescription + +Specifies a path expansion upper boundary to limit the complexity of code Graph Engine analyzes before failing fast. Set the value to -1 to remove any upper boundary. --pathexplimit inherits value from SFGE_PATH_EXPANSION_LIMIT env-var, if set. Its default value is derived from JVM heap space allocation. + +# flags.ruledisablewarningviolationSummary + +disable warning violations from Salesforce Graph Engine. Alternatively, set value using environment variable `SFGE_RULE_DISABLE_WARNING_VIOLATION` + +# flags.ruledisablewarningviolationDescription + +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. + +# flags.rulethreadcountSummary + +specify number of threads that evaluate DFA rules. Alternatively, set value using environment variable `SFGE_RULE_THREAD_COUNT`. Default is 4 + +# flags.rulethreadcountDescription + +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. + +# flags.rulethreadtimeoutSummary + +specify timeout for individual rule threads in milliseconds. Alternatively, set the timeout value using environment variable `SFGE_RULE_THREAD_TIMEOUT`. Default: 90000 ms + +# flags.rulethreadtimeoutDescription + +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. + +# flags.sfgejvmargsSummary + +specify Java Virtual Machine (JVM) arguments to optimize Salesforce Graph Engine execution to your system (optional) + +# flags.sfgejvmargsDescription + +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. + +# flags.targetSummary + +return location of source code + +# flags.targetDescription + +Returns the source code location. Use glob patterns or specify individual methods with #-syntax. Multiple values are specified as a comma-separated list. + +# flags.withpilotSummary + +allow pilot rules to execute + +# flags.withpilotDescription + +Allows pilot rules to execute. + +# validations.methodLevelTargetCannotBeGlob + +Method-level targets supplied to --target cannot be globs + +# validations.methodLevelTargetMustBeRealFile + +Method-level target %s must be a real file + +# validations.projectdirIsRequired + +--projectdir is required for this command. + +# examples + +The paths specified for --projectdir must contain all files specified through --target cumulatively. + $ <%= config.bin %> <%= command.id %> --target "./myproject/main/default/classes/*.cls" --projectdir "./myproject/" + $ <%= config.bin %> <%= command.id %> --target "./**/*.cls" --projectdir "./" + $ <%= config.bin %> <%= command.id %> --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: + $ <%= config.bin %> <%= command.id %> --target "./**/*.cls" --projectdir "./myproject/" +Globs must be wrapped in quotes, as in these Windows and Unix examples, which evaluate rules against all .cls files in the current directory and subdirectories except for IgnoreMe.cls: +Unix example: + $ <%= config.bin %> <%= command.id %> --target "./**/*.cls,!./**/IgnoreMe.cls" ... +Windows example: + $ <%= config.bin %> <%= command.id %> --target ".\**\*.cls,!.\**\IgnoreMe.cls" ... +You can target individual methods within a file with a suffix hash (#) on the file's path, and with a semi-colon-delimited list of method names. This syntax is incompatible with globs and directories. This example evaluates rules against all methods named Method1 or Method2 in File1.cls, and all methods named Method3 in File2.cls: + $ <%= config.bin %> <%= command.id %> --target "./File1.cls#Method1;Method2,./File2.cls#Method3" ... +Use --normalize-severity to output a normalized severity across all engines, in addition to the engine-specific severity. Normalized severity is 1 (high), 2 (moderate), and 3 (low): + $ <%= config.bin %> <%= command.id %> --target "./some-project/" --projectdir "./some-project/" --format csv --normalize-severity +Use --severity-threshold to throw a non-zero exit code when rule violations of a specific normalized severity or greater are found. If there are any rule violations with a severity of 2 or 1, the exit code is equal to the severity of the most severe violation: + $ <%= config.bin %> <%= command.id %> --target "./some-project/" --projectdir "./some-project/" --severity-threshold 2 +use --rule-thread-count to allow more (or fewer) entrypoints to be evaluated concurrently: + $ <%= config.bin %> <%= command.id %> --rule-thread-count 6 ... +Use --rule-thread-timeout to increase or decrease the maximum runtime for a single entrypoint evaluation. This increases the timeout from the 15-minute default to 150 minutes: + $ <%= config.bin %> <%= command.id %> --rule-thread-timeout 9000000 ... +Use --sfgejvmargs to pass Java Virtual Machine args to override system defaults while executing Salesforce Graph Engine's rules. +The example overrides the system's default heap space allocation to 8 GB and decreases chances of encountering OutOfMemory error. + $ <%= config.bin %> <%= command.id %> --sfgejvmargs "-Xmx8g" ... +Use --with-pilot to allow execution of pilot rules: +This example allows pilot rules in the "Performance" category to execute. + $ <%= config.bin %> <%= command.id %> --category 'Performance' --with-pilot ... diff --git a/messages/run-pathless.js b/messages/run-pathless.js deleted file mode 100644 index 960309334..000000000 --- a/messages/run-pathless.js +++ /dev/null @@ -1,88 +0,0 @@ -module.exports = { - "commandDescription": "scan a codebase with a selection of rules", - "commandDescriptionLong": `Scans a codebase with a selection of rules. You can scan the codebase with all the rules in the registry, or use parameters to filter the rules based on rulename, category, or ruleset. You can specify the format of the output, such as XML or JUnit. You can print the output to the console (default) or to a file using the --outfile parameter.`, - "flags": { - "rulesetDescription": "[deprecated] rulesets to run", - "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.", - "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.", - '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." - }, - "validations": { - "methodLevelTargetingDisallowed": "The target '%s' is invalid because method-level targeting isn't supported with this command.", - "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": { - "invalidEnvJson": "--env parameter must be a well-formed JSON.", - "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.", - "examples": `This example evaluates all rules against somefile.js. -Invoking code analyzer without specifying any rules causes all rules to be run. - $ sfdx scanner:run --format xml --target "somefile.js" - -This example evaluates all rules in the Design and Best Practices categories. -When you specify multiple categories or rulesets, the results are combined with a logical OR. - $ sfdx scanner:run --format xml --target "somefile.js" -- - -This example evaluates all rules except those in the Design or Best Practices categories. -Exclude categories by specifying the negation operator and enclosing the values in single quotes. - $ sfdx scanner:run --format xml --target "somefile.js" --category '!Design,!Best Practices' - -Wrap globs in quotes. These examples evaluate rules against all .js files in the current directory, except for IgnoreMe.js. -Unix example: - $ sfdx scanner:run --target './**/*.js,!./**/IgnoreMe.js' ... -Windows example: - $ sfdx scanner:run --target ".\\**\\*.js,!.\\**\\IgnoreMe.js" ... - -This example scans the project contained in '/my-project' if the current working directory is another directory. -Specify tsconfig.json if the current working directory does not contain the tsconfig.json that corresponds to the TypeScript files being scanned. - $ sfdx scanner:run --target "/my-project/**/*.ts" --tsconfig "/my-project/tsconfig.json" - -This example evaluates rules against somefile.js, including Jasmine in the environment variables. -Uses --env to override the default ESLint environment variables to add frameworks. - $ sfdx scanner:run --target "somefile.js" --env '{"jasmine": true}' - -This example evaluates rules aginst somefile.js using eslint-lwc and pmd engines. -Use --engine to include or exclude engines. Any engine listed will be run, regardless of its current 'disabled' attribute. - $ sfdx scanner:run --target "somefile.js" --engine "eslint-lwc,pmd" - -This example executes CPD engine against known file extensions in "/some/dir". CPD helps detect blocks of code duplication in selected languages. -Use --engine to invoke engines that are not enabled by default. - $ sfdx scanner:run --target "/some/dir" --engine cpd - -This example executes rules defined in pmd_rule_ref.xml against the files in 'src'. -To use PMD with your own rule reference file, use --pmdconfig. Note that rule filters are not applied. - $ sfdx scanner:run --target "src" --pmdconfig "pmd_rule_ref.xml" - -This example uses a custom config to scan the files in 'src'. -To use ESLint with your own .eslintrc.json file, use --eslintconfig. Make sure that the directory you run the command from has all the NPM dependencies installed. - $ sfdx scanner:run --target "src" --eslintconfig "/home/my/setup/.eslintrc.json" - -This example uses --normalize-severity to output normalized severity and engine-specific severity across all engines. Normalized severity is: 1 (high), 2 (moderate), and 3 (low). - $ sfdx scanner:run --target "/some-project/" --format csv --normalize-severity - -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/" -` -}; diff --git a/messages/run-pathless.md b/messages/run-pathless.md new file mode 100644 index 000000000..db341aa81 --- /dev/null +++ b/messages/run-pathless.md @@ -0,0 +1,153 @@ +# commandSummary + +scan a codebase with a selection of rules + +# commandDescription + +Scans a codebase with a selection of rules. You can scan the codebase with all the rules in the registry, or use parameters to filter the rules based on rulename, category, or ruleset. You can specify the format of the output, such as XML or JUnit. You can print the output to the console (default) or to a file using the --outfile parameter. + +# flags.rulesetSummary + +[deprecated] rulesets to run + +# flags.rulesetDescription + +[deprecated] One or more rulesets to run. Specify multiple values as a comma-separated list. + +# flags.targetSummary + +source code location + +# flags.targetDescription + +Source code location. May use glob patterns. Specify multiple values as a comma-separated list. + +# flags.envSummary + +[deprecated] override ESLint's default environment variables, in JSON-formatted string + +# flags.envDescription + +[deprecated] Overrides ESLint's default environmental variables, in JSON-formatted string. + +# flags.envParamDeprecationWarning + +--env parameter is being deprecated, and will be removed in a future release. + +# flags.tsconfigSummary + +location of tsconfig.json file + +# flags.tsconfigDescription + +Location of tsconfig.json file used by eslint-typescript engine. + +# flags.engineSummary + +specify which engines to run + +# flags.engineDescription + +Specifies one or more engines to run. Submit multiple values as a comma-separated list. + +# flags.eslintConfigSummary + +specify the location of eslintrc config to customize eslint engine + +# flags.eslintConfigDescription + +Specifies the location of eslintrc config to customize eslint engine. + +# flags.pmdConfigSummary + +specify location of PMD rule reference XML file to customize rule selection + +# flags.pmdConfigDescription + +Specifies the location of PMD rule reference XML file to customize rule selection. + +# flags.verboseViolationsSummary + +return retire-js violation message details + +# flags.verboseViolationsDescription + +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. + +# validations.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.invalidEnvJson + +--env parameter must be a well-formed JSON. + +# output.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. + +# examples + +This example evaluates all rules against somefile.js. +Invoking code analyzer without specifying any rules causes all rules to be run. + $ <%= config.bin %> <%= command.id %> --format xml --target "somefile.js" + +This example evaluates all rules in the Design and Best Practices categories. +When you specify multiple categories or rulesets, the results are combined with a logical OR. + $ <%= config.bin %> <%= command.id %> --format xml --target "somefile.js" -- + +This example evaluates all rules except those in the Design or Best Practices categories. +Exclude categories by specifying the negation operator and enclosing the values in single quotes. + $ <%= config.bin %> <%= command.id %> --format xml --target "somefile.js" --category '!Design,!Best Practices' + +Wrap globs in quotes. These examples evaluate rules against all .js files in the current directory, except for IgnoreMe.js. +Unix example: + $ <%= config.bin %> <%= command.id %> --target './**/*.js,!./**/IgnoreMe.js' ... +Windows example: + $ <%= config.bin %> <%= command.id %> --target ".\**\*.js,!.\**\IgnoreMe.js" ... + +This example scans the project contained in '/my-project' if the current working directory is another directory. +Specify tsconfig.json if the current working directory does not contain the tsconfig.json that corresponds to the TypeScript files being scanned. + $ <%= config.bin %> <%= command.id %> --target "/my-project/**/*.ts" --tsconfig "/my-project/tsconfig.json" + +This example evaluates rules against somefile.js, including Jasmine in the environment variables. +Uses --env to override the default ESLint environment variables to add frameworks. + $ <%= config.bin %> <%= command.id %> --target "somefile.js" --env '{"jasmine": true}' + +This example evaluates rules aginst somefile.js using eslint-lwc and pmd engines. +Use --engine to include or exclude engines. Any engine listed will be run, regardless of its current 'disabled' attribute. + $ <%= config.bin %> <%= command.id %> --target "somefile.js" --engine "eslint-lwc,pmd" + +This example executes CPD engine against known file extensions in "/some/dir". CPD helps detect blocks of code duplication in selected languages. +Use --engine to invoke engines that are not enabled by default. + $ <%= config.bin %> <%= command.id %> --target "/some/dir" --engine cpd + +This example executes rules defined in pmd_rule_ref.xml against the files in 'src'. +To use PMD with your own rule reference file, use --pmdconfig. Note that rule filters are not applied. + $ <%= config.bin %> <%= command.id %> --target "src" --pmdconfig "pmd_rule_ref.xml" + +This example uses a custom config to scan the files in 'src'. +To use ESLint with your own .eslintrc.json file, use --eslintconfig. Make sure that the directory you run the command from has all the NPM dependencies installed. + $ <%= config.bin %> <%= command.id %> --target "src" --eslintconfig "/home/my/setup/.eslintrc.json" + +This example uses --normalize-severity to output normalized severity and engine-specific severity across all engines. Normalized severity is: 1 (high), 2 (moderate), and 3 (low). + $ <%= config.bin %> <%= command.id %> --target "/some-project/" --format csv --normalize-severity + +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. + $ <%= config.bin %> <%= command.id %> --target "/some-project/" --severity-threshold 2 + +The paths specified for --projectdir must contain all files specified through --target cumulatively. + $ <%= config.bin %> <%= command.id %> --target "./myproject/main/default/classes/*.cls" --projectdir "./myproject/" + $ <%= config.bin %> <%= command.id %> --target "./**/*.cls" --projectdir "./" + $ <%= config.bin %> <%= command.id %> --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: + $ <%= config.bin %> <%= command.id %> --target "./**/*.cls" --projectdir "./myproject/" diff --git a/package.json b/package.json index 3c8832829..c25f5893c 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,24 @@ { "name": "@salesforce/sfdx-scanner", "description": "Static code scanner that applies quality and security rules to Apex code, and provides feedback.", - "version": "3.19.0", + "version": "3.20.0", "author": "ISV SWAT", "bugs": "https://github.com/forcedotcom/sfdx-scanner/issues", "dependencies": { "@babel/core": "^7.11.0", "@babel/eslint-parser": "^7", - "@eslint/js": "^8.35.0", - "@lwc/eslint-plugin-lwc": "^1.1.2", + "@eslint/js": "^8.56.0", + "@lwc/eslint-plugin-lwc": "^1.7.0", "@oclif/core": "^3.3.2", - "@salesforce/command": "^5", - "@salesforce/core": "^3", + "@salesforce/core": "^5", "@salesforce/eslint-config-lwc": "^3.2.1", "@salesforce/eslint-plugin-lightning": "^1.0.0", - "@typescript-eslint/eslint-plugin": "^5.14.0", - "@typescript-eslint/parser": "^5.14.0", + "@salesforce/sf-plugins-core": "^5.0.4", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", "cross-spawn": "^7.0.3", "csv-stringify": "^6.0.5", - "eslint": "^8.35.0", + "eslint": "^8.56.0", "eslint-plugin-import": "^2.25.4", "eslint-plugin-jest": "^26.1.1", "find-java-home": "1.2.2", @@ -37,7 +37,7 @@ "ts-node": "^10", "tslib": "^2", "tsyringe": "^4.1.0", - "typescript": "^4.6.2", + "typescript": "~5.1.0", "untildify": "^4.0.0", "uuid": "^9.0.0", "word-wrap": "^1.2.3", @@ -54,8 +54,8 @@ "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", "@oclif/plugin-help": "^5", - "@oclif/test": "^2", - "@salesforce/dev-config": "^3", + "@salesforce/cli-plugins-testkit": "^5.0.4", + "@salesforce/dev-config": "^4.1.0", "@salesforce/ts-sinon": "^1.1.2", "@types/chai": "^4", "@types/cross-spawn": "^6.0.2", @@ -73,7 +73,7 @@ "@types/uuid": "^8.3.4", "chai": "^4", "cross-env": "^7.0.3", - "eslint": "^8.35.0", + "eslint-plugin-sf-plugin": "^1.16.15", "mocha": "^9", "mocha-junit-reporter": "^2.0.0", "nyc": "^15.0.0", @@ -91,18 +91,20 @@ "/messages", "/npm-shrinkwrap.json", "/oclif.manifest.json", + "/pmd-appexchange", "/html-templates", "/retire-js", "/oclif.lock" ], "homepage": "https://forcedotcom.github.io/sfdx-scanner", "keywords": [ - "sfdx-plugin" + "sfdx-plugin", + "sf-plugin" ], "license": "MIT", "oclif": { "commands": "./lib/commands", - "bin": "sfdx", + "bin": "sf", "topics": { "scanner": { "description": "scan code to detect code quality issues and security vulnerabilities", @@ -119,14 +121,17 @@ "devPlugins": [ "@oclif/plugin-help" ], + "additionalHelpFlags": [ + "-h" + ], "topicSeparator": " ", "flexibleTaxonomy": true }, "nyc": { - "branches": "80", - "lines": "90", - "functions": "90", - "statements": "90" + "branches": "60", + "lines": "75", + "functions": "75", + "statements": "75" }, "repository": "forcedotcom/sfdx-scanner", "scripts": { @@ -136,11 +141,11 @@ "lint-typescript": "eslint ./src --ext .ts --max-warnings 0", "test": "./gradlew test jacocoTestCoverageVerification && nyc mocha --timeout 10000 --retries 5 \"./test/**/*.test.ts\"", "test-quiet": "cross-env SFGE_LOGGING=false ./gradlew test jacocoTestCoverageVerification && nyc mocha --timeout 10000 --retries 5 \"./test/**/*.test.ts\"", - "test-cli-messaging": "./gradlew cli-messaging:test", + "test-cli-messaging": "./gradlew cli-messaging:test cli-messaging:jacocoTestCoverageVerification", "test-pmd-cataloger": "./gradlew pmd-cataloger:test pmd-cataloger:jacocoTestCoverageVerification", "test-sfge": "./gradlew sfge:test sfge:jacocoTestCoverageVerification", "test-sfge-quiet": "cross-env SFGE_LOGGING=false ./gradlew sfge:test sfge:jacocoTestCoverageVerification", - "test-typescript": "nyc mocha --timeout 10000 --retries 5 \"./test/**/*.test.ts\"", + "test-typescript": "tsc -b && nyc mocha --timeout 60000 \"./test/**/*.test.ts\"", "version": "oclif readme && git add README.md" } } diff --git a/pmd-appexchange/docs/AvoidApiSessionId.md b/pmd-appexchange/docs/AvoidApiSessionId.md new file mode 100644 index 000000000..0f4a66bd4 --- /dev/null +++ b/pmd-appexchange/docs/AvoidApiSessionId.md @@ -0,0 +1,18 @@ +AvoidApiSessionId[](#avoidapisessionid) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Session ID use is not approved. + + +**Priority:** High (2) + +**Description:** + + Detects use of Api.Session_ID to retrieve a session ID. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidAuraWithLockerDisabled.md b/pmd-appexchange/docs/AvoidAuraWithLockerDisabled.md new file mode 100644 index 000000000..487d9fd31 --- /dev/null +++ b/pmd-appexchange/docs/AvoidAuraWithLockerDisabled.md @@ -0,0 +1,18 @@ +AvoidAuraWithLockerDisabled[](#avoidaurawithlockerdisabled) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + To enable Lightning Locker, update the apiVersion to version 40 or greater. + + +**Priority:** Critical (1) + +**Description:** + + Detects use of API versions with Lightning Locker disabled in Aura components. Use API version 40 or greater. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidCallingSystemResetPasswordWithEmailTemplate.md b/pmd-appexchange/docs/AvoidCallingSystemResetPasswordWithEmailTemplate.md new file mode 100644 index 000000000..d522f0b12 --- /dev/null +++ b/pmd-appexchange/docs/AvoidCallingSystemResetPasswordWithEmailTemplate.md @@ -0,0 +1,18 @@ +AvoidCallingSystemResetPasswordWithEmailTemplate[](#avoidcallingsystemresetpasswordwithemailtemplate) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Before calling System.resetPasswordWithEmailTemplate(), perform the necessary authorization checks. + + +**Priority:** Critical (1) + +**Description:** + + Detects where System.resetPasswordWithEmailTemplate() exists in Apex code. Use this method with caution. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidChangeProtection.md b/pmd-appexchange/docs/AvoidChangeProtection.md new file mode 100644 index 000000000..ea3644f55 --- /dev/null +++ b/pmd-appexchange/docs/AvoidChangeProtection.md @@ -0,0 +1,18 @@ +AvoidChangeProtection[](#avoidchangeprotection) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Update your code to avoid using FeatureManagement.changeProtection. + + +**Priority:** High (2) + +**Description:** + + Detects potential misuse of FeatureManagement.changeProtection. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidChangeProtectionUnprotected.md b/pmd-appexchange/docs/AvoidChangeProtectionUnprotected.md new file mode 100644 index 000000000..3abed876f --- /dev/null +++ b/pmd-appexchange/docs/AvoidChangeProtectionUnprotected.md @@ -0,0 +1,18 @@ +AvoidChangeProtectionUnprotected[](#avoidchangeprotectionunprotected) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Update your code to avoid using FeatureManagement.changeProtection called by an UnProtected argument. + + +**Priority:** Critical (1) + +**Description:** + + Detects potential misuse of FeatureManagement.changeProtection. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidHardcodedCredentials.md b/pmd-appexchange/docs/AvoidHardcodedCredentials.md new file mode 100644 index 000000000..79ef09293 --- /dev/null +++ b/pmd-appexchange/docs/AvoidHardcodedCredentials.md @@ -0,0 +1,47 @@ +AvoidHardcodedCredentials[](#avoidhardcodedcredentials) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Remove hard-coded credentials from source code. + + +**Priority:** Medium (3) + +**Description:** + + Identifies hard-coded credentials in source code that must be protected using Protected Custom metadata or Protected Custom settings. + +**Example(s):** + + Correct Method + +``` + + + List + false + + Protected + +``` + +Incorrect Method + +``` +public with sharing class test3 { + public test3() { + String key = 'supersecurepassword'; + HttpRequest req = new HttpRequest(); + req.setEndpoint('https://www.example.com/test?APIKEY='+key); + req.setMethod('GET'); + Http http = new Http(); + HTTPResponse res = http.send(req); + return res.getBody(); + } +``` + + + + + diff --git a/pmd-appexchange/docs/AvoidJavaScriptCustomRule.md b/pmd-appexchange/docs/AvoidJavaScriptCustomRule.md new file mode 100644 index 000000000..0456cbb7f --- /dev/null +++ b/pmd-appexchange/docs/AvoidJavaScriptCustomRule.md @@ -0,0 +1,18 @@ +AvoidJavaScriptCustomRule[](#avoidjavascriptcustomrule) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Avoid using JavaScript to execute custom button actions. + + +**Priority:** High (2) + +**Description:** + + Detects use of custom JavaScript actions in custom rules. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidJavaScriptHomePageComponent.md b/pmd-appexchange/docs/AvoidJavaScriptHomePageComponent.md new file mode 100644 index 000000000..ec8373665 --- /dev/null +++ b/pmd-appexchange/docs/AvoidJavaScriptHomePageComponent.md @@ -0,0 +1,18 @@ +AvoidJavaScriptHomePageComponent[](#avoidjavascripthomepagecomponent) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Avoid JavaScript in a home page component body. + + +**Priority:** High (2) + +**Description:** + + Detects use of custom JavaScript actions in home page components. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidJavaScriptWeblink.md b/pmd-appexchange/docs/AvoidJavaScriptWeblink.md new file mode 100644 index 000000000..fee204a03 --- /dev/null +++ b/pmd-appexchange/docs/AvoidJavaScriptWeblink.md @@ -0,0 +1,18 @@ +AvoidJavaScriptWeblink[](#avoidjavascriptweblink) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Avoid using JavaScript in web links. + + +**Priority:** High (2) + +**Description:** + + Detects use of custom JavaScript actions in web links. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidJsLinksInCustomObject.md b/pmd-appexchange/docs/AvoidJsLinksInCustomObject.md new file mode 100644 index 000000000..0be776671 --- /dev/null +++ b/pmd-appexchange/docs/AvoidJsLinksInCustomObject.md @@ -0,0 +1,18 @@ +AvoidJsLinksInCustomObject[](#avoidjslinksincustomobject) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Avoid clickable JavaScript-style URLs. + + +**Priority:** Critical (1) + +**Description:** + + Detects instances of JavaScript-style URLs (javascript:) in Salesforce DOM components, such as web links and buttons. Avoid JavaScript-style URLs in managed packages. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidJsLinksInWebLinks.md b/pmd-appexchange/docs/AvoidJsLinksInWebLinks.md new file mode 100644 index 000000000..90168ffe5 --- /dev/null +++ b/pmd-appexchange/docs/AvoidJsLinksInWebLinks.md @@ -0,0 +1,18 @@ +AvoidJsLinksInWebLinks[](#avoidjslinksinweblinks) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Avoid clickable JavaScript-style URLs. + + +**Priority:** Critical (1) + +**Description:** + + Detects instances of JavaScript-style URLs (javascript:) in Salesforce DOM components, such as web links and buttons. Avoid JavaScript-style URLs in managed packages. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidLmcIsExposedTrue.md b/pmd-appexchange/docs/AvoidLmcIsExposedTrue.md new file mode 100644 index 000000000..c83d05a4a --- /dev/null +++ b/pmd-appexchange/docs/AvoidLmcIsExposedTrue.md @@ -0,0 +1,18 @@ +AvoidLmcIsExposedTrue[](#avoidlmcisexposedtrue) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Use Lightning Message Channel with isExposed set to false. + + +**Priority:** High (2) + +**Description:** + + Detects a Lightning Message Channel with isExposed=true, which isn’t allowed in managed packages. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidLwcBubblesComposedTrue.md b/pmd-appexchange/docs/AvoidLwcBubblesComposedTrue.md new file mode 100644 index 000000000..d3d7d675c --- /dev/null +++ b/pmd-appexchange/docs/AvoidLwcBubblesComposedTrue.md @@ -0,0 +1,18 @@ +AvoidLwcBubblesComposedTrue[](#avoidlwcbubblescomposedtrue) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Avoid setting both Lightning Web component bubbles and composed=true at the same time. + + +**Priority:** Medium (3) + +**Description:** + + Detects Lightning Web Component event configurations where bubbles and composed are both set to true. To avoid sharing sensitive information unintentionally, use this configuration with caution. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidSystemModeInFlows.md b/pmd-appexchange/docs/AvoidSystemModeInFlows.md new file mode 100644 index 000000000..78d97092d --- /dev/null +++ b/pmd-appexchange/docs/AvoidSystemModeInFlows.md @@ -0,0 +1,18 @@ +AvoidSystemModeInFlows[](#avoidsystemmodeinflows) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Reconfigure to avoid running flows in system mode. + + +**Priority:** Medium (3) + +**Description:** + + Detects where default mode must be used in flows instead of system mode. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdInApex.md b/pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdInApex.md new file mode 100644 index 000000000..b3b906be8 --- /dev/null +++ b/pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdInApex.md @@ -0,0 +1,18 @@ +AvoidUnauthorizedApiSessionIdInApex[](#avoidunauthorizedapisessionidinapex) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Use of API.Session_ID might not be authorized. + + +**Priority:** High (2) + +**Description:** + + Detects use of Api.Session_ID to retrieve a session ID. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdInFlows.md b/pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdInFlows.md new file mode 100644 index 000000000..58c47e803 --- /dev/null +++ b/pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdInFlows.md @@ -0,0 +1,18 @@ +AvoidUnauthorizedApiSessionIdInFlows[](#avoidunauthorizedapisessionidinflows) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + $Api.Session_ID usage is not approved. + + +**Priority:** High (2) + +**Description:** + + Detects use of session ID in SOAP API calls in flows. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdVisualforce.md b/pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdVisualforce.md new file mode 100644 index 000000000..b65146a24 --- /dev/null +++ b/pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdVisualforce.md @@ -0,0 +1,18 @@ +AvoidUnauthorizedApiSessionIdVisualforce[](#avoidunauthorizedapisessionidvisualforce) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Retrieval of session ID using API.Session_ID is not authorized. + + +**Priority:** Medium (3) + +**Description:** + + Detects use of Api.Session_ID to retrieve a session ID in Visualforce code. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidUnauthorizedGetSessionIdInApex.md b/pmd-appexchange/docs/AvoidUnauthorizedGetSessionIdInApex.md new file mode 100644 index 000000000..b389d7e97 --- /dev/null +++ b/pmd-appexchange/docs/AvoidUnauthorizedGetSessionIdInApex.md @@ -0,0 +1,18 @@ +AvoidUnauthorizedGetSessionIdInApex[](#avoidunauthorizedgetsessionidinapex) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Use of UserInfo.getSessionId might not be authorized. + + +**Priority:** Medium (3) + +**Description:** + + Detects use of UserInfo.getSessionId() to retrieve a session ID. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidUnauthorizedGetSessionIdInVisualforce.md b/pmd-appexchange/docs/AvoidUnauthorizedGetSessionIdInVisualforce.md new file mode 100644 index 000000000..cabaaa7d3 --- /dev/null +++ b/pmd-appexchange/docs/AvoidUnauthorizedGetSessionIdInVisualforce.md @@ -0,0 +1,18 @@ +AvoidUnauthorizedGetSessionIdInVisualforce[](#avoidunauthorizedgetsessionidinvisualforce) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Use of session ID with GETSESSIONID is not authorized. + + +**Priority:** High (2) + +**Description:** + + Detects use of GETSESSIONID() to retrieve a session ID in Visualforce code. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidUnsafeSystemMovePassword.md b/pmd-appexchange/docs/AvoidUnsafeSystemMovePassword.md new file mode 100644 index 000000000..5e396f3c0 --- /dev/null +++ b/pmd-appexchange/docs/AvoidUnsafeSystemMovePassword.md @@ -0,0 +1,18 @@ +AvoidUnsafeSystemMovePassword[](#avoidunsafesystemmovepassword) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Before calling System.movePassword(), perform the necessary authorization checks. + + +**Priority:** Critical (1) + +**Description:** + + Detects where System.movePassword() is used in Apex code. Use this method with caution. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidUnsafeSystemResetPassword.md b/pmd-appexchange/docs/AvoidUnsafeSystemResetPassword.md new file mode 100644 index 000000000..aacb724c8 --- /dev/null +++ b/pmd-appexchange/docs/AvoidUnsafeSystemResetPassword.md @@ -0,0 +1,18 @@ +AvoidUnsafeSystemResetPassword[](#avoidunsafesystemresetpassword) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Before calling System.resetPassword(), perform the necessary authorization checks. + + +**Priority:** Critical (1) + +**Description:** + + Detects where System.resetPassword() exists in Apex code. Use this method with caution. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidUnsafeSystemSetPassword.md b/pmd-appexchange/docs/AvoidUnsafeSystemSetPassword.md new file mode 100644 index 000000000..c7497e038 --- /dev/null +++ b/pmd-appexchange/docs/AvoidUnsafeSystemSetPassword.md @@ -0,0 +1,18 @@ +AvoidUnsafeSystemSetPassword[](#avoidunsafesystemsetpassword) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Before calling System.setPassword() in Apex, perform necessary authorization checks. + + +**Priority:** Critical (1) + +**Description:** + + Detects where System.setPassword() exists in Apex code. Use this method with caution. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidWithoutSharingInRestApiController.md b/pmd-appexchange/docs/AvoidWithoutSharingInRestApiController.md new file mode 100644 index 000000000..f5243a8ad --- /dev/null +++ b/pmd-appexchange/docs/AvoidWithoutSharingInRestApiController.md @@ -0,0 +1,18 @@ +AvoidWithoutSharingInRestApiController[](#avoidwithoutsharinginrestapicontroller) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Use "with sharing" in Apex classes with the @RestResource annotation. + + +**Priority:** High (2) + +**Description:** + + Detects use of "without sharing" in an Apex class exposed with the @RestResource annotation. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/LimitConnectedAppScope.md b/pmd-appexchange/docs/LimitConnectedAppScope.md new file mode 100644 index 000000000..b1aa409c8 --- /dev/null +++ b/pmd-appexchange/docs/LimitConnectedAppScope.md @@ -0,0 +1,18 @@ +LimitConnectedAppScope[](#limitconnectedappscope) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Update the connected app request to limited scope instead of full scope. + + +**Priority:** Medium (3) + +**Description:** + + Detects if a connected app uses full scope. Explain this use case in your AppExchange security review submission. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/LimitPermissionSetAssignment.md b/pmd-appexchange/docs/LimitPermissionSetAssignment.md new file mode 100644 index 000000000..39a964dd0 --- /dev/null +++ b/pmd-appexchange/docs/LimitPermissionSetAssignment.md @@ -0,0 +1,18 @@ +LimitPermissionSetAssignment[](#limitpermissionsetassignment) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Ensure that DML operations against PermissionSetAssignment use trusted input. + + +**Priority:** High (2) + +**Description:** + + Detects usage of PermissionSetAssignment. Use caution when allowing DML operations against the PermissionSetAssignment object. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/LoadJavaScriptHtmlScript.md b/pmd-appexchange/docs/LoadJavaScriptHtmlScript.md new file mode 100644 index 000000000..0d51761b2 --- /dev/null +++ b/pmd-appexchange/docs/LoadJavaScriptHtmlScript.md @@ -0,0 +1,26 @@ +LoadJavaScriptHtmlScript[](#loadjavascripthtmlscript) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Load JavaScript only from static resources. + + +**Priority:** High (2) + +**Description:** + + Determines HTML script locations where JavaScript code must be loaded as static resources. + +**Example(s):** + + + +``` +