Skip to content

Commit

Permalink
Merge 69701e8 into 07efa72
Browse files Browse the repository at this point in the history
  • Loading branch information
ascandella committed Jun 29, 2015
2 parents 07efa72 + 69701e8 commit 583197f
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 88 deletions.
6 changes: 5 additions & 1 deletion phabricator-plugin.iml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
Expand Down Expand Up @@ -121,6 +122,10 @@
<orderEntry type="library" name="Maven: net.sourceforge.nekohtml:nekohtml:1.9.13" level="project" />
<orderEntry type="library" name="Maven: net.sf.trove4j:trove4j:3.0.3" level="project" />
<orderEntry type="library" name="Maven: net.java.dev.jna:jna:3.2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.0.23-beta" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy:0.6.11" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.jenkins-ci.main:jenkins-war:war:1.597" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.jenkins-ci.main:jenkins-core:1.597" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.jenkins-ci.plugins.icon-shim:icon-set:1.0.5" level="project" />
Expand Down Expand Up @@ -259,7 +264,6 @@
<orderEntry type="library" scope="TEST" name="Maven: org.jenkins-ci:test-annotations:1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.jvnet.mock-javamail:mock-javamail:1.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: junit:junit:4.11" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.jenkins-ci:htmlunit:2.6-jenkins-6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.jvnet.hudson:htmlunit-core-js:2.6-hudson-1" level="project" />
Expand Down
14 changes: 13 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
</pluginRepositories>

<dependencies>
<!-- production dependencies -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
Expand All @@ -68,6 +69,14 @@
<artifactId>jna</artifactId>
<version>3.2.2</version>
</dependency>

<!-- test dependencies -->
<dependency>
<scope>test</scope>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.0.23-beta</version>
</dependency>
</dependencies>

<build>
Expand All @@ -83,7 +92,10 @@
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.6</version>
<configuration>
<format>xml</format>
<formats>
<format>xml</format>
<format>html</format>
</formats>
<maxmem>256m</maxmem>
<!-- aggregated reports for multi-module projects -->
<aggregate>true</aggregate>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.uber.jenkins.phabricator.conduit.ArcanistUsageException;
import com.uber.jenkins.phabricator.conduit.Differential;
import com.uber.jenkins.phabricator.utils.CommonUtils;
import com.uber.jenkins.phabricator.conduit.DifferentialClient;
import hudson.EnvVars;
import hudson.Launcher;
import hudson.model.AbstractBuild;
Expand Down Expand Up @@ -89,16 +90,17 @@ public Environment setUp(AbstractBuild build,
}
}

DifferentialClient diffClient = new DifferentialClient(diffID, starter, conduitToken, arcPath);
Differential diff;
try {
diff = new Differential(diffID, starter, conduitToken, arcPath);
diff = new Differential(diffClient);
diff.decorate(build, this.getPhabricatorURL());

logger.println("Applying patch for differential");

// Post a silent notification if option is enabled
if (showBuildStartedMessage) {
diff.postComment(diff.getBuildStartedMessage(environment));
diffClient.postComment(diff.getBuildStartedMessage(environment));
}
} catch (ArcanistUsageException e) {
logger.println("[arcanist] unable to apply patch");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.uber.jenkins.phabricator.conduit.ArcanistUsageException;
import com.uber.jenkins.phabricator.conduit.Differential;

import com.uber.jenkins.phabricator.conduit.DifferentialClient;
import com.uber.jenkins.phabricator.uberalls.UberallsClient;
import com.uber.jenkins.phabricator.utils.CommonUtils;
import com.uber.jenkins.phabricator.utils.Logger;
Expand Down Expand Up @@ -117,15 +118,16 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau

LauncherFactory starter = new LauncherFactory(launcher, environment, listener.getLogger(), build.getWorkspace());

DifferentialClient diffClient = new DifferentialClient(diffID, starter, conduitToken, arcPath);
Differential diff;
try {
diff = new Differential(diffID, starter, conduitToken, arcPath);
diff = new Differential(diffClient);
} catch (ArcanistUsageException e) {
logger.info("arcanist", "unable to fetch differential");
return true;
}

String revisionID = diff.getRevisionID();
String revisionID = diff.getRevisionID(true);
if (CommonUtils.isBlank(revisionID)) {
return this.ignoreBuild(logger.getStream(), "Unable to load revisionID from conduit for diff ID " + diffID);
}
Expand Down Expand Up @@ -172,7 +174,7 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau
if (runHarbormaster) {
logger.info("uberalls", "Sending build result to Harbormaster with PHID '" + phid + "', success: " + harbormasterSuccess);
try {
diff.harbormaster(phid, harbormasterSuccess);
diffClient.harbormaster(phid, harbormasterSuccess);
} catch (ArcanistUsageException e) {
logger.info("arcanist", "unable to post to harbormaster");
return true;
Expand Down Expand Up @@ -214,15 +216,15 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau

JSONObject result = null;
try {
result = diff.postComment(comment, silent, commentAction);
result = diffClient.postComment(comment, silent, commentAction);
} catch (ArcanistUsageException e) {
logger.info("arcanist", "unable to post comment");
}
if(!(result.get("errorMessage") instanceof JSONNull)) {
logger.info("arcanist", "Get error " + result.get("errorMessage") + " with action " +
commentAction + "; trying again with action 'none'");
try {
diff.postComment(comment, silent, "none");
diffClient.postComment(comment, silent, "none");
} catch (ArcanistUsageException e) {
logger.info("arcanist", "unable to post comment");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,52 +25,22 @@
import com.uber.jenkins.phabricator.PhabricatorPostbuildSummaryAction;
import hudson.EnvVars;
import hudson.model.AbstractBuild;
import hudson.model.Result;
import net.sf.json.JSONException;
import net.sf.json.JSONNull;
import net.sf.json.JSONObject;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class Differential {
private final JSONObject rawJSON;
private final LauncherFactory launcher;
private final String conduitToken;
private final String arcPath;
private JSONObject rawJSON;

public Differential(String diffID, LauncherFactory launcher, String conduitToken, String arcPath) throws IOException, InterruptedException, ArcanistUsageException {
this.conduitToken = conduitToken;
this.arcPath = arcPath;
this.launcher = launcher;
Map params = new HashMap<String, String>();
params.put("ids", new String[]{diffID});
private final DifferentialClient client;

JSONObject query = this.callConduit("differential.querydiffs", params);
JSONObject response;
try {
response = query.getJSONObject("response");
} catch (JSONException e) {
e.printStackTrace();
throw new ArcanistUsageException(
String.format("No 'response' object found in conduit call: (%s) %s",
e.getMessage(),
query.toString(2)));
}
try {
this.rawJSON = response.getJSONObject(diffID);
} catch (JSONException e) {
e.printStackTrace();
throw new ArcanistUsageException(
String.format("Unable to find '%s' key in response: (%s) %s",
diffID,
e.getMessage(),
response.toString(2)));

}
public Differential(DifferentialClient client) throws ArcanistUsageException, IOException, InterruptedException {
this.client = client;
this.rawJSON = client.fetchDiff();
}

public String getRevisionID(boolean formatted) {
Expand All @@ -84,50 +54,6 @@ public String getRevisionID(boolean formatted) {
return rawRevisionId;
}

public String getRevisionID() {
return this.getRevisionID(true);
}

/**
* Sets a harbormaster build status
* @param phid Phabricator object ID
* @param pass whether or not the build passed
* @throws IOException
* @throws InterruptedException
*/
public void harbormaster(String phid, boolean pass) throws IOException, InterruptedException, ArcanistUsageException {
Map params = new HashMap<String, String>();
params.put("type", pass ? "pass" : "fail");
params.put("buildTargetPHID", phid);

this.callConduit("harbormaster.sendmessage", params);
}

private JSONObject callConduit(String methodName, Map<String, String> params) throws IOException, InterruptedException, ArcanistUsageException {
ArcanistClient arc = new ArcanistClient(this.arcPath, "call-conduit", params, this.conduitToken, methodName);
return arc.parseConduit(this.launcher.launch(), this.launcher.getStderr());
}

/**
* Posts a comment to a differential
* @param message
* @param silent whether or not to trigger an email
* @param action phabricator comment action, e.g. 'resign', 'reject', 'none'
*/
public JSONObject postComment(String message, boolean silent, String action) throws IOException, InterruptedException, ArcanistUsageException {
Map params = new HashMap<String, String>();
params.put("revision_id", this.getRevisionID(false));
params.put("action", action);
params.put("message", message);
params.put("silent", silent);

return this.callConduit("differential.createcomment", params);
}

public JSONObject postComment(String message) throws IOException, InterruptedException, ArcanistUsageException {
return postComment(message, true, "none");
}

/**
* Get the summary message
* @param phabricatorURL
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package com.uber.jenkins.phabricator.conduit;

import com.uber.jenkins.phabricator.LauncherFactory;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

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

/**
* DifferentialClient handles all interaction with conduit/arc for differentials
*/
public class DifferentialClient {
private final String arcPath;
private final String conduitToken;
private final LauncherFactory launcher;
private final String diffID;

public DifferentialClient(String diffID, LauncherFactory launcher, String conduitToken, String arcPath) {
this.diffID = diffID;
this.launcher = launcher;
this.conduitToken = conduitToken;
this.arcPath = arcPath;
}

/**
* Posts a comment to a differential
* @param message
* @param silent whether or not to trigger an email
* @param action phabricator comment action, e.g. 'resign', 'reject', 'none'
*/
public JSONObject postComment(String message, boolean silent, String action) throws IOException, InterruptedException, ArcanistUsageException {
Map params = new HashMap<String, String>();
params.put("revision_id", this.diffID);
params.put("action", action);
params.put("message", message);
params.put("silent", silent);

return this.callConduit("differential.createcomment", params);
}

public JSONObject fetchDiff() throws ArcanistUsageException, IOException, InterruptedException {
Map params = new HashMap<String, String>();
params.put("ids", new String[]{this.diffID});
JSONObject query = this.callConduit("differential.querydiffs", params);
JSONObject response;
try {
response = query.getJSONObject("response");
} catch (JSONException e) {
e.printStackTrace();
throw new ArcanistUsageException(
String.format("No 'response' object found in conduit call: (%s) %s",
e.getMessage(),
query.toString(2)));
}
try {
return response.getJSONObject(diffID);
} catch (JSONException e) {
e.printStackTrace();
throw new ArcanistUsageException(
String.format("Unable to find '%s' key in response: (%s) %s",
diffID,
e.getMessage(),
response.toString(2)));

}
}

protected JSONObject callConduit(String methodName, Map<String, String> params) throws IOException, InterruptedException, ArcanistUsageException {
ArcanistClient arc = new ArcanistClient(this.arcPath, "call-conduit", params, this.conduitToken, methodName);
return arc.parseConduit(this.launcher.launch(), this.launcher.getStderr());
}

/**
* Sets a harbormaster build status
* @param phid Phabricator object ID
* @param pass whether or not the build passed
* @throws IOException
* @throws InterruptedException
*/
public void harbormaster(String phid, boolean pass) throws IOException, InterruptedException, ArcanistUsageException {
Map params = new HashMap<String, String>();
params.put("type", pass ? "pass" : "fail");
params.put("buildTargetPHID", phid);

this.callConduit("harbormaster.sendmessage", params);
}


/**
* Post a comment on the differential
* @param message the string message to post
* @return
* @throws IOException
* @throws InterruptedException
* @throws ArcanistUsageException
*/
public JSONObject postComment(String message) throws IOException, InterruptedException, ArcanistUsageException {
return postComment(message, true, "none");
}
}

0 comments on commit 583197f

Please sign in to comment.