Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions cli-messaging/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
plugins {
java
}

version = "1.0"
java.sourceCompatibility = JavaVersion.VERSION_1_8
group = "com.salesforce.messaging"

repositories {
mavenCentral()
}

dependencies {
implementation ("com.googlecode.json-simple:json-simple:1.1.1") {
exclude("junit")
}
implementation("com.google.code.gson:gson:2.3")
testImplementation("junit", "junit", "4.12")
implementation("com.google.guava:guava:28.0-jre")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
}

tasks.getByName<Test>("test") {
useJUnitPlatform()
}
Binary file added cli-messaging/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions cli-messaging/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
1 change: 1 addition & 0 deletions cli-messaging/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = "cli-messaging"
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
package sfdc.sfdx.scanner.messaging;

import com.google.gson.Gson;
package com.salesforce.messaging;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically a copy of pmd-cataloger/src/main/java/sfdc/sfdx/scanner/messaging/SfdxMessager.java.


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SfdxMessager {
import com.google.gson.Gson;

public class CliMessager {
// The START string gives us something to scan for when we're processing output.
private static final String START = "SFDX-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 List<Message> MESSAGES = new ArrayList<>();

private static SfdxMessager INSTANCE = null;

public static SfdxMessager getInstance() {
if (INSTANCE == null) {
INSTANCE = new SfdxMessager();
}
return INSTANCE;
public static CliMessager getInstance() {
return LazyHolder.INSTANCE;
}

/**
Expand All @@ -31,7 +26,7 @@ public static SfdxMessager getInstance() {
*
* @param exception to send to Typescript layer
*/
public void addMessage(SfdxScannerException exception) {
public void addMessage(MessagePassableException exception) {
final EventKey eventKey = exception.getEventKey();
addMessage(
exception.getFullStacktrace(),
Expand Down Expand Up @@ -65,7 +60,12 @@ public void addMessage(String internalLog, EventKey eventKey, String... args) {
MESSAGES.add(message);
}


/**
* Convert all messages stored by the instance into a JSON-formatted string, enclosed in the start and end strings.
* Java code can use this method to log the messages to console, and TypeScript code can seek the start and stop
* strings to get an array of messages that can be deserialized.
* @return
*/
public String getAllMessagesWithFormatting() {
final String messagesAsJson = getMessagesAsJson();
return START + messagesAsJson + END;
Expand All @@ -75,7 +75,6 @@ private String getMessagesAsJson() {
return new Gson().toJson(MESSAGES);
}


/**
* TO BE USED ONLY BY TESTS!
*
Expand All @@ -93,15 +92,8 @@ public void resetMessages() {
MESSAGES.clear();
}

enum MessageHandler {
UX,
INTERNAL
}

enum MessageType {
INFO,
WARNING,
ERROR
private static final class LazyHolder {
// Postpone initialization until first use
private static final CliMessager INSTANCE = new CliMessager();
}
}

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package sfdc.sfdx.scanner.messaging;
import static sfdc.sfdx.scanner.messaging.SfdxMessager.*;
package com.salesforce.messaging;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically a copy of pmd-cataloger/src/main/java/sfdc/sfdx/messaging/EventKey.java.

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.js'!
INFO_GENERAL_INTERNAL_LOG("info.generalInternalLog", 1, MessageType.INFO, MessageHandler.INTERNAL, true),
WARNING_INVALID_CAT_SKIPPED("warning.invalidCategorySkipped", 1, MessageType.WARNING, MessageHandler.UX, true),
WARNING_INVALID_RULESET_SKIPPED("warning.invalidRulesetSkipped", 1, MessageType.WARNING, MessageHandler.UX, true),
Expand All @@ -19,13 +19,15 @@ public enum EventKey {
ERROR_EXTERNAL_MULTIPLE_RULE_DESC("error.external.multipleRuleDesc", 2, MessageType.ERROR, MessageHandler.UX, false),
ERROR_EXTERNAL_RECURSION_LIMIT("error.external.recursionLimitReached", 2, MessageType.ERROR, MessageHandler.UX, false),
ERROR_EXTERNAL_XML_NOT_READABLE("error.external.xmlNotReadable", 2, MessageType.ERROR, MessageHandler.UX, false),
ERROR_EXTERNAL_XML_NOT_PARSABLE("error.external.xmlNotParsable", 2, MessageType.ERROR, MessageHandler.UX, false);

String messageKey;
int argCount;
MessageType messageType;
MessageHandler messageHandler;
boolean verbose;//true: only when verbose is true, false: ignores verbose flag and always prints
ERROR_EXTERNAL_XML_NOT_PARSABLE("error.external.xmlNotParsable", 2, MessageType.ERROR, MessageHandler.UX, false),
WARNING_MULTIPLE_METHOD_TARGET_MATCHES("warning.multipleMethodTargetMatches", 3, MessageType.WARNING, MessageHandler.UX, true),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created both new messages as warnings. The "multiple matches found" is verbose-only, the "no matches found" is always.
Question: Might it be better to make the former info instead of warning? I could see it going either way.

WARNING_NO_METHOD_TARGET_MATCHES("warning.noMethodTargetMatches", 2, MessageType.WARNING, MessageHandler.UX, false);

final String messageKey;
final int argCount;
final MessageType messageType;
final MessageHandler messageHandler;
final boolean verbose;//true: only when verbose is true, false: ignores verbose flag and always prints

EventKey(String messageKey, int argCount, MessageType messageType, MessageHandler messageHandler, boolean verbose) {
this.messageKey = messageKey;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
package sfdc.sfdx.scanner.messaging;
package com.salesforce.messaging;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically a copy of pmd-cataloger/src/main/java/sfdc/sfdx/messaging/Message.java.


import com.google.gson.Gson;
import static sfdc.sfdx.scanner.messaging.SfdxMessager.*;
import java.time.Instant;
import java.util.List;

public class Message {
private String messageKey;
private List<String> args;
private String internalLog;
private MessageType type;
private MessageHandler handler;
private boolean verbose;
private long time;
final private String messageKey;
final private List<String> args;
final private String internalLog;
final private MessageType type;
final private MessageHandler handler;
final private boolean verbose;
final private long time;

Message(String messageKey, List<String> args, String internalLog, MessageType type, MessageHandler handler, boolean verbose) {
this.messageKey = messageKey;
this.args = args;
this.internalLog = internalLog;
this.type = type;
this.handler = handler;
this.time = Instant.now().toEpochMilli();
this.verbose = verbose;
}

String toJson() {
return new Gson().toJson(this);
this.time = Instant.now().toEpochMilli();
}

public String getMessageKey() {
Expand All @@ -40,4 +34,14 @@ public String getInternalLog() {
return internalLog;
}

enum MessageHandler {
UX,
INTERNAL
}

enum MessageType {
INFO,
WARNING,
ERROR
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
package sfdc.sfdx.scanner.messaging;
package com.salesforce.messaging;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically a copy of pmd-cataloger/src/main/java/sfdc/sfdx/messaging/SfdxScannerException.java.


import com.google.common.base.Throwables;
import sfdc.sfdx.scanner.messaging.EventKey;

import java.util.Arrays;

/**
* Internal exception representation.
* Extends RuntimeException to avoid declaring everywhere
* Handles capability to plug into SfdxMessager
* Handles capability to plug into CliMessager
*/
public class SfdxScannerException extends RuntimeException {
public class MessagePassableException extends RuntimeException {

private final EventKey eventKey;
private final String[] args;

public SfdxScannerException(EventKey eventKey, String... args) {
public MessagePassableException(EventKey eventKey, String... args) {
this(eventKey, null, args);
}

public SfdxScannerException(EventKey eventKey, Throwable throwable, String... args) {
public MessagePassableException(EventKey eventKey, Throwable throwable, String... args) {
super(throwable);

this.eventKey = eventKey;
Expand All @@ -40,7 +39,7 @@ public String getFullStacktrace() {

@Override
public String toString() {
return "SfdxScannerException{" +
return "MessagePassableException{" +
"eventKey=" + eventKey +
", args=" + Arrays.toString(args) +
'}';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package sfdc.sfdx.scanner.messaging;
package com.salesforce.messaging;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically a copy of pmd-cataloger/src/test/java/sfdc/sfdx/messaging/EventKeyTest.java.


import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
Expand All @@ -12,7 +12,7 @@
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import static sfdc.sfdx.scanner.messaging.SfdxMessager.*;
import static com.salesforce.messaging.Message.*;

import java.io.IOException;
import java.nio.file.Files;
Expand Down
2 changes: 2 additions & 0 deletions messages/EventKeyTemplates.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ module.exports = {
"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",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New messages.

"noMethodTargetMatches": "No methods in file %s matched name #%s()",
"pmdConfigError": "PMD failed to evaluate rule '%s'. Message: %s"
},
"error": {
Expand Down
7 changes: 6 additions & 1 deletion messages/run-dfa.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ module.exports = {
"sevthresholdDescription": "throws an error when violations of specific severity (or more severe) are detected, invokes --normalize-severity",
"sevthresholdDescriptionLong": "Throws an error if violations are found with equal or greater severity than provided value. Values are 1 (high), 2 (moderate), and 3 (low). Exit code is the most severe violation. Using this flag also invokes the --normalize-severity flag",
"targetDescription": "location of source code",
"targetDescriptionLong": "Source code location. May use glob patterns. Multiple values can be specified as a comma-separated list"
"targetDescriptionLong": "Source code location. May use glob patterns, or specify individual methods with #-syntax. Multiple values can be specified as a comma-separated list"
},
"validations": {
"methodLevelTargetCannotBeGlob": "Method-level targets supplied to --target cannot be globs",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New messages for validations of flags.

"methodLevelTargetMustBeRealFile": "Method-level target %s must be a real file",
"projectdirCannotBeGlob": "--projectdir cannot specify globs",
"projectdirMustBeDir": "--projectdir must specify directories",
"projectdirMustExist": "--projectdir must specify existing paths"
Expand All @@ -37,6 +39,9 @@ module.exports = {
Unix example: $ sfdx scanner:run:dfa --target './**/*.cls,!./**/IgnoreMe.cls' ...
Windows example: > sfdx scanner:run:dfa --target ".\\**\\*.cls,!.\\**\\IgnoreMe.cls" ...
Evaluate rules against all .cls files below the current directory, except for IgnoreMe.cls.
Individual methods within a file may be targeted by suffixing the file's path with a hash (#), and a semi-colon-delimited list of method names. This syntax is incompatible with globs and directories.
E.g., $ sfdx scanner:run:dfa --target "./File1.cls#Method1;Method2,./File2.cls#Method3" ...
Evaluates rules against ALL methods named Method1 or Method2 in File1.cls, and ALL methods named Method3 in File2.cls.
Use --normalize-severity to output a normalized (across all engines) severity (1 [high], 2 [moderate], and 3 [low]) in addition to the engine specific severity (when shown).
E.g., $ 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. For this example, if there are any rule violations with a severity of 2 or more (which includes 1-high and 2-moderate), the exit code will be equal to the severity of the most severe violation.
Expand Down
1 change: 1 addition & 0 deletions pmd-cataloger/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ tasks.register<Copy>("installPmd") {
}

dependencies {
implementation(project(":cli-messaging"))
implementation ("com.googlecode.json-simple:json-simple:1.1.1") {
exclude("junit")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package sfdc.sfdx.scanner.pmd;

import sfdc.sfdx.scanner.messaging.EventKey;
import sfdc.sfdx.scanner.messaging.SfdxMessager;
import sfdc.sfdx.scanner.messaging.SfdxScannerException;
import com.salesforce.messaging.EventKey;
import com.salesforce.messaging.CliMessager;
import com.salesforce.messaging.MessagePassableException;

import java.util.*;

Expand Down Expand Up @@ -57,7 +57,7 @@ private void addPathForLanguage(String path, String language, String sourceJar)
addCategoryPathForLanguage(path, language, sourceJar);
categoryToSourceJar.put(path, sourceJar);
} else {
SfdxMessager.getInstance().addMessage("Adding path " + path + " for language " + language, EventKey.WARNING_XML_DROPPED, path);
CliMessager.getInstance().addMessage("Adding path " + path + " for language " + language, EventKey.WARNING_XML_DROPPED, path);
}
}
}
Expand All @@ -81,7 +81,7 @@ private void addPath(String path, String language, String sourceJar, Map<String,
}

if (jarWithConflict != null) {
throw new SfdxScannerException(EventKey.ERROR_EXTERNAL_DUPLICATE_XML_PATH, path, sourceJar, jarWithConflict);
throw new MessagePassableException(EventKey.ERROR_EXTERNAL_DUPLICATE_XML_PATH, path, sourceJar, jarWithConflict);
}

if (pathsByLanguage.containsKey(language)) {
Expand Down
Loading