From 85254b193a05e396673c1a8f7ec864b7e10111bd Mon Sep 17 00:00:00 2001 From: raghavgarg098 Date: Thu, 8 Apr 2021 19:27:00 +0530 Subject: [PATCH 1/3] Expand environment variables in the sparse checkout paths. --- .../extensions/impl/SparseCheckoutPath.java | 44 ++++++++++++++----- .../extensions/impl/SparseCheckoutPaths.java | 31 ++++++------- .../impl/SparseCheckoutPathsTest.java | 22 ++++++++++ 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPath.java b/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPath.java index c07399ca21..0ca4b43fe3 100644 --- a/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPath.java +++ b/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPath.java @@ -3,6 +3,7 @@ import com.google.common.base.Function; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.EnvVars; import hudson.Extension; import hudson.model.AbstractDescribableImpl; import hudson.model.Descriptor; @@ -10,15 +11,17 @@ import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.Whitelisted; import org.kohsuke.stapler.DataBoundConstructor; +import javax.annotation.Nullable; import java.io.Serializable; import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class SparseCheckoutPath extends AbstractDescribableImpl implements Serializable { private static final long serialVersionUID = -6177158367915899356L; - @SuppressFBWarnings(value="SE_TRANSIENT_FIELD_NOT_RESTORED", justification="Default value is OK in deserialization") - public static final transient SparseCheckoutPathToPath SPARSE_CHECKOUT_PATH_TO_PATH = new SparseCheckoutPathToPath(); + @SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification = "Default value is OK in deserialization") private final String path; @@ -56,20 +59,41 @@ public String toString() { return path; } - private static class SparseCheckoutPathToPath implements Function, Serializable { - public String apply(@NonNull SparseCheckoutPath sparseCheckoutPath) { - return sparseCheckoutPath.getPath(); - } + public Descriptor getDescriptor() { + return Jenkins.get().getDescriptor(getClass()); } - public Descriptor getDescriptor() - { - return Jenkins.get().getDescriptor(getClass()); + public static class SparseCheckoutPathToPath implements Function, Serializable { + @Nullable + private EnvVars envVars; + + SparseCheckoutPathToPath(@Nullable EnvVars envVars) { + this.envVars = envVars; + } + + public String apply(@NonNull SparseCheckoutPath sparseCheckoutPath) { + String path = sparseCheckoutPath.getPath(); + if (envVars == null) { + return path; + } + + // Pattern to look for substring of the form ${ENV_VAR}. + Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}"); + Matcher matcher = pattern.matcher(path); + while (matcher.find()) { + String varName = matcher.group(1); + String value = envVars.get(varName, ""); + path = path.replace("${" + varName + "}", value); + } + return path; + } } @Extension public static class DescriptorImpl extends Descriptor { @Override - public String getDisplayName() { return "Path"; } + public String getDisplayName() { + return "Path"; + } } } diff --git a/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPaths.java b/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPaths.java index 13b8f23edb..1537b09cac 100644 --- a/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPaths.java +++ b/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPaths.java @@ -1,6 +1,7 @@ package hudson.plugins.git.extensions.impl; import com.google.common.collect.Lists; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.model.Run; import hudson.model.TaskListener; @@ -8,13 +9,13 @@ import hudson.plugins.git.GitSCM; import hudson.plugins.git.extensions.GitSCMExtension; import hudson.plugins.git.extensions.GitSCMExtensionDescriptor; +import hudson.plugins.git.extensions.impl.SparseCheckoutPath.SparseCheckoutPathToPath; import org.jenkinsci.plugins.gitclient.CheckoutCommand; import org.jenkinsci.plugins.gitclient.CloneCommand; import org.jenkinsci.plugins.gitclient.GitClient; import org.jenkinsci.plugins.gitclient.UnsupportedCommand; import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.Whitelisted; import org.kohsuke.stapler.DataBoundConstructor; -import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; import java.util.Collections; @@ -36,27 +37,19 @@ public List getSparseCheckoutPaths() { @Override public void decorateCloneCommand(GitSCM scm, Run build, GitClient git, TaskListener listener, CloneCommand cmd) throws IOException, InterruptedException, GitException { - if (! sparseCheckoutPaths.isEmpty()) { + if (!sparseCheckoutPaths.isEmpty()) { listener.getLogger().println("Using no checkout clone with sparse checkout."); } } @Override public void decorateCheckoutCommand(GitSCM scm, Run build, GitClient git, TaskListener listener, CheckoutCommand cmd) throws IOException, InterruptedException, GitException { - cmd.sparseCheckoutPaths(Lists.transform(sparseCheckoutPaths, SparseCheckoutPath.SPARSE_CHECKOUT_PATH_TO_PATH)); + cmd.sparseCheckoutPaths(Lists.transform(sparseCheckoutPaths, new SparseCheckoutPathToPath(build.getEnvironment(listener)))); } @Override public void determineSupportForJGit(GitSCM scm, @NonNull UnsupportedCommand cmd) { - cmd.sparseCheckoutPaths(Lists.transform(sparseCheckoutPaths, SparseCheckoutPath.SPARSE_CHECKOUT_PATH_TO_PATH)); - } - - @Extension - public static class DescriptorImpl extends GitSCMExtensionDescriptor { - @Override - public String getDisplayName() { - return "Sparse Checkout paths"; - } + cmd.sparseCheckoutPaths(Lists.transform(sparseCheckoutPaths, new SparseCheckoutPathToPath(null))); } /** @@ -67,11 +60,11 @@ public boolean equals(Object o) { if (this == o) { return true; } - + if (o == null || getClass() != o.getClass()) { return false; } - + SparseCheckoutPaths that = (SparseCheckoutPaths) o; return Objects.equals(getSparseCheckoutPaths(), that.getSparseCheckoutPaths()); } @@ -83,7 +76,7 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(getSparseCheckoutPaths()); } - + /** * {@inheritDoc} */ @@ -93,4 +86,12 @@ public String toString() { "sparseCheckoutPaths=" + sparseCheckoutPaths + '}'; } + + @Extension + public static class DescriptorImpl extends GitSCMExtensionDescriptor { + @Override + public String getDisplayName() { + return "Sparse Checkout paths"; + } + } } diff --git a/src/test/java/hudson/plugins/git/extensions/impl/SparseCheckoutPathsTest.java b/src/test/java/hudson/plugins/git/extensions/impl/SparseCheckoutPathsTest.java index 5e8ca27aae..ceba264a53 100644 --- a/src/test/java/hudson/plugins/git/extensions/impl/SparseCheckoutPathsTest.java +++ b/src/test/java/hudson/plugins/git/extensions/impl/SparseCheckoutPathsTest.java @@ -23,6 +23,7 @@ */ package hudson.plugins.git.extensions.impl; +import hudson.EnvVars; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; @@ -40,9 +41,12 @@ import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.Before; import org.junit.Test; +import org.mockito.Mock; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class SparseCheckoutPathsTest { @@ -122,6 +126,24 @@ public void testDecorateCheckoutCommand() throws Exception { assertThat(cmd.getSparsePathNames(), hasItems(SRC_DIR_NAME)); } + @Test + public void testDecorateCheckoutCommandExpandsEnvVariable() throws Exception { + GitSCM scm = null; + GitClient git = null; + Run build = mock(Run.class); + EnvVars envVars = new EnvVars(); + envVars.put("SPARSE_CHECKOUT_DIRECTORY", SRC_DIR_NAME); + when(build.getEnvironment(listener)).thenReturn(envVars); + + MyCheckoutCommand cmd = new MyCheckoutCommand(); + List sparseCheckoutPathList = new ArrayList<>(); + sparseCheckoutPathList.add(new SparseCheckoutPath("${SPARSE_CHECKOUT_DIRECTORY}")); + SparseCheckoutPaths sparseCheckoutPaths = new SparseCheckoutPaths(sparseCheckoutPathList); + sparseCheckoutPaths.decorateCheckoutCommand(scm, build, git, listener, cmd); + + assertThat(cmd.getSparsePathNames(), hasItems(SRC_DIR_NAME)); + } + @Test public void equalsContract() { EqualsVerifier.forClass(SparseCheckoutPaths.class).usingGetClass().verify(); From b84b46fb25ad8afb42f35f8af0c7b467b0118c48 Mon Sep 17 00:00:00 2001 From: raghavgarg098 Date: Thu, 8 Apr 2021 23:44:09 +0530 Subject: [PATCH 2/3] Removed line spaces and unintended changes. --- .../extensions/impl/SparseCheckoutPath.java | 16 +++++++-------- .../extensions/impl/SparseCheckoutPaths.java | 20 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPath.java b/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPath.java index 0ca4b43fe3..3c460d0ab6 100644 --- a/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPath.java +++ b/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPath.java @@ -21,7 +21,8 @@ public class SparseCheckoutPath extends AbstractDescribableImpl getDescriptor() { - return Jenkins.get().getDescriptor(getClass()); - } - public static class SparseCheckoutPathToPath implements Function, Serializable { @Nullable private EnvVars envVars; @@ -89,11 +86,14 @@ public String apply(@NonNull SparseCheckoutPath sparseCheckoutPath) { } } + public Descriptor getDescriptor() + { + return Jenkins.get().getDescriptor(getClass()); + } + @Extension public static class DescriptorImpl extends Descriptor { @Override - public String getDisplayName() { - return "Path"; - } + public String getDisplayName() { return "Path"; } } } diff --git a/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPaths.java b/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPaths.java index 1537b09cac..2e3e2e3004 100644 --- a/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPaths.java +++ b/src/main/java/hudson/plugins/git/extensions/impl/SparseCheckoutPaths.java @@ -37,7 +37,7 @@ public List getSparseCheckoutPaths() { @Override public void decorateCloneCommand(GitSCM scm, Run build, GitClient git, TaskListener listener, CloneCommand cmd) throws IOException, InterruptedException, GitException { - if (!sparseCheckoutPaths.isEmpty()) { + if (! sparseCheckoutPaths.isEmpty()) { listener.getLogger().println("Using no checkout clone with sparse checkout."); } } @@ -49,7 +49,15 @@ public void decorateCheckoutCommand(GitSCM scm, Run build, GitClient git, @Override public void determineSupportForJGit(GitSCM scm, @NonNull UnsupportedCommand cmd) { - cmd.sparseCheckoutPaths(Lists.transform(sparseCheckoutPaths, new SparseCheckoutPathToPath(null))); + cmd.sparseCheckoutPaths(Lists.transform(sparseCheckoutPaths, SparseCheckoutPath.SPARSE_CHECKOUT_PATH_TO_PATH)); + } + + @Extension + public static class DescriptorImpl extends GitSCMExtensionDescriptor { + @Override + public String getDisplayName() { + return "Sparse Checkout paths"; + } } /** @@ -86,12 +94,4 @@ public String toString() { "sparseCheckoutPaths=" + sparseCheckoutPaths + '}'; } - - @Extension - public static class DescriptorImpl extends GitSCMExtensionDescriptor { - @Override - public String getDisplayName() { - return "Sparse Checkout paths"; - } - } } From cb0e9af35751c77e442fafff89081fffcf91cae2 Mon Sep 17 00:00:00 2001 From: raghavgarg098 Date: Fri, 9 Apr 2021 13:03:47 +0530 Subject: [PATCH 3/3] Fixed the failing tests. --- .../plugins/git/extensions/impl/SparseCheckoutPathsTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/hudson/plugins/git/extensions/impl/SparseCheckoutPathsTest.java b/src/test/java/hudson/plugins/git/extensions/impl/SparseCheckoutPathsTest.java index ceba264a53..67a17a2650 100644 --- a/src/test/java/hudson/plugins/git/extensions/impl/SparseCheckoutPathsTest.java +++ b/src/test/java/hudson/plugins/git/extensions/impl/SparseCheckoutPathsTest.java @@ -119,7 +119,8 @@ public void testDecorateCloneCommandEmpty() throws Exception { @Test public void testDecorateCheckoutCommand() throws Exception { GitSCM scm = null; - Run build = null; + Run build = mock(Run.class); + when(build.getEnvironment(listener)).thenReturn(new EnvVars()); GitClient git = null; MyCheckoutCommand cmd = new MyCheckoutCommand(); sparseCheckoutPaths.decorateCheckoutCommand(scm, build, git, listener, cmd);