Skip to content
Permalink
Browse files

[FIXED JENKINS-5723] Permit arbitrary --config options to be defined …

…for a given Mercurial installation.
  • Loading branch information...
jglick committed Feb 18, 2014
1 parent 5dfe772 commit c777dc9cbef3abbb0da25fdca9bcfa14622d77e2
@@ -101,5 +101,10 @@
<version>0.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<version>0.5.2</version>
</dependency>
</dependencies>
</project>
@@ -43,12 +43,11 @@
import hudson.model.TaskListener;
import hudson.remoting.VirtualChannel;
import hudson.util.ArgumentListBuilder;
import jenkins.model.Jenkins;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
@@ -60,6 +59,8 @@
import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import jenkins.model.Jenkins;
import org.ini4j.Ini;

/**
* Encapsulates the invocation of the Mercurial command.
@@ -180,6 +181,15 @@ private static ArgumentListBuilder findHgExe(@CheckForNull MercurialInstallation
if (allowDebug && inst.getDebug()) {
b.add("--debug");
}
String config = inst.getConfig();
if (config != null) {
for (Map.Entry<String,? extends Map<String,String>> entry : new Ini(new StringReader(config)).entrySet()) {
String sectionName = entry.getKey();
for (Map.Entry<String,String> entry2 : entry.getValue().entrySet()) {
b.add("--config", sectionName + '.' + entry2.getKey() + '=' + entry2.getValue());
}
}
}
}
if (credentials instanceof UsernamePasswordCredentials) {
UsernamePasswordCredentials upc = (UsernamePasswordCredentials) credentials;
@@ -24,25 +24,28 @@

package hudson.plugins.mercurial;

import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import hudson.CopyOnWrite;
import hudson.EnvVars;
import hudson.Extension;
import hudson.Util;
import hudson.model.EnvironmentSpecific;
import hudson.model.TaskListener;
import hudson.model.Hudson;
import hudson.model.Node;
import hudson.model.TaskListener;
import hudson.slaves.NodeSpecific;
import hudson.tools.ToolDescriptor;
import hudson.tools.ToolProperty;
import hudson.tools.ToolInstallation;

import hudson.tools.ToolProperty;
import hudson.util.FormValidation;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import javax.annotation.CheckForNull;
import org.ini4j.Ini;
import org.ini4j.InvalidFileFormatException;
import org.kohsuke.stapler.DataBoundConstructor;

import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import org.kohsuke.stapler.QueryParameter;

/**
* Installation of Mercurial.
@@ -61,15 +64,21 @@
private boolean debug;
private boolean useCaches;
private boolean useSharing;
private final String config;

@DataBoundConstructor
@Deprecated
public MercurialInstallation(String name, String home, String executable,
boolean debug, boolean useCaches,
boolean useSharing, List<? extends ToolProperty<?>> properties) {
this(name, home, executable, debug, useCaches, useSharing, null, properties);
}

@DataBoundConstructor public MercurialInstallation(String name, String home, String executable, boolean debug, boolean useCaches, boolean useSharing, String config, List<? extends ToolProperty<?>> properties) {
super(name, home, properties);
this.executable = Util.fixEmpty(executable);
this.debug = debug;
this.useCaches = useCaches || useSharing;
this.config = Util.fixEmptyAndTrim(config);
this.useSharing = useSharing;
}

@@ -93,6 +102,10 @@ public boolean isUseSharing() {
return useSharing;
}

public @CheckForNull String getConfig() {
return config;
}

public static MercurialInstallation[] allInstallations() {
return Hudson.getInstance().getDescriptorByType(DescriptorImpl.class)
.getInstallations();
@@ -139,6 +152,21 @@ public void setInstallations(MercurialInstallation... installations) {
save();
}

@java.lang.SuppressWarnings("ResultOfObjectAllocationIgnored")
public FormValidation doCheckConfig(@QueryParameter String value) {
if (value == null) {
return FormValidation.ok();
}
try {
new Ini(new StringReader(value));
return FormValidation.ok();
} catch (InvalidFileFormatException x) {
return FormValidation.error(x.getMessage());
} catch (IOException x) {
return FormValidation.error(x, "should not happen");
}
}

}

}
@@ -17,4 +17,7 @@
<f:entry field="debug" title="${%Debug Flag}">
<f:checkbox/>
</f:entry>
<f:entry field="config" title="${%Custom Configuration}">
<f:textarea/>
</f:entry>
</j:jelly>
@@ -0,0 +1,12 @@
<p>
Extra configuration in the same format as <code>~/.hgrc</code> (or <code>Mercurial.ini</code> for Windows users).
Various miscellaneous Mercurial options can be set, or you can set default options for commands.
For example:
</p>
<pre>
[defaults]
clone = --uncompressed
bundle = --type none
[extensions]
eol =
</pre>
@@ -0,0 +1,61 @@
/*
* The MIT License
*
* Copyright 2014 Jesse Glick.
*
* 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 hudson.plugins.mercurial;

import hudson.FilePath;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import hudson.tools.ToolProperty;
import java.io.File;
import java.util.Collections;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.JenkinsRule;

public class CustomConfigTest {

@Rule public JenkinsRule r = new JenkinsRule();
@Rule public MercurialRule m = new MercurialRule(r);
@Rule public TemporaryFolder tmp = new TemporaryFolder();

@Bug(5723)
@Test public void customConfiguration() throws Exception {
File repo = tmp.getRoot();
m.hg(repo, "init");
m.touchAndCommit(repo, "f");
r.jenkins.getDescriptorByType(MercurialInstallation.DescriptorImpl.class).setInstallations(new MercurialInstallation("test", "", "hg", false, false, false, "[format]\nusestore = false", Collections.<ToolProperty<?>>emptyList()));
FreeStyleProject p = r.createFreeStyleProject();
p.setScm(new MercurialSCM("test", repo.getPath(), MercurialSCM.RevisionType.BRANCH, null, null, null, null, false, null, false));
FreeStyleBuild b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
FilePath ws = b.getWorkspace();
assertNotNull(ws);
String requires = ws.child(".hg/requires").readToString();
assertFalse(requires, requires.contains("store"));
}

}
@@ -33,19 +33,20 @@
import hudson.tools.ToolProperty;
import hudson.util.ArgumentListBuilder;
import hudson.util.StreamTaskListener;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;

import java.io.File;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import static org.junit.Assert.assertEquals;

import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.JenkinsRule;


public class HgExeFunctionalTest {
@@ -112,4 +113,11 @@ public void credentialsUsernamePasswordTest() throws Exception {
hgexe.close();
}

@Bug(5723)
@Test public void customConfiguration() throws Exception {
HgExe hgexe = new HgExe(new MercurialInstallation(INSTALLATION, "", "hg", false, false, false, "[defaults]\nclone = --uncompressed\n", Collections.<ToolProperty<?>>emptyList()), null, this.launcher, j.jenkins, this.listener, this.vars);
ArgumentListBuilder b = hgexe.seed(false).add("clone", "http://some.thing/");
assertEquals("hg --config defaults.clone=--uncompressed clone http://some.thing/", b.toString());
}

}

0 comments on commit c777dc9

Please sign in to comment.
You can’t perform that action at this time.