Skip to content

Commit

Permalink
Revert "Traverse up the material dependency tree for someone to repor…
Browse files Browse the repository at this point in the history
…t to."

This reverts commit b604b35.
  • Loading branch information
rushi committed Jul 28, 2020
1 parent ed2cae7 commit 1686df2
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 121 deletions.
149 changes: 68 additions & 81 deletions plugin/src/main/java/com/github/gmazzo/gocd/BuildWatcherPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import com.github.gmazzo.gocd.email.EmailNotifier;
import com.github.gmazzo.gocd.model.Message;
import com.github.gmazzo.gocd.model.api.*;
import com.github.gmazzo.gocd.model.api.PipelineInstance;
import com.github.gmazzo.gocd.model.api.PluginSettings;
import com.github.gmazzo.gocd.model.api.StageResult;
import com.github.gmazzo.gocd.model.api.StageStatus;
import com.github.gmazzo.gocd.model.api.ValidateConfiguration;
import com.github.gmazzo.gocd.slack.SlackNotifier;
import com.google.gson.Gson;
import com.thoughtworks.go.plugin.api.GoApplicationAccessor;
Expand All @@ -20,15 +24,46 @@
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.github.gmazzo.gocd.model.api.PluginSettings.*;
import javax.xml.bind.DatatypeConverter;

import static com.github.gmazzo.gocd.model.api.PluginSettings.PLACEHOLDER_LABEL;
import static com.github.gmazzo.gocd.model.api.PluginSettings.PLACEHOLDER_PIPELINE;
import static com.github.gmazzo.gocd.model.api.PluginSettings.PLACEHOLDER_PIPELINE_COUNTER;
import static com.github.gmazzo.gocd.model.api.PluginSettings.PLACEHOLDER_STAGE;
import static com.github.gmazzo.gocd.model.api.PluginSettings.PLACEHOLDER_STAGE_COUNTER;
import static com.github.gmazzo.gocd.model.api.PluginSettings.PLACEHOLDER_STATE_CURRENT;
import static com.github.gmazzo.gocd.model.api.PluginSettings.PLACEHOLDER_STATE_PREVIOUS;
import static com.github.gmazzo.gocd.model.api.PluginSettings.PLACEHOLDER_USER;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_EMAIL_AUTH_PASSWORD;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_EMAIL_AUTH_USER;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_EMAIL_CC;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_EMAIL_FROM;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_EMAIL_SMTP_PORT;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_EMAIL_SMTP_SERVER;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_EMAIL_SMTP_SSL;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_MESSAGE_PIPE_BROKEN;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_MESSAGE_PIPE_FIXED;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_MESSAGE_PIPE_STILL_BROKEN;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_SERVER_API_PASSWORD;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_SERVER_API_USERNAME;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_SERVER_BASE_URL;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_SLACK_API_TOKEN;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_SLACK_BOT_IMAGE;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_SLACK_BOT_USERNAME;
import static com.github.gmazzo.gocd.model.api.PluginSettings.SETTING_SLACK_CHANNEL;
import static com.github.gmazzo.utils.HttpUtils.response;
import static com.github.gmazzo.utils.IOUtils.readStream;
import static com.github.gmazzo.utils.MapUtils.map;
import static com.github.gmazzo.utils.StringUtils.*;
import static java.lang.Integer.parseInt;
import static com.github.gmazzo.utils.StringUtils.capitalize;
import static com.github.gmazzo.utils.StringUtils.extractEmail;
import static com.github.gmazzo.utils.StringUtils.isBlank;

@Extension
public class BuildWatcherPlugin implements GoPlugin {
Expand Down Expand Up @@ -125,41 +160,30 @@ private void handleStageStatus(StageStatus.Pipeline pipeline) {

StageResult currentResult = pipeline.stage.result;

LOGGER.info("Starting execution of the handleStageStatus() method");

if (currentResult.isFinal()) {
PipelineInstance currentInstance = getPipelineInstance(settings, pipeline.name, pipeline.counter);
PipelineInstance previousInstance = getPipelineInstance(settings, pipeline.name, pipeline.counter - 1);
StageResult previousResult = getPreviousStageResult(previousInstance, pipeline.stage.name);

Set<String> users = new LinkedHashSet<>();
relevantMaterialRevisions(currentInstance).forEach(
$ -> users.addAll(getMaterialUsers($.modifications))
);
LOGGER.info("Number of users found: " + users.size());

String userEmail = getMaterialUser(currentInstance);
String changesResume = getChangesResume(currentInstance);

users.forEach(userEmail -> {
LOGGER.info("userEmail: " + userEmail);

Message message = getMessage(settings, userEmail, pipeline, currentResult, previousResult, changesResume);
LOGGER.info("handleStageStatus: userEmail=" + userEmail + ", current=" + currentResult +
", previous=" + previousResult + ", message=" + message);
if (message != null) {
// sends the notification
getNotifiers(settings).forEach(n -> {
try {
n.sendMessage(userEmail, message);

} catch (Exception e) {
LOGGER.error("sendMessage failed: notifier=" + n +
", userEmail=" + userEmail + ", current=" + currentResult +
", previous=" + previousResult + ", message=" + message, e);
}
});
}
});
Message message = getMessage(settings, userEmail, pipeline, currentResult, previousResult, changesResume);

LOGGER.info("handleStageStatus: userEmail=" + userEmail + ", current=" + currentResult +
", previous=" + previousResult + ", message=" + message);

if (message != null) {
// sends the notification
getNotifiers(settings).forEach(n -> {
try {
n.sendMessage(userEmail, message);

} catch (Exception e) {
LOGGER.error("sendMessage failed: notifier=" + n +
", userEmail=" + userEmail + ", current=" + currentResult +
", previous=" + previousResult + ", message=" + message, e);
}
});
}

} else {
LOGGER.info("Ignoring non final state: stage=" +
Expand Down Expand Up @@ -188,51 +212,14 @@ private PipelineInstance getPipelineInstance(PluginSettings settings, String nam
}
}

private List<PipelineInstance.MaterialRevision> relevantMaterialRevisions(PipelineInstance instance) {
Map<Boolean, List<PipelineInstance.MaterialRevision>> materialRevisions = instance.buildCause.revisions.stream()
.collect(Collectors.partitioningBy(r -> Objects.equals(r.material.type, "Pipeline")));

LOGGER.info("Starting execution of the relevantMaterialRevisions() method");

LOGGER.info("Printing out all relevant material revisions...");

LOGGER.info("Printing out type: pipeline...");
materialRevisions.get(true).forEach(m -> LOGGER.info(m.material.fingerprint));

LOGGER.info("Printing out type: !pipeline...");
materialRevisions.get(false).forEach(m -> LOGGER.info(m.material.fingerprint));

List<PipelineInstance.MaterialRevision> res = new LinkedList<>(materialRevisions.get(false));

if (materialRevisions.get(false).size() == 0 && materialRevisions.get(true).size() > 0) {
LOGGER.info("Only able to find pipeline material revisions, processing parents...");

materialRevisions.get(true)
.forEach(
$ -> getPipelinesFromModifications($).forEach(p -> res.addAll(relevantMaterialRevisions(p)))
);
}

return res;
}

private List<PipelineInstance> getPipelinesFromModifications(PipelineInstance.MaterialRevision materialRevision) {
PluginSettings settings = getSettings();

return materialRevision.modifications.stream()
.filter($ -> !Objects.equals($.revision, ""))
.map($ -> extractPipelineAndCounter($.revision))
.filter(Objects::nonNull)
.map($ -> getPipelineInstance(settings, $.get("pipeline"), parseInt($.get("counter"))))
.collect(Collectors.toList());
}

private List<String> getMaterialUsers(List<PipelineInstance.Modification> modifications) {
return modifications.stream()
.filter(m -> m.emailAddress != null || m.userName != null)
private String getMaterialUser(PipelineInstance instance) {
return instance.buildCause.revisions.stream()
.flatMap(m -> m.modifications.stream())
.sorted((a, b) -> -Long.compare(a.modifiedTime, b.modifiedTime))
.findFirst()
.map(m -> m.emailAddress != null ? m.emailAddress : extractEmail(m.userName))
.filter(Objects::nonNull)
.collect(Collectors.toList());
.filter($ -> $ != null)
.orElseThrow(() -> new IllegalArgumentException("No modifications found for material!"));
}

private StageResult getPreviousStageResult(PipelineInstance instance, String stage) {
Expand All @@ -246,7 +233,7 @@ private StageResult getPreviousStageResult(PipelineInstance instance, String sta
private String getChangesResume(PipelineInstance instance) {
return instance.buildCause.revisions.stream()
.flatMap($ -> $.modifications.stream())
.map($ -> "Material changed:\n\tRevision: " + $.revision + ($.comment != null ? "\n\tComment: " + $.comment : "") + ($.userName != null ? "\n\tUsername: " + $.userName : ""))
.map($ -> $.revision + ":\n" + $.comment + " - " + $.userName)
.collect(Collectors.joining("\n\n"));
}

Expand Down Expand Up @@ -275,7 +262,7 @@ private Message getMessage(PluginSettings settings, String userEmail, StageStatu
'/' + pipeline.stage.name + '/' + pipeline.stage.counter;
}
if (!isBlank(message)) {
String text = "\n" + message.replaceAll(PLACEHOLDER_USER, userEmail)
String text = message.replaceAll(PLACEHOLDER_USER, userEmail)
.replaceAll(PLACEHOLDER_PIPELINE, pipeline.name)
.replaceAll(PLACEHOLDER_PIPELINE_COUNTER, String.valueOf(pipeline.counter))
.replaceAll(PLACEHOLDER_STAGE, pipeline.stage.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,30 @@ public void sendMessage(String userEmail, Message message) {
private String buildHtml(Message message) {
StringBuilder tags = new StringBuilder();

boolean col2 = false;
int rowSpan = 1;
for (Message.Tag tag : message.tags) {
if (rowSpan > 1) {
col2 |= !tag.isShort;
if (col2) {
tags.append("</tr><tr>");
rowSpan++;
col2 = !tag.isShort;

} else {
col2 = true;
}

tags.append("<td width=\"100\"><b>");
tags.append(escapeHtml3(tag.name));
tags.append("</b><br/>");
tags.append(escapeHtml3(tag.value).replace("\n", "<br/>").replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;"));
tags.append(escapeHtml3(tag.value));
tags.append("</td>");

rowSpan++;
}

StringBuilder sb = new StringBuilder();
sb.append("<table style=\"width: 100%;\"><tr><td colSpan=\"3\">");
sb.append("<table><tr><td colSpan=\"3\">");
sb.append(escapeHtml3(message.text));
sb.append("</td></tr><tr><td colSpan=\"3\">&nbsp;</td></tr><tr><td rowSpan=\"");
sb.append("</td></tr><tr><td rowSpan=\"");
sb.append(rowSpan + (message.link != null ? 1 : 0));
sb.append("\" style=\"background-color: ");
sb.append(message.type == Message.Type.GOOD ? "#36a64f" :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,9 @@ public static class BuildCause {

public static class MaterialRevision {

@SerializedName("material")
public Material material;

@SerializedName("modifications")
public List<Modification> modifications;

@SerializedName("changed")
public boolean changed;
}

public static class Material {
@SerializedName("fingerprint")
public String fingerprint;

@SerializedName("description")
public String description;

@SerializedName("id")
public Integer id;

@SerializedName("type")
public String type;
}

public static class Modification {
Expand Down
15 changes: 0 additions & 15 deletions plugin/src/main/java/com/github/gmazzo/utils/StringUtils.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.github.gmazzo.utils;

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -20,18 +19,4 @@ public static String extractEmail(String text) {
return m.find() ? m.group() : null;
}

public static HashMap<String, String> extractPipelineAndCounter(String text) {
String[] parts = text.split("/");

if (parts.length < 2) {
return null;
}

HashMap<String, String> res = new HashMap<>();
res.put("pipeline", parts[0]);
res.put("counter", parts[1]);

return res;
}

}

0 comments on commit 1686df2

Please sign in to comment.