Skip to content

Commit

Permalink
Merge pull request #116 from CrystallDEV/fix/issue-115
Browse files Browse the repository at this point in the history
Fix #115 by using a custom object for dynamic fields
  • Loading branch information
KocproZ authored May 21, 2023
2 parents 57c742b + a9b9629 commit d44265c
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import java.util.List;
import javax.inject.Inject;
import jenkins.model.JenkinsLocationConfiguration;
import nz.co.jammehcow.jenkinsdiscord.exception.WebhookException;
Expand All @@ -35,7 +34,7 @@ public class DiscordPipelineStep extends AbstractStepImpl {
private String notes;
private String customAvatarUrl;
private String customUsername;
private List<String> fields;
private DynamicFieldContainer dynamicFieldContainer;
private boolean successful;
private boolean unstable;
private boolean enableArtifactsList;
Expand Down Expand Up @@ -187,12 +186,15 @@ public String getScmWebUrl() {
}

@DataBoundSetter
public void setFields(List<String> fields) {
this.fields = fields;
public void setDynamicFieldContainer(String fieldsString) {
this.dynamicFieldContainer = DynamicFieldContainer.of(fieldsString);
}

public List<String> getFields() {
return fields;
public String getDynamicFieldContainer() {
if(dynamicFieldContainer == null){
return "";
}
return dynamicFieldContainer.toString();
}

public static class DiscordPipelineStepExecution extends AbstractSynchronousNonBlockingStepExecution<Void> {
Expand Down Expand Up @@ -259,12 +261,8 @@ protected Void run() throws Exception {
wh.setCustomUsername(step.getCustomUsername());
}

// Add all key value field pairs to the webhook by splitting them with the delimiter
if (step.fields != null) {
step.fields.stream()
.map(s -> s.split(":"))
.forEach(pair -> wh.addField(pair[0], pair[1]));
}
// Add all key value field pairs to the webhook
addDynamicFieldsToWebhook(wh);

try {
wh.send();
Expand All @@ -275,6 +273,18 @@ protected Void run() throws Exception {
return null;
}

/**
* Add all key value field pairs to the webhook
*/
private void addDynamicFieldsToWebhook(DiscordWebhook wh){
// Early exit if we don't have any dynamicFieldContainer set
if(step.dynamicFieldContainer == null){
return;
}
// Go through all fields and add them to the webhook
step.dynamicFieldContainer.getFields().forEach(pair -> wh.addField(pair.getKey(), pair.getValue()));
}

private String checkLimitAndTruncate(String fieldName, String value, int limit) {
if (value == null) return "";
if (value.length() > limit) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package nz.co.jammehcow.jenkinsdiscord;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
* @author Marek Hasselder
*/
public class DynamicFieldContainer {

private final List<DynamicField> fields = new ArrayList<>();

public List<DynamicField> getFields() {
return fields;
}

public DynamicFieldContainer addField(String key, String value) {
fields.add(new DynamicField(key, value));
return this;
}

@Override
public String toString() {
// Could be optimized using >8 Java Features
StringBuilder builder = new StringBuilder();
for (int i = 0; i < fields.size(); i++) {
// Serialize the field using the custom toString method
builder.append(fields.get(i).toString());
if (i + 1 < fields.size()) {
builder.append(", ");
}
}
return builder.toString();
}

/**
* Creates a new dynamic field container using the fieldsString.
*
* @param fieldsString the string containing the dynamic fields (key1:value1, key2:value2)
* @return a dynamic field container containing the
* @throws RuntimeException if the string is in a wrong format
*/
public static DynamicFieldContainer of(String fieldsString) {
DynamicFieldContainer fieldContainer = new DynamicFieldContainer();

try {
for (String s : fieldsString.split(", ")) {
String[] pair = s.split(":");
fieldContainer.addField(pair[0], pair[1]);
}
} catch (Exception e) {
throw new RuntimeException("Dynamic fields string is in a wrong format. Using empty container as fallback");
}

return fieldContainer;
}

public static class DynamicField {

private final String key;
private final String value;

public DynamicField(String key, String value) {
Objects.requireNonNull(key);
Objects.requireNonNull(value);
this.key = key;
this.value = value;
}

public String getKey() {
return key;
}

public String getValue() {
return value;
}

@Override
public String toString() {
return String.format("%s:%s", key, value);
}
}


}
45 changes: 28 additions & 17 deletions src/main/java/nz/co/jammehcow/jenkinsdiscord/WebhookPublisher.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@
import hudson.tasks.Notifier;
import hudson.tasks.Publisher;
import hudson.util.FormValidation;
import java.util.List;
import java.io.IOException;
import java.util.Map;
import jenkins.model.JenkinsLocationConfiguration;
import nz.co.jammehcow.jenkinsdiscord.exception.WebhookException;
import nz.co.jammehcow.jenkinsdiscord.util.EmbedDescription;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;

import java.io.IOException;
import java.util.Map;

/**
* Author: jammehcow.
* Date: 22/04/17.
Expand All @@ -38,7 +37,7 @@ public class WebhookPublisher extends Notifier {
private final String notes;
private final String customAvatarUrl;
private final String customUsername;
private final List<String> fields;
private DynamicFieldContainer dynamicFieldContainer;
private final boolean sendOnStateChange;
private final boolean sendOnlyFailed;
private boolean enableUrlLinking;
Expand All @@ -61,7 +60,6 @@ public WebhookPublisher(
String branchName,
String customAvatarUrl,
String customUsername,
List<String> fields,
boolean sendOnStateFailed,
boolean sendOnlyFailed,
boolean enableUrlLinking,
Expand All @@ -85,7 +83,6 @@ public WebhookPublisher(
this.notes = notes;
this.customAvatarUrl = customAvatarUrl;
this.customUsername = customUsername;
this.fields = fields;
this.sendLogFile = sendLogFile;
this.sendStartNotification = sendStartNotification;
this.scmWebUrl = scmWebUrl;
Expand All @@ -111,8 +108,16 @@ public String getCustomUsername() {
return this.customUsername;
}

public List<String> getFields() {
return fields;
@DataBoundSetter
public void setDynamicFieldContainer(String fieldsString) {
this.dynamicFieldContainer = DynamicFieldContainer.of(fieldsString);
}

public String getDynamicFieldContainer() {
if(dynamicFieldContainer == null){
return "";
}
return dynamicFieldContainer.toString();
}

public String getNotes() {
Expand Down Expand Up @@ -199,10 +204,7 @@ public boolean prebuild(AbstractBuild<?, ?> build, BuildListener listener) {
}
wh.setDescription(new EmbedDescription(build, globalConfig, description, false, false, null).toString());

// Add all key value field pairs to the webhook by splitting them with the delimiter
fields.stream()
.map(s -> s.split(":"))
.forEach(pair -> wh.addField(pair[0], pair[1]));
addDynamicFieldsToWebhook(dynamicFieldContainer, wh);

// Send the webhook
wh.send();
Expand Down Expand Up @@ -321,10 +323,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListener lis
.toString()
);

// Add all key value field pairs to the webhook by splitting them with the delimiter
fields.stream()
.map(s -> s.split(":"))
.forEach(pair -> wh.addField(pair[0], pair[1]));
addDynamicFieldsToWebhook(dynamicFieldContainer, wh);
wh.setStatus(statusColor);

if (this.enableFooterInfo)
Expand All @@ -340,6 +339,18 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListener lis
return true;
}

/**
* Add all key value field pairs to the webhook
*/
private void addDynamicFieldsToWebhook(DynamicFieldContainer dynamicFieldContainer, DiscordWebhook wh){
// Early exit if we don't have any dynamicFieldContainer set
if(dynamicFieldContainer == null){
return;
}
// Go through all fields and add them to the webhook
dynamicFieldContainer.getFields().forEach(pair -> wh.addField(pair.getKey(), pair.getValue()));
}

public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
<f:entry title="Custom name" field="customUsername">
<f:textbox />
</f:entry>
<!-- TODO add option to add more textboxes -->
<f:entry title="Fields" field="fields">
<f:entry title="Dynamic fields" field="dynamicFieldContainer">
<f:textbox />
</f:entry>
<f:entry title="Enable URL linking" field="enableUrlLinking">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
Field that contains key value pairs in an array in the following format `key1:value1, key2:value2, [...]`
</div>

0 comments on commit d44265c

Please sign in to comment.