Skip to content
This repository was archived by the owner on Feb 13, 2020. It is now read-only.

Commit

Permalink
Implement help executor
Browse files Browse the repository at this point in the history
  • Loading branch information
ikikko committed Feb 3, 2015
1 parent 96c5c9f commit b9e8a2d
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@ public enum Emoji {
ASTONISHED(":astonished:"),
RAGE(":rage:"),
CRY(":cry:"),
SMILEY(":smiley:");
SMILEY(":smiley:"),
BOOK(":book:");

private String symbol;

public String getSymbol() {
return symbol;
}

Emoji(String symbol) {
this.symbol = symbol;
}
Expand Down Expand Up @@ -99,7 +104,6 @@ public String messageWithProjectInfo(AbstractProject project) {
builder.append(" ");
builder.append(message);
builder.append("\n");
builder.append("\n");
builder.append(rootUrl);
if (project != null) {
builder.append(project.getUrl());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand All @@ -27,24 +28,43 @@ protected WebhookExecutor(WebhookRequest req, StaplerResponse rsp, String comman
public abstract void execute();

protected void output(String message) {
output(message, null);
output(message, (AbstractProject) null);
}

protected void output(String message, AbstractProject project) {
outputInternal(Level.INFO, HttpServletResponse.SC_OK, TypetalkMessage.Emoji.SMILEY, message, project);
output(message, message, project);
}

protected void output(String description, List<String> messages) {
output(description, messages, TypetalkMessage.Emoji.SMILEY);
}

protected void output(String description, List<String> messages, TypetalkMessage.Emoji emoji) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < messages.size() - 1; i++) {
builder.append(messages.get(i) + "\n");
}
builder.append(messages.get(messages.size() - 1));

// FIXME 本当なら直接 internal は呼ばないほうがいい。けど、parameterObjects を導入したら解決するので、それで
outputInternal(Level.INFO, HttpServletResponse.SC_OK, emoji, description, builder.toString(), null);
}

protected void output(String description, String message, AbstractProject project) {
outputInternal(Level.INFO, HttpServletResponse.SC_OK, TypetalkMessage.Emoji.SMILEY, description, message, project);
}

protected void outputError(String message) {
outputError(message, HttpServletResponse.SC_BAD_REQUEST);
}

protected void outputError(String message, int status) {
outputInternal(Level.WARNING, status, TypetalkMessage.Emoji.CRY, message, null);
outputInternal(Level.WARNING, status, TypetalkMessage.Emoji.CRY, message, message, null);
}

private void outputInternal(Level level, int status, TypetalkMessage.Emoji emoji, String message, AbstractProject project) {
private void outputInternal(Level level, int status, TypetalkMessage.Emoji emoji, String description, String message, AbstractProject project) {
try {
logger.log(level, message);
logger.log(level, description);

rsp.setContentType("application/json");
rsp.setStatus(status);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.jenkinsci.plugins.typetalk.webhookaction;

import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.typetalk.webhookaction.executorimpl.BuildExecutor;
import org.jenkinsci.plugins.typetalk.webhookaction.executorimpl.HelpExecutor;
import org.jenkinsci.plugins.typetalk.webhookaction.executorimpl.ListExecutor;
Expand All @@ -11,18 +12,28 @@

public class WebhookExecutorFactory {
public static WebhookExecutor create(WebhookRequest req, StaplerResponse rsp) {
LinkedList<String> messageList = new LinkedList<>(Arrays.asList(req.getPostMessage().split("\\s+")));
String botUser = messageList.poll(); // not used
String command = messageList.poll();
LinkedList<String> parameters = new LinkedList<>(Arrays.asList(req.getPostMessage().split("\\s+")));
String botUser = parameters.poll(); // not used
String command = parameters.poll();

// default command is 'help'
if (StringUtils.isBlank(command)) {
return new HelpExecutor(req, rsp, botUser, parameters);
}

switch (command) {
case "build":
String job = messageList.poll();
return new BuildExecutor(req, rsp, job, messageList);
String job = parameters.poll();
if (StringUtils.isBlank(job)) {
// show help if job is not specified
return HelpExecutor.createBuildHelpExecutor(req, rsp, botUser);
}

return new BuildExecutor(req, rsp, job, parameters);
case "list":
return new ListExecutor(req, rsp, command);
case "help":
return new HelpExecutor(req, rsp, command);
return new HelpExecutor(req, rsp, botUser, parameters);
default:
return new UndefinedExecutor(req, rsp, command);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,77 @@
package org.jenkinsci.plugins.typetalk.webhookaction.executorimpl;

import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.typetalk.api.TypetalkMessage;
import org.jenkinsci.plugins.typetalk.webhookaction.WebhookExecutor;
import org.jenkinsci.plugins.typetalk.webhookaction.WebhookRequest;
import org.kohsuke.stapler.StaplerResponse;

// TODO add help executor
public class HelpExecutor extends UndefinedExecutor {
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public HelpExecutor(WebhookRequest req, StaplerResponse rsp, String command) {
super(req, rsp, command);
public class HelpExecutor extends WebhookExecutor {

private String botUser;
private LinkedList<String> parameters;

public static HelpExecutor createBuildHelpExecutor(WebhookRequest req, StaplerResponse rsp, String botUser) {
LinkedList<String> parameters = new LinkedList<>();
parameters.add("build");
return new HelpExecutor(req, rsp, botUser, parameters);
}

public HelpExecutor(WebhookRequest req, StaplerResponse rsp, String botUser, LinkedList<String> parameters) {
super(req, rsp, "help");
this.botUser = botUser;
this.parameters = parameters;
}

@Override
public void execute() {
output("Command [ help ] is executed", getMessages(), TypetalkMessage.Emoji.BOOK);
}

private List<String> getMessages() {
String command = parameters.poll();
if (StringUtils.isBlank(command)) {
return getDefaultMessages();
}

switch (command) {
case "build":
return getBuildMessages();
default:
return getDefaultMessages();
}
}

private List<String> getDefaultMessages() {
List<String> messages = new ArrayList<>();
messages.add("Usage");
messages.add("```");
messages.add(botUser + " build <project> (<key=value>)");
messages.add(botUser + " help (<sub command>)");
messages.add("```");

return messages;
}

private List<String> getBuildMessages() {
List<String> messages = new ArrayList<>();
messages.add("Usage");
messages.add("```");
messages.add(botUser + " build <project> (<key=value>)");
messages.add("```");
messages.add(TypetalkMessage.Emoji.BOOK.getSymbol() + " Sample");
messages.add("```");
messages.add(botUser + " build helloWorldProject | build without parameters");
messages.add(botUser + " build helloWorldProject 1.0.0 | build with only single parameter");
messages.add(botUser + " build helloWorldProject version=1.0.0 | build with single parameter");
messages.add(botUser + " build helloWorldProject version=1.0.0 env=stage | build with multiple parameters");
messages.add("```");

return messages;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,23 @@ class WebhookExecutorFactorySpec extends Specification {
executor.class == ListExecutor
}

def "create HelpExecutor"() {
@Unroll
def "create HelpExecutor : #message"() {
setup:
req.postMessage >> "@jenkins+ help"
req.postMessage >> message

when:
def executor = WebhookExecutorFactory.create(req, res)

then:
executor.class == HelpExecutor

where:
message || result
"@jenkins+" || true
"@jenkins+ help" || true
"@jenkins+ help build" || true
"@jenkins+ build" || true
}

def "create UndefinedExecutor"() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.jenkinsci.plugins.typetalk.webhookaction.executorimpl

import jenkins.model.JenkinsLocationConfiguration
import org.jenkinsci.plugins.typetalk.webhookaction.WebhookExecutor
import org.jenkinsci.plugins.typetalk.webhookaction.WebhookRequest
import org.junit.Rule
import org.jvnet.hudson.test.JenkinsRule
import org.kohsuke.stapler.StaplerResponse
import spock.lang.Specification
import spock.lang.Unroll

import javax.servlet.http.HttpServletResponse

class HelpExecutorSpec extends Specification {

@Rule JenkinsRule j

def req = Mock(WebhookRequest)
def res = Mock(StaplerResponse)

WebhookExecutor executor
def writer = new StringWriter()

def setup() {
res.writer >> new PrintWriter(writer)
}

@Unroll
def "execute : parameters #parameters"() {
setup:
setUpRootUrl()
executor = new HelpExecutor(req, res, "@jenkins+", parameters as LinkedList)

when:
executor.execute()

then:
1 * res.setStatus(HttpServletResponse.SC_OK)
writer.toString().contains("build <project>")
writer.toString().contains("help")

where:
parameters || result
[] || true
["dummy"] || true
}

def "execute : parameters [build]"() {
setup:
setUpRootUrl()
executor = new HelpExecutor(req, res, "@jenkins+", ["build"] as LinkedList)

when:
executor.execute()

then:
1 * res.setStatus(HttpServletResponse.SC_OK)
writer.toString().contains("build <project> (<key=value>)")
writer.toString().contains("build helloWorldProject version=1.0.0 env=stage")
}

// --- helper method ---

def setUpRootUrl() {
JenkinsLocationConfiguration.get().url = "http://localhost:8080/"
}

}

0 comments on commit b9e8a2d

Please sign in to comment.