Skip to content

Commit

Permalink
Merge pull request #62 from misery/master
Browse files Browse the repository at this point in the history
[FIXED JENKINS-10706] Add env variable MERCURIAL_REVISION_BRANCH
A couple of minor comments outstanding, but those can be fixed up later or not at all.
  • Loading branch information
jglick committed Apr 11, 2015
2 parents 5e5b7ca + 43a0abf commit f3fd807
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 11 deletions.
36 changes: 36 additions & 0 deletions src/main/java/hudson/plugins/mercurial/HgExe.java
Expand Up @@ -55,6 +55,8 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -345,6 +347,40 @@ private Set<String> heads(FilePath repo, boolean useTimeout, boolean usingHg15Sy
return id;
}

/**
* Gets the branch name of given revision number or of the current workspace.
* @param rev the revision to identify; defaults to current working copy
*/
public @CheckForNull String branch(FilePath repository, @CheckForNull String rev) throws IOException, InterruptedException {
ArgumentListBuilder builder = new ArgumentListBuilder("id", "--branch");
if (rev != null)
builder.add("--rev", rev);
String branch = popen(repository, listener, false, builder).trim();
if (branch.isEmpty()) {
listener.error(Messages.HgExe_expected_to_get_a_branch_name_but_got_nothing());
return null;
}
return branch;
}

/**
* Gets the version of used Mercurial installation.
*/
public @CheckForNull String version() throws IOException, InterruptedException {
String version = popen(null, listener, false, new ArgumentListBuilder("version"));
if (version.isEmpty()) {
listener.error(Messages.HgExe_expected_to_get_hg_version_name_but_got_nothing());
return null;
}
Matcher m = Pattern.compile("^Mercurial Distributed SCM \\(version ([0-9][^)]*)\\)").matcher(version);
if (!m.lookingAt() || m.groupCount() < 1)
{
listener.error(Messages.HgExe_cannot_extract_hg_version());
return null;
}
return m.group(1);
}

/**
* Gets the current value of a specified config item.
*/
Expand Down
21 changes: 16 additions & 5 deletions src/main/java/hudson/plugins/mercurial/MercurialSCM.java
Expand Up @@ -37,6 +37,7 @@
import hudson.util.ArgumentListBuilder;
import hudson.util.ForkOutputStream;
import hudson.util.ListBoxModel;
import hudson.util.VersionNumber;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
Expand Down Expand Up @@ -73,6 +74,7 @@ public class MercurialSCM extends SCM implements Serializable {
private static final String ENV_MERCURIAL_REVISION = "MERCURIAL_REVISION";
private static final String ENV_MERCURIAL_REVISION_SHORT = "MERCURIAL_REVISION_SHORT";
private static final String ENV_MERCURIAL_REVISION_NUMBER = "MERCURIAL_REVISION_NUMBER";
private static final String ENV_MERCURIAL_REVISION_BRANCH = "MERCURIAL_REVISION_BRANCH";
private static final String ENV_MERCURIAL_REPOSITORY_URL = "MERCURIAL_REPOSITORY_URL";

// old fields are left so that old config data can be read in, but
Expand Down Expand Up @@ -352,7 +354,8 @@ public SCMRevisionState calcRevisionsFromBuild(Run<?, ?> build, FilePath workspa
try {
String tip = hg.tip(workspace2Repo(workspace, env), null);
String rev = hg.tipNumber(workspace2Repo(workspace, env), null);
return tip != null && rev != null ? new MercurialTagAction(tip, rev, getSubdir(env)) : null;
String branch = revisionType != RevisionType.BRANCH ? hg.branch(workspace2Repo(workspace, env), null) : null;
return tip != null && rev != null ? new MercurialTagAction(tip, rev, getSubdir(env), branch) : null;
} finally {
hg.close();
}
Expand Down Expand Up @@ -420,6 +423,7 @@ PollingResult compare(Launcher launcher, TaskListener listener, MercurialTagActi
String _revision = getRevisionExpanded(project, env);
String remote = hg.tip(repository, _revision);
String rev = hg.tipNumber(repository, _revision);
String branch = revisionType != RevisionType.BRANCH ? hg.branch(repository, _revision) : null;

if (remote == null) {
throw new IOException("failed to find ID of branch head");
Expand All @@ -428,11 +432,11 @@ PollingResult compare(Launcher launcher, TaskListener listener, MercurialTagActi
throw new IOException("failed to find revision of branch head");
}
if (remote.equals(baseline.id)) { // shortcut
return new PollingResult(baseline, new MercurialTagAction(remote, rev, getSubdir(env)), Change.NONE);
return new PollingResult(baseline, new MercurialTagAction(remote, rev, getSubdir(env), branch), Change.NONE);
}
Set<String> changedFileNames = parseStatus(hg.popen(repository, listener, false, new ArgumentListBuilder("status", "--rev", baseline.id, "--rev", remote)));

MercurialTagAction cur = new MercurialTagAction(remote, rev, getSubdir(env));
MercurialTagAction cur = new MercurialTagAction(remote, rev, getSubdir(env), branch);
return new PollingResult(baseline,cur,computeDegreeOfChanges(changedFileNames,output));
} finally {
hg.close();
Expand Down Expand Up @@ -709,8 +713,9 @@ private void update(Run<?, ?> build, Launcher launcher, FilePath repository, Nod

String tip = hg.tip(repository, null);
String rev = hg.tipNumber(repository, null);
String branch = revisionType != RevisionType.BRANCH ? hg.branch(repository, null) : null;
if (tip != null && rev != null) {
build.addAction(new MercurialTagAction(tip, rev, getSubdir(env)));
build.addAction(new MercurialTagAction(tip, rev, getSubdir(env), branch));
}
} finally {
hg.close();
Expand Down Expand Up @@ -765,6 +770,9 @@ private void clone(Run<?, ?> build, Launcher launcher, FilePath repository, Node
args.add("share");
args.add("--noupdate");
args.add(cachedSource.getRepoLocation());
if (new VersionNumber(hg.version()).compareTo(new VersionNumber("3.3")) >= 0) {
args.add("-B");
}
} else {
args.add("clone");
args.add("--noupdate");
Expand Down Expand Up @@ -820,8 +828,9 @@ private void clone(Run<?, ?> build, Launcher launcher, FilePath repository, Node

String tip = hg.tip(repository, null);
String rev = hg.tipNumber(repository, null);
String branch = revisionType != RevisionType.BRANCH ? hg.branch(repository, null) : null;
if (tip != null && rev != null) {
build.addAction(new MercurialTagAction(tip, rev, getSubdir(env)));
build.addAction(new MercurialTagAction(tip, rev, getSubdir(env), branch));
}
} finally {
hg.close();
Expand All @@ -839,6 +848,8 @@ void buildEnvVarsFromActionable(Actionable build, Map<String, String> env) {
env.put(ENV_MERCURIAL_REVISION, a.id);
env.put(ENV_MERCURIAL_REVISION_SHORT, a.getShortId());
env.put(ENV_MERCURIAL_REVISION_NUMBER, a.rev);
if (revisionType != RevisionType.BRANCH)
env.put(ENV_MERCURIAL_REVISION_BRANCH, a.getBranch());
env.put(ENV_MERCURIAL_REPOSITORY_URL, this.getSource());
}
}
Expand Down
13 changes: 12 additions & 1 deletion src/main/java/hudson/plugins/mercurial/MercurialTagAction.java
Expand Up @@ -32,10 +32,16 @@ public class MercurialTagAction extends SCMRevisionState {
*/
public final String subdir;

public MercurialTagAction(@NonNull String id, @NonNull String rev, @Nullable String subdir) {
/**
* Branch name of current revision.
*/
public final String branch;

public MercurialTagAction(@NonNull String id, @NonNull String rev, @Nullable String subdir, @Nullable String branch) {
this.id = id;
this.rev = rev;
this.subdir = subdir;
this.branch = branch;
}

@Exported(name = "mercurialNodeName")
Expand All @@ -53,6 +59,11 @@ public String getSubdir() {
return subdir;
}

@Exported(name = "mercurialRevisionBranch")
public String getBranch() {
return branch;
}

/**
* Mercurial often uses a short ID form that consists of 12 letters.
*/
Expand Down
@@ -1,9 +1,12 @@
HgExe.expected_to_get_a_revision_number_but_got_instead=Expected to get a revision number but got ''{0}'' instead.
HgExe.expected_to_get_a_branch_name_but_got_nothing=Expected to get a branch name but got an empty name instead.
HgExe.expected_to_get_hg_version_name_but_got_nothing=Expected to get a mercurial version but got an empty string instead.
HgExe.cannot_extract_hg_version=Cannot extract hg version
MercurialInstallation.mercurial=Mercurial
MercurialSCM.dependent_changes_detected=Dependent changes detected
MercurialSCM.failed_to_clone=Failed to clone {0}
MercurialSCM.failed_to_compare_with_remote_repository=Failed to compare with remote repository because hg could not be found; check that you''ve properly configured your Mercurial installation
MercurialSCM.non_dependent_changes_detected=Non-dependent changes detected
MercurialStatus.mercurial=Mercurial
MercurialTagAction.BuildData=Mercurial Build Data
MercurialRevisionColumn.DisplayName=Mercurial Branch
MercurialRevisionColumn.DisplayName=Mercurial Branch
Expand Up @@ -54,7 +54,7 @@ public Change compare(MercurialSCM scm, Launcher launcher, TaskListener listener
PollingResult pr = scm.compare(
launcher,
listener,
new MercurialTagAction("tip","",null),
new MercurialTagAction("tip","",null,null),
listener.getLogger(),
Computer.currentComputer().getNode(),
new FilePath(tmp.getRoot()),
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/hudson/plugins/mercurial/HgExeFunctionalTest.java
Expand Up @@ -33,6 +33,7 @@
import hudson.tools.ToolProperty;
import hudson.util.ArgumentListBuilder;
import hudson.util.StreamTaskListener;
import hudson.util.VersionNumber;
import java.io.File;
import java.nio.charset.Charset;
import java.util.Collections;
Expand All @@ -42,6 +43,8 @@
import static org.junit.Assert.assertEquals;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
Expand Down Expand Up @@ -120,4 +123,13 @@ public void credentialsUsernamePasswordTest() throws Exception {
assertEquals("hg --config defaults.clone=--uncompressed clone http://some.thing/", b.toString());
}

@Test public void checkVersion() throws Exception {
HgExe hgexe = new HgExe(
this.mercurialInstallation, null,
this.launcher, j.jenkins,
this.listener, this.vars);
String version = hgexe.version();
assertNotNull(version);
assertTrue(new VersionNumber(version).compareTo(new VersionNumber("1.0")) >= 0);
}
}
4 changes: 2 additions & 2 deletions src/test/java/hudson/plugins/mercurial/MercurialSCMTest.java
Expand Up @@ -52,7 +52,7 @@ public class MercurialSCMTest {
final String EXPECTED_SHORT_ID = "123456789012";
new MercurialSCM("","","", "", "", null, true).buildEnvVarsFromActionable(new Actionable() {
@Override public List<Action> getActions() {
return Collections.<Action>singletonList(new MercurialTagAction(EXPECTED_SHORT_ID + "1627e63489b4096a8858e559a456", "rev", null));
return Collections.<Action>singletonList(new MercurialTagAction(EXPECTED_SHORT_ID + "1627e63489b4096a8858e559a456", "rev", null, null));
}
@Override public String getDisplayName() {return null;}
@Override public String getSearchUrl() {return null;}
Expand All @@ -65,7 +65,7 @@ public class MercurialSCMTest {
final String EXPECTED_REPOSITORY_URL = "http://mercurialserver/testrepo";
new MercurialSCM("",EXPECTED_REPOSITORY_URL,"", "", "", null, true).buildEnvVarsFromActionable(new Actionable() {
@Override public List<Action> getActions() {
return Collections.<Action>singletonList(new MercurialTagAction("1627e63489b4096a8858e559a456", "rev", null)); }
return Collections.<Action>singletonList(new MercurialTagAction("1627e63489b4096a8858e559a456", "rev", null, null)); }
@Override public String getDisplayName() {return null;}
@Override public String getSearchUrl() {return null;}
}, actualEnvironment);
Expand Down
Expand Up @@ -6,7 +6,7 @@

public class MercurialTagActionTest {
@Test public void getShortIdReturnsFirstTwelveCharactersOfId(){
MercurialTagAction action = new MercurialTagAction("1234567890121627e63489b4096a8858e559a456", "", "");
MercurialTagAction action = new MercurialTagAction("1234567890121627e63489b4096a8858e559a456", "", "", null);

assertEquals("123456789012", action.getShortId());
}
Expand Down
35 changes: 35 additions & 0 deletions src/test/java/hudson/plugins/mercurial/SCMTestBase.java
Expand Up @@ -746,6 +746,41 @@ public Proc onLaunch(Launcher.ProcStarter p) throws IOException {
assertEquals(Result.SUCCESS, b.getResult());
}

private void initRepoWithTag() throws Exception {
m.hg(repo, "init");
m.touchAndCommit(repo, "init");
m.hg(repo, "branch", "stable");
m.touchAndCommit(repo, "stable commit");
m.hg(repo, "tag", "release");
m.hg(repo, "update", "--clean", "default");
}

@Bug(10706)
@Test public void testGetBranchFromTag() throws Exception {
initRepoWithTag();
FreeStyleProject p = j.createFreeStyleProject();
p.setScm(new MercurialSCM(hgInstallation(), repo.getPath(), MercurialSCM.RevisionType.TAG, "release", null, null, null, false, null));

FreeStyleBuild b = j.buildAndAssertSuccess(p);
MercurialTagAction action = b.getAction(MercurialTagAction.class);
assertNotNull(action);
assertEquals("stable", action.getBranch());
assertEquals("stable", b.getEnvironment().get("MERCURIAL_REVISION_BRANCH"));
}

@Bug(10706)
@Test public void testGetNoBranchFromBranch() throws Exception {
initRepoWithTag();
FreeStyleProject p = j.createFreeStyleProject();
p.setScm(new MercurialSCM(hgInstallation(), repo.getPath(), MercurialSCM.RevisionType.BRANCH, "default", null, null, null, false, null));

FreeStyleBuild b = j.buildAndAssertSuccess(p);
MercurialTagAction action = b.getAction(MercurialTagAction.class);
assertNotNull(action);
assertEquals(null, action.getBranch());
assertEquals(null, b.getEnvironment().get("MERCURIAL_REVISION_BRANCH"));
}

/* TODO the following will pass, but canUpdate is not going to work without further changes:
public void testParameterizedBuildsSource() throws Exception {
p = createFreeStyleProject();
Expand Down

0 comments on commit f3fd807

Please sign in to comment.