Skip to content

Commit

Permalink
Allow to customize the message that gets printed in the chat room
Browse files Browse the repository at this point in the history
  • Loading branch information
retoo committed Feb 22, 2015
1 parent fcbbef8 commit 60160e9
Show file tree
Hide file tree
Showing 8 changed files with 669 additions and 99 deletions.
88 changes: 86 additions & 2 deletions src/main/java/jenkins/plugins/hipchat/HipChatNotifier.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package jenkins.plugins.hipchat;

import com.google.common.base.Preconditions;
import hudson.Extension;
import hudson.Launcher;
import hudson.Util;
Expand Down Expand Up @@ -42,10 +43,20 @@ public class HipChatNotifier extends Notifier {
private boolean notifyFailure;
private boolean notifyBackToNormal;

private String messageStarted;
private String messageBackToNormal;
private String messageSuccess;
private String messageFailure;
private String messageAborted;
private String messageNotBuilt;
private String messageUnstable;

@DataBoundConstructor
public HipChatNotifier(String token, String room, boolean startNotification, boolean notifySuccess,
boolean notifyAborted, boolean notifyNotBuilt, boolean notifyUnstable, boolean notifyFailure,
boolean notifyBackToNormal) {
boolean notifyBackToNormal,
String messageStarted, String messageBackToNormal, String messageSuccess, String messageFailure,
String messageAborted, String messageNotBuilt, String messageUnstable) {
this.token = token;
this.room = room;
this.startNotification = startNotification;
Expand All @@ -55,8 +66,17 @@ public HipChatNotifier(String token, String room, boolean startNotification, boo
this.notifyUnstable = notifyUnstable;
this.notifyFailure = notifyFailure;
this.notifyBackToNormal = notifyBackToNormal;
this.messageStarted = messageStarted;
this.messageBackToNormal = messageBackToNormal;
this.messageSuccess = messageSuccess;
this.messageFailure = messageFailure;
this.messageAborted = messageAborted;
this.messageNotBuilt = messageNotBuilt;
this.messageUnstable = messageUnstable;
}

/* notification enabled disabled setter/getter */

public boolean isStartNotification() {
return startNotification;
}
Expand Down Expand Up @@ -113,6 +133,70 @@ public void setNotifyBackToNormal(boolean notifyBackToNormal) {
this.notifyBackToNormal = notifyBackToNormal;
}

/* notification message configuration*/

public String getMessageStarted() {
return messageStarted;
}

public void setMessageStarted(String messageStarted) {
this.messageStarted = messageStarted;
}

public String getMessageBackToNormal() {
return messageBackToNormal;
}

public void setMessageBackToNormal(String messageBackToNormal) {
this.messageBackToNormal = messageBackToNormal;
}

public String getMessageSuccess() {
return messageSuccess;
}

public void setMessageSuccess(String messageSuccess) {
this.messageSuccess = messageSuccess;
}

public String getMessageFailure() {
return messageFailure;
}

public void setMessageFailure(String messageFailure) {
this.messageFailure = messageFailure;
}

public String getMessageAborted() {
return messageAborted;
}

public void setMessageAborted(String messageAborted) {
this.messageAborted = messageAborted;
}

public String getMessageNotBuilt() {
return messageNotBuilt;
}

public void setMessageNotBuilt(String messageNotBuilt) {
this.messageNotBuilt = messageNotBuilt;
}

public String getMessageUnstable() {
return messageUnstable;
}

public void setMessageUnstable(String messageUnstable) {
this.messageUnstable = messageUnstable;
}

public String getMessageDefault(String enumName) {
NotificationType type = NotificationType.valueOf(enumName);
Preconditions.checkNotNull(type, "unknown NotificationType %s", enumName);
return type.getDefaultTemplate();
}

public String getRoom() {
return StringUtils.isBlank(room) ? getDescriptor().getRoom() : room;
}
Expand Down Expand Up @@ -179,7 +263,7 @@ private Result findPreviousBuildResult(AbstractBuild<?,?> build) {

private void publishNotificationIfEnabled(NotificationType notificationType, AbstractBuild<?, ?> build) {
if (isNotificationEnabled(notificationType)) {
getHipChatService().publish(notificationType.getMessage(build), notificationType.getColor());
getHipChatService().publish(notificationType.getMessage(build, this), notificationType.getColor());
}
}

Expand Down
217 changes: 129 additions & 88 deletions src/main/java/jenkins/plugins/hipchat/NotificationType.java
Original file line number Diff line number Diff line change
@@ -1,135 +1,176 @@
package jenkins.plugins.hipchat;

import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import hudson.EnvVars;
import hudson.model.AbstractBuild;
import hudson.model.CauseAction;
import hudson.model.Result;
import hudson.scm.ChangeLogSet;
import hudson.util.LogTaskListener;
import hudson.util.VariableResolver;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;

import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Maps.newHashMap;
import static hudson.Util.replaceMacro;
import static java.util.logging.Level.INFO;

public enum NotificationType {

STARTED("green") {
@Override
protected String getConfiguredTemplateFor(HipChatNotifier notifier) {
return notifier.getMessageStarted();
}

@Override
protected String getStatusMessage(AbstractBuild<?, ?> build) {
String changes = getStatusMessageWithChanges(build);
if (changes != null) {
return changes;
} else {
CauseAction cause = build.getAction(CauseAction.class);
if (cause != null) {
return cause.getShortDescription();
} else {
return Messages.Starting();
}
}
}
},
@Override
public String getDefaultTemplate() {
return Messages.Started();
}
},
ABORTED("gray") {
@Override
protected String getConfiguredTemplateFor(HipChatNotifier notifier) {
return notifier.getMessageAborted();
}

@Override
protected String getStatusMessage(AbstractBuild<?, ?> build) {
return Messages.Aborted(build.getDurationString());
}
},
@Override
public String getDefaultTemplate() {
return Messages.Aborted();
}
},
SUCCESS("green") {
@Override
protected String getConfiguredTemplateFor(HipChatNotifier notifier) {
return notifier.getMessageSuccess();
}

@Override
protected String getStatusMessage(AbstractBuild<?, ?> build) {
return Messages.Success(build.getDurationString());
}
},
@Override
public String getDefaultTemplate() {
return Messages.Success();
}
},
FAILURE("red") {
@Override
protected String getConfiguredTemplateFor(HipChatNotifier notifier) {
return notifier.getMessageFailure();
}

@Override
protected String getStatusMessage(AbstractBuild<?, ?> build) {
return Messages.Failure(build.getDurationString());
}
},
@Override
public String getDefaultTemplate() {
return Messages.Failure();
}
},
NOT_BUILT("gray") {
@Override
protected String getConfiguredTemplateFor(HipChatNotifier notifier) {
return notifier.getMessageNotBuilt();
}

@Override
protected String getStatusMessage(AbstractBuild<?, ?> build) {
return Messages.NotBuilt();
}
},
@Override
public String getDefaultTemplate() {
return Messages.NotBuilt();
}
},
BACK_TO_NORMAL("green") {
@Override
protected String getConfiguredTemplateFor(HipChatNotifier notifier) {
return notifier.getMessageBackToNormal();
}

@Override
protected String getStatusMessage(AbstractBuild<?, ?> build) {
return Messages.BackToNormal(build.getDurationString());
}
},
@Override
public String getDefaultTemplate() {
return Messages.BackToNormal();
}
},
UNSTABLE("yellow") {
@Override
protected String getConfiguredTemplateFor(HipChatNotifier notifier) {
return notifier.getMessageUnstable();
}

@Override
protected String getStatusMessage(AbstractBuild<?, ?> build) {
return Messages.Unstable(build.getDurationString());
}
},
@Override
public String getDefaultTemplate() {
return Messages.Unstable();
}
},
UNKNOWN("purple") {
@Override
protected String getConfiguredTemplateFor(HipChatNotifier notifier) {
throw new IllegalStateException();
}

@Override
public String getDefaultTemplate() {
return null;
}
};

@Override
protected String getStatusMessage(AbstractBuild<?, ?> build) {
throw new IllegalStateException("Unable to generate status message for UNKNOWN notification type");
}
};
private static final Logger logger = Logger.getLogger(NotificationType.class.getName());
private final String color;

private NotificationType(String color) {
this.color = color;
}

protected abstract String getStatusMessage(AbstractBuild<?, ?> build);
protected abstract String getConfiguredTemplateFor(HipChatNotifier notifier);
public abstract String getDefaultTemplate();

public String getColor() {
return color;
}

private static String getStatusMessageWithChanges(AbstractBuild<?, ?> build) {
if (!build.hasChangeSetComputed()) {
logger.log(Level.FINE, "No changeset computed for job {0}", build.getProject().getFullDisplayName());
return null;
}

Set<String> authors = new HashSet<String>();
int changedFiles = 0;
for (Object o : build.getChangeSet().getItems()) {
ChangeLogSet.Entry entry = (ChangeLogSet.Entry) o;
logger.log(Level.FINEST, "Entry {0}", entry);
authors.add(entry.getAuthor().getDisplayName());
try {
changedFiles += entry.getAffectedFiles().size();
} catch (UnsupportedOperationException e) {
logger.log(Level.INFO, "Unable to collect the affected files for job {0}",
build.getProject().getFullDisplayName());
return null;
}
}
if (changedFiles == 0) {
logger.log(Level.FINE, "No changes detected");
return null;
}
public final String getMessage(AbstractBuild<?, ?> build, HipChatNotifier notifier) {
String format = getTemplateFor(notifier);
Map<String, String> messageVariables = collectParametersFor(build);

return Messages.StartWithChanges(StringUtils.join(authors, ", "), changedFiles);
return replaceMacro(format, new VariableResolver.ByMap<String>(messageVariables));
}

public final String getMessage(AbstractBuild<?, ?> build) {
String rootUrl = Jenkins.getInstance().getRootUrl();
StringBuilder sb = new StringBuilder(150);
sb.append(Messages.MessageStart(build.getProject().getFullDisplayName(), build.getDisplayName()));
sb.append(' ');
sb.append(getStatusMessage(build));
private String getTemplateFor(HipChatNotifier notifier) {
String userConfig = this.getConfiguredTemplateFor(notifier);
String defaultConfig = this.getDefaultTemplate();
if (userConfig == null || userConfig.trim().isEmpty()) {
Preconditions.checkState(defaultConfig != null, "default config not set for %s", this);
return defaultConfig;
} else {
return userConfig;
}
}

sb.append(" (<a href=\"").append(rootUrl).append(build.getUrl()).append("\">Open</a>)");
private Map<String, String> collectParametersFor(AbstractBuild build) {
Map<String, String> merged = newHashMap();
merged.putAll(build.getBuildVariables());
merged.putAll(getEnvVars(build));

String cause = NotificationTypeUtils.getCause(build);
String changes = NotificationTypeUtils.getChanges(build);

merged.put("DURATION", build.getDurationString());
merged.put("URL", NotificationTypeUtils.getUrl(build));
merged.put("CAUSE", cause);
merged.put("CHANGES_OR_CAUSE", changes != null ? changes : cause);
merged.put("CHANGES", changes);
merged.put("PRINT_FULL_ENV", merged.toString());
return merged;
}

return sb.toString();
private EnvVars getEnvVars(AbstractBuild build) {
try {
return build.getEnvironment(new LogTaskListener(logger, INFO));
} catch (IOException e) {
throw propagate(e);
} catch (InterruptedException e) {
throw propagate(e);
}
}

public static final NotificationType fromResults(Result previousResult, Result result) {
Expand Down
Loading

0 comments on commit 60160e9

Please sign in to comment.