From 5c0b36da02f72abb15c52042bf5817ff5e7ec24d Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 3 Jan 2012 20:44:16 -0800 Subject: [PATCH] made the location of Maven local repositories pluggable --- changelog.html | 3 + .../main/java/hudson/maven/MavenBuild.java | 7 +- .../java/hudson/maven/MavenModuleSet.java | 78 +++++++++++++++++-- .../hudson/maven/MavenModuleSetBuild.java | 19 +++-- .../src/main/java/hudson/maven/MavenUtil.java | 6 +- .../DefaultLocalRepositoryLocator.java | 30 +++++++ .../local_repo/LocalRepositoryLocator.java | 29 +++++++ .../LocalRepositoryLocatorDescriptor.java | 11 +++ .../PerExecutorLocalRepositoryLocator.java | 28 +++++++ .../PerJobLocalRepositoryLocator.java | 30 +++++++ .../MavenModuleSet/configure-entries.jelly | 4 +- .../hudson/maven/MavenModuleSet/global.jelly | 1 + .../MavenModuleSet/help-localRepository.html | 5 ++ .../LocalRepositoryLocator/config.groovy | 3 + .../java/hudson/maven/MavenModuleSetTest.java | 23 ++++++ 15 files changed, 258 insertions(+), 19 deletions(-) create mode 100644 maven-plugin/src/main/java/hudson/maven/local_repo/DefaultLocalRepositoryLocator.java create mode 100644 maven-plugin/src/main/java/hudson/maven/local_repo/LocalRepositoryLocator.java create mode 100644 maven-plugin/src/main/java/hudson/maven/local_repo/LocalRepositoryLocatorDescriptor.java create mode 100644 maven-plugin/src/main/java/hudson/maven/local_repo/PerExecutorLocalRepositoryLocator.java create mode 100644 maven-plugin/src/main/java/hudson/maven/local_repo/PerJobLocalRepositoryLocator.java create mode 100644 maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/help-localRepository.html create mode 100644 maven-plugin/src/main/resources/hudson/maven/local_repo/LocalRepositoryLocator/config.groovy create mode 100644 test/src/test/java/hudson/maven/MavenModuleSetTest.java diff --git a/changelog.html b/changelog.html index 2c1ced9feb..6cf4643eb7 100644 --- a/changelog.html +++ b/changelog.html @@ -80,6 +80,9 @@ Upcoming changes
  • Added the Reploy-To header support. (pull #306) +
  • + The location of Maven local repository is now pluggable, and supported per-executor configuration out of the box. + (pull #293)
  • Jobs now support display name separate from its unique name issue 11762 diff --git a/maven-plugin/src/main/java/hudson/maven/MavenBuild.java b/maven-plugin/src/main/java/hudson/maven/MavenBuild.java index 2e16473094..e7d47e2c4f 100644 --- a/maven-plugin/src/main/java/hudson/maven/MavenBuild.java +++ b/maven-plugin/src/main/java/hudson/maven/MavenBuild.java @@ -25,6 +25,7 @@ package hudson.maven; import hudson.EnvVars; import hudson.FilePath; +import hudson.maven.local_repo.LocalRepositoryLocator; import hudson.maven.reporters.MavenArtifactRecord; import hudson.maven.reporters.SurefireArchiver; import hudson.slaves.WorkspaceList; @@ -687,10 +688,10 @@ public class MavenBuild extends AbstractMavenBuild { getParent().getParent(), launcher, envVars, getMavenOpts(listener, envVars), null )); ArgumentListBuilder margs = new ArgumentListBuilder("-N","-B"); - if(mms.usesPrivateRepository()) - // use the per-project repository. should it be per-module? But that would cost too much in terms of disk + FilePath localRepo = mms.getLocalRepository().locate(MavenBuild.this); + if(localRepo!=null) // the workspace must be on this node, so getRemote() is safe. - margs.add("-Dmaven.repo.local="+getWorkspace().child(".repository").getRemote()); + margs.add("-Dmaven.repo.local="+localRepo.getRemote()); if (mms.getAlternateSettings() != null) { if (IOUtils.isAbsolute(mms.getAlternateSettings())) { diff --git a/maven-plugin/src/main/java/hudson/maven/MavenModuleSet.java b/maven-plugin/src/main/java/hudson/maven/MavenModuleSet.java index 91151adb99..95dbbdc96f 100644 --- a/maven-plugin/src/main/java/hudson/maven/MavenModuleSet.java +++ b/maven-plugin/src/main/java/hudson/maven/MavenModuleSet.java @@ -24,7 +24,7 @@ */ package hudson.maven; -import static hudson.Util.fixEmpty; +import static hudson.Util.*; import static hudson.model.ItemGroupMixIn.loadChildren; import hudson.CopyOnWrite; import hudson.EnvVars; @@ -34,6 +34,9 @@ import hudson.FilePath; import hudson.Functions; import hudson.Indenter; import hudson.Util; +import hudson.maven.local_repo.DefaultLocalRepositoryLocator; +import hudson.maven.local_repo.LocalRepositoryLocator; +import hudson.maven.local_repo.PerJobLocalRepositoryLocator; import hudson.maven.settings.SettingsProviderUtils; import hudson.model.AbstractProject; import hudson.model.Action; @@ -183,8 +186,20 @@ public class MavenModuleSet extends AbstractMavenProject mavenValidationLevels = new LinkedHashMap(); + /** + * @since 1.448 + */ + private LocalRepositoryLocator localRepository = new DefaultLocalRepositoryLocator(); + public DescriptorImpl() { super(); load(); @@ -1105,6 +1160,18 @@ public class MavenModuleSet extends AbstractMavenProject poms; try { - poms = getModuleRoot().act(new PomParser(listener, mvn, project, mavenVersion, envVars, getWorkspace())); + poms = getModuleRoot().act(new PomParser(listener, mvn, mavenVersion, envVars, MavenModuleSetBuild.this)); } catch (IOException e) { if (project.isIncrementalBuild()) { // If POM parsing failed we should do a full build next time. @@ -1074,8 +1075,9 @@ public class MavenModuleSetBuild extends AbstractMavenBuild~/.m2/repository + * + * @author Kohsuke Kawaguchi + */ +public class DefaultLocalRepositoryLocator extends LocalRepositoryLocator { + @DataBoundConstructor + public DefaultLocalRepositoryLocator() { + } + + @Override + public FilePath locate(AbstractMavenBuild build) { + return null; + } + + @Extension + public static class DescriptorImpl extends LocalRepositoryLocatorDescriptor { + @Override + public String getDisplayName() { + return "Default (~/.m2/repository)"; + } + } +} diff --git a/maven-plugin/src/main/java/hudson/maven/local_repo/LocalRepositoryLocator.java b/maven-plugin/src/main/java/hudson/maven/local_repo/LocalRepositoryLocator.java new file mode 100644 index 0000000000..660ca3bf9d --- /dev/null +++ b/maven-plugin/src/main/java/hudson/maven/local_repo/LocalRepositoryLocator.java @@ -0,0 +1,29 @@ +package hudson.maven.local_repo; + +import hudson.ExtensionPoint; +import hudson.FilePath; +import hudson.maven.AbstractMavenBuild; +import hudson.model.AbstractDescribableImpl; + +/** + * Strategy pattern that decides the location of the Maven local repository for a build. + * + * @author Kohsuke Kawaguchi + * @since 1.448 + * @see LocalRepositoryLocatorDescriptor + */ +public abstract class LocalRepositoryLocator extends AbstractDescribableImpl implements ExtensionPoint { + /** + * Called during the build on the master to determine the location of the local Maven repository. + * + * @return + * null to let Maven uses its default location. Otherwise this must be located on the same + * node as {@link AbstractMavenBuild#getWorkspace()} does. + */ + public abstract FilePath locate(AbstractMavenBuild build); + + @Override + public LocalRepositoryLocatorDescriptor getDescriptor() { + return (LocalRepositoryLocatorDescriptor)super.getDescriptor(); + } +} diff --git a/maven-plugin/src/main/java/hudson/maven/local_repo/LocalRepositoryLocatorDescriptor.java b/maven-plugin/src/main/java/hudson/maven/local_repo/LocalRepositoryLocatorDescriptor.java new file mode 100644 index 0000000000..a31cb5be73 --- /dev/null +++ b/maven-plugin/src/main/java/hudson/maven/local_repo/LocalRepositoryLocatorDescriptor.java @@ -0,0 +1,11 @@ +package hudson.maven.local_repo; + +import hudson.model.Descriptor; + +/** + * @author Kohsuke Kawaguchi + * @since 1.448 + * @see LocalRepositoryLocator + */ +public abstract class LocalRepositoryLocatorDescriptor extends Descriptor { +} diff --git a/maven-plugin/src/main/java/hudson/maven/local_repo/PerExecutorLocalRepositoryLocator.java b/maven-plugin/src/main/java/hudson/maven/local_repo/PerExecutorLocalRepositoryLocator.java new file mode 100644 index 0000000000..f89f54b636 --- /dev/null +++ b/maven-plugin/src/main/java/hudson/maven/local_repo/PerExecutorLocalRepositoryLocator.java @@ -0,0 +1,28 @@ +package hudson.maven.local_repo; + +import hudson.Extension; +import hudson.FilePath; +import hudson.maven.AbstractMavenBuild; +import hudson.model.Executor; +import org.kohsuke.stapler.DataBoundConstructor; + +/** + * @author Kohsuke Kawaguchi + */ +public class PerExecutorLocalRepositoryLocator extends LocalRepositoryLocator { + @DataBoundConstructor + public PerExecutorLocalRepositoryLocator() {} + + @Override + public FilePath locate(AbstractMavenBuild build) { + return build.getBuiltOn().getRootPath().child("maven-repositories/"+ Executor.currentExecutor().getNumber()); + } + + @Extension + public static class DescriptorImpl extends LocalRepositoryLocatorDescriptor { + @Override + public String getDisplayName() { + return "Local to the executor"; + } + } +} diff --git a/maven-plugin/src/main/java/hudson/maven/local_repo/PerJobLocalRepositoryLocator.java b/maven-plugin/src/main/java/hudson/maven/local_repo/PerJobLocalRepositoryLocator.java new file mode 100644 index 0000000000..c2aa89d3ae --- /dev/null +++ b/maven-plugin/src/main/java/hudson/maven/local_repo/PerJobLocalRepositoryLocator.java @@ -0,0 +1,30 @@ +package hudson.maven.local_repo; + +import hudson.Extension; +import hudson.FilePath; +import hudson.maven.AbstractMavenBuild; +import org.kohsuke.stapler.DataBoundConstructor; + +/** + * Uses a local repository isolated per job. + * + * @author Kohsuke Kawaguchi + */ +public class PerJobLocalRepositoryLocator extends LocalRepositoryLocator { + @DataBoundConstructor + public PerJobLocalRepositoryLocator() { + } + + @Override + public FilePath locate(AbstractMavenBuild build) { + return build.getWorkspace().child(".repository"); + } + + @Extension + public static class DescriptorImpl extends LocalRepositoryLocatorDescriptor { + @Override + public String getDisplayName() { + return "Local to the workspace"; + } + } +} diff --git a/maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/configure-entries.jelly b/maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/configure-entries.jelly index 68b993bd04..e760ee6fd6 100644 --- a/maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/configure-entries.jelly +++ b/maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/configure-entries.jelly @@ -97,7 +97,9 @@ THE SOFTWARE. + checked="${it.getExplicitLocalRepository()!=null}" inline="true"> + + + \ No newline at end of file diff --git a/maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/help-localRepository.html b/maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/help-localRepository.html new file mode 100644 index 0000000000..2b3140d4e9 --- /dev/null +++ b/maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/help-localRepository.html @@ -0,0 +1,5 @@ +
    + Specifies the default setting of the local repository location when jobs do not specify one. + See the per-job configuration of this (under the "Advanced" button) for more discussion + of what this option means. +
    \ No newline at end of file diff --git a/maven-plugin/src/main/resources/hudson/maven/local_repo/LocalRepositoryLocator/config.groovy b/maven-plugin/src/main/resources/hudson/maven/local_repo/LocalRepositoryLocator/config.groovy new file mode 100644 index 0000000000..a11ae6e464 --- /dev/null +++ b/maven-plugin/src/main/resources/hudson/maven/local_repo/LocalRepositoryLocator/config.groovy @@ -0,0 +1,3 @@ +package hudson.maven.local_repo.LocalRepositoryLocator; + +// default no-op config fragment \ No newline at end of file diff --git a/test/src/test/java/hudson/maven/MavenModuleSetTest.java b/test/src/test/java/hudson/maven/MavenModuleSetTest.java new file mode 100644 index 0000000000..0341b3483e --- /dev/null +++ b/test/src/test/java/hudson/maven/MavenModuleSetTest.java @@ -0,0 +1,23 @@ +package hudson.maven; + +import hudson.maven.local_repo.PerJobLocalRepositoryLocator; +import org.jvnet.hudson.test.HudsonTestCase; + +/** + * @author Kohsuke Kawaguchi + */ +public class MavenModuleSetTest extends HudsonTestCase { + public void testConfigRoundtripLocalRepository() throws Exception { + MavenModuleSet p = createMavenProject(); + configRoundtrip(p); + + assertNull(p.getExplicitLocalRepository()); + + // make sure it roundtrips + PerJobLocalRepositoryLocator before = new PerJobLocalRepositoryLocator(); + p.setLocalRepository(before); + configRoundtrip(p); + assertEqualDataBoundBeans(p.getLocalRepository(),before); + assertTrue(before!=p.getLocalRepository()); + } +} -- GitLab