Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-47609] Add clone option "core.longpaths" to enable .git/config "core" property #856

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,20 @@
public class CloneOption extends GitSCMExtension {
private final boolean shallow;
private final boolean noTags;
private final boolean longPath;
private final String reference;
private final Integer timeout;
private Integer depth;
private boolean honorRefspec;

public CloneOption(boolean shallow, String reference, Integer timeout) {
this(shallow, false, reference, timeout);
public CloneOption(boolean shallow, String reference, Integer timeout) { this(shallow, false, false, reference, timeout);
}

@DataBoundConstructor
public CloneOption(boolean shallow, boolean noTags, String reference, Integer timeout) {
public CloneOption(boolean shallow, boolean noTags, boolean longPath, String reference, Integer timeout) {
this.shallow = shallow;
this.noTags = noTags;
this.longPath = longPath;
this.reference = reference;
this.timeout = timeout;
this.honorRefspec = false;
Expand All @@ -59,6 +60,9 @@ public boolean isNoTags() {
return noTags;
}

@Whitelisted
public boolean isLongPath() { return longPath; }

/**
* This setting allows the job definition to control whether the refspec
* will be honored during the first clone or not.
Expand Down Expand Up @@ -137,6 +141,10 @@ public void decorateCloneCommand(GitSCM scm, Run<?, ?> build, GitClient git, Tas
listener.getLogger().println("Avoid fetching tags");
cmd.tags(false);
}
if (longPath) {
listener.getLogger().println("Setting core.longpaths to true");
cmd.longPath(true);
}
if (honorRefspec) {
listener.getLogger().println("Honoring refspec on initial clone");
// Read refspec configuration from the first configured repository.
Expand Down Expand Up @@ -209,6 +217,7 @@ public boolean equals(Object o) {

return shallow == that.shallow
&& noTags == that.noTags
&& longPath == that.longPath
&& Objects.equals(depth, that.depth)
&& honorRefspec == that.honorRefspec
&& Objects.equals(reference, that.reference)
Expand All @@ -220,7 +229,7 @@ public boolean equals(Object o) {
*/
@Override
public int hashCode() {
return Objects.hash(shallow, noTags, depth, honorRefspec, reference, timeout);
return Objects.hash(shallow, noTags, longPath, depth, honorRefspec, reference, timeout);
}

/**
Expand All @@ -231,6 +240,7 @@ public String toString() {
return "CloneOption{" +
"shallow=" + shallow +
", noTags=" + noTags +
", longPath=" + longPath +
", reference='" + reference + '\'' +
", timeout=" + timeout +
", depth=" + depth +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ def f = namespace(lib.FormTagLib)
f.entry(field:"noTags") {
f.checkbox(title:_("Fetch tags"), negative:true, checked:(instance==null||!instance.noTags))
}
f.entry(field:"longPath") {
f.checkbox(title:_("Honor refspec on initial clone"))
}
f.entry(field:"honorRefspec") {
f.checkbox(title:_("Honor refspec on initial clone"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public void decorateCloneCommandShouldUseValidShallowDepth() throws Exception {
PrintStream logger = mock(PrintStream.class);
when(listener.getLogger()).thenReturn(logger);

CloneOption cloneOption = new CloneOption(true, false, null, null);
CloneOption cloneOption = new CloneOption(true, false, false,null, null);
cloneOption.setDepth(configuredDepth);

cloneOption.decorateCloneCommand(scm, build, git, listener, cloneCommand);
Expand All @@ -87,7 +87,7 @@ public void decorateFetchCommandShouldUseValidShallowDepth() throws Exception {
PrintStream logger = mock(PrintStream.class);
when(listener.getLogger()).thenReturn(logger);

CloneOption cloneOption = new CloneOption(true, false, null, null);
CloneOption cloneOption = new CloneOption(true, false, false,null, null);
cloneOption.setDepth(configuredDepth);

cloneOption.decorateFetchCommand(scm, git, listener, fetchCommand);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package hudson.plugins.git.extensions.impl;

import hudson.EnvVars;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.plugins.git.GitSCM;
import hudson.plugins.git.util.Build;
import hudson.plugins.git.util.BuildData;
import org.jenkinsci.plugins.gitclient.CloneCommand;
import org.jenkinsci.plugins.gitclient.GitClient;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.mockito.Mockito;

import java.io.PrintStream;

import static org.mockito.Mockito.*;
import static org.mockito.Mockito.verify;

public class CloneOptionLongPathTest {

@ClassRule
public static JenkinsRule j = new JenkinsRule();

private GitSCM scm;
private Run<?, ?> build;
private GitClient git;
private TaskListener listener;

@Before
public void mockDependencies() throws Exception {
scm = mock(GitSCM.class);
build = mock(Run.class);
git = mock(GitClient.class);
listener = mock(TaskListener.class);

BuildData buildData = mock(BuildData.class);
buildData.lastBuild = mock(Build.class);
when(build.getEnvironment(listener)).thenReturn(mock(EnvVars.class));
when(scm.getBuildData(build)).thenReturn(buildData);
}

@Issue("JENKINS-47609")
@Test
public void decorateCloneCommandShouldUseValidLongPath() throws Exception {
CloneCommand cloneCommand = mock(CloneCommand.class, Mockito.RETURNS_SELF);

PrintStream logger = mock(PrintStream.class);
when(listener.getLogger()).thenReturn(logger);

boolean enableLongPath = true;
CloneOption cloneOption = new CloneOption(true, false, enableLongPath,null, null);

cloneOption.decorateCloneCommand(scm, build, git, listener, cloneCommand);

verify(cloneCommand).longPath(true);
verify(logger).println("Setting core.longpaths to true");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protected GitSCMExtension getExtension() {
final boolean dontFetchTags = true;
final String noReference = null;
final Integer noTimeout = null;
return new CloneOption(shallowClone, dontFetchTags, noReference, noTimeout);
return new CloneOption(shallowClone, dontFetchTags, false, noReference, noTimeout);
}

@Test
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/jenkins/plugins/git/GitSCMBuilderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ public void withGitTool() throws Exception {
@Test
public void withRefSpecAndCloneOption() throws Exception {
instance.withRefSpec("+refs/heads/master:refs/remotes/@{remote}/master");
instance.withExtension(new CloneOption(false, false, null, null));
instance.withExtension(new CloneOption(false, false, false, null, null));
assertThat(instance.refSpecs(), contains("+refs/heads/master:refs/remotes/@{remote}/master"));
GitSCM scm = instance.build();
assertThat(scm.getBrowser(), is(nullValue()));
Expand Down