Skip to content

Commit

Permalink
Merge c783d38 into e84f77d
Browse files Browse the repository at this point in the history
  • Loading branch information
iarkhanhelsky committed Nov 30, 2018
2 parents e84f77d + c783d38 commit 1ccf5ca
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@
public class PhabricatorBuildWrapper extends BuildWrapper {

private static final String CONDUIT_TAG = "conduit";
private static final String DEFAULT_GIT_PATH = "git";
private static final String DIFFERENTIAL_SUMMARY = "PHABRICATOR_DIFFERENTIAL_SUMMARY";
private static final String DIFFERENTIAL_AUTHOR = "PHABRICATOR_DIFFERENTIAL_AUTHOR";
private static final String DIFFERENTIAL_BASE_COMMIT = "PHABRICATOR_DIFFERENTIAL_BASE_COMMIT";
private static final String DIFFERENTIAL_BRANCH = "PHABRICATOR_DIFFERENTIAL_BRANCH";

private static final String DEFAULT_GIT_BRANCH = "origin/master";
private static final String DEFAULT_HG_BRANCH = "default";

private final boolean createCommit;
private final boolean applyToMaster;
private final boolean skipForcedClean;
Expand Down Expand Up @@ -190,7 +192,12 @@ public Environment setUp(
if (skipApplyPatch) {
logger.info("arcanist", "Skipping applying arc patch as configured in job");
} else {
String baseCommit = "origin/master";

String baseCommit = DEFAULT_GIT_BRANCH;
if ("hg".equals(scmType)) {
baseCommit = DEFAULT_HG_BRANCH;
}

if (!applyToMaster) {
baseCommit = diff.getBaseCommit();
}
Expand All @@ -199,9 +206,8 @@ public Environment setUp(
final String conduitUrl = this.getPhabricatorURL(build.getParent());
Task.Result result = new ApplyPatchTask(
logger, starter, baseCommit, diffID, conduitUrl, conduitToken, getArcPath(),
DEFAULT_GIT_PATH, createCommit, skipForcedClean, createBranch,
patchWithForceFlag, scmType
).run();
createCommit, skipForcedClean, createBranch,
patchWithForceFlag, scmType).run();

if (result != Task.Result.SUCCESS) {
logger.warn("arcanist", "Error applying arc patch; got non-zero exit code " + result);
Expand Down
181 changes: 121 additions & 60 deletions src/main/java/com/uber/jenkins/phabricator/tasks/ApplyPatchTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package com.uber.jenkins.phabricator.tasks;

import com.google.common.annotations.VisibleForTesting;
import com.uber.jenkins.phabricator.LauncherFactory;
import com.uber.jenkins.phabricator.conduit.ArcanistClient;
import com.uber.jenkins.phabricator.utils.Logger;
Expand All @@ -28,45 +29,76 @@
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ApplyPatchTask extends Task {
private static final String DEFAULT_GIT_PATH = "git";
private static final String DEFAULT_HG_PATH = "hg";

private final LauncherFactory starter;
private final String baseCommit;
private final String diffID;
private final PrintStream logStream;

private final String scmType;

private String gitPath;
private String hgPath;
private final String arcPath;

private final boolean skipForcedClean;

private final String baseCommit;

private final String conduitUrl;
private final String conduitToken;
private final String arcPath;

private final String diffID;
private final boolean createCommit;
private final String gitPath;
private final boolean skipForcedClean;
private final boolean createBranch;
private final boolean patchWithForceFlag;
private final String scmType;

public ApplyPatchTask(
Logger logger, LauncherFactory starter, String baseCommit,
String diffID, String conduitUrl, String conduitToken,
String arcPath, String gitPath, boolean createCommit,
String diffID, String conduitUrl, String conduitToken, String arcPath,
boolean createCommit,
boolean skipForcedClean, boolean createBranch,
boolean patchWithForceFlag, String scmType) {
super(logger);

this.arcPath = arcPath;
this.gitPath = DEFAULT_GIT_PATH;
this.hgPath = DEFAULT_HG_PATH;

this.scmType = scmType;

this.starter = starter;
this.logStream = logger.getStream();

this.baseCommit = baseCommit;
this.diffID = diffID;
this.conduitUrl = conduitUrl;
this.conduitToken = conduitToken;
this.arcPath = arcPath;
this.gitPath = gitPath;

this.createCommit = createCommit;
this.skipForcedClean = skipForcedClean;
this.createBranch = createBranch;
this.patchWithForceFlag = patchWithForceFlag;
this.scmType = scmType;
}

this.logStream = logger.getStream();
/**
* Allows to override default exeturable path used for git
*/
@VisibleForTesting
void setGitPath(String gitPath) {
this.gitPath = gitPath;
}

/**
* Allows to override default exeturable path used for git
*/
@VisibleForTesting
void setHgPath(String hgPath) {
this.hgPath = hgPath;
}

/**
Expand All @@ -91,64 +123,93 @@ protected void setup() {
@Override
protected void execute() {
try {
int exitCode;
if (this.scmType.equals("git")) {
exitCode = starter.launch()
.cmds(Arrays.asList(gitPath, "reset", "--hard", baseCommit))
.stdout(logStream)
.join();

if (exitCode != 0) {
info("Got non-zero exit code resetting to base commit " + baseCommit + ": " + exitCode);
}

if (!skipForcedClean) {
// Clean workspace, otherwise `arc patch` may fail
starter.launch()
.stdout(logStream)
.cmds(Arrays.asList(gitPath, "clean", "-fd", "-f"))
.join();
}

// Update submodules recursively.
starter.launch()
.stdout(logStream)
.cmds(Arrays.asList(gitPath, "submodule", "update", "--init", "--recursive"))
.join();
}
prepareRepositoryState();
this.result = applyArcPatch() == 0 ? Result.SUCCESS : Result.FAILURE;
} catch (IOException | InterruptedException e) {
e.printStackTrace(logStream);
this.result = Result.FAILURE;
}
}

List<String> arcPatchParams = new ArrayList<String>(Arrays.asList("--diff", diffID));
private int applyArcPatch() throws IOException, InterruptedException {
int exitCode;
List<String> arcPatchParams = new ArrayList<String>(Arrays.asList("--diff", diffID));

if (this.scmType.equals("git")) {
switch (scmType) {
case "git":
case "hg":
if (!createCommit) {
arcPatchParams.add("--nocommit");
}

if (!createBranch) {
arcPatchParams.add("--nobranch");
}
}

if (patchWithForceFlag) {
arcPatchParams.add("--force");
}

ArcanistClient arc = new ArcanistClient(
arcPath,
"patch",
conduitUrl,
conduitToken,
arcPatchParams.toArray(new String[arcPatchParams.size()]));

exitCode = arc.callConduit(starter.launch(), logStream);
this.result = exitCode == 0 ? Result.SUCCESS : Result.FAILURE;
} catch (IOException e) {
e.printStackTrace(logStream);
this.result = Result.FAILURE;
} catch (InterruptedException e) {
e.printStackTrace(logStream);
this.result = Result.FAILURE;
break;
case "svn":
break;
default:
info("Unknown scm type " + scmType + " skipping");
}

if (patchWithForceFlag) {
arcPatchParams.add("--force");
}

ArcanistClient arc = new ArcanistClient(
arcPath,
"patch",
conduitUrl,
conduitToken,
arcPatchParams.toArray(new String[arcPatchParams.size()]));

exitCode = arc.callConduit(starter.launch(), logStream);
return exitCode;
}

private void prepareRepositoryState() throws InterruptedException, IOException {
List<String> resetToBaseCommit = Collections.emptyList();
List<String> cleanWorkingDir = Collections.emptyList();
List<String> updateSubmodules = Collections.emptyList();

switch (scmType) {
case "git":
resetToBaseCommit = Arrays.asList(gitPath, "reset", "--hard", baseCommit);
cleanWorkingDir = Arrays.asList(gitPath, "clean", "-fd", "-f");
updateSubmodules = Arrays.asList(gitPath, "submodule", "update", "--init", "--recursive");
break;
case "hg":
resetToBaseCommit = Arrays.asList(hgPath, "update", "--clean", baseCommit);
// Purge is core extension but not enabled by default
cleanWorkingDir = Arrays.asList(hgPath, "--config", "extensions.purge=", "purge", "--files", "--dirs");
// Submodules updated by resetToBaseCommit command
updateSubmodules = Collections.emptyList();
break;
case "svn":
break;
default:
info("Unknown scm type " + scmType + " skipping");
return;
}

int exitCode = launch(resetToBaseCommit);

if (exitCode != 0) {
info("Got non-zero exit code resetting to base commit " + baseCommit + ": " + exitCode);
}

if (!skipForcedClean) {
launch(cleanWorkingDir);
}

launch(updateSubmodules);
}

private int launch(List<String> cmds) throws IOException, InterruptedException {
if (cmds.isEmpty()) {
return 0;
}
return starter.launch().cmds(cmds).stdout(logStream).join();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
<f:entry title="SCM type" field="scmType" description="SCM used in this job">
<f:radio name="scmType" title="git" value="git" checked="${instance.scmType == 'git' || instance.scmType == null}" />
<f:radio name="scmType" title="hg" value="hg" checked="${instance.scmType == 'hg'}" />
<f:radio name="scmType" title="svn" value="svn" checked="${instance.scmType == 'svn'}" />
</f:entry>
<f:entry title="Create git commit" field="createCommit"
description="Create a git commit with the patch">
<f:entry title="Create commit" field="createCommit"
description="Create a commit with the patch. Supports: git, hg">
<f:checkbox />
</f:entry>
<f:entry title="Apply patch to master" field="applyToMaster"
description="If true, always arc patch apply to master">
<f:checkbox />
</f:entry>
<f:entry title="Skip Forced Git clean" field="skipForcedClean"
description="Skip 'git clean -fd -f' step.">
<f:entry title="Skip forced clean" field="skipForcedClean"
description="Skip repository clean step. Git: 'git clean -fd -f', hg: 'hg purge --dirs --files'">
<f:checkbox default="false" />
</f:entry>
<f:entry title="Create git branch" field="createBranch"
description="Create a git branch with the patch">
<f:entry title="Create branch" field="createBranch"
description="Create a branch with the patch. Supports: git, hg">
<f:checkbox />
</f:entry>
<f:entry title="Run 'arc patch' with '--force'" field="patchWithForceFlag"
Expand Down

0 comments on commit 1ccf5ca

Please sign in to comment.