diff --git a/Documentation/CACHE-HOWTO.md b/Documentation/CACHE-HOWTO.md index aa15f626af65..c0877acfba08 100644 --- a/Documentation/CACHE-HOWTO.md +++ b/Documentation/CACHE-HOWTO.md @@ -17,18 +17,17 @@ ### Overview -Cache configuration provides you additional control over incremental maven behavior. Follow it step by step to +Cache configuration provides you additional control over incremental Maven behavior. Follow it step by step to understand how it works and figure out your optimal config ### Minimal config -Absolutely minimal config which enables incremental maven with local cache +Absolutely minimal config which enables incremental Maven with local cache ```xml - + true @@ -48,14 +47,13 @@ Absolutely minimal config which enables incremental maven with local cache Just add `` section under `` ```xml - - - true - XX - - https://yourserver:port - - + + true + XX + + https://yourserver:port + + ``` ### Adding more file types to input @@ -63,28 +61,30 @@ Just add `` section under `` Add all the project specific source code files in ``. Scala in this case: ```xml - - - - {*.java,*.xml,*.properties,*.scala} - - + + + {*.java,*.xml,*.properties,*.scala} + + ``` ### Adding source directory for bespoke project layouts -In most of the cases incremental maven will recognize directories automatically by build introspection. If not, you can +In most of the cases incremental Maven will recognize directories automatically by build introspection. If not, you can add additional directories with ``. Also you can filter out undesirable dirs and files by using exclude tag ```xml - - - - {*.java,*.xml,*.properties,*.scala} - importantdir/ - tempfile.out - - + + + {*.java,*.xml,*.properties,*.scala} + + importantdir/ + + + tempfile.out + + + ``` ### Plugin property is env specific (breaks checksum and caching) @@ -92,17 +92,20 @@ add additional directories with ``. Also you can filter out undesirable Consider to exclude env specific properties: ```xml - - - - ... - - - - argLine - - - + + + ... + + + + + + argLine + + + + + ``` Implications - builds with different `argLine` will have identical checksum. Validate that is semantically valid. @@ -113,18 +116,21 @@ If plugin configuration property points to `somedir` it will be scanned with def processing rule ```xml - - - - ... - - - - - - - - + + + ... + + + + + + + + + + + + ``` ### Local repository is not updated because `install` is cached @@ -132,55 +138,65 @@ processing rule Add `executionControl/runAlways` section ```xml - - - - ... - - - ... - - - - unpack-autoupdate - - - install - + + + + + + + unpack-autoupdate + + + + + + + install + + + - ``` ### I occasionally cached build with `-DskipTests=true` and tests do not run now -If you add command line flags to your build, they do not participate in effective pom - maven defers final value +If you add command line flags to your build, they do not participate in effective pom - Maven defers final value resolution to plugin runtime. To invalidate build if filed value is different in runtime, add reconciliation section to `executionControl`: ```xml - - - + + + ... - - - - - - - - - - + + + + ... + + + + + + + + + + + + + + + ``` Please notice `skipValue` attribute. It denotes value which forces skipped execution. Read `propertyName="skipTests" skipValue="true"` as if property skipTests has value true, plugin will skip execution If -you declare such value incremental maven will reuse appropriate full-build though technically they are different, but +you declare such value incremental Maven will reuse appropriate full-build though technically they are different, but because full-build is better it is safe to reuse ### How to renormalize line endings in working copy after committing .gitattributes (git 2.16+) @@ -201,4 +217,4 @@ git reset --hard ### I want to cache interim build and override it later with final version Solution: set `-Dremote.cache.save.final=true` to nodes which produce final builds. Such builds will not be overridden -and eventually will replace all interim builds \ No newline at end of file +and eventually will replace all interim builds diff --git a/Documentation/CACHE-PARAMETERS.md b/Documentation/CACHE-PARAMETERS.md index 7633ddbea158..12042c634076 100644 --- a/Documentation/CACHE-PARAMETERS.md +++ b/Documentation/CACHE-PARAMETERS.md @@ -26,8 +26,8 @@ This documents contains various configuration parameters supported by cache engi | `-Dremote.cache.configPath=true/false` | Location of cache configuration file | Cache config is not in default location | | `-Dremote.cache.enabled=true/false` | Remote cache and associated features disabled/enabled | To remove noise from logs then remote cache is not available | | `-Dremote.cache.save.enabled=true/false` | Remote cache save allowed or not | To designate nodes which allowed to push in remote shared cache | -| `-Dremote.cache.save.final=true/false` | Is it allowed or not to override produced cache | To ensure that reference build is not overriden by interim build | -| `-Dremote.cache.failFast=true/false` | Fail on the first module whcih cannot be restored from cache | Remote cache setup/tuning/troubleshooting | +| `-Dremote.cache.save.final=true/false` | Is it allowed or not to override produced cache | To ensure that reference build is not overridden by interim build | +| `-Dremote.cache.failFast=true/false` | Fail on the first module which cannot be restored from cache | Remote cache setup/tuning/troubleshooting | | `-Dremote.cache.baselineUrl=` | Location of baseline build for comparison | Remote cache setup/tuning/troubleshooting | ## Project level properties diff --git a/Documentation/CACHE-REMOTE.md b/Documentation/CACHE-REMOTE.md index f5fe38721d70..c89e5de19818 100644 --- a/Documentation/CACHE-REMOTE.md +++ b/Documentation/CACHE-REMOTE.md @@ -17,7 +17,7 @@ # Overview -This document describes generic approach to cache setup. The process require expertise in maven equivalent to expertise +This document describes generic approach to cache setup. The process require expertise in Maven equivalent to expertise required to author and Maven your project build, it implies good knowledge of both Maven and the project. Due to Maven model limitation the process is manual, but allows you to achieve sufficient control and transparency over caching logic. @@ -113,8 +113,8 @@ Once discrepancy between remote and local builds detected cache will fail with d in `target/incremental-maven` directory: ``` -* buildinfo-baseline-3c64673e23259e6f.xml - build specficiation from baseline build -* buildinfo-db43936e0666ce7.xml - build specification of locall build +* buildinfo-baseline-3c64673e23259e6f.xml - build specification from baseline build +* buildinfo-db43936e0666ce7.xml - build specification of local build * buildsdiff.xml - comparison report with list of discrepancies ``` @@ -242,7 +242,7 @@ relax consistency rules in favor of compatibility, remove property from tracked Current implementation doesn't support version changes between cache entries. It will result in cache invalidation for each new version. -To mitigate the issue please consider migrating off traditional maven release approach - try to use single version id in +To mitigate the issue please consider migrating off traditional Maven release approach - try to use single version id in project (eg `MY-PROJECT-LOCAL`). Such approach simplifies git branching workflow significantly. Deployment of artifacts with specific version from builds with cache is not supported yet. diff --git a/Documentation/CACHE.md b/Documentation/CACHE.md index 391becc7b5f7..7449ef5cc7ec 100644 --- a/Documentation/CACHE.md +++ b/Documentation/CACHE.md @@ -17,19 +17,19 @@ ## Overview -Idea of Incremental Maven is to specify module inputs and outputs and make them known to standard maven core. This +Idea of Incremental Maven is to specify module inputs and outputs and make them known to standard Maven core. This allows accurate analysis and determination of out-of-date build artifacts in the build dependencies graph. Making the dependency graph analysis deterministic leads to improvements in build times by avoiding re-building unnecessary modules. -Cache does not make any low-level interventions to build process and delegates actual build work to maven core. This -guarantees that build results are identical to results produced by standard maven and are fully reproducible. -To achieve accurate input and outputs calculation incremental maven combines automatic introspection +Cache does not make any low-level interventions to build process and delegates actual build work to Maven core. This +guarantees that build results are identical to results produced by standard Maven and are fully reproducible. +To achieve accurate input and outputs calculation incremental Maven combines automatic introspection of [project object model](https://maven.apache.org/pom.html#What_is_the_POM) in conjunction with configuration-driven rules for fine-grained content and execution control. For content analysis it digests based approach which is more reliable over widely used file timestamps in tools like Make or Apache Ant. Deterministic build state allows reliably cache even intermediate outputs of build and share them between teams using remote cache. Deterministic inputs calculation allows distributed and parallel builds running in heterogeneous environments (like cloud of build agents) -could efficiently reuse cached build artifacts. Therefore incremental maven is particularly well-suited for large maven +could efficiently reuse cached build artifacts. Therefore incremental Maven is particularly well-suited for large Maven projects that have significant number of small modules. Remote cache in conjunction with precise input identification effectively enables "change once - build once" approach. @@ -51,7 +51,7 @@ of today build with some tolerance (implementation, configuration and environmen ### Implementation insights -At very simple form, the incremental maven is essentially a hash function which takes maven project and produces hash +At very simple form, the incremental Maven is essentially a hash function which takes Maven project and produces hash code (checksum). Then hash value is used to fetch and restore build result. As with any hash, there could be collisions and instabilities. Collision could happen if the same hash produced from the different build states and will result in unintended reuse. Instability means that same input yields different hash sums @@ -79,7 +79,7 @@ verification it's still consumer's responsibility to verify final product qualit Given all the information above, the Incremental Maven is recommended to use in scenarios when productivity and performance are in priority. Typical cases are: -* Speedup CI. In conjunction with remote cache incremental maven could drastically reduce build times, validate pull +* Speedup CI. In conjunction with remote cache incremental Maven could drastically reduce build times, validate pull requests faster and reduce load on CI nodes * Speedup developer builds. By reusing cached builds developers could verify changes much faster and be more productive. No more `-DskipTests` and similar. @@ -92,35 +92,35 @@ This also allows you to validate cache correctness and reconcile cache outcomes ## Getting Started -To on-board incremental maven you need to complete several steps: +To on-board incremental Maven you need to complete several steps: -* Get incremental maven distribution -* Add cache config in .mvn +* Get incremental Maven distribution +* Add cache config in `.mvn` * Validate build results and iteratively adjust config to project specifics -* Migrate CI to incremental maven with remote cache (to get full benefit) - optional +* Migrate CI to incremental Maven with remote cache (to get full benefit) - optional -### Get incremental maven distribution +### Get incremental Maven distribution The recommended way is to add [Takari Maven Wrapper](https://github.com/takari/maven-wrapper) to your project. In that -case `maven-wrapper.properties` should reference the latest incremental maven distribution: +case `maven-wrapper.properties` should reference the latest incremental Maven distribution: ```properties distributionUrl=https://your-server/maven-incremental.zip wrapperUrl=https://your-server/maven-wrapper-0.5.5.jar ``` -Benefits of using maven wrapper are following: +Benefits of using Maven wrapper are following: * simple distribution across workstations and CI envs -* maven stays compatible to your branch +* Maven stays compatible to your branch * further upgrades are simplified significantly - If you refuse wrapper - then download, unzip and install it just as usual maven. Further it will be assumed you use - maven wrapper (`mvnw`) + If you refuse wrapper - then download, unzip and install it just as usual Maven. Further it will be assumed you use + Maven wrapper (`mvnw`) ### Adding cache config -Copy [default config](maven-cache-config.xml) and [xml schema](../maven-core/src/main/resources/cache-config.xsd) -to [.mvn](https://maven.apache.org/configure.html) dir of yor project. +Copy [default config `maven-cache-config.xml`](maven-cache-config.xml) +to [`.mvn/`](https://maven.apache.org/configure.html) dir of your project. To get overall understanding of cache machinery it is recommended to review the config and read comments. In typical scenario you need to adjust: @@ -135,15 +135,15 @@ See also: * [Remote cache setup](CACHE-REMOTE.md) - instruction how to setup shared cache * [Cache How-To](CACHE-HOWTO.md) - cookbook for frequently encountered questions * [Cache Parameters](CACHE-PARAMETERS.md) - description of supported parameters -* Attached [sample config file](maven-cache-config.xml) and elements annotations in xsd schema. (Ctrl+Q in idea should +* Attached [sample `maven-cache-config.xml` config file](maven-cache-config.xml) and elements annotations in xsd schema. (Ctrl+Q in idea should show annotations in popup) ### Adjusting cache config -Having incremental maven and the config in place you're all set. To run first cacheable build just +Having incremental Maven and the config in place you're all set. To run first cacheable build just execute: `mvnw clean install` -* Ensure that the config is picked up and incremental maven is picked up. Just check log output - you will notice cache +* Ensure that the config is picked up and incremental Maven is picked up. Just check log output - you will notice cache related output or initialization error message. * Navigate to your local repo directory - there should be sibling next to your local repo named `cache` * Find `buildinfo.xml` for typical module and review it. Ensure that diff --git a/Documentation/maven-cache-config.xml b/Documentation/maven-cache-config.xml index a2a7ad8ee1c3..12425fdf8939 100644 --- a/Documentation/maven-cache-config.xml +++ b/Documentation/maven-cache-config.xml @@ -15,9 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. --> - + true diff --git a/apache-maven/pom.xml b/apache-maven/pom.xml index 2cc6ca31d533..276a2cac3e9e 100644 --- a/apache-maven/pom.xml +++ b/apache-maven/pom.xml @@ -47,6 +47,10 @@ under the License. org.apache.maven maven-core + + org.apache.maven + maven-caching + org.apache.maven maven-compat diff --git a/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm b/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm index 6ac9f31124b7..d5cba211a660 100644 --- a/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm +++ b/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm @@ -42,8 +42,6 @@ subject to the terms and conditions of the following licenses: #* *##set ( $spdx = 'EPL-1.0' ) #* *##elseif ( $license.url.contains( "www.apache.org/licenses/LICENSE-2.0" ) ) #* *##set ( $spdx = 'ASL-2.0' ) -#* *##elseif ( $license.url.contains( "www.eclipse.org/org/documents/edl-v10.php" ) ) -#* *##set ( $spdx = 'EDL-1.0' ) #* *##elseif ( $license.url.contains( "www.mozilla.org/en-US/MPL/1.1" ) ) #* *##set ( $spdx = 'MPL-1.1' ) #* *##elseif ( $license.url.contains( "www.gnu.org/licenses/gpl" ) ) diff --git a/apache-maven/src/main/appended-resources/licenses/EDL-1.0.txt b/apache-maven/src/main/appended-resources/licenses/EDL-1.0.txt deleted file mode 100644 index 259e0377f30f..000000000000 --- a/apache-maven/src/main/appended-resources/licenses/EDL-1.0.txt +++ /dev/null @@ -1,23 +0,0 @@ -Eclipse Distribution License - v 1.0 -Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided -that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation and/or other materials provided -with the distribution. -- Neither the name of the Eclipse Foundation, Inc. nor the names of its contributors may be used to endorse -or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/maven-caching/pom.xml b/maven-caching/pom.xml new file mode 100644 index 000000000000..b37f39c8a38c --- /dev/null +++ b/maven-caching/pom.xml @@ -0,0 +1,105 @@ + + + + + + 4.0.0 + + + org.apache.maven + maven + 3.8.3-SNAPSHOT + + + maven-caching + + Maven Caching + Maven Caching classes. + + + + + org.apache.maven + maven-core + provided + + + + + + + src/main/resources + true + + + + + + org.apache.rat + apache-rat-plugin + + + lifecycle-executor.txt + plugin-manager.txt + project-builder.txt + src/site/resources/design/** + + + + + + + + org.codehaus.plexus + plexus-component-metadata + + + org.eclipse.sisu + sisu-maven-plugin + + + org.codehaus.modello + modello-maven-plugin + + 1.1.0 + + src/main/mdo/cache-config.mdo + src/main/mdo/cache-build.mdo + src/main/mdo/cache-diff.mdo + src/main/mdo/cache-report.mdo + + 1.0.0 + ${basedir}/target/generated-sources/modello + + + + modello-cache + + java + xpp3-reader + xpp3-writer + xsd + + + + + + + diff --git a/maven-core/src/main/java/org/apache/maven/caching/ArtifactsRepository.java b/maven-caching/src/main/java/org/apache/maven/caching/ArtifactsRepository.java similarity index 79% rename from maven-core/src/main/java/org/apache/maven/caching/ArtifactsRepository.java rename to maven-caching/src/main/java/org/apache/maven/caching/ArtifactsRepository.java index 65315498c7ff..f3f45cf5d07b 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/ArtifactsRepository.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/ArtifactsRepository.java @@ -20,8 +20,8 @@ */ import org.apache.maven.artifact.Artifact; -import org.apache.maven.caching.jaxb.CacheReportType; -import org.apache.maven.caching.xml.BuildInfo; +import org.apache.maven.caching.xml.report.CacheReport; +import org.apache.maven.caching.xml.Build; import org.apache.maven.execution.MavenSession; import java.io.IOException; @@ -32,11 +32,11 @@ public interface ArtifactsRepository { - BuildInfo findBuild( CacheContext context ) throws IOException; + Build findBuild( CacheContext context ) throws IOException; - void saveBuildInfo( CacheResult cacheResult, BuildInfo buildInfo ) throws IOException; + void saveBuildInfo( CacheResult cacheResult, Build build ) throws IOException; void saveArtifactFile( CacheResult cacheResult, Artifact artifact ) throws IOException; - void saveCacheReport( String buildId, MavenSession session, CacheReportType cacheReport ) throws IOException; + void saveCacheReport( String buildId, MavenSession session, CacheReport cacheReport ) throws IOException; } diff --git a/maven-core/src/main/java/org/apache/maven/caching/CacheContext.java b/maven-caching/src/main/java/org/apache/maven/caching/CacheContext.java similarity index 88% rename from maven-core/src/main/java/org/apache/maven/caching/CacheContext.java rename to maven-caching/src/main/java/org/apache/maven/caching/CacheContext.java index 569286d8b841..d34a78cc2069 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/CacheContext.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/CacheContext.java @@ -19,7 +19,7 @@ * under the License. */ -import org.apache.maven.caching.jaxb.ProjectsInputInfoType; +import org.apache.maven.caching.xml.build.ProjectsInputInfo; import org.apache.maven.execution.MavenSession; import org.apache.maven.project.MavenProject; @@ -31,10 +31,10 @@ public class CacheContext { private final MavenProject project; - private final ProjectsInputInfoType inputInfo; + private final ProjectsInputInfo inputInfo; private final MavenSession session; - public CacheContext( MavenProject project, ProjectsInputInfoType inputInfo, MavenSession session ) + public CacheContext( MavenProject project, ProjectsInputInfo inputInfo, MavenSession session ) { this.project = checkNotNull( project ); this.inputInfo = checkNotNull( inputInfo ); @@ -46,7 +46,7 @@ public MavenProject getProject() return project; } - public ProjectsInputInfoType getInputInfo() + public ProjectsInputInfo getInputInfo() { return inputInfo; } diff --git a/maven-core/src/main/java/org/apache/maven/caching/CacheController.java b/maven-caching/src/main/java/org/apache/maven/caching/CacheController.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/CacheController.java rename to maven-caching/src/main/java/org/apache/maven/caching/CacheController.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/CacheControllerImpl.java b/maven-caching/src/main/java/org/apache/maven/caching/CacheControllerImpl.java similarity index 84% rename from maven-core/src/main/java/org/apache/maven/caching/CacheControllerImpl.java rename to maven-caching/src/main/java/org/apache/maven/caching/CacheControllerImpl.java index ad9d490c6ebb..cdd6ccddd34c 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/CacheControllerImpl.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/CacheControllerImpl.java @@ -19,6 +19,34 @@ * under the License. */ +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Pattern; + +import javax.annotation.Nonnull; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + import com.google.common.base.Optional; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -26,28 +54,27 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.mutable.MutableBoolean; -import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.caching.checksum.KeyUtils; import org.apache.maven.caching.checksum.MavenProjectInput; import org.apache.maven.caching.hash.HashAlgorithm; import org.apache.maven.caching.hash.HashFactory; -import org.apache.maven.caching.jaxb.ArtifactType; -import org.apache.maven.caching.jaxb.BuildDiffType; -import org.apache.maven.caching.jaxb.BuildInfoType; -import org.apache.maven.caching.jaxb.CacheReportType; -import org.apache.maven.caching.jaxb.CompletedExecutionType; -import org.apache.maven.caching.jaxb.DigestItemType; -import org.apache.maven.caching.jaxb.ProjectReportType; -import org.apache.maven.caching.jaxb.ProjectsInputInfoType; -import org.apache.maven.caching.jaxb.PropertyNameType; -import org.apache.maven.caching.jaxb.TrackedPropertyType; -import org.apache.maven.caching.xml.BuildInfo; +import org.apache.maven.caching.xml.Build; import org.apache.maven.caching.xml.CacheConfig; import org.apache.maven.caching.xml.CacheSource; import org.apache.maven.caching.xml.DtoUtils; import org.apache.maven.caching.xml.XmlService; +import org.apache.maven.caching.xml.build.Artifact; +import org.apache.maven.caching.xml.build.CompletedExecution; +import org.apache.maven.caching.xml.build.DigestItem; +import org.apache.maven.caching.xml.build.ProjectsInputInfo; +import org.apache.maven.caching.xml.build.Scm; +import org.apache.maven.caching.xml.diff.Diff; +import org.apache.maven.caching.xml.config.PropertyName; +import org.apache.maven.caching.xml.config.TrackedProperty; +import org.apache.maven.caching.xml.report.CacheReport; +import org.apache.maven.caching.xml.report.ProjectReport; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MojoExecutionEvent; import org.apache.maven.lifecycle.internal.ProjectIndex; @@ -58,36 +85,9 @@ import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.apache.maven.repository.RepositorySystem; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.ReflectionUtils; -import javax.annotation.Nonnull; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.TreeSet; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.regex.Pattern; - import static java.nio.file.StandardOpenOption.CREATE; import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -105,45 +105,47 @@ /** * CacheControllerImpl */ -@Component( role = CacheController.class ) +@Singleton +@Named public class CacheControllerImpl implements CacheController { public static final String FILE_SEPARATOR_SUBST = "_"; private static final String GENERATEDSOURCES = "generatedsources"; private static final String GENERATEDSOURCES_PREFIX = GENERATEDSOURCES + FILE_SEPARATOR_SUBST; - @Requirement + + @Inject private Logger logger; - @Requirement + @Inject private MavenPluginManager mavenPluginManager; - @Requirement + @Inject private MavenProjectHelper projectHelper; - @Requirement + @Inject private LocalArtifactsRepository localCache; - @Requirement + @Inject private RemoteArtifactsRepository remoteCache; - @Requirement + @Inject private CacheConfig cacheConfig; - @Requirement + @Inject private RepositorySystem repoSystem; - @Requirement + @Inject private ArtifactHandlerManager artifactHandlerManager; - @Requirement + @Inject private XmlService xmlService; - private final ConcurrentMap artifactDigestByKey = new ConcurrentHashMap<>(); + private final ConcurrentMap artifactDigestByKey = new ConcurrentHashMap<>(); private final ConcurrentMap cacheResults = new ConcurrentHashMap<>(); - private volatile BuildInfoType.Scm scm; + private volatile Scm scm; @Override @Nonnull @@ -159,7 +161,7 @@ public CacheResult findCachedBuild( MavenSession session, MavenProject project, logInfo( project, "Attempting to restore project from build cache" ); - ProjectsInputInfoType inputInfo = calculateInput( project, session, projectIndex ); + ProjectsInputInfo inputInfo = calculateInput( project, session, projectIndex ); final CacheContext context = new CacheContext( project, inputInfo, session ); // remote build first @@ -184,7 +186,7 @@ public CacheResult findCachedBuild( MavenSession session, MavenProject project, private CacheResult findCachedBuild( List mojoExecutions, CacheContext context ) { - BuildInfo cachedBuild = null; + Build cachedBuild = null; try { cachedBuild = localCache.findBuild( context ); @@ -199,7 +201,7 @@ private CacheResult findCachedBuild( List mojoExecutions, CacheCo private CacheResult findLocalBuild( List mojoExecutions, CacheContext context ) { - BuildInfo localBuild = null; + Build localBuild = null; try { localBuild = localCache.findLocalBuild( context ); @@ -212,7 +214,7 @@ private CacheResult findLocalBuild( List mojoExecutions, CacheCon } } - private CacheResult analyzeResult( CacheContext context, List mojoExecutions, BuildInfo info ) + private CacheResult analyzeResult( CacheContext context, List mojoExecutions, Build info ) { try @@ -221,7 +223,7 @@ private CacheResult analyzeResult( CacheContext context, List moj { final MavenProject project = context.getProject(); - final ProjectsInputInfoType inputInfo = context.getInputInfo(); + final ProjectsInputInfo inputInfo = context.getInputInfo(); logInfo( project, "Found cached build, restoring from cache " + inputInfo.getChecksum() ); @@ -280,7 +282,7 @@ private CacheResult analyzeResult( CacheContext context, List moj } } - private boolean canIgnoreMissingSegment( BuildInfo info, List mojoExecutions ) + private boolean canIgnoreMissingSegment( Build info, List mojoExecutions ) { final List postCachedSegment = info.getPostCachedSegment( mojoExecutions ); for ( MojoExecution mojoExecution : postCachedSegment ) @@ -297,11 +299,11 @@ private boolean canIgnoreMissingSegment( BuildInfo info, List moj public boolean restoreProjectArtifacts( CacheResult cacheResult ) { - final BuildInfo buildInfo = cacheResult.getBuildInfo(); + final Build build = cacheResult.getBuildInfo(); final CacheContext context = cacheResult.getContext(); final MavenProject project = context.getProject(); - final ArtifactType artifact = buildInfo.getArtifact(); + final Artifact artifact = build.getArtifact(); artifact.setVersion( project.getVersion() ); try @@ -321,7 +323,7 @@ public boolean restoreProjectArtifacts( CacheResult cacheResult ) putChecksum( artifact, context.getInputInfo().getChecksum() ); } - for ( ArtifactType attachedArtifact : buildInfo.getAttachedArtifacts() ) + for ( Artifact attachedArtifact : build.getAttachedArtifacts() ) { attachedArtifact.setVersion( project.getVersion() ); if ( isNotBlank( attachedArtifact.getFileName() ) ) @@ -366,17 +368,17 @@ public boolean restoreProjectArtifacts( CacheResult cacheResult ) return true; } - private void putChecksum( ArtifactType artifact, String projectChecksum ) + private void putChecksum( Artifact artifact, String projectChecksum ) { - final DigestItemType projectArtifact = DtoUtils.createdDigestedByProjectChecksum( artifact, projectChecksum ); + final DigestItem projectArtifact = DtoUtils.createdDigestedByProjectChecksum( artifact, projectChecksum ); final String dependencyKey = KeyUtils.getArtifactKey( artifact ); artifactDigestByKey.put( dependencyKey, projectArtifact ); if ( !"pom".equals( artifact.getType() ) ) { final ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( artifact.getType() ); - ArtifactType copy = DtoUtils.copy( artifact ); + Artifact copy = DtoUtils.copy( artifact ); copy.setType( artifactHandler.getPackaging() ); artifactDigestByKey.put( KeyUtils.getArtifactKey( copy ), projectArtifact ); copy.setType( artifactHandler.getExtension() ); @@ -384,7 +386,7 @@ private void putChecksum( ArtifactType artifact, String projectChecksum ) } } - private ProjectsInputInfoType calculateInput( MavenProject project, MavenSession session, + private ProjectsInputInfo calculateInput( MavenProject project, MavenSession session, ProjectIndex projectIndex ) { try @@ -420,34 +422,34 @@ public void save( CacheResult cacheResult, List mojoExecutions, attachGeneratedSources( project ); attachOutputs( project ); - final Artifact projectArtifact = project.getArtifact(); + final org.apache.maven.artifact.Artifact projectArtifact = project.getArtifact(); final HashFactory hashFactory = cacheConfig.getHashFactory(); final HashAlgorithm algorithm = hashFactory.createAlgorithm(); - final ArtifactType projectArtifactDto = artifactDto( project.getArtifact(), algorithm ); + final Artifact projectArtifactDto = artifactDto( project.getArtifact(), algorithm ); - final List attachedArtifacts = + final List attachedArtifacts = project.getAttachedArtifacts() != null ? project.getAttachedArtifacts() : Collections.emptyList(); - List attachedArtifactDtos = artifactDtos( attachedArtifacts, algorithm ); + List attachedArtifactDtos = artifactDtos( attachedArtifacts, algorithm ); - List completedExecution = buildExecutionInfo( mojoExecutions, executionEvents ); + List completedExecution = buildExecutionInfo( mojoExecutions, executionEvents ); - final BuildInfo buildInfo = new BuildInfo( session.getGoals(), projectArtifactDto, attachedArtifactDtos, + final Build build = new Build( session.getGoals(), projectArtifactDto, attachedArtifactDtos, context.getInputInfo(), completedExecution, hashFactory.getAlgorithm() ); - populateGitInfo( buildInfo, session ); - buildInfo.getDto().setFinal( cacheConfig.isSaveFinal() ); - cacheResults.put( getVersionlessProjectKey( project ), rebuilded( cacheResult, buildInfo ) ); + populateGitInfo( build, session ); + build.getDto().set_final( cacheConfig.isSaveFinal() ); + cacheResults.put( getVersionlessProjectKey( project ), rebuilded( cacheResult, build ) ); // if package phase presence means new artifacts were packaged if ( project.hasLifecyclePhase( "package" ) ) { localCache.beforeSave( context ); - localCache.saveBuildInfo( cacheResult, buildInfo ); + localCache.saveBuildInfo( cacheResult, build ); if ( projectArtifact.getFile() != null ) { localCache.saveArtifactFile( cacheResult, projectArtifact ); putChecksum( projectArtifactDto, context.getInputInfo().getChecksum() ); } - for ( Artifact attachedArtifact : attachedArtifacts ) + for ( org.apache.maven.artifact.Artifact attachedArtifact : attachedArtifacts ) { if ( attachedArtifact.getFile() != null && isOutputArtifact( attachedArtifact.getFile().getName() ) ) @@ -455,19 +457,19 @@ public void save( CacheResult cacheResult, List mojoExecutions, localCache.saveArtifactFile( cacheResult, attachedArtifact ); } } - for ( ArtifactType attachedArtifactDto : attachedArtifactDtos ) + for ( Artifact attachedArtifactDto : attachedArtifactDtos ) { putChecksum( attachedArtifactDto, context.getInputInfo().getChecksum() ); } } else { - localCache.saveBuildInfo( cacheResult, buildInfo ); + localCache.saveBuildInfo( cacheResult, build ); } if ( cacheConfig.isBaselineDiffEnabled() ) { - produceDiffReport( cacheResult, buildInfo ); + produceDiffReport( cacheResult, build ); } } @@ -485,36 +487,36 @@ public void save( CacheResult cacheResult, List mojoExecutions, } } - public void produceDiffReport( CacheResult cacheResult, BuildInfo buildInfo ) + public void produceDiffReport( CacheResult cacheResult, Build build ) { MavenProject project = cacheResult.getContext().getProject(); - Optional baselineHolder = remoteCache.findBaselineBuild( project ); + Optional baselineHolder = remoteCache.findBaselineBuild( project ); if ( baselineHolder.isPresent() ) { - BuildInfo baseline = baselineHolder.get(); + Build baseline = baselineHolder.get(); String outputDirectory = project.getBuild().getDirectory(); Path reportOutputDir = Paths.get( outputDirectory, "incremental-maven" ); logInfo( project, "Saving cache builds diff to: " + reportOutputDir ); - BuildDiffType diff = new CacheDiff( buildInfo.getDto(), baseline.getDto(), cacheConfig ).compare(); + Diff diff = new CacheDiff( build.getDto(), baseline.getDto(), cacheConfig ).compare(); try { Files.createDirectories( reportOutputDir ); - final ProjectsInputInfoType baselineInputs = baseline.getDto().getProjectsInputInfo(); + final ProjectsInputInfo baselineInputs = baseline.getDto().getProjectsInputInfo(); final String checksum = baselineInputs.getChecksum(); Files.write( reportOutputDir.resolve( "buildinfo-baseline-" + checksum + ".xml" ), xmlService.toBytes( baseline.getDto() ), TRUNCATE_EXISTING, CREATE ); Files.write( reportOutputDir.resolve( "buildinfo-" + checksum + ".xml" ), - xmlService.toBytes( buildInfo.getDto() ), TRUNCATE_EXISTING, CREATE ); + xmlService.toBytes( build.getDto() ), TRUNCATE_EXISTING, CREATE ); Files.write( reportOutputDir.resolve( "buildsdiff-" + checksum + ".xml" ), xmlService.toBytes( diff ), TRUNCATE_EXISTING, CREATE ); - final Optional pom = CacheDiff.findPom( buildInfo.getDto().getProjectsInputInfo() ); + final Optional pom = CacheDiff.findPom( build.getDto().getProjectsInputInfo() ); if ( pom.isPresent() ) { Files.write( reportOutputDir.resolve( "effective-pom-" + checksum + ".xml" ), pom.get().getValue().getBytes( StandardCharsets.UTF_8 ), TRUNCATE_EXISTING, CREATE ); } - final Optional baselinePom = CacheDiff.findPom( baselineInputs ); + final Optional baselinePom = CacheDiff.findPom( baselineInputs ); if ( baselinePom.isPresent() ) { Files.write( reportOutputDir.resolve( @@ -534,10 +536,11 @@ public void produceDiffReport( CacheResult cacheResult, BuildInfo buildInfo ) } } - private List artifactDtos( List attachedArtifacts, HashAlgorithm digest ) throws IOException + private List artifactDtos( List attachedArtifacts, + HashAlgorithm digest ) throws IOException { - List result = new ArrayList<>(); - for ( Artifact attachedArtifact : attachedArtifacts ) + List result = new ArrayList<>(); + for ( org.apache.maven.artifact.Artifact attachedArtifact : attachedArtifacts ) { if ( attachedArtifact.getFile() != null && isOutputArtifact( attachedArtifact.getFile().getName() ) ) { @@ -547,27 +550,28 @@ private List artifactDtos( List attachedArtifacts, HashA return result; } - private ArtifactType artifactDto( Artifact projectArtifact, HashAlgorithm algorithm ) throws IOException + private Artifact artifactDto( org.apache.maven.artifact.Artifact projectArtifact, + HashAlgorithm algorithm ) throws IOException { - final ArtifactType dto = DtoUtils.createDto( projectArtifact ); + final Artifact dto = DtoUtils.createDto( projectArtifact ); if ( projectArtifact.getFile() != null && projectArtifact.getFile().isFile() ) { final Path file = projectArtifact.getFile().toPath(); dto.setFileHash( algorithm.hash( file ) ); - dto.setFileSize( BigInteger.valueOf( Files.size( file ) ) ); + dto.setFileSize( Files.size( file ) ); } return dto; } - private List buildExecutionInfo( List mojoExecutions, - Map executionEvents ) + private List buildExecutionInfo( List mojoExecutions, + Map executionEvents ) { - List list = new ArrayList<>(); + List list = new ArrayList<>(); for ( MojoExecution mojoExecution : mojoExecutions ) { final String executionKey = ProjectUtils.mojoExecutionKey( mojoExecution ); final MojoExecutionEvent executionEvent = executionEvents.get( executionKey ); - CompletedExecutionType executionInfo = new CompletedExecutionType(); + CompletedExecution executionInfo = new CompletedExecution(); executionInfo.setExecutionKey( executionKey ); executionInfo.setMojoClassName( mojoExecution.getMojoDescriptor().getImplementation() ); if ( executionEvent != null ) @@ -579,14 +583,14 @@ private List buildExecutionInfo( List moj return list; } - private void recordMojoProperties( CompletedExecutionType execution, MojoExecutionEvent executionEvent ) + private void recordMojoProperties( CompletedExecution execution, MojoExecutionEvent executionEvent ) { final MojoExecution mojoExecution = executionEvent.getExecution(); final boolean logAll = cacheConfig.isLogAllProperties( mojoExecution ); - List trackedProperties = cacheConfig.getTrackedProperties( mojoExecution ); - List noLogProperties = cacheConfig.getNologProperties( mojoExecution ); - List forceLogProperties = cacheConfig.getLoggedProperties( mojoExecution ); + List trackedProperties = cacheConfig.getTrackedProperties( mojoExecution ); + List noLogProperties = cacheConfig.getNologProperties( mojoExecution ); + List forceLogProperties = cacheConfig.getLoggedProperties( mojoExecution ); final Mojo mojo = executionEvent.getMojo(); final File baseDir = executionEvent.getProject().getBasedir(); @@ -627,13 +631,13 @@ private void recordMojoProperties( CompletedExecutionType execution, MojoExecuti } } - private boolean isExcluded( String propertyName, boolean logAll, List excludedProperties, - List forceLogProperties ) + private boolean isExcluded( String propertyName, boolean logAll, List excludedProperties, + List forceLogProperties ) { if ( !forceLogProperties.isEmpty() ) { - for ( PropertyNameType logProperty : forceLogProperties ) + for ( PropertyName logProperty : forceLogProperties ) { if ( StringUtils.equals( propertyName, logProperty.getPropertyName() ) ) { @@ -645,7 +649,7 @@ private boolean isExcluded( String propertyName, boolean logAll, List trackedProperties ) + private boolean isTracked( String propertyName, List trackedProperties ) { - for ( TrackedPropertyType trackedProperty : trackedProperties ) + for ( TrackedProperty trackedProperty : trackedProperties ) { if ( StringUtils.equals( propertyName, trackedProperty.getPropertyName() ) ) { @@ -670,15 +674,15 @@ private boolean isTracked( String propertyName, List tracke return false; } - private boolean isCachedSegmentPropertiesPresent( MavenProject project, BuildInfo buildInfo, + private boolean isCachedSegmentPropertiesPresent( MavenProject project, Build build, List mojoExecutions ) { for ( MojoExecution mojoExecution : mojoExecutions ) { // completion of all mojos checked above, so we expect tp have execution info here - final List trackedProperties = cacheConfig.getTrackedProperties( mojoExecution ); - final CompletedExecutionType cachedExecution = buildInfo.findMojoExecutionInfo( mojoExecution ); + final List trackedProperties = cacheConfig.getTrackedProperties( mojoExecution ); + final CompletedExecution cachedExecution = build.findMojoExecutionInfo( mojoExecution ); if ( cachedExecution == null ) { @@ -750,10 +754,10 @@ public void saveCacheReport( MavenSession session ) try { - CacheReportType cacheReport = new CacheReportType(); + CacheReport cacheReport = new CacheReport(); for ( CacheResult result : cacheResults.values() ) { - ProjectReportType projectReport = new ProjectReportType(); + ProjectReport projectReport = new ProjectReport(); CacheContext context = result.getContext(); MavenProject project = context.getProject(); projectReport.setGroupId( project.getGroupId() ); @@ -772,7 +776,7 @@ else if ( result.getSource() == CacheSource.BUILD && cacheConfig.isSaveToRemote( projectReport.setSharedToRemote( true ); projectReport.setUrl( remoteCache.getResourceUrl( context, BUILDINFO_XML ) ); } - cacheReport.getProject().add( projectReport ); + cacheReport.addProject( projectReport ); } String buildId = UUID.randomUUID().toString(); @@ -784,7 +788,7 @@ else if ( result.getSource() == CacheSource.BUILD && cacheConfig.isSaveToRemote( } } - private void populateGitInfo( BuildInfo buildInfo, MavenSession session ) throws IOException + private void populateGitInfo( Build build, MavenSession session ) throws IOException { if ( scm == null ) { @@ -798,13 +802,13 @@ private void populateGitInfo( BuildInfo buildInfo, MavenSession session ) throws } catch ( IOException e ) { - scm = new BuildInfoType.Scm(); + scm = new Scm(); logger.error( "Cannot populate git info", e ); } } } } - buildInfo.getDto().setScm( scm ); + build.getDto().setScm( scm ); } private void zipAndAttachArtifact( MavenProject project, Path dir, String classifier ) throws IOException @@ -838,7 +842,7 @@ private Path classifierToPath( Path outputDir, String classifier ) return outputDir.resolve( relPath ); } - private void restoreGeneratedSources( ArtifactType artifact, Path artifactFilePath, MavenProject project ) + private void restoreGeneratedSources( Artifact artifact, Path artifactFilePath, MavenProject project ) throws IOException { final Path targetDir = Paths.get( project.getBuild().getDirectory() ); diff --git a/maven-core/src/main/java/org/apache/maven/caching/CacheDiff.java b/maven-caching/src/main/java/org/apache/maven/caching/CacheDiff.java similarity index 75% rename from maven-core/src/main/java/org/apache/maven/caching/CacheDiff.java rename to maven-caching/src/main/java/org/apache/maven/caching/CacheDiff.java index 9e066a598eff..82be28f56d8e 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/CacheDiff.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/CacheDiff.java @@ -22,13 +22,13 @@ import com.google.common.base.Optional; import com.google.common.collect.Sets; import org.apache.commons.lang3.StringUtils; -import org.apache.maven.caching.jaxb.BuildDiffType; -import org.apache.maven.caching.jaxb.BuildInfoType; -import org.apache.maven.caching.jaxb.CompletedExecutionType; -import org.apache.maven.caching.jaxb.DigestItemType; -import org.apache.maven.caching.jaxb.MismatchType; -import org.apache.maven.caching.jaxb.ProjectsInputInfoType; -import org.apache.maven.caching.jaxb.PropertyValueType; +import org.apache.maven.caching.xml.build.Build; +import org.apache.maven.caching.xml.build.CompletedExecution; +import org.apache.maven.caching.xml.build.DigestItem; +import org.apache.maven.caching.xml.build.ProjectsInputInfo; +import org.apache.maven.caching.xml.build.PropertyValue; +import org.apache.maven.caching.xml.diff.Diff; +import org.apache.maven.caching.xml.diff.Mismatch; import org.apache.maven.caching.xml.CacheConfig; import java.util.ArrayList; @@ -44,11 +44,11 @@ public class CacheDiff { private final CacheConfig config; - private final BuildInfoType current; - private final BuildInfoType baseline; - private final LinkedList report; + private final Build current; + private final Build baseline; + private final LinkedList report; - public CacheDiff( BuildInfoType current, BuildInfoType baseline, CacheConfig config ) + public CacheDiff( Build current, Build baseline, CacheConfig config ) { this.current = current; this.baseline = baseline; @@ -56,7 +56,7 @@ public CacheDiff( BuildInfoType current, BuildInfoType baseline, CacheConfig con this.report = new LinkedList<>(); } - public BuildDiffType compare() + public Diff compare() { if ( !StringUtils.equals( current.getHashFunction(), baseline.getHashFunction() ) ) @@ -74,17 +74,17 @@ public BuildDiffType compare() compareFiles( current.getProjectsInputInfo(), baseline.getProjectsInputInfo() ); compareDependencies( current.getProjectsInputInfo(), baseline.getProjectsInputInfo() ); - final BuildDiffType buildDiffType = new BuildDiffType(); - buildDiffType.getMismatch().addAll( report ); + final Diff buildDiffType = new Diff(); + buildDiffType.getMismatches().addAll( report ); return buildDiffType; } - private void compareEffectivePoms( ProjectsInputInfoType current, ProjectsInputInfoType baseline ) + private void compareEffectivePoms( ProjectsInputInfo current, ProjectsInputInfo baseline ) { - Optional currentPom = findPom( current ); + Optional currentPom = findPom( current ); String currentPomHash = currentPom.isPresent() ? currentPom.get().getHash() : null; - Optional baseLinePom = findPom( baseline ); + Optional baseLinePom = findPom( baseline ); String baselinePomHash = baseLinePom.isPresent() ? baseLinePom.get().getHash() : null; if ( !StringUtils.equals( currentPomHash, baselinePomHash ) ) @@ -98,9 +98,9 @@ private void compareEffectivePoms( ProjectsInputInfoType current, ProjectsInputI } } - public static Optional findPom( ProjectsInputInfoType projectInputs ) + public static Optional findPom( ProjectsInputInfo projectInputs ) { - for ( DigestItemType digestItemType : projectInputs.getItem() ) + for ( DigestItem digestItemType : projectInputs.getItems() ) { if ( "pom".equals( digestItemType.getType() ) ) { @@ -111,11 +111,11 @@ public static Optional findPom( ProjectsInputInfoType projectInp return Optional.absent(); } - private void compareFiles( ProjectsInputInfoType current, ProjectsInputInfoType baseline ) + private void compareFiles( ProjectsInputInfo current, ProjectsInputInfo baseline ) { - final Map currentFiles = new HashMap<>(); - for ( DigestItemType item : current.getItem() ) + final Map currentFiles = new HashMap<>(); + for ( DigestItem item : current.getItems() ) { if ( "file".equals( item.getType() ) ) { @@ -123,8 +123,8 @@ private void compareFiles( ProjectsInputInfoType current, ProjectsInputInfoType } } - final Map baselineFiles = new HashMap<>(); - for ( DigestItemType item : baseline.getItem() ) + final Map baselineFiles = new HashMap<>(); + for ( DigestItem item : baseline.getItems() ) { if ( "file".equals( item.getType() ) ) { @@ -147,12 +147,12 @@ private void compareFiles( ProjectsInputInfoType current, ProjectsInputInfoType return; } - for ( Map.Entry entry : currentFiles.entrySet() ) + for ( Map.Entry entry : currentFiles.entrySet() ) { String filePath = entry.getKey(); - DigestItemType currentFile = entry.getValue(); + DigestItem currentFile = entry.getValue(); // should be null safe because sets are compared above for differences - final DigestItemType baselineFile = baselineFiles.get( filePath ); + final DigestItem baselineFile = baselineFiles.get( filePath ); if ( !StringUtils.equals( currentFile.getHash(), baselineFile.getHash() ) ) { @@ -178,18 +178,18 @@ private void compareFiles( ProjectsInputInfoType current, ProjectsInputInfoType } } - private void compareDependencies( ProjectsInputInfoType current, ProjectsInputInfoType baseline ) + private void compareDependencies( ProjectsInputInfo current, ProjectsInputInfo baseline ) { - final Map currentDependencies = new HashMap<>(); - for ( DigestItemType digestItemType : current.getItem() ) + final Map currentDependencies = new HashMap<>(); + for ( DigestItem digestItemType : current.getItems() ) { if ( "dependency".equals( digestItemType.getType() ) ) { currentDependencies.put( digestItemType.getValue(), digestItemType ); } } - final Map baselineDependencies = new HashMap<>(); - for ( DigestItemType item : baseline.getItem() ) + final Map baselineDependencies = new HashMap<>(); + for ( DigestItem item : baseline.getItems() ) { if ( "dependency".equals( item.getType() ) ) { @@ -214,12 +214,12 @@ private void compareDependencies( ProjectsInputInfoType current, ProjectsInputIn return; } - for ( Map.Entry entry : currentDependencies.entrySet() ) + for ( Map.Entry entry : currentDependencies.entrySet() ) { String dependencyKey = entry.getKey(); - DigestItemType currentDependency = entry.getValue(); + DigestItem currentDependency = entry.getValue(); // null safe - sets compared for differences above - final DigestItemType baselineDependency = baselineDependencies.get( dependencyKey ); + final DigestItem baselineDependency = baselineDependencies.get( dependencyKey ); if ( !StringUtils.equals( currentDependency.getHash(), baselineDependency.getHash() ) ) { addNewMismatch( dependencyKey, currentDependency.getHash(), baselineDependency.getHash(), @@ -232,23 +232,23 @@ private void compareDependencies( ProjectsInputInfoType current, ProjectsInputIn } - private void compareExecutions( BuildInfoType.Executions current, BuildInfoType.Executions baseline ) + private void compareExecutions( List current, List baseline ) { - Map baselineExecutionsByKey = new HashMap<>(); - for ( CompletedExecutionType completedExecutionType : baseline.getExecution() ) + Map baselineExecutionsByKey = new HashMap<>(); + for ( CompletedExecution completedExecutionType : baseline ) { baselineExecutionsByKey.put( completedExecutionType.getExecutionKey(), completedExecutionType ); } - Map currentExecutionsByKey = new HashMap<>(); - for ( CompletedExecutionType e1 : current.getExecution() ) + Map currentExecutionsByKey = new HashMap<>(); + for ( CompletedExecution e1 : current ) { currentExecutionsByKey.put( e1.getExecutionKey(), e1 ); } // such situation normally means different poms and mismatch in effective poms, // but in any case it is helpful to report - for ( CompletedExecutionType baselineExecution : baseline.getExecution() ) + for ( CompletedExecution baselineExecution : baseline ) { if ( !currentExecutionsByKey.containsKey( baselineExecution.getExecutionKey() ) ) { @@ -261,7 +261,7 @@ private void compareExecutions( BuildInfoType.Executions current, BuildInfoType. } } - for ( CompletedExecutionType currentExecution : current.getExecution() ) + for ( CompletedExecution currentExecution : current ) { if ( !baselineExecutionsByKey.containsKey( currentExecution.getExecutionKey() ) ) { @@ -275,17 +275,17 @@ private void compareExecutions( BuildInfoType.Executions current, BuildInfoType. continue; } - final CompletedExecutionType baselineExecution = + final CompletedExecution baselineExecution = baselineExecutionsByKey.get( currentExecution.getExecutionKey() ); comparePlugins( currentExecution, baselineExecution ); } } - private void comparePlugins( CompletedExecutionType current, CompletedExecutionType baseline ) + private void comparePlugins( CompletedExecution current, CompletedExecution baseline ) { // TODO add support for skip values - final List trackedProperties = new ArrayList<>(); - for ( PropertyValueType propertyValueType : current.getConfiguration().getProperty() ) + final List trackedProperties = new ArrayList<>(); + for ( PropertyValue propertyValueType : current.getProperties() ) { if ( propertyValueType.isTracked() ) { @@ -297,15 +297,15 @@ private void comparePlugins( CompletedExecutionType current, CompletedExecutionT return; } - final Map baselinePropertiesByName = new HashMap<>(); - for ( PropertyValueType propertyValueType : baseline.getConfiguration().getProperty() ) + final Map baselinePropertiesByName = new HashMap<>(); + for ( PropertyValue propertyValueType : baseline.getProperties() ) { baselinePropertiesByName.put( propertyValueType.getName(), propertyValueType ); } - for ( PropertyValueType p : trackedProperties ) + for ( PropertyValue p : trackedProperties ) { - final PropertyValueType baselineValue = baselinePropertiesByName.get( p.getName() ); + final PropertyValue baselineValue = baselinePropertiesByName.get( p.getName() ); if ( baselineValue == null || !StringUtils.equals( baselineValue.getValue(), p.getValue() ) ) { addNewMismatch( @@ -325,7 +325,7 @@ private void comparePlugins( CompletedExecutionType current, CompletedExecutionT private void addNewMismatch( String item, String current, String baseline, String reason, String resolution ) { - final MismatchType mismatch = new MismatchType(); + final Mismatch mismatch = new Mismatch(); mismatch.setItem( item ); mismatch.setCurrent( current ); mismatch.setBaseline( baseline ); @@ -336,7 +336,7 @@ private void addNewMismatch( String item, String current, String baseline, Strin private void addNewMismatch( String property, String reason, String resolution ) { - final MismatchType mismatchType = new MismatchType(); + final Mismatch mismatchType = new Mismatch(); mismatchType.setItem( property ); mismatchType.setReason( reason ); mismatchType.setResolution( resolution ); diff --git a/maven-core/src/main/java/org/apache/maven/caching/CacheEventSpy.java b/maven-caching/src/main/java/org/apache/maven/caching/CacheEventSpy.java similarity index 87% rename from maven-core/src/main/java/org/apache/maven/caching/CacheEventSpy.java rename to maven-caching/src/main/java/org/apache/maven/caching/CacheEventSpy.java index 3cd5578d9be3..39b83d6b70a3 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/CacheEventSpy.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/CacheEventSpy.java @@ -19,23 +19,25 @@ * under the License. */ +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + import org.apache.maven.caching.xml.CacheConfig; import org.apache.maven.eventspy.AbstractEventSpy; -import org.apache.maven.eventspy.EventSpy; import org.apache.maven.execution.ExecutionEvent; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; /** * Triggers cache report generation on build completion */ -@Component( role = EventSpy.class ) +@Singleton +@Named public class CacheEventSpy extends AbstractEventSpy { - @Requirement + @Inject private CacheConfig cacheConfig; - @Requirement + @Inject private CacheController cacheController; @Override diff --git a/maven-core/src/main/java/org/apache/maven/caching/CacheResult.java b/maven-caching/src/main/java/org/apache/maven/caching/CacheResult.java similarity index 67% rename from maven-core/src/main/java/org/apache/maven/caching/CacheResult.java rename to maven-caching/src/main/java/org/apache/maven/caching/CacheResult.java index 8d886764f8b8..e96abe6bb46e 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/CacheResult.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/CacheResult.java @@ -19,7 +19,7 @@ * under the License. */ -import org.apache.maven.caching.xml.BuildInfo; +import org.apache.maven.caching.xml.Build; import org.apache.maven.caching.xml.CacheSource; import static java.util.Objects.requireNonNull; @@ -30,13 +30,13 @@ public class CacheResult { private final RestoreStatus status; - private final BuildInfo buildInfo; + private final Build build; private final CacheContext context; - private CacheResult( RestoreStatus status, BuildInfo buildInfo, CacheContext context ) + private CacheResult( RestoreStatus status, Build build, CacheContext context ) { this.status = requireNonNull( status ); - this.buildInfo = buildInfo; + this.build = build; this.context = context; } @@ -51,25 +51,25 @@ public static CacheResult empty() return new CacheResult( RestoreStatus.EMPTY, null, null ); } - public static CacheResult failure( BuildInfo buildInfo, CacheContext context ) + public static CacheResult failure( Build build, CacheContext context ) { - requireNonNull( buildInfo ); + requireNonNull( build ); requireNonNull( context ); - return new CacheResult( RestoreStatus.FAILURE, buildInfo, context ); + return new CacheResult( RestoreStatus.FAILURE, build, context ); } - public static CacheResult success( BuildInfo buildInfo, CacheContext context ) + public static CacheResult success( Build build, CacheContext context ) { - requireNonNull( buildInfo ); + requireNonNull( build ); requireNonNull( context ); - return new CacheResult( RestoreStatus.SUCCESS, buildInfo, context ); + return new CacheResult( RestoreStatus.SUCCESS, build, context ); } - public static CacheResult partialSuccess( BuildInfo buildInfo, CacheContext context ) + public static CacheResult partialSuccess( Build build, CacheContext context ) { - requireNonNull( buildInfo ); + requireNonNull( build ); requireNonNull( context ); - return new CacheResult( RestoreStatus.PARTIAL, buildInfo, context ); + return new CacheResult( RestoreStatus.PARTIAL, build, context ); } public static CacheResult failure( CacheContext context ) @@ -78,11 +78,11 @@ public static CacheResult failure( CacheContext context ) return new CacheResult( RestoreStatus.FAILURE, null, context ); } - public static CacheResult rebuilded( CacheResult orig, BuildInfo buildInfo ) + public static CacheResult rebuilded( CacheResult orig, Build build ) { requireNonNull( orig ); - requireNonNull( buildInfo ); - return new CacheResult( orig.status, buildInfo, orig.context ); + requireNonNull( build ); + return new CacheResult( orig.status, build, orig.context ); } public boolean isSuccess() @@ -90,14 +90,14 @@ public boolean isSuccess() return status == RestoreStatus.SUCCESS; } - public BuildInfo getBuildInfo() + public Build getBuildInfo() { - return buildInfo; + return build; } public CacheSource getSource() { - return buildInfo != null ? buildInfo.getSource() : null; + return build != null ? build.getSource() : null; } public CacheContext getContext() @@ -117,6 +117,6 @@ public RestoreStatus getStatus() public boolean isFinal() { - return buildInfo != null && buildInfo.getDto().isFinal(); + return build != null && build.getDto().is_final(); } } diff --git a/maven-caching/src/main/java/org/apache/maven/caching/CachingMojoExecutor.java b/maven-caching/src/main/java/org/apache/maven/caching/CachingMojoExecutor.java new file mode 100644 index 000000000000..c45dbae6f0bd --- /dev/null +++ b/maven-caching/src/main/java/org/apache/maven/caching/CachingMojoExecutor.java @@ -0,0 +1,595 @@ +package org.apache.maven.caching; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.artifact.resolver.filter.CumulativeScopeArtifactFilter; +import org.apache.maven.caching.xml.Build; +import org.apache.maven.caching.xml.CacheConfig; +import org.apache.maven.caching.xml.CacheState; +import org.apache.maven.execution.ExecutionEvent; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.execution.MojoExecutionEvent; +import org.apache.maven.lifecycle.LifecycleExecutionException; +import org.apache.maven.lifecycle.MissingProjectException; +import org.apache.maven.lifecycle.internal.DependencyContext; +import org.apache.maven.lifecycle.internal.ExecutionEventCatapult; +import org.apache.maven.lifecycle.internal.IDependencyContext; +import org.apache.maven.lifecycle.internal.LifecycleDependencyResolver; +import org.apache.maven.lifecycle.internal.MojoExecutor; +import org.apache.maven.lifecycle.internal.NoResolutionContext; +import org.apache.maven.lifecycle.internal.PhaseRecorder; +import org.apache.maven.lifecycle.internal.ProjectIndex; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.plugin.MavenPluginManager; +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.plugin.MojoExecution.Source; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.PluginConfigurationException; +import org.apache.maven.plugin.PluginIncompatibleException; +import org.apache.maven.plugin.PluginManagerException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.logging.Logger; +import org.codehaus.plexus.util.StringUtils; +import org.eclipse.sisu.Priority; + +import static org.apache.maven.caching.ProjectUtils.isLaterPhase; +import static org.apache.maven.caching.checksum.KeyUtils.getVersionlessProjectKey; +import static org.apache.maven.caching.xml.CacheState.DISABLED; +import static org.apache.maven.caching.xml.CacheState.INITIALIZED; + + +/** + *

+ * Cache-enabled version of the MojoExecutor + *

+ */ +@Singleton +@Named +@Priority( 10 ) +public class CachingMojoExecutor implements MojoExecutor +{ + + @Inject + private Logger logger; + + @Inject + private BuildPluginManager pluginManager; + + @Inject + private MavenPluginManager mavenPluginManager; + + @Inject + private LifecycleDependencyResolver lifeCycleDependencyResolver; + + @Inject + private ExecutionEventCatapult eventCatapult; + + @Inject + private CacheController cacheController; + + @Inject + private CacheConfig cacheConfig; + + @Inject + private MojoParametersListener mojoListener; + + public CachingMojoExecutor() + { + } + + public DependencyContext newDependencyContext( MavenSession session, List mojoExecutions ) + { + Set scopesToCollect = new TreeSet<>(); + Set scopesToResolve = new TreeSet<>(); + + collectDependencyRequirements( scopesToResolve, scopesToCollect, mojoExecutions ); + + return new DependencyContext( session.getCurrentProject(), scopesToCollect, scopesToResolve ); + } + + private void collectDependencyRequirements( Set scopesToResolve, Set scopesToCollect, + Collection mojoExecutions ) + { + for ( MojoExecution mojoExecution : mojoExecutions ) + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + scopesToResolve.addAll( toScopes( mojoDescriptor.getDependencyResolutionRequired() ) ); + + scopesToCollect.addAll( toScopes( mojoDescriptor.getDependencyCollectionRequired() ) ); + } + } + + private Collection toScopes( String classpath ) + { + Collection scopes = Collections.emptyList(); + + if ( StringUtils.isNotEmpty( classpath ) ) + { + if ( Artifact.SCOPE_COMPILE.equals( classpath ) ) + { + scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED ); + } + else if ( Artifact.SCOPE_RUNTIME.equals( classpath ) ) + { + scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME ); + } + else if ( Artifact.SCOPE_COMPILE_PLUS_RUNTIME.equals( classpath ) ) + { + scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, + Artifact.SCOPE_RUNTIME ); + } + else if ( Artifact.SCOPE_RUNTIME_PLUS_SYSTEM.equals( classpath ) ) + { + scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME ); + } + else if ( Artifact.SCOPE_TEST.equals( classpath ) ) + { + scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, + Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST ); + } + } + return Collections.unmodifiableCollection( scopes ); + } + + public void execute( MavenSession session, List mojoExecutions, ProjectIndex projectIndex ) + throws LifecycleExecutionException + { + DependencyContext dependencyContext = newDependencyContext( session, mojoExecutions ); + + PhaseRecorder phaseRecorder = new PhaseRecorder( session.getCurrentProject() ); + + final MavenProject project = session.getCurrentProject(); + final Source source = getSource( mojoExecutions ); + + // execute clean bound goals before restoring to not interfere/slowdown clean + CacheState cacheState = DISABLED; + CacheResult result = CacheResult.empty(); + if ( source == Source.LIFECYCLE ) + { + List cleanPhase = getCleanPhase( mojoExecutions ); + for ( MojoExecution mojoExecution : cleanPhase ) + { + execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); + } + cacheState = cacheConfig.initialize( project, session ); + if ( cacheState == INITIALIZED ) + { + result = cacheController.findCachedBuild( session, project, projectIndex, mojoExecutions ); + } + } + + boolean restorable = result.isSuccess() || result.isPartialSuccess(); + boolean restored = result.isSuccess(); // if partially restored need to save increment + if ( restorable ) + { + restored &= restoreProject( result, mojoExecutions, projectIndex, dependencyContext, phaseRecorder ); + } + else + { + for ( MojoExecution mojoExecution : mojoExecutions ) + { + if ( source == Source.CLI || isLaterPhase( mojoExecution.getLifecyclePhase(), "post-clean" ) ) + { + execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); + } + } + } + + if ( cacheState == INITIALIZED && ( !restorable || !restored ) ) + { + final Map executionEvents = mojoListener.getProjectExecutions( project ); + cacheController.save( result, mojoExecutions, executionEvents ); + } + + if ( cacheConfig.isFailFast() && !result.isSuccess() ) + { + throw new LifecycleExecutionException( + "Failed to restore project[" + getVersionlessProjectKey( project ) + "] from cache, failing build.", + project ); + } + } + + private Source getSource( List mojoExecutions ) + { + if ( mojoExecutions == null || mojoExecutions.isEmpty() ) + { + return null; + } + for ( MojoExecution mojoExecution : mojoExecutions ) + { + if ( mojoExecution.getSource() == Source.CLI ) + { + return Source.CLI; + } + } + return Source.LIFECYCLE; + } + + private boolean restoreProject( CacheResult cacheResult, + List mojoExecutions, + ProjectIndex projectIndex, + DependencyContext dependencyContext, + PhaseRecorder phaseRecorder ) throws LifecycleExecutionException + { + + final Build build = cacheResult.getBuildInfo(); + final MavenProject project = cacheResult.getContext().getProject(); + final MavenSession session = cacheResult.getContext().getSession(); + final List cachedSegment = build.getCachedSegment( mojoExecutions ); + + boolean restored = cacheController.restoreProjectArtifacts( cacheResult ); + if ( !restored ) + { + logger.info( + "[CACHE][" + project.getArtifactId() + + "] Cannot restore project artifacts, continuing with non cached build" ); + return false; + } + + for ( MojoExecution cacheCandidate : cachedSegment ) + { + + if ( cacheController.isForcedExecution( project, cacheCandidate ) ) + { + logger.info( + "[CACHE][" + project.getArtifactId() + "] Mojo execution is forced by project property: " + + cacheCandidate.getMojoDescriptor().getFullGoalName() ); + execute( session, cacheCandidate, projectIndex, dependencyContext, phaseRecorder ); + } + else + { + restored = verifyCacheConsistency( cacheCandidate, build, project, session, projectIndex, + dependencyContext, phaseRecorder ); + if ( !restored ) + { + break; + } + } + } + + if ( !restored ) + { + // cleanup partial state + project.getArtifact().setFile( null ); + project.getArtifact().setResolved( false ); + project.getAttachedArtifacts().clear(); + mojoListener.remove( project ); + // build as usual + for ( MojoExecution mojoExecution : cachedSegment ) + { + execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); + } + } + + for ( MojoExecution mojoExecution : build.getPostCachedSegment( mojoExecutions ) ) + { + execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); + } + return restored; + } + + private boolean verifyCacheConsistency( MojoExecution cacheCandidate, + Build cachedBuild, + MavenProject project, + MavenSession session, + ProjectIndex projectIndex, + DependencyContext dependencyContext, + PhaseRecorder phaseRecorder ) throws LifecycleExecutionException + { + + AtomicBoolean consistent = new AtomicBoolean( true ); + final MojoExecutionManager mojoChecker = new MojoExecutionManager( project, cacheController, cachedBuild, + consistent, logger, cacheConfig ); + + if ( mojoChecker.needCheck( cacheCandidate, session ) ) + { + try + { + // actual execution will not happen (if not forced). decision delayed to execution time + // then all properties are resolved. + cacheCandidate.setMojoExecutionManager( mojoChecker ); + IDependencyContext nop = new NoResolutionContext( dependencyContext ); + execute( session, cacheCandidate, projectIndex, nop, phaseRecorder ); + } + finally + { + cacheCandidate.setMojoExecutionManager( null ); + } + } + else + { + logger.info( + "[CACHE][" + project.getArtifactId() + "] Skipping plugin execution (cached): " + + cacheCandidate.getMojoDescriptor().getFullGoalName() ); + } + + return consistent.get(); + } + + private List getCleanPhase( List mojoExecutions ) + { + List list = new ArrayList<>(); + for ( MojoExecution mojoExecution : mojoExecutions ) + { + if ( isLaterPhase( mojoExecution.getLifecyclePhase(), "post-clean" ) ) + { + break; + } + list.add( mojoExecution ); + } + return list; + } + + public void execute( MavenSession session, + MojoExecution mojoExecution, + ProjectIndex projectIndex, + IDependencyContext dependencyContext, + PhaseRecorder phaseRecorder ) throws LifecycleExecutionException + { + execute( session, mojoExecution, projectIndex, dependencyContext ); + phaseRecorder.observeExecution( mojoExecution ); + } + + private void execute( MavenSession session, + MojoExecution mojoExecution, + ProjectIndex projectIndex, + IDependencyContext dependencyContext ) throws LifecycleExecutionException + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + try + { + mavenPluginManager.checkRequiredMavenVersion( mojoDescriptor.getPluginDescriptor() ); + } + catch ( PluginIncompatibleException e ) + { + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e ); + } + + if ( mojoDescriptor.isProjectRequired() && !session.getRequest().isProjectPresent() ) + { + Throwable cause = new MissingProjectException( + "Goal requires a project to execute" + " but there is no POM in this directory (" + + session.getExecutionRootDirectory() + ")." + + " Please verify you invoked Maven from the correct directory." ); + throw new LifecycleExecutionException( mojoExecution, null, cause ); + } + + if ( mojoDescriptor.isOnlineRequired() && session.isOffline() ) + { + if ( Source.CLI.equals( mojoExecution.getSource() ) ) + { + Throwable cause = new IllegalStateException( + "Goal requires online mode for execution" + " but Maven is currently offline." ); + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), cause ); + } + else + { + eventCatapult.fire( ExecutionEvent.Type.MojoSkipped, session, mojoExecution ); + + return; + } + } + + List forkedProjects = executeForkedExecutions( mojoExecution, session, projectIndex ); + + ensureDependenciesAreResolved( mojoDescriptor, session, dependencyContext ); + + eventCatapult.fire( ExecutionEvent.Type.MojoStarted, session, mojoExecution ); + + try + { + try + { + pluginManager.executeMojo( session, mojoExecution ); + } + catch ( MojoFailureException + | PluginManagerException + | PluginConfigurationException + | MojoExecutionException e ) + { + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e ); + } + + eventCatapult.fire( ExecutionEvent.Type.MojoSucceeded, session, mojoExecution ); + } + catch ( LifecycleExecutionException e ) + { + eventCatapult.fire( ExecutionEvent.Type.MojoFailed, session, mojoExecution, e ); + + throw e; + } + finally + { + for ( MavenProject forkedProject : forkedProjects ) + { + forkedProject.setExecutionProject( null ); + } + } + } + + public void ensureDependenciesAreResolved( MojoDescriptor mojoDescriptor, + MavenSession session, + IDependencyContext dependencyContext ) throws LifecycleExecutionException + + { + MavenProject project = dependencyContext.getProject(); + boolean aggregating = mojoDescriptor.isAggregator(); + + if ( dependencyContext.isResolutionRequiredForCurrentProject() ) + { + Collection scopesToCollect = dependencyContext.getScopesToCollectForCurrentProject(); + Collection scopesToResolve = dependencyContext.getScopesToResolveForCurrentProject(); + + lifeCycleDependencyResolver.resolveProjectDependencies( project, scopesToCollect, scopesToResolve, session, + aggregating, Collections.emptySet() ); + + dependencyContext.synchronizeWithProjectState(); + } + + if ( aggregating ) + { + Collection scopesToCollect = toScopes( mojoDescriptor.getDependencyCollectionRequired() ); + Collection scopesToResolve = toScopes( mojoDescriptor.getDependencyResolutionRequired() ); + + if ( dependencyContext.isResolutionRequiredForAggregatedProjects( scopesToCollect, scopesToResolve ) ) + { + for ( MavenProject aggregatedProject : session.getProjects() ) + { + if ( aggregatedProject != project ) + { + lifeCycleDependencyResolver.resolveProjectDependencies( aggregatedProject, scopesToCollect, + scopesToResolve, session, aggregating, Collections.emptySet() ); + } + } + } + } + + ArtifactFilter artifactFilter = getArtifactFilter( mojoDescriptor ); + List projectsToResolve = LifecycleDependencyResolver.getProjects( session.getCurrentProject(), + session, mojoDescriptor.isAggregator() ); + for ( MavenProject projectToResolve : projectsToResolve ) + { + projectToResolve.setArtifactFilter( artifactFilter ); + } + } + + private ArtifactFilter getArtifactFilter( MojoDescriptor mojoDescriptor ) + { + String scopeToResolve = mojoDescriptor.getDependencyResolutionRequired(); + String scopeToCollect = mojoDescriptor.getDependencyCollectionRequired(); + + List scopes = new ArrayList<>( 2 ); + if ( StringUtils.isNotEmpty( scopeToCollect ) ) + { + scopes.add( scopeToCollect ); + } + if ( StringUtils.isNotEmpty( scopeToResolve ) ) + { + scopes.add( scopeToResolve ); + } + + if ( scopes.isEmpty() ) + { + return null; + } + else + { + return new CumulativeScopeArtifactFilter( scopes ); + } + } + + public List executeForkedExecutions( MojoExecution mojoExecution, + MavenSession session, + ProjectIndex projectIndex ) throws LifecycleExecutionException + { + List forkedProjects = Collections.emptyList(); + + Map> forkedExecutions = mojoExecution.getForkedExecutions(); + + if ( !forkedExecutions.isEmpty() ) + { + eventCatapult.fire( ExecutionEvent.Type.ForkStarted, session, mojoExecution ); + + MavenProject project = session.getCurrentProject(); + + forkedProjects = new ArrayList<>( forkedExecutions.size() ); + + try + { + for ( Map.Entry> fork : forkedExecutions.entrySet() ) + { + String projectId = fork.getKey(); + + int index = projectIndex.getIndices().get( projectId ); + + MavenProject forkedProject = projectIndex.getProjects().get( projectId ); + + forkedProjects.add( forkedProject ); + + MavenProject executedProject = forkedProject.clone(); + + forkedProject.setExecutionProject( executedProject ); + + List mojoExecutions = fork.getValue(); + + if ( mojoExecutions.isEmpty() ) + { + continue; + } + + try + { + session.setCurrentProject( executedProject ); + session.getProjects().set( index, executedProject ); + projectIndex.getProjects().put( projectId, executedProject ); + + eventCatapult.fire( ExecutionEvent.Type.ForkedProjectStarted, session, mojoExecution ); + + execute( session, mojoExecutions, projectIndex ); + + eventCatapult.fire( ExecutionEvent.Type.ForkedProjectSucceeded, session, mojoExecution ); + } + catch ( LifecycleExecutionException e ) + { + eventCatapult.fire( ExecutionEvent.Type.ForkedProjectFailed, session, mojoExecution, e ); + + throw e; + } + finally + { + projectIndex.getProjects().put( projectId, forkedProject ); + session.getProjects().set( index, forkedProject ); + session.setCurrentProject( project ); + } + } + + eventCatapult.fire( ExecutionEvent.Type.ForkSucceeded, session, mojoExecution ); + } + catch ( LifecycleExecutionException e ) + { + eventCatapult.fire( ExecutionEvent.Type.ForkFailed, session, mojoExecution, e ); + + throw e; + } + } + + return forkedProjects; + } +} diff --git a/maven-core/src/main/java/org/apache/maven/caching/Clock.java b/maven-caching/src/main/java/org/apache/maven/caching/Clock.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/Clock.java rename to maven-caching/src/main/java/org/apache/maven/caching/Clock.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/DefaultPluginScanConfig.java b/maven-caching/src/main/java/org/apache/maven/caching/DefaultPluginScanConfig.java similarity index 94% rename from maven-core/src/main/java/org/apache/maven/caching/DefaultPluginScanConfig.java rename to maven-caching/src/main/java/org/apache/maven/caching/DefaultPluginScanConfig.java index 408d097cf10e..31d7cb2ec663 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/DefaultPluginScanConfig.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/DefaultPluginScanConfig.java @@ -19,7 +19,7 @@ * under the License. */ -import org.apache.maven.caching.jaxb.DirScanConfigType; +import org.apache.maven.caching.xml.config.DirScanConfig; import javax.annotation.Nonnull; @@ -56,7 +56,7 @@ public ScanConfigProperties getTagScanProperties( String tagName ) } @Override - public DirScanConfigType dto() + public DirScanConfig dto() { return null; } diff --git a/maven-core/src/main/java/org/apache/maven/caching/HttpRepositoryImpl.java b/maven-caching/src/main/java/org/apache/maven/caching/HttpRepositoryImpl.java similarity index 83% rename from maven-core/src/main/java/org/apache/maven/caching/HttpRepositoryImpl.java rename to maven-caching/src/main/java/org/apache/maven/caching/HttpRepositoryImpl.java index fbbe509bb28d..501bd38728b3 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/HttpRepositoryImpl.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/HttpRepositoryImpl.java @@ -19,6 +19,17 @@ * under the License. */ +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + import com.google.common.base.Optional; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; @@ -31,50 +42,40 @@ import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.maven.artifact.Artifact; import org.apache.maven.caching.checksum.MavenProjectInput; -import org.apache.maven.caching.jaxb.ArtifactType; -import org.apache.maven.caching.jaxb.BuildInfoType; -import org.apache.maven.caching.jaxb.CacheReportType; -import org.apache.maven.caching.jaxb.ProjectReportType; -import org.apache.maven.caching.xml.BuildInfo; +import org.apache.maven.caching.xml.Build; import org.apache.maven.caching.xml.CacheConfig; import org.apache.maven.caching.xml.CacheSource; import org.apache.maven.caching.xml.XmlService; +import org.apache.maven.caching.xml.build.Artifact; +import org.apache.maven.caching.xml.report.CacheReport; +import org.apache.maven.caching.xml.report.ProjectReport; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; - /** * HttpRepositoryImpl */ -@Component( role = RemoteArtifactsRepository.class ) +@Singleton +@Named public class HttpRepositoryImpl implements RemoteArtifactsRepository { public static final String BUILDINFO_XML = "buildinfo.xml"; public static final String CACHE_REPORT_XML = "cache-report.xml"; - @Requirement + @Inject private Logger logger; - @Requirement + @Inject LegacySupport legacySupport; - @Requirement + @Inject XmlService xmlService; - @Requirement + @Inject private CacheConfig cacheConfig; @SuppressWarnings( {"checkstyle:constantname", "checkstyle:magicnumber"} ) @@ -92,38 +93,39 @@ protected HttpClient initialValue() }; @Override - public BuildInfo findBuild( CacheContext context ) + public Build findBuild( CacheContext context ) { final String resourceUrl = getResourceUrl( context, BUILDINFO_XML ); String artifactId = context.getProject().getArtifactId(); if ( exists( artifactId, resourceUrl ) ) { final byte[] bytes = getResourceContent( resourceUrl, artifactId ); - final BuildInfoType dto = xmlService.fromBytes( BuildInfoType.class, bytes ); - return new BuildInfo( dto, CacheSource.REMOTE ); + final org.apache.maven.caching.xml.build.Build dto = xmlService.loadBuild( bytes ); + return new Build( dto, CacheSource.REMOTE ); } return null; } @Override - public byte[] getArtifactContent( CacheContext context, ArtifactType artifact ) + public byte[] getArtifactContent( CacheContext context, Artifact artifact ) { return getResourceContent( getResourceUrl( context, artifact.getFileName() ), context.getProject().getArtifactId() ); } @Override - public void saveBuildInfo( CacheResult cacheResult, BuildInfo buildInfo ) throws IOException + public void saveBuildInfo( CacheResult cacheResult, Build build ) + throws IOException { CacheContext context = cacheResult.getContext(); final String resourceUrl = getResourceUrl( cacheResult.getContext(), BUILDINFO_XML ); - putToRemoteCache( new ByteArrayInputStream( xmlService.toBytes( buildInfo.getDto() ) ), resourceUrl, + putToRemoteCache( new ByteArrayInputStream( xmlService.toBytes( build.getDto() ) ), resourceUrl, context.getProject().getArtifactId() ); } @Override - public void saveCacheReport( String buildId, MavenSession session, CacheReportType cacheReport ) throws IOException + public void saveCacheReport( String buildId, MavenSession session, CacheReport cacheReport ) throws IOException { MavenProject rootProject = session.getTopLevelProject(); final String resourceUrl = cacheConfig.getUrl() + "/" + MavenProjectInput.CACHE_IMPLMENTATION_VERSION @@ -136,7 +138,8 @@ public void saveCacheReport( String buildId, MavenSession session, CacheReportTy } @Override - public void saveArtifactFile( CacheResult cacheResult, Artifact artifact ) throws IOException + public void saveArtifactFile( CacheResult cacheResult, + org.apache.maven.artifact.Artifact artifact ) throws IOException { CacheContext context = cacheResult.getContext(); final String resourceUrl = getResourceUrl( cacheResult.getContext(), ProjectUtils.normalizedName( artifact ) ); @@ -241,20 +244,20 @@ private void putToRemoteCache( InputStream instream, String url, String logRefer } } - private final AtomicReference>> cacheReportSupplier = new AtomicReference<>(); + private final AtomicReference>> cacheReportSupplier = new AtomicReference<>(); @Override - public Optional findBaselineBuild( MavenProject project ) + public Optional findBaselineBuild( MavenProject project ) { - final Optional> cachedProjectsHolder = findCacheInfo() - .transform( CacheReportType::getProject ); + final Optional> cachedProjectsHolder = findCacheInfo() + .transform( CacheReport::getProjects ); if ( !cachedProjectsHolder.isPresent() ) { return Optional.absent(); } - Optional cachedProjectHolder = Optional.absent(); - for ( ProjectReportType p : cachedProjectsHolder.get() ) + Optional cachedProjectHolder = Optional.absent(); + for ( ProjectReport p : cachedProjectsHolder.get() ) { if ( project.getArtifactId().equals( p.getArtifactId() ) && project.getGroupId().equals( p.getGroupId() ) ) @@ -267,8 +270,8 @@ public Optional findBaselineBuild( MavenProject project ) if ( cachedProjectHolder.isPresent() ) { String url; - final ProjectReportType projectReport = cachedProjectHolder.get(); - if ( projectReport.isSetUrl() ) + final ProjectReport projectReport = cachedProjectHolder.get(); + if ( projectReport.getUrl() != null ) { url = cachedProjectHolder.get().getUrl(); logInfo( "Retrieving baseline buildinfo: " + projectReport.getUrl(), project.getArtifactId() ); @@ -285,8 +288,8 @@ public Optional findBaselineBuild( MavenProject project ) if ( exists( project.getArtifactId(), url ) ) { byte[] content = getResourceContent( url, project.getArtifactId() ); - final BuildInfoType dto = xmlService.fromBytes( BuildInfoType.class, content ); - return Optional.of( new BuildInfo( dto, CacheSource.REMOTE ) ); + final org.apache.maven.caching.xml.build.Build dto = xmlService.loadBuild( content ); + return Optional.of( new Build( dto, CacheSource.REMOTE ) ); } else { @@ -304,17 +307,17 @@ public Optional findBaselineBuild( MavenProject project ) return Optional.absent(); } - private Optional findCacheInfo() + private Optional findCacheInfo() { - Supplier> candidate = Suppliers.memoize( () -> + Supplier> candidate = Suppliers.memoize( () -> { try { logInfo( "Downloading baseline cache report from: " + cacheConfig.getBaselineCacheUrl(), "DEBUG" ); byte[] content = getResourceContent( cacheConfig.getBaselineCacheUrl(), "cache-info" ); - CacheReportType cacheReportType = xmlService.fromBytes( CacheReportType.class, content ); + CacheReport cacheReportType = xmlService.loadCacheReport( content ); return Optional.of( cacheReportType ); } catch ( Exception e ) diff --git a/maven-core/src/main/java/org/apache/maven/caching/LocalArtifactsRepository.java b/maven-caching/src/main/java/org/apache/maven/caching/LocalArtifactsRepository.java similarity index 80% rename from maven-core/src/main/java/org/apache/maven/caching/LocalArtifactsRepository.java rename to maven-caching/src/main/java/org/apache/maven/caching/LocalArtifactsRepository.java index c5916b2c64ba..7a0530d1cafa 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/LocalArtifactsRepository.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/LocalArtifactsRepository.java @@ -20,9 +20,9 @@ */ import com.google.common.base.Optional; -import org.apache.maven.caching.jaxb.ArtifactType; -import org.apache.maven.caching.xml.BuildInfo; +import org.apache.maven.caching.xml.Build; import org.apache.maven.caching.xml.CacheSource; +import org.apache.maven.caching.xml.build.Artifact; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; @@ -37,11 +37,11 @@ public interface LocalArtifactsRepository extends ArtifactsRepository void beforeSave( CacheContext environment ) throws IOException; - Path getArtifactFile( CacheContext context, CacheSource source, ArtifactType artifact ) throws IOException; + Path getArtifactFile( CacheContext context, CacheSource source, Artifact artifact ) throws IOException; void clearCache( CacheContext context ); - Optional findBestMatchingBuild( MavenSession session, Dependency dependency ) throws IOException; + Optional findBestMatchingBuild( MavenSession session, Dependency dependency ) throws IOException; - BuildInfo findLocalBuild( CacheContext context ) throws IOException; + Build findLocalBuild( CacheContext context ) throws IOException; } diff --git a/maven-core/src/main/java/org/apache/maven/caching/LocalRepositoryImpl.java b/maven-caching/src/main/java/org/apache/maven/caching/LocalRepositoryImpl.java similarity index 81% rename from maven-core/src/main/java/org/apache/maven/caching/LocalRepositoryImpl.java rename to maven-caching/src/main/java/org/apache/maven/caching/LocalRepositoryImpl.java index ec75b476e4b4..36284dd3fcd0 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/LocalRepositoryImpl.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/LocalRepositoryImpl.java @@ -19,6 +19,26 @@ * under the License. */ +import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.cache.CacheBuilder; @@ -30,38 +50,19 @@ import com.google.common.collect.Ordering; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.tuple.Pair; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.caching.jaxb.ArtifactType; -import org.apache.maven.caching.jaxb.BuildInfoType; -import org.apache.maven.caching.jaxb.CacheReportType; -import org.apache.maven.caching.xml.BuildInfo; +import org.apache.maven.caching.xml.Build; import org.apache.maven.caching.xml.CacheConfig; import org.apache.maven.caching.xml.CacheSource; import org.apache.maven.caching.xml.XmlService; +import org.apache.maven.caching.xml.build.Artifact; +import org.apache.maven.caching.xml.build.Scm; +import org.apache.maven.caching.xml.report.CacheReport; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; -import java.io.File; -import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; - import static java.nio.file.StandardOpenOption.CREATE; import static java.nio.file.StandardOpenOption.CREATE_NEW; import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; @@ -75,7 +76,8 @@ /** * LocalRepositoryImpl */ -@Component( role = LocalArtifactsRepository.class ) +@Singleton +@Named public class LocalRepositoryImpl implements LocalArtifactsRepository { @@ -86,45 +88,46 @@ public class LocalRepositoryImpl implements LocalArtifactsRepository private static final long ONE_DAY_MILLIS = DAYS.toMillis( 1 ); private static final String EMPTY = ""; private static final LastModifiedComparator LAST_MODIFIED_COMPARATOR = new LastModifiedComparator(); - private static final Function, Long> GET_LAST_MODIFIED = + private static final Function, Long> GET_LAST_MODIFIED = pair -> pair.getRight().lastModified(); - @Requirement + @Inject private Logger logger; - @Requirement + @Inject private LegacySupport legacySupport; - @Requirement + @Inject private RemoteArtifactsRepository remoteRepository; - @Requirement + @Inject private XmlService xmlService; - @Requirement + @Inject private CacheConfig cacheConfig; - private final LoadingCache, Optional> bestBuildCache = - CacheBuilder.newBuilder().build( - CacheLoader.from( new Function, Optional>() + private final LoadingCache, + Optional> bestBuildCache = + CacheBuilder.newBuilder().build( CacheLoader.from( new Function, + Optional>() + { + @Override + public Optional apply( Pair input ) + { + try { - @Override - public Optional apply( Pair input ) - { - try - { - return findBestMatchingBuildImpl( input ); - } - catch ( IOException e ) - { - logger.error( "Cannot find dependency in cache", e ); - return Optional.absent(); - } - } - } ) ); + return findBestMatchingBuildImpl( input ); + } + catch ( IOException e ) + { + logger.error( "Cannot find dependency in cache", e ); + return Optional.absent(); + } + } + } ) ); @Override - public BuildInfo findLocalBuild( CacheContext context ) throws IOException + public Build findLocalBuild( CacheContext context ) throws IOException { Path localBuildInfoPath = localBuildPath( context, BUILDINFO_XML, false ); logDebug( context, "Checking local build info: " + localBuildInfoPath ); @@ -133,8 +136,8 @@ public BuildInfo findLocalBuild( CacheContext context ) throws IOException logInfo( context, "Local build found by checksum " + context.getInputInfo().getChecksum() ); try { - final BuildInfoType dto = xmlService.fromFile( BuildInfoType.class, localBuildInfoPath.toFile() ); - return new BuildInfo( dto, CacheSource.LOCAL ); + org.apache.maven.caching.xml.build.Build dto = xmlService.loadBuild( localBuildInfoPath.toFile() ); + return new Build( dto, CacheSource.LOCAL ); } catch ( Exception e ) { @@ -146,7 +149,7 @@ public BuildInfo findLocalBuild( CacheContext context ) throws IOException } @Override - public BuildInfo findBuild( CacheContext context ) throws IOException + public Build findBuild( CacheContext context ) throws IOException { Path buildInfoPath = remoteBuildPath( context, BUILDINFO_XML ); @@ -157,8 +160,8 @@ public BuildInfo findBuild( CacheContext context ) throws IOException logInfo( context, "Downloaded build found by checksum " + context.getInputInfo().getChecksum() ); try { - final BuildInfoType dto = xmlService.fromFile( BuildInfoType.class, buildInfoPath.toFile() ); - return new BuildInfo( dto, CacheSource.REMOTE ); + org.apache.maven.caching.xml.build.Build dto = xmlService.loadBuild( buildInfoPath.toFile() ); + return new Build( dto, CacheSource.REMOTE ); } catch ( Exception e ) { @@ -201,18 +204,18 @@ else if ( now > created + ONE_DAY_MILLIS && now < lastModified + ONE_DAY_MILLIS } } - final BuildInfo buildInfo = remoteRepository.findBuild( context ); - if ( buildInfo != null ) + final Build build = remoteRepository.findBuild( context ); + if ( build != null ) { logInfo( context, "Build info downloaded from remote repo, saving to: " + buildInfoPath ); Files.createDirectories( buildInfoPath.getParent() ); - Files.write( buildInfoPath, xmlService.toBytes( buildInfo.getDto() ), CREATE_NEW ); + Files.write( buildInfoPath, xmlService.toBytes( build.getDto() ), CREATE_NEW ); } else { FileUtils.touch( lookupInfoPath.toFile() ); } - return buildInfo; + return build; } catch ( Exception e ) { @@ -242,10 +245,11 @@ public void clearCache( CacheContext context ) cacheDirs.add( dir ); } } - if ( cacheDirs.size() > cacheConfig.getMaxLocalBuildsCached() ) + int maxLocalBuildsCached = cacheConfig.getMaxLocalBuildsCached() - 1; + if ( cacheDirs.size() > maxLocalBuildsCached ) { Collections.sort( cacheDirs, LAST_MODIFIED_COMPARATOR ); - for ( Path dir : cacheDirs.subList( 0, cacheDirs.size() - cacheConfig.getMaxLocalBuildsCached() ) ) + for ( Path dir : cacheDirs.subList( 0, cacheDirs.size() - maxLocalBuildsCached ) ) { FileUtils.deleteDirectory( dir.toFile() ); } @@ -266,13 +270,15 @@ public void clearCache( CacheContext context ) } @Override - public Optional findBestMatchingBuild( MavenSession session, Dependency dependency ) + public Optional findBestMatchingBuild( + MavenSession session, Dependency dependency ) { return bestBuildCache.getUnchecked( Pair.of( session, dependency ) ); } - private Optional findBestMatchingBuildImpl( Pair dependencySession ) + private Optional findBestMatchingBuildImpl( + Pair dependencySession ) throws IOException { final MavenSession session = dependencySession.getLeft(); @@ -280,7 +286,8 @@ private Optional findBestMatchingBuildImpl( Pair, Pair> filesByVersion = ArrayListMultimap.create(); + final Multimap, Pair> + filesByVersion = ArrayListMultimap.create(); Files.walkFileTree( artifactCacheDir, new SimpleFileVisitor() { @@ -292,9 +299,9 @@ public FileVisitResult visitFile( Path o, BasicFileAttributes basicFileAttribute { try { - final BuildInfoType dto = xmlService.fromFile( BuildInfoType.class, file ); - final Pair buildInfoAndFile = Pair.of( new BuildInfo( dto, CacheSource.LOCAL ), - file ); + final org.apache.maven.caching.xml.build.Build dto = xmlService.loadBuild( file ); + final Pair buildInfoAndFile = + Pair.of( new Build( dto, CacheSource.LOCAL ), file ); final String cachedVersion = dto.getArtifact().getVersion(); final String cachedBranch = getScmRef( dto.getScm() ); filesByVersion.put( Pair.of( cachedVersion, cachedBranch ), buildInfoAndFile ); @@ -324,7 +331,7 @@ public FileVisitResult visitFile( Path o, BasicFileAttributes basicFileAttribute final String currentRef = getScmRef( ProjectUtils.readGitInfo( session ) ); // first lets try by branch and version - Collection> bestMatched = new LinkedList<>(); + Collection> bestMatched = new LinkedList<>(); if ( isNotBlank( currentRef ) ) { bestMatched = filesByVersion.get( Pair.of( dependency.getVersion(), currentRef ) ); @@ -345,16 +352,16 @@ public FileVisitResult visitFile( Path o, BasicFileAttributes basicFileAttribute bestMatched = filesByVersion.values(); } - List> orderedFiles = Ordering.natural().onResultOf( + List> orderedFiles = Ordering.natural().onResultOf( GET_LAST_MODIFIED ).reverse().sortedCopy( bestMatched ); return Optional.of( orderedFiles.get( 0 ).getLeft() ); } - private String getScmRef( BuildInfoType.Scm scm ) + private String getScmRef( Scm scm ) { if ( scm != null ) { - return scm.isSetSourceBranch() ? scm.getSourceBranch() : scm.getRevision(); + return scm.getSourceBranch() != null ? scm.getSourceBranch() : scm.getRevision(); } else { @@ -363,7 +370,7 @@ private String getScmRef( BuildInfoType.Scm scm ) } @Override - public Path getArtifactFile( CacheContext context, CacheSource source, ArtifactType artifact ) throws IOException + public Path getArtifactFile( CacheContext context, CacheSource source, Artifact artifact ) throws IOException { if ( source == CacheSource.LOCAL ) { @@ -391,20 +398,21 @@ public void beforeSave( CacheContext environment ) } @Override - public void saveBuildInfo( CacheResult cacheResult, BuildInfo buildInfo ) throws IOException + public void saveBuildInfo( CacheResult cacheResult, Build build ) + throws IOException { final Path path = localBuildPath( cacheResult.getContext(), BUILDINFO_XML, true ); - Files.write( path, xmlService.toBytes( buildInfo.getDto() ), TRUNCATE_EXISTING, CREATE ); + Files.write( path, xmlService.toBytes( build.getDto() ), TRUNCATE_EXISTING, CREATE ); if ( cacheConfig.isRemoteCacheEnabled() && cacheConfig.isSaveToRemote() && !cacheResult.isFinal() ) { - remoteRepository.saveBuildInfo( cacheResult, buildInfo ); + remoteRepository.saveBuildInfo( cacheResult, build ); } } @Override - public void saveCacheReport( String buildId, MavenSession session, CacheReportType cacheReport ) throws IOException + public void saveCacheReport( String buildId, MavenSession session, CacheReport cacheReport ) throws IOException { - Path path = Paths.get( getMultimoduleRoot( session ), "target", "maven-incremental" ); + Path path = getMultimoduleRoot( session ).resolve( "target" ).resolve( "maven-incremental" ); Files.createDirectories( path ); Files.write( path.resolve( "cache-report." + buildId + ".xml" ), xmlService.toBytes( cacheReport ), TRUNCATE_EXISTING, CREATE ); @@ -416,7 +424,8 @@ public void saveCacheReport( String buildId, MavenSession session, CacheReportTy } @Override - public void saveArtifactFile( CacheResult cacheResult, Artifact artifact ) throws IOException + public void saveArtifactFile( CacheResult cacheResult, org.apache.maven.artifact.Artifact artifact ) + throws IOException { // safe artifacts to cache File artifactFile = artifact.getFile(); diff --git a/maven-core/src/main/java/org/apache/maven/caching/MojoExecutionManager.java b/maven-caching/src/main/java/org/apache/maven/caching/MojoExecutionManager.java similarity index 89% rename from maven-core/src/main/java/org/apache/maven/caching/MojoExecutionManager.java rename to maven-caching/src/main/java/org/apache/maven/caching/MojoExecutionManager.java index 9c07e5815e69..961a9c4a49f2 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/MojoExecutionManager.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/MojoExecutionManager.java @@ -20,11 +20,11 @@ */ import org.apache.commons.lang3.StringUtils; -import org.apache.maven.caching.jaxb.CompletedExecutionType; -import org.apache.maven.caching.jaxb.TrackedPropertyType; -import org.apache.maven.caching.xml.BuildInfo; import org.apache.maven.caching.xml.CacheConfig; import org.apache.maven.caching.xml.DtoUtils; +import org.apache.maven.caching.xml.Build; +import org.apache.maven.caching.xml.config.TrackedProperty; +import org.apache.maven.caching.xml.build.CompletedExecution; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.Mojo; import org.apache.maven.plugin.MojoCheker; @@ -47,21 +47,21 @@ public class MojoExecutionManager implements MojoCheker private final long createdTimestamp; private final Logger logger; private final MavenProject project; - private final BuildInfo buildInfo; + private final Build build; private final AtomicBoolean consistent; private final CacheController cacheController; private final CacheConfig cacheConfig; public MojoExecutionManager( MavenProject project, CacheController cacheController, - BuildInfo buildInfo, + Build build, AtomicBoolean consistent, Logger logger, CacheConfig cacheConfig ) { this.createdTimestamp = System.currentTimeMillis(); this.project = project; this.cacheController = cacheController; - this.buildInfo = buildInfo; + this.build = build; this.consistent = consistent; this.logger = logger; this.cacheConfig = cacheConfig; @@ -86,7 +86,7 @@ public boolean needCheck( MojoExecution mojoExecution, MavenSession session ) public boolean check( MojoExecution execution, Mojo mojo, MavenSession session ) { - final CompletedExecutionType completedExecution = buildInfo.findMojoExecutionInfo( execution ); + final CompletedExecution completedExecution = build.findMojoExecutionInfo( execution ); final String fullGoalName = execution.getMojoDescriptor().getFullGoalName(); if ( completedExecution != null && !isParamsMatched( project, execution, mojo, completedExecution ) ) @@ -114,17 +114,17 @@ public boolean check( MojoExecution execution, Mojo mojo, MavenSession session ) private boolean isParamsMatched( MavenProject project, MojoExecution mojoExecution, Mojo mojo, - CompletedExecutionType completedExecution ) + CompletedExecution completedExecution ) { - List tracked = cacheConfig.getTrackedProperties( mojoExecution ); + List tracked = cacheConfig.getTrackedProperties( mojoExecution ); - for ( TrackedPropertyType trackedProperty : tracked ) + for ( TrackedProperty trackedProperty : tracked ) { final String propertyName = trackedProperty.getPropertyName(); String expectedValue = DtoUtils.findPropertyValue( propertyName, completedExecution ); - if ( expectedValue == null && trackedProperty.isSetDefaultValue() ) + if ( expectedValue == null && trackedProperty.getDefaultValue() != null ) { expectedValue = trackedProperty.getDefaultValue(); } diff --git a/maven-core/src/main/java/org/apache/maven/caching/MojoParametersListener.java b/maven-caching/src/main/java/org/apache/maven/caching/MojoParametersListener.java similarity index 93% rename from maven-core/src/main/java/org/apache/maven/caching/MojoParametersListener.java rename to maven-caching/src/main/java/org/apache/maven/caching/MojoParametersListener.java index 8750a8dcca67..78c81befdfdd 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/MojoParametersListener.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/MojoParametersListener.java @@ -19,30 +19,32 @@ * under the License. */ +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + import org.apache.maven.execution.MojoExecutionEvent; import org.apache.maven.execution.MojoExecutionListener; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - /** * MojoParametersListener */ -@Component( role = MojoExecutionListener.class, - hint = "MojoParametersListener" ) +@Singleton +@Named public class MojoParametersListener implements MojoExecutionListener { private final ConcurrentMap> projectExecutions = new ConcurrentHashMap<>(); - @Requirement + @Inject private Logger logger; @Override diff --git a/maven-core/src/main/java/org/apache/maven/caching/PluginScanConfig.java b/maven-caching/src/main/java/org/apache/maven/caching/PluginScanConfig.java similarity index 93% rename from maven-core/src/main/java/org/apache/maven/caching/PluginScanConfig.java rename to maven-caching/src/main/java/org/apache/maven/caching/PluginScanConfig.java index 93bcccba0b1c..da5767767f8d 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/PluginScanConfig.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/PluginScanConfig.java @@ -19,7 +19,7 @@ * under the License. */ -import org.apache.maven.caching.jaxb.DirScanConfigType; +import org.apache.maven.caching.xml.config.DirScanConfig; import javax.annotation.Nonnull; @@ -37,5 +37,5 @@ public interface PluginScanConfig @Nonnull ScanConfigProperties getTagScanProperties( String tagName ); - DirScanConfigType dto(); + DirScanConfig dto(); } diff --git a/maven-core/src/main/java/org/apache/maven/caching/PluginScanConfigImpl.java b/maven-caching/src/main/java/org/apache/maven/caching/PluginScanConfigImpl.java similarity index 75% rename from maven-core/src/main/java/org/apache/maven/caching/PluginScanConfigImpl.java rename to maven-caching/src/main/java/org/apache/maven/caching/PluginScanConfigImpl.java index 87791905100d..34f71802e1f7 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/PluginScanConfigImpl.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/PluginScanConfigImpl.java @@ -20,9 +20,9 @@ */ import org.apache.commons.lang3.StringUtils; -import org.apache.maven.caching.jaxb.DirScanConfigType; -import org.apache.maven.caching.jaxb.TagNameType; -import org.apache.maven.caching.jaxb.TagScanConfigType; +import org.apache.maven.caching.xml.config.DirScanConfig; +import org.apache.maven.caching.xml.config.TagExclude; +import org.apache.maven.caching.xml.config.TagScanConfig; import javax.annotation.Nonnull; import java.util.List; @@ -33,9 +33,9 @@ public class PluginScanConfigImpl implements PluginScanConfig { - private final DirScanConfigType dto; + private final DirScanConfig dto; - public PluginScanConfigImpl( DirScanConfigType scanConfig ) + public PluginScanConfigImpl( DirScanConfig scanConfig ) { this.dto = scanConfig; } @@ -52,18 +52,18 @@ public boolean accept( String tagName ) // include or exclude is a choice element, could be only obe property set //noinspection ConstantConditions - final List includes = dto.getInclude(); + final List includes = dto.getIncludes(); if ( !includes.isEmpty() ) { return findTagScanProperties( tagName ) != null; } - return !contains( dto.getExclude(), tagName ); + return !contains( dto.getExcludes(), tagName ); } - private boolean contains( List excludes, String tagName ) + private boolean contains( List excludes, String tagName ) { - for ( TagNameType exclude : excludes ) + for ( TagExclude exclude : excludes ) { if ( StringUtils.equals( exclude.getTagName(), tagName ) ) { @@ -83,7 +83,7 @@ public PluginScanConfig mergeWith( final PluginScanConfig overrideConfig ) return overrideConfig; } - final DirScanConfigType override = overrideConfig.dto(); + final DirScanConfig override = overrideConfig.dto(); if ( override == null ) { return this; @@ -94,8 +94,8 @@ public PluginScanConfig mergeWith( final PluginScanConfig overrideConfig ) return overrideConfig; } - DirScanConfigType merged = new DirScanConfigType(); - if ( override.isSetMode() ) + DirScanConfig merged = new DirScanConfig(); + if ( override.getMode() != null ) { merged.setMode( override.getMode() ); } @@ -104,11 +104,11 @@ public PluginScanConfig mergeWith( final PluginScanConfig overrideConfig ) merged.setMode( dto.getMode() ); } - merged.getExclude().addAll( dto.getExclude() ); - merged.getExclude().addAll( override.getExclude() ); + merged.getExcludes().addAll( dto.getExcludes() ); + merged.getExcludes().addAll( override.getExcludes() ); - merged.getInclude().addAll( dto.getInclude() ); - merged.getInclude().addAll( override.getInclude() ); + merged.getIncludes().addAll( dto.getIncludes() ); + merged.getIncludes().addAll( override.getIncludes() ); return new PluginScanConfigImpl( merged ); } @@ -121,22 +121,22 @@ public ScanConfigProperties getTagScanProperties( String tagName ) } @Override - public DirScanConfigType dto() + public DirScanConfig dto() { return dto; } private ScanConfigProperties findTagScanProperties( String tagName ) { - ScanConfigProperties scanConfigProperties = findConfigByName( tagName, dto.getInclude() ); + ScanConfigProperties scanConfigProperties = findConfigByName( tagName, dto.getIncludes() ); if ( scanConfigProperties == null ) { - scanConfigProperties = findConfigByName( tagName, dto.getTagScanConfig() ); + scanConfigProperties = findConfigByName( tagName, dto.getTagScanConfigs() ); } return scanConfigProperties; } - private ScanConfigProperties findConfigByName( String tagName, List configs ) + private ScanConfigProperties findConfigByName( String tagName, List configs ) { if ( configs == null ) @@ -144,7 +144,7 @@ private ScanConfigProperties findConfigByName( String tagName, List findBaselineBuild( MavenProject project ); + Optional findBaselineBuild( MavenProject project ); } diff --git a/maven-core/src/main/java/org/apache/maven/caching/RestoreStatus.java b/maven-caching/src/main/java/org/apache/maven/caching/RestoreStatus.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/RestoreStatus.java rename to maven-caching/src/main/java/org/apache/maven/caching/RestoreStatus.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/ScanConfigProperties.java b/maven-caching/src/main/java/org/apache/maven/caching/ScanConfigProperties.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/ScanConfigProperties.java rename to maven-caching/src/main/java/org/apache/maven/caching/ScanConfigProperties.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/ZipUtils.java b/maven-caching/src/main/java/org/apache/maven/caching/ZipUtils.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/ZipUtils.java rename to maven-caching/src/main/java/org/apache/maven/caching/ZipUtils.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/checksum/DependencyNotResolvedException.java b/maven-caching/src/main/java/org/apache/maven/caching/checksum/DependencyNotResolvedException.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/checksum/DependencyNotResolvedException.java rename to maven-caching/src/main/java/org/apache/maven/caching/checksum/DependencyNotResolvedException.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/checksum/DigestUtils.java b/maven-caching/src/main/java/org/apache/maven/caching/checksum/DigestUtils.java similarity index 90% rename from maven-core/src/main/java/org/apache/maven/caching/checksum/DigestUtils.java rename to maven-caching/src/main/java/org/apache/maven/caching/checksum/DigestUtils.java index e837da1f8587..f9fc0dd608bb 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/checksum/DigestUtils.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/checksum/DigestUtils.java @@ -22,7 +22,7 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.apache.maven.caching.hash.HashChecksum; -import org.apache.maven.caching.jaxb.DigestItemType; +import org.apache.maven.caching.xml.build.DigestItem; import org.mozilla.universalchardet.UniversalDetector; import java.io.IOException; @@ -54,15 +54,15 @@ protected UniversalDetector initialValue() }; - public static DigestItemType pom( HashChecksum checksum, String effectivePom ) + public static DigestItem pom( HashChecksum checksum, String effectivePom ) { return item( "pom", effectivePom, checksum.update( effectivePom.getBytes( UTF_8 ) ) ); } - public static DigestItemType file( HashChecksum checksum, Path basedir, Path file ) throws IOException + public static DigestItem file( HashChecksum checksum, Path basedir, Path file ) throws IOException { byte[] content = Files.readAllBytes( file ); - DigestItemType item = item( "file", normalize( basedir, file ), checksum.update( content ) ); + DigestItem item = item( "file", normalize( basedir, file ), checksum.update( content ) ); try { populateContentDetails( file, content, item ); @@ -74,7 +74,7 @@ public static DigestItemType file( HashChecksum checksum, Path basedir, Path fil return item; } - private static void populateContentDetails( Path file, byte[] content, DigestItemType item ) throws IOException + private static void populateContentDetails( Path file, byte[] content, DigestItem item ) throws IOException { String contentType = Files.probeContentType( file ); if ( contentType != null ) @@ -136,7 +136,7 @@ private static boolean isBinary( String contentType ) ); } - public static DigestItemType dependency( HashChecksum checksum, String key, String hash ) + public static DigestItem dependency( HashChecksum checksum, String key, String hash ) { return item( "dependency", key, checksum.update( hash ) ); } @@ -158,9 +158,9 @@ private static Path relativize( Path basedirPath, Path file ) } } - private static DigestItemType item( String type, String reference, String hash ) + private static DigestItem item( String type, String reference, String hash ) { - final DigestItemType item = new DigestItemType(); + final DigestItem item = new DigestItem(); item.setType( type ); item.setValue( reference ); item.setHash( hash ); diff --git a/maven-core/src/main/java/org/apache/maven/caching/checksum/KeyUtils.java b/maven-caching/src/main/java/org/apache/maven/caching/checksum/KeyUtils.java similarity index 93% rename from maven-core/src/main/java/org/apache/maven/caching/checksum/KeyUtils.java rename to maven-caching/src/main/java/org/apache/maven/caching/checksum/KeyUtils.java index 04d9207cb0dc..3fa9d5d8744d 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/checksum/KeyUtils.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/checksum/KeyUtils.java @@ -20,8 +20,7 @@ */ import org.apache.commons.lang3.StringUtils; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.caching.jaxb.ArtifactType; +import org.apache.maven.caching.xml.build.Artifact; import org.apache.maven.model.Dependency; import org.apache.maven.project.MavenProject; @@ -48,14 +47,14 @@ public static String getVersionlessDependencyKey( Dependency dependency ) return StringUtils.joinWith( SEPARATOR, dependency.getGroupId(), dependency.getArtifactId() ); } - public static String getArtifactKey( ArtifactType artifact ) + public static String getArtifactKey( Artifact artifact ) { return artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getType() + ( artifact.getClassifier() != null ? ":" + artifact.getClassifier() : "" ) + ":" + artifact.getVersion(); } - public static String getArtifactKey( Artifact artifact ) + public static String getArtifactKey( org.apache.maven.artifact.Artifact artifact ) { return artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getType() + ( artifact.getClassifier() != null ? ":" + artifact.getClassifier() : "" ) diff --git a/maven-core/src/main/java/org/apache/maven/caching/checksum/MavenProjectInput.java b/maven-caching/src/main/java/org/apache/maven/caching/checksum/MavenProjectInput.java similarity index 92% rename from maven-core/src/main/java/org/apache/maven/caching/checksum/MavenProjectInput.java rename to maven-caching/src/main/java/org/apache/maven/caching/checksum/MavenProjectInput.java index 8e5873ce7dcd..69c79d586ba2 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/checksum/MavenProjectInput.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/checksum/MavenProjectInput.java @@ -19,7 +19,6 @@ * under the License. */ - import com.google.common.base.Optional; import com.google.common.collect.Iterables; import org.apache.commons.lang3.StringUtils; @@ -33,17 +32,18 @@ import org.apache.maven.caching.ProjectUtils; import org.apache.maven.caching.RemoteArtifactsRepository; import org.apache.maven.caching.ScanConfigProperties; +import org.apache.maven.caching.hash.HashFactory; import org.apache.maven.caching.hash.HashAlgorithm; import org.apache.maven.caching.hash.HashChecksum; -import org.apache.maven.caching.hash.HashFactory; -import org.apache.maven.caching.jaxb.DigestItemType; -import org.apache.maven.caching.jaxb.ProjectsInputInfoType; -import org.apache.maven.caching.xml.BuildInfo; +import org.apache.maven.caching.xml.Build; import org.apache.maven.caching.xml.CacheConfig; import org.apache.maven.caching.xml.DtoUtils; +import org.apache.maven.caching.xml.build.DigestItem; +import org.apache.maven.caching.xml.build.ProjectsInputInfo; +import org.apache.maven.caching.xml.config.Exclude; +import org.apache.maven.caching.xml.config.Include; import org.apache.maven.execution.MavenSession; import org.apache.maven.lifecycle.internal.ProjectIndex; -import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; @@ -94,7 +94,6 @@ import static org.apache.commons.lang3.StringUtils.stripToEmpty; import static org.apache.maven.caching.ProjectUtils.isBuilding; import static org.apache.maven.caching.ProjectUtils.isSnapshot; -import static org.apache.maven.caching.jaxb.PathSetType.Include; /** * MavenProjectInput @@ -138,7 +137,7 @@ public class MavenProjectInput private final RepositorySystem repoSystem; private final ArtifactHandlerManager artifactHandlerManager; private final CacheConfig config; - private final ConcurrentMap projectArtifactsByKey; + private final ConcurrentMap projectArtifactsByKey; private final PathIgnoringCaseComparator fileComparator; private final DependencyComparator dependencyComparator; private final List filteredOutPaths; @@ -152,7 +151,7 @@ public MavenProjectInput( MavenProject project, MavenSession session, CacheConfig config, ProjectIndex projectIndex, - ConcurrentMap artifactsByKey, + ConcurrentMap artifactsByKey, RepositorySystem repoSystem, ArtifactHandlerManager artifactHandlerManager, Logger logger, @@ -175,13 +174,14 @@ public MavenProjectInput( MavenProject project, this.processPlugins = Boolean.parseBoolean( properties.getProperty( CACHE_PROCESS_PLUGINS, config.isProcessPlugins() ) ); - Build build = project.getBuild(); + org.apache.maven.model.Build build = project.getBuild(); filteredOutPaths = new ArrayList<>( Arrays.asList( normalizedPath( build.getDirectory() ), // target by default normalizedPath( build.getOutputDirectory() ), normalizedPath( build.getTestOutputDirectory() ) ) ); - for ( String excludePath : config.getGlobalExcludePaths() ) + List excludes = config.getGlobalExcludePaths(); + for ( Exclude excludePath : excludes ) { - filteredOutPaths.add( Paths.get( excludePath ) ); + filteredOutPaths.add( Paths.get( excludePath.getValue() ) ); } for ( String propertyName : properties.stringPropertyNames() ) @@ -196,30 +196,30 @@ public MavenProjectInput( MavenProject project, this.dependencyComparator = new DependencyComparator(); } - public ProjectsInputInfoType calculateChecksum( HashFactory hashFactory ) throws IOException + public ProjectsInputInfo calculateChecksum( HashFactory hashFactory ) throws IOException { long time = Clock.time(); final String effectivePom = getEffectivePom( project.getOriginalEffectiveModel() ); final SortedSet inputFiles = getInputFiles(); - final SortedMap dependenciesChecksum = getMutableDependencies(); + final SortedMap dependenciesChecksum = getMutableDependencies(); final long inputTime = Clock.elapsed( time ); time = Clock.time(); // hash items: effective pom + input files + dependencies final int count = 1 + inputFiles.size() + dependenciesChecksum.size(); - final List items = new ArrayList<>( count ); + final List items = new ArrayList<>( count ); final HashChecksum checksum = hashFactory.createChecksum( count ); - Optional baselineHolder = Optional.absent(); + Optional baselineHolder = Optional.absent(); if ( config.isBaselineDiffEnabled() ) { baselineHolder = remoteCache.findBaselineBuild( project ).transform( b -> b.getDto().getProjectsInputInfo() ); } - DigestItemType effectivePomChecksum = DigestUtils.pom( checksum, effectivePom ); + DigestItem effectivePomChecksum = DigestUtils.pom( checksum, effectivePom ); items.add( effectivePomChecksum ); final boolean compareWithBaseline = config.isBaselineDiffEnabled() && baselineHolder.isPresent(); if ( compareWithBaseline ) @@ -230,7 +230,7 @@ public ProjectsInputInfoType calculateChecksum( HashFactory hashFactory ) throws boolean sourcesMatched = true; for ( Path file : inputFiles ) { - DigestItemType fileDigest = DigestUtils.file( checksum, baseDirPath, file ); + DigestItem fileDigest = DigestUtils.file( checksum, baseDirPath, file ); items.add( fileDigest ); if ( compareWithBaseline ) { @@ -243,9 +243,9 @@ public ProjectsInputInfoType calculateChecksum( HashFactory hashFactory ) throws } boolean dependenciesMatched = true; - for ( Map.Entry entry : dependenciesChecksum.entrySet() ) + for ( Map.Entry entry : dependenciesChecksum.entrySet() ) { - DigestItemType dependencyDigest = + DigestItem dependencyDigest = DigestUtils.dependency( checksum, entry.getKey(), entry.getValue().getHash() ); items.add( dependencyDigest ); if ( compareWithBaseline ) @@ -259,15 +259,15 @@ public ProjectsInputInfoType calculateChecksum( HashFactory hashFactory ) throws logInfo( "Dependencies: " + ( dependenciesMatched ? "MATCHED" : "OUT OF DATE" ) ); } - final ProjectsInputInfoType projectsInputInfoType = new ProjectsInputInfoType(); + final ProjectsInputInfo projectsInputInfoType = new ProjectsInputInfo(); projectsInputInfoType.setChecksum( checksum.digest() ); - projectsInputInfoType.getItem().addAll( items ); + projectsInputInfoType.getItems().addAll( items ); final long checksumTime = Clock.elapsed( time ); if ( logger.isDebugEnabled() ) { - for ( DigestItemType item : projectsInputInfoType.getItem() ) + for ( DigestItem item : projectsInputInfoType.getItems() ) { logger.debug( "Hash calculated, item: " + item.getType() + ", hash: " + item.getHash() ); } @@ -279,10 +279,10 @@ public ProjectsInputInfoType calculateChecksum( HashFactory hashFactory ) throws return projectsInputInfoType; } - private void checkEffectivePomMatch( ProjectsInputInfoType baselineBuild, DigestItemType effectivePomChecksum ) + private void checkEffectivePomMatch( ProjectsInputInfo baselineBuild, DigestItem effectivePomChecksum ) { - Optional pomHolder = Optional.absent(); - for ( DigestItemType it : baselineBuild.getItem() ) + Optional pomHolder = Optional.absent(); + for ( DigestItem it : baselineBuild.getItems() ) { if ( it.getType().equals( "pom" ) ) { @@ -293,7 +293,7 @@ private void checkEffectivePomMatch( ProjectsInputInfoType baselineBuild, Digest if ( pomHolder.isPresent() ) { - DigestItemType pomItem = pomHolder.get(); + DigestItem pomItem = pomHolder.get(); final boolean matches = StringUtils.equals( pomItem.getHash(), effectivePomChecksum.getHash() ); if ( !matches ) { @@ -305,10 +305,10 @@ private void checkEffectivePomMatch( ProjectsInputInfoType baselineBuild, Digest } } - private boolean checkItemMatchesBaseline( ProjectsInputInfoType baselineBuild, DigestItemType fileDigest ) + private boolean checkItemMatchesBaseline( ProjectsInputInfo baselineBuild, DigestItem fileDigest ) { - Optional baselineFileDigest = Optional.absent(); - for ( DigestItemType it : baselineBuild.getItem() ) + Optional baselineFileDigest = Optional.absent(); + for ( DigestItem it : baselineBuild.getItems() ) { if ( it.getType().equals( fileDigest.getType() ) && fileDigest.getValue().equals( it.getValue().trim() ) ) @@ -360,7 +360,7 @@ private String getEffectivePom( Model prototype ) throws IOException List plugins = normalizePlugins( prototype.getBuild().getPlugins() ); - Build build = new Build(); + org.apache.maven.model.Build build = new org.apache.maven.model.Build(); build.setPluginManagement( pluginManagement ); build.setPlugins( plugins ); @@ -393,7 +393,7 @@ private SortedSet getInputFiles() HashSet visitedDirs = new HashSet<>(); ArrayList collectedFiles = new ArrayList<>(); - Build build = project.getBuild(); + org.apache.maven.model.Build build = project.getBuild(); final boolean recursive = true; startWalk( Paths.get( build.getSourceDirectory() ), dirGlob, recursive, collectedFiles, visitedDirs ); @@ -756,10 +756,10 @@ private boolean isFilteredOutSubpath( Path path ) return false; } - private SortedMap getMutableDependencies() throws IOException + private SortedMap getMutableDependencies() throws IOException { MultimoduleDiscoveryStrategy strategy = config.getMultimoduleDiscoveryStrategy(); - SortedMap result = new TreeMap<>(); + SortedMap result = new TreeMap<>(); for ( Dependency dependency : project.getDependencies() ) { @@ -783,7 +783,7 @@ private SortedMap getMutableDependencies() throws IOExce final Artifact dependencyArtifact = repoSystem.createDependencyArtifact( dependency ); final String artifactKey = KeyUtils.getArtifactKey( dependencyArtifact ); - DigestItemType resolved = null; + DigestItem resolved = null; if ( currentlyBuilding ) { resolved = projectArtifactsByKey.get( artifactKey ); @@ -797,10 +797,10 @@ private SortedMap getMutableDependencies() throws IOExce if ( partOfMultiModule ) { // TODO lookup in remote cache is not necessary for abfx, for versioned projects - make sense - final Optional bestMatchResult = localCache.findBestMatchingBuild( session, dependency ); + final Optional bestMatchResult = localCache.findBestMatchingBuild( session, dependency ); if ( bestMatchResult.isPresent() ) { - final BuildInfo bestMatched = bestMatchResult.get(); + final Build bestMatched = bestMatchResult.get(); resolved = bestMatched.findArtifact( dependency ); } } @@ -822,7 +822,7 @@ private SortedMap getMutableDependencies() throws IOExce } @Nonnull - private DigestItemType resolveArtifact( final Artifact dependencyArtifact, + private DigestItem resolveArtifact( final Artifact dependencyArtifact, MultimoduleDiscoveryStrategy strategy ) throws IOException { diff --git a/maven-core/src/main/java/org/apache/maven/caching/checksum/MultimoduleDiscoveryStrategy.java b/maven-caching/src/main/java/org/apache/maven/caching/checksum/MultimoduleDiscoveryStrategy.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/checksum/MultimoduleDiscoveryStrategy.java rename to maven-caching/src/main/java/org/apache/maven/caching/checksum/MultimoduleDiscoveryStrategy.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/checksum/WalkKey.java b/maven-caching/src/main/java/org/apache/maven/caching/checksum/WalkKey.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/checksum/WalkKey.java rename to maven-caching/src/main/java/org/apache/maven/caching/checksum/WalkKey.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/CloseableBuffer.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/CloseableBuffer.java similarity index 90% rename from maven-core/src/main/java/org/apache/maven/caching/hash/CloseableBuffer.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/CloseableBuffer.java index 0fec3646ffa4..91acdf27b6d3 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/hash/CloseableBuffer.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/hash/CloseableBuffer.java @@ -35,22 +35,21 @@ */ public class CloseableBuffer implements AutoCloseable { - /* Java 8 - private static final Cleaner CLEANER = doPrivileged((PrivilegedAction) () -> { - final boolean isOldJava = System.getProperty("java.specification.version", "9").startsWith("1."); - if (isOldJava) { - return DirectCleaner.isSupported() ? new DirectCleaner() : new NoopCleaner(); - } else { - return UnsafeCleaner.isSupported() ? new UnsafeCleaner() : new NoopCleaner(); - } - }); - */ + private static final Cleaner CLEANER = doPrivileged( new PrivilegedAction() { @Override public Cleaner run() { - return DirectCleaner.isSupported() ? new DirectCleaner() : new NoopCleaner(); + final String jsv = System.getProperty( "java.specification.version", "9" ); + if ( jsv.startsWith( "1." ) ) + { + return DirectCleaner.isSupported() ? new DirectCleaner() : new NoopCleaner(); + } + else + { + return UnsafeCleaner.isSupported() ? new UnsafeCleaner() : new NoopCleaner(); + } } } ); diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/Hash.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/Hash.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/hash/Hash.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/Hash.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/HashAlgorithm.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/HashAlgorithm.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/hash/HashAlgorithm.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/HashAlgorithm.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/HashChecksum.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/HashChecksum.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/hash/HashChecksum.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/HashChecksum.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/HashFactory.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/HashFactory.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/hash/HashFactory.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/HashFactory.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/HexUtils.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/HexUtils.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/hash/HexUtils.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/HexUtils.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/ReflectionUtils.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/ReflectionUtils.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/hash/ReflectionUtils.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/ReflectionUtils.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/SHA.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/SHA.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/hash/SHA.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/SHA.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/ThreadLocalBuffer.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/ThreadLocalBuffer.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/hash/ThreadLocalBuffer.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/ThreadLocalBuffer.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/ThreadLocalDigest.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/ThreadLocalDigest.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/hash/ThreadLocalDigest.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/ThreadLocalDigest.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/XX.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/XX.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/hash/XX.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/XX.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/hash/XXMM.java b/maven-caching/src/main/java/org/apache/maven/caching/hash/XXMM.java similarity index 91% rename from maven-core/src/main/java/org/apache/maven/caching/hash/XXMM.java rename to maven-caching/src/main/java/org/apache/maven/caching/hash/XXMM.java index 8e09299c247e..7afe2403ffbe 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/hash/XXMM.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/hash/XXMM.java @@ -57,8 +57,8 @@ private static class Algorithm extends XX.Algorithm @Override public byte[] hash( Path path ) throws IOException { - try ( FileChannel channel = FileChannel.open( path, - READ ); CloseableBuffer buffer = CloseableBuffer.mappedBuffer( channel, READ_ONLY ) ) + try ( FileChannel channel = FileChannel.open( path, READ ); + CloseableBuffer buffer = CloseableBuffer.mappedBuffer( channel, READ_ONLY ) ) { return toByteArray( XX.INSTANCE.hashBytes( buffer.getBuffer() ) ); } diff --git a/maven-core/src/main/java/org/apache/maven/caching/xml/AllExternalSrategy.java b/maven-caching/src/main/java/org/apache/maven/caching/xml/AllExternalSrategy.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/xml/AllExternalSrategy.java rename to maven-caching/src/main/java/org/apache/maven/caching/xml/AllExternalSrategy.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/xml/BuildInfo.java b/maven-caching/src/main/java/org/apache/maven/caching/xml/Build.java similarity index 61% rename from maven-core/src/main/java/org/apache/maven/caching/xml/BuildInfo.java rename to maven-caching/src/main/java/org/apache/maven/caching/xml/Build.java index 0b61bfd89d74..72a5021fc1e5 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/xml/BuildInfo.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/xml/Build.java @@ -20,28 +20,24 @@ */ import com.google.common.collect.Iterables; -import org.apache.maven.artifact.Artifact; import org.apache.maven.caching.ProjectUtils; import org.apache.maven.caching.checksum.MavenProjectInput; import org.apache.maven.caching.hash.HashAlgorithm; -import org.apache.maven.caching.jaxb.ArtifactType; -import org.apache.maven.caching.jaxb.BuildInfoType; -import org.apache.maven.caching.jaxb.CompletedExecutionType; -import org.apache.maven.caching.jaxb.DigestItemType; -import org.apache.maven.caching.jaxb.ProjectsInputInfoType; +import org.apache.maven.caching.xml.build.Artifact; +import org.apache.maven.caching.xml.build.CompletedExecution; +import org.apache.maven.caching.xml.build.DigestItem; +import org.apache.maven.caching.xml.build.ProjectsInputInfo; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecution; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.StringUtils; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collections; -import java.util.GregorianCalendar; +import java.util.Date; import java.util.List; import java.util.Objects; @@ -51,28 +47,22 @@ /** * BuildInfo */ -public class BuildInfo +public class Build { - final BuildInfoType dto; + final org.apache.maven.caching.xml.build.Build dto; CacheSource source; - public BuildInfo( List goals, - ArtifactType artifact, - List attachedArtifacts, - ProjectsInputInfoType projectsInputInfo, - List completedExecutions, - String hashAlgorithm ) + public Build( List goals, + Artifact artifact, + List attachedArtifacts, + ProjectsInputInfo projectsInputInfo, + List completedExecutions, + String hashAlgorithm ) { - this.dto = new BuildInfoType(); + this.dto = new org.apache.maven.caching.xml.build.Build(); this.dto.setCacheImplementationVersion( MavenProjectInput.CACHE_IMPLMENTATION_VERSION ); - try - { - this.dto.setBuildTime( DatatypeFactory.newInstance().newXMLGregorianCalendar( new GregorianCalendar() ) ); - } - catch ( DatatypeConfigurationException ignore ) - { - } + this.dto.setBuildTime( new Date() ); try { this.dto.setBuildServer( InetAddress.getLocalHost().getCanonicalHostName() ); @@ -83,10 +73,9 @@ public BuildInfo( List goals, } this.dto.setHashFunction( hashAlgorithm ); this.dto.setArtifact( artifact ); - this.dto.setGoals( createGoals( goals ) ); - this.dto.setAttachedArtifacts( new BuildInfoType.AttachedArtifacts() ); - this.dto.getAttachedArtifacts().getArtifact().addAll( attachedArtifacts ); - this.dto.setExecutions( createExecutions( completedExecutions ) ); + this.dto.setGoals( goals ); + this.dto.setAttachedArtifacts( attachedArtifacts ); + this.dto.setExecutions( completedExecutions ); this.dto.setProjectsInputInfo( projectsInputInfo ); this.source = CacheSource.BUILD; } @@ -96,38 +85,24 @@ public CacheSource getSource() return source; } - private BuildInfoType.Executions createExecutions( List completedExecutions ) + public Build( org.apache.maven.caching.xml.build.Build dto, CacheSource source ) { - BuildInfoType.Executions executions = new BuildInfoType.Executions(); - executions.getExecution().addAll( completedExecutions ); - return executions; - } - - public BuildInfo( BuildInfoType buildInfo, CacheSource source ) - { - this.dto = buildInfo; + this.dto = dto; this.source = source; } - public static BuildInfoType.Goals createGoals( List list ) - { - BuildInfoType.Goals goals = new BuildInfoType.Goals(); - goals.getGoal().addAll( list ); - return goals; - } - - public static BuildInfoType.AttachedArtifacts createAttachedArtifacts( List artifacts, - HashAlgorithm algorithm ) throws IOException + public static List createAttachedArtifacts( List artifacts, + HashAlgorithm algorithm ) throws IOException { - BuildInfoType.AttachedArtifacts attachedArtifacts = new BuildInfoType.AttachedArtifacts(); - for ( Artifact artifact : artifacts ) + List attachedArtifacts = new ArrayList<>(); + for ( org.apache.maven.artifact.Artifact artifact : artifacts ) { - final ArtifactType dto = DtoUtils.createDto( artifact ); + final Artifact dto = DtoUtils.createDto( artifact ); if ( artifact.getFile() != null ) { dto.setFileHash( algorithm.hash( artifact.getFile().toPath() ) ); } - attachedArtifacts.getArtifact().add( dto ); + attachedArtifacts.add( dto ); } return attachedArtifacts; } @@ -148,12 +123,15 @@ public boolean isAllExecutionsPresent( List mojos, Logger logger private boolean hasCompletedExecution( String mojoExecutionKey ) { - final List completedExecutions = dto.getExecutions().getExecution(); - for ( CompletedExecutionType completedExecution : completedExecutions ) + final List completedExecutions = dto.getExecutions(); + if ( dto.getExecutions() != null ) { - if ( StringUtils.equals( completedExecution.getExecutionKey(), mojoExecutionKey ) ) + for ( CompletedExecution completedExecution : completedExecutions ) { - return true; + if ( StringUtils.equals( completedExecution.getExecutionKey(), mojoExecutionKey ) ) + { + return true; + } } } return false; @@ -165,16 +143,16 @@ public String toString() return "BuildInfo{" + "dto=" + dto + '}'; } - public CompletedExecutionType findMojoExecutionInfo( MojoExecution mojoExecution ) + public CompletedExecution findMojoExecutionInfo( MojoExecution mojoExecution ) { - if ( !dto.isSetExecutions() ) + if ( dto.getExecutions() == null ) { return null; } - final List executions = dto.getExecutions().getExecution(); - for ( CompletedExecutionType execution : executions ) + final List executions = dto.getExecutions(); + for ( CompletedExecution execution : executions ) { if ( StringUtils.equals( execution.getExecutionKey(), mojoExecutionKey( mojoExecution ) ) ) { @@ -189,28 +167,28 @@ public String getCacheImplementationVersion() return dto.getCacheImplementationVersion(); } - public ArtifactType getArtifact() + public Artifact getArtifact() { return dto.getArtifact(); } - public List getAttachedArtifacts() + public List getAttachedArtifacts() { - if ( dto.isSetAttachedArtifacts() ) + if ( dto.getAttachedArtifacts() != null ) { - return dto.getAttachedArtifacts().getArtifact(); + return dto.getAttachedArtifacts(); } return Collections.emptyList(); } - public BuildInfoType getDto() + public org.apache.maven.caching.xml.build.Build getDto() { return dto; } public String getHighestCompletedGoal() { - return Iterables.getLast( dto.getGoals().getGoal() ); + return Iterables.getLast( dto.getGoals() ); } public List getCachedSegment( List mojoExecutions ) @@ -245,16 +223,16 @@ public List getPostCachedSegment( List mojoExecuti return list; } - public DigestItemType findArtifact( Dependency dependency ) + public DigestItem findArtifact( Dependency dependency ) { if ( ProjectUtils.isPom( dependency ) ) { throw new IllegalArgumentException( "Pom dependencies should not be treated as artifacts: " + dependency ); } - List artifacts = new ArrayList<>( getAttachedArtifacts() ); + List artifacts = new ArrayList<>( getAttachedArtifacts() ); artifacts.add( getArtifact() ); - for ( ArtifactType artifact : artifacts ) + for ( Artifact artifact : artifacts ) { if ( isEquals( dependency, artifact ) ) { @@ -264,7 +242,7 @@ public DigestItemType findArtifact( Dependency dependency ) return null; } - private boolean isEquals( Dependency dependency, ArtifactType artifact ) + private boolean isEquals( Dependency dependency, Artifact artifact ) { return Objects.equals( dependency.getGroupId(), artifact.getArtifactId() ) && Objects.equals( dependency.getArtifactId(), artifact.getArtifactId() ) && Objects.equals( dependency.getType(), diff --git a/maven-core/src/main/java/org/apache/maven/caching/xml/CacheConfig.java b/maven-caching/src/main/java/org/apache/maven/caching/xml/CacheConfig.java similarity index 83% rename from maven-core/src/main/java/org/apache/maven/caching/xml/CacheConfig.java rename to maven-caching/src/main/java/org/apache/maven/caching/xml/CacheConfig.java index 2f5137d9a3ea..16a300bfbb9f 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/xml/CacheConfig.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/xml/CacheConfig.java @@ -22,9 +22,10 @@ import org.apache.maven.caching.PluginScanConfig; import org.apache.maven.caching.checksum.MultimoduleDiscoveryStrategy; import org.apache.maven.caching.hash.HashFactory; -import org.apache.maven.caching.jaxb.PathSetType; -import org.apache.maven.caching.jaxb.PropertyNameType; -import org.apache.maven.caching.jaxb.TrackedPropertyType; +import org.apache.maven.caching.xml.config.Exclude; +import org.apache.maven.caching.xml.config.Include; +import org.apache.maven.caching.xml.config.PropertyName; +import org.apache.maven.caching.xml.config.TrackedProperty; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; @@ -44,15 +45,15 @@ public interface CacheConfig CacheState initialize( MavenProject project, MavenSession session ); @Nonnull - List getTrackedProperties( MojoExecution mojoExecution ); + List getTrackedProperties( MojoExecution mojoExecution ); boolean isLogAllProperties( MojoExecution mojoExecution ); @Nonnull - List getLoggedProperties( MojoExecution mojoExecution ); + List getLoggedProperties( MojoExecution mojoExecution ); @Nonnull - List getNologProperties( MojoExecution mojoExecution ); + List getNologProperties( MojoExecution mojoExecution ); @Nonnull List getEffectivePomExcludeProperties( Plugin plugin ); @@ -62,10 +63,10 @@ public interface CacheConfig String getDefaultGlob(); @Nonnull - List getGlobalIncludePaths(); + List getGlobalIncludePaths(); @Nonnull - List getGlobalExcludePaths(); + List getGlobalExcludePaths(); @Nonnull PluginScanConfig getPluginDirScanConfig( Plugin plugin ); diff --git a/maven-core/src/main/java/org/apache/maven/caching/xml/CacheConfigImpl.java b/maven-caching/src/main/java/org/apache/maven/caching/xml/CacheConfigImpl.java similarity index 64% rename from maven-core/src/main/java/org/apache/maven/caching/xml/CacheConfigImpl.java rename to maven-caching/src/main/java/org/apache/maven/caching/xml/CacheConfigImpl.java index 9dd0e85f578f..71be02ef36a2 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/xml/CacheConfigImpl.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/xml/CacheConfigImpl.java @@ -19,6 +19,19 @@ * under the License. */ +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; + +import javax.annotation.Nonnull; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import org.apache.commons.lang3.StringUtils; @@ -27,38 +40,32 @@ import org.apache.maven.caching.PluginScanConfigImpl; import org.apache.maven.caching.checksum.MultimoduleDiscoveryStrategy; import org.apache.maven.caching.hash.HashFactory; -import org.apache.maven.caching.jaxb.CacheType; -import org.apache.maven.caching.jaxb.ConfigurationType; -import org.apache.maven.caching.jaxb.CoordinatesBaseType; -import org.apache.maven.caching.jaxb.ExecutablesType; -import org.apache.maven.caching.jaxb.ExecutionConfigurationScanType; -import org.apache.maven.caching.jaxb.ExecutionControlType; -import org.apache.maven.caching.jaxb.ExecutionIdsListType; -import org.apache.maven.caching.jaxb.GoalReconciliationType; -import org.apache.maven.caching.jaxb.GoalsListType; -import org.apache.maven.caching.jaxb.PathSetType; -import org.apache.maven.caching.jaxb.PluginConfigurationScanType; -import org.apache.maven.caching.jaxb.PluginSetType; -import org.apache.maven.caching.jaxb.PropertyNameType; -import org.apache.maven.caching.jaxb.TrackedPropertyType; +import org.apache.maven.caching.xml.config.AttachedOutputs; +import org.apache.maven.caching.xml.config.CacheConfig; +import org.apache.maven.caching.xml.config.Configuration; +import org.apache.maven.caching.xml.config.CoordinatesBase; +import org.apache.maven.caching.xml.config.Exclude; +import org.apache.maven.caching.xml.config.Executables; +import org.apache.maven.caching.xml.config.ExecutionConfigurationScan; +import org.apache.maven.caching.xml.config.ExecutionControl; +import org.apache.maven.caching.xml.config.ExecutionIdsList; +import org.apache.maven.caching.xml.config.GoalReconciliation; +import org.apache.maven.caching.xml.config.GoalsList; +import org.apache.maven.caching.xml.config.Include; +import org.apache.maven.caching.xml.config.Local; +import org.apache.maven.caching.xml.config.PluginConfigurationScan; +import org.apache.maven.caching.xml.config.PluginSet; +import org.apache.maven.caching.xml.config.ProjectDiscoveryStrategy; +import org.apache.maven.caching.xml.config.PropertyName; +import org.apache.maven.caching.xml.config.Remote; +import org.apache.maven.caching.xml.config.TrackedProperty; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; import org.apache.maven.plugin.MojoExecution; import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; -import javax.annotation.Nonnull; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.regex.Pattern; - import static com.google.common.base.Preconditions.checkState; import static java.lang.Boolean.TRUE; import static java.lang.Boolean.parseBoolean; @@ -67,9 +74,9 @@ /** * CacheConfigImpl */ -@Component( role = CacheConfig.class, - instantiationStrategy = "singleton" ) -public class CacheConfigImpl implements CacheConfig +@Singleton +@Named +public class CacheConfigImpl implements org.apache.maven.caching.xml.CacheConfig { public static final String CONFIG_PATH_PROPERTY_NAME = "remote.cache.configPath"; @@ -79,15 +86,17 @@ public class CacheConfigImpl implements CacheConfig public static final String FAIL_FAST_PROPERTY_NAME = "remote.cache.failFast"; public static final String BASELINE_BUILD_URL_PROPERTY_NAME = "remote.cache.baselineUrl"; - @Requirement + @Inject private Logger logger; - @Requirement + @Inject private XmlService xmlService; private volatile CacheState state = CacheState.NOT_INITIALIZED; - private volatile CacheType cacheConfig; + private volatile CacheConfig cacheConfig; private volatile HashFactory hashFactory; + private MavenSession session; + private MavenProject project; private final Supplier> excludePatterns = Suppliers.memoize( new Supplier>() { @@ -108,7 +117,10 @@ public synchronized CacheState initialize( MavenProject project, MavenSession se return state; } - final String enabled = System.getProperty( CACHE_ENABLED_PROPERTY_NAME, "true" ); + this.project = project; + this.session = session; + + final String enabled = getProperty( CACHE_ENABLED_PROPERTY_NAME, "true" ); if ( !parseBoolean( enabled ) ) { logger.info( "Cache disabled by command line flag, project will be built fully and not cached" ); @@ -116,25 +128,16 @@ public synchronized CacheState initialize( MavenProject project, MavenSession se return state; } - Path configPath = null; + Path configPath; - String configPathText = System.getProperty( CONFIG_PATH_PROPERTY_NAME ); + String configPathText = getProperty( CONFIG_PATH_PROPERTY_NAME, null ); if ( StringUtils.isNotBlank( configPathText ) ) { configPath = Paths.get( configPathText ); } - if ( configPath == null ) - { - configPathText = project.getProperties().getProperty( CONFIG_PATH_PROPERTY_NAME ); - if ( StringUtils.isNotBlank( configPathText ) ) - { - configPath = Paths.get( configPathText ); - } - } - - if ( configPath == null ) + else { - configPath = Paths.get( getMultimoduleRoot( session ), ".mvn", "maven-cache-config.xml" ); + configPath = getMultimoduleRoot( session ).resolve( ".mvn" ).resolve( "maven-cache-config.xml" ); } if ( !Files.exists( configPath ) ) @@ -148,7 +151,7 @@ public synchronized CacheState initialize( MavenProject project, MavenSession se try { logger.info( "Loading cache configuration from " + configPath ); - cacheConfig = xmlService.fromFile( CacheType.class, configPath.toFile() ); + cacheConfig = xmlService.loadCacheConfig( configPath.toFile() ); } catch ( Exception e ) { @@ -180,13 +183,13 @@ public synchronized CacheState initialize( MavenProject project, MavenSession se @Nonnull @Override - public List getTrackedProperties( MojoExecution mojoExecution ) + public List getTrackedProperties( MojoExecution mojoExecution ) { checkInitializedState(); - final GoalReconciliationType reconciliationConfig = findReconciliationConfig( mojoExecution ); + final GoalReconciliation reconciliationConfig = findReconciliationConfig( mojoExecution ); if ( reconciliationConfig != null ) { - return reconciliationConfig.getReconcile(); + return reconciliationConfig.getReconciles(); } else { @@ -197,32 +200,32 @@ public List getTrackedProperties( MojoExecution mojoExecuti @Override public boolean isLogAllProperties( MojoExecution mojoExecution ) { - final GoalReconciliationType reconciliationConfig = findReconciliationConfig( mojoExecution ); + final GoalReconciliation reconciliationConfig = findReconciliationConfig( mojoExecution ); if ( reconciliationConfig != null && reconciliationConfig.isLogAll() ) { return true; } - return cacheConfig.isSetExecutionControl() && cacheConfig.getExecutionControl().isSetReconcile() + return cacheConfig.getExecutionControl() != null && cacheConfig.getExecutionControl().getReconcile() != null && cacheConfig.getExecutionControl().getReconcile().isLogAllProperties(); } - private GoalReconciliationType findReconciliationConfig( MojoExecution mojoExecution ) + private GoalReconciliation findReconciliationConfig( MojoExecution mojoExecution ) { - if ( !cacheConfig.isSetExecutionControl() ) + if ( cacheConfig.getExecutionControl() == null ) { return null; } - final ExecutionControlType executionControl = cacheConfig.getExecutionControl(); - if ( !executionControl.isSetReconcile() ) + final ExecutionControl executionControl = cacheConfig.getExecutionControl(); + if ( executionControl.getReconcile() == null ) { return null; } - final List reconciliation = executionControl.getReconcile().getPlugin(); + final List reconciliation = executionControl.getReconcile().getPlugins(); - for ( GoalReconciliationType goalReconciliationConfig : reconciliation ) + for ( GoalReconciliation goalReconciliationConfig : reconciliation ) { final String goal = mojoExecution.getGoal(); @@ -238,14 +241,14 @@ private GoalReconciliationType findReconciliationConfig( MojoExecution mojoExecu @Nonnull @Override - public List getLoggedProperties( MojoExecution mojoExecution ) + public List getLoggedProperties( MojoExecution mojoExecution ) { checkInitializedState(); - final GoalReconciliationType reconciliationConfig = findReconciliationConfig( mojoExecution ); + final GoalReconciliation reconciliationConfig = findReconciliationConfig( mojoExecution ); if ( reconciliationConfig != null ) { - return reconciliationConfig.getLog(); + return reconciliationConfig.getLogs(); } else { @@ -255,13 +258,13 @@ public List getLoggedProperties( MojoExecution mojoExecution ) @Nonnull @Override - public List getNologProperties( MojoExecution mojoExecution ) + public List getNologProperties( MojoExecution mojoExecution ) { checkInitializedState(); - final GoalReconciliationType reconciliationConfig = findReconciliationConfig( mojoExecution ); + final GoalReconciliation reconciliationConfig = findReconciliationConfig( mojoExecution ); if ( reconciliationConfig != null ) { - return reconciliationConfig.getNolog(); + return reconciliationConfig.getNologs(); } else { @@ -274,25 +277,25 @@ public List getNologProperties( MojoExecution mojoExecution ) public List getEffectivePomExcludeProperties( Plugin plugin ) { checkInitializedState(); - final PluginConfigurationScanType pluginConfig = findPluginScanConfig( plugin ); + final PluginConfigurationScan pluginConfig = findPluginScanConfig( plugin ); - if ( pluginConfig != null && pluginConfig.isSetEffectivePom() ) + if ( pluginConfig != null && pluginConfig.getEffectivePom() != null ) { - return pluginConfig.getEffectivePom().getExcludeProperty(); + return pluginConfig.getEffectivePom().getExcludeProperties(); } return Collections.emptyList(); } - private PluginConfigurationScanType findPluginScanConfig( Plugin plugin ) + private PluginConfigurationScan findPluginScanConfig( Plugin plugin ) { - if ( !cacheConfig.isSetInput() ) + if ( cacheConfig.getInput() == null ) { return null; } - final List pluginConfigs = cacheConfig.getInput().getPlugin(); - for ( PluginConfigurationScanType pluginConfig : pluginConfigs ) + final List pluginConfigs = cacheConfig.getInput().getPlugins(); + for ( PluginConfigurationScan pluginConfig : pluginConfigs ) { if ( isPluginMatch( plugin, pluginConfig ) ) { @@ -302,10 +305,10 @@ private PluginConfigurationScanType findPluginScanConfig( Plugin plugin ) return null; } - private boolean isPluginMatch( Plugin plugin, CoordinatesBaseType pluginConfig ) + private boolean isPluginMatch( Plugin plugin, CoordinatesBase pluginConfig ) { return StringUtils.equals( pluginConfig.getArtifactId(), - plugin.getArtifactId() ) && ( !pluginConfig.isSetGroupId() || StringUtils.equals( + plugin.getArtifactId() ) && ( pluginConfig.getGroupId() == null || StringUtils.equals( pluginConfig.getGroupId(), plugin.getGroupId() ) ); } @@ -315,8 +318,8 @@ private boolean isPluginMatch( Plugin plugin, CoordinatesBaseType pluginConfig ) public PluginScanConfig getPluginDirScanConfig( Plugin plugin ) { checkInitializedState(); - final PluginConfigurationScanType pluginConfig = findPluginScanConfig( plugin ); - if ( pluginConfig == null || !pluginConfig.isSetDirScan() ) + final PluginConfigurationScan pluginConfig = findPluginScanConfig( plugin ); + if ( pluginConfig == null || pluginConfig.getDirScan() == null ) { return new DefaultPluginScanConfig(); } @@ -329,13 +332,13 @@ public PluginScanConfig getPluginDirScanConfig( Plugin plugin ) public PluginScanConfig getExecutionDirScanConfig( Plugin plugin, PluginExecution exec ) { checkInitializedState(); - final PluginConfigurationScanType pluginScanConfig = findPluginScanConfig( plugin ); + final PluginConfigurationScan pluginScanConfig = findPluginScanConfig( plugin ); if ( pluginScanConfig != null ) { - final ExecutionConfigurationScanType executionScanConfig = findExecutionScanConfig( exec, - pluginScanConfig.getExecution() ); - if ( executionScanConfig != null && executionScanConfig.isSetDirScan() ) + final ExecutionConfigurationScan executionScanConfig = findExecutionScanConfig( exec, + pluginScanConfig.getExecutions() ); + if ( executionScanConfig != null && executionScanConfig.getDirScan() != null ) { return new PluginScanConfigImpl( executionScanConfig.getDirScan() ); } @@ -344,12 +347,12 @@ public PluginScanConfig getExecutionDirScanConfig( Plugin plugin, PluginExecutio return new DefaultPluginScanConfig(); } - private ExecutionConfigurationScanType findExecutionScanConfig( PluginExecution execution, - List scanConfigs ) + private ExecutionConfigurationScan findExecutionScanConfig( PluginExecution execution, + List scanConfigs ) { - for ( ExecutionConfigurationScanType executionScanConfig : scanConfigs ) + for ( ExecutionConfigurationScan executionScanConfig : scanConfigs ) { - if ( executionScanConfig.getExecId().contains( execution.getId() ) ) + if ( executionScanConfig.getExecIds().contains( execution.getId() ) ) { return executionScanConfig; } @@ -373,18 +376,18 @@ public String getDefaultGlob() @Nonnull @Override - public List getGlobalIncludePaths() + public List getGlobalIncludePaths() { checkInitializedState(); - return cacheConfig.getInput().getGlobal().getInclude(); + return cacheConfig.getInput().getGlobal().getIncludes(); } @Nonnull @Override - public List getGlobalExcludePaths() + public List getGlobalExcludePaths() { checkInitializedState(); - return cacheConfig.getInput().getGlobal().getExclude(); + return cacheConfig.getInput().getGlobal().getExcludes(); } @Nonnull @@ -392,9 +395,9 @@ public List getGlobalExcludePaths() public MultimoduleDiscoveryStrategy getMultimoduleDiscoveryStrategy() { checkInitializedState(); - final ConfigurationType.ProjectDiscoveryStrategy projectDiscoveryStrategy = + final ProjectDiscoveryStrategy projectDiscoveryStrategy = cacheConfig.getConfiguration().getProjectDiscoveryStrategy(); - if ( projectDiscoveryStrategy.isSetSpecificVersion() ) + if ( projectDiscoveryStrategy != null && projectDiscoveryStrategy.getSpecificVersion() != null ) { return new SentinelVersionStartegy( projectDiscoveryStrategy.getSpecificVersion() ); } @@ -413,7 +416,7 @@ public HashFactory getHashFactory() public boolean canIgnore( MojoExecution mojoExecution ) { checkInitializedState(); - if ( !cacheConfig.isSetExecutionControl() || !cacheConfig.getExecutionControl().isSetIgnoreMissing() ) + if ( cacheConfig.getExecutionControl() == null || cacheConfig.getExecutionControl().getIgnoreMissing() == null ) { return false; } @@ -425,7 +428,7 @@ public boolean canIgnore( MojoExecution mojoExecution ) public boolean isForcedExecution( MojoExecution execution ) { checkInitializedState(); - if ( !cacheConfig.isSetExecutionControl() || !cacheConfig.getExecutionControl().isSetRunAlways() ) + if ( cacheConfig.getExecutionControl() == null || cacheConfig.getExecutionControl().getRunAlways() == null ) { return false; } @@ -433,10 +436,10 @@ public boolean isForcedExecution( MojoExecution execution ) return executionMatches( execution, cacheConfig.getExecutionControl().getRunAlways() ); } - private boolean executionMatches( MojoExecution execution, ExecutablesType executablesType ) + private boolean executionMatches( MojoExecution execution, Executables executablesType ) { - final List pluginConfigs = executablesType.getPlugin(); - for ( PluginSetType pluginConfig : pluginConfigs ) + final List pluginConfigs = executablesType.getPlugins(); + for ( PluginSet pluginConfig : pluginConfigs ) { if ( isPluginMatch( execution.getPlugin(), pluginConfig ) ) { @@ -444,20 +447,20 @@ private boolean executionMatches( MojoExecution execution, ExecutablesType execu } } - final List executionIds = executablesType.getExecution(); - for ( ExecutionIdsListType executionConfig : executionIds ) + final List executionIds = executablesType.getExecutions(); + for ( ExecutionIdsList executionConfig : executionIds ) { - if ( isPluginMatch( execution.getPlugin(), executionConfig ) && executionConfig.getExecId().contains( + if ( isPluginMatch( execution.getPlugin(), executionConfig ) && executionConfig.getExecIds().contains( execution.getExecutionId() ) ) { return true; } } - final List pluginsGoalsList = executablesType.getGoals(); - for ( GoalsListType pluginGoals : pluginsGoalsList ) + final List pluginsGoalsList = executablesType.getGoalsLists(); + for ( GoalsList pluginGoals : pluginsGoalsList ) { - if ( isPluginMatch( execution.getPlugin(), pluginGoals ) && pluginGoals.getGoal().contains( + if ( isPluginMatch( execution.getPlugin(), pluginGoals ) && pluginGoals.getGoals().contains( execution.getGoal() ) ) { return true; @@ -503,13 +506,13 @@ public boolean isFailFast() @Override public boolean isBaselineDiffEnabled() { - return System.getProperties().containsKey( BASELINE_BUILD_URL_PROPERTY_NAME ); + return getProperty( BASELINE_BUILD_URL_PROPERTY_NAME, null ) != null; } @Override public String getBaselineCacheUrl() { - return System.getProperty( BASELINE_BUILD_URL_PROPERTY_NAME ); + return getProperty( BASELINE_BUILD_URL_PROPERTY_NAME, null ); } @Override @@ -524,15 +527,15 @@ public String getUrl() public int getMaxLocalBuildsCached() { checkInitializedState(); - return getLocal().getMaxBuildsCached().intValue(); + return getLocal().getMaxBuildsCached(); } @Override public List getAttachedOutputs() { checkInitializedState(); - final ConfigurationType.AttachedOutputs attachedOutputs = getConfiguration().getAttachedOutputs(); - return attachedOutputs == null ? Collections.emptyList() : attachedOutputs.getDirName(); + final AttachedOutputs attachedOutputs = getConfiguration().getAttachedOutputs(); + return attachedOutputs == null ? Collections.emptyList() : attachedOutputs.getDirNames(); } @Nonnull @@ -545,10 +548,10 @@ public List getExcludePatterns() private List compileExcludePatterns() { - if ( cacheConfig.isSetOutput() && cacheConfig.getOutput().isSetExclude() ) + if ( cacheConfig.getOutput() != null && cacheConfig.getOutput().getExclude() != null ) { List patterns = new ArrayList<>(); - for ( String pattern : cacheConfig.getOutput().getExclude().getPattern() ) + for ( String pattern : cacheConfig.getOutput().getExclude().getPatterns() ) { patterns.add( Pattern.compile( pattern ) ); } @@ -557,17 +560,17 @@ private List compileExcludePatterns() return Collections.emptyList(); } - private ConfigurationType.Remote getRemote() + private Remote getRemote() { return getConfiguration().getRemote(); } - private ConfigurationType.Local getLocal() + private Local getLocal() { return getConfiguration().getLocal(); } - private ConfigurationType getConfiguration() + private Configuration getConfiguration() { return cacheConfig.getConfiguration(); } @@ -576,4 +579,22 @@ private void checkInitializedState() { checkState( state == CacheState.INITIALIZED, "Cache is not initialized. Actual state: " + state ); } + + private String getProperty( String key, String defaultValue ) + { + String value = session.getUserProperties().getProperty( key ); + if ( value == null ) + { + value = session.getSystemProperties().getProperty( key ); + if ( value == null ) + { + value = project.getProperties().getProperty( key ); + if ( value == null ) + { + value = defaultValue; + } + } + } + return value; + } } diff --git a/maven-core/src/main/java/org/apache/maven/caching/xml/CacheSource.java b/maven-caching/src/main/java/org/apache/maven/caching/xml/CacheSource.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/xml/CacheSource.java rename to maven-caching/src/main/java/org/apache/maven/caching/xml/CacheSource.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/xml/CacheState.java b/maven-caching/src/main/java/org/apache/maven/caching/xml/CacheState.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/xml/CacheState.java rename to maven-caching/src/main/java/org/apache/maven/caching/xml/CacheState.java diff --git a/maven-core/src/main/java/org/apache/maven/caching/xml/DtoUtils.java b/maven-caching/src/main/java/org/apache/maven/caching/xml/DtoUtils.java similarity index 58% rename from maven-core/src/main/java/org/apache/maven/caching/xml/DtoUtils.java rename to maven-caching/src/main/java/org/apache/maven/caching/xml/DtoUtils.java index a2810ab86824..690b7c19fe01 100644 --- a/maven-core/src/main/java/org/apache/maven/caching/xml/DtoUtils.java +++ b/maven-caching/src/main/java/org/apache/maven/caching/xml/DtoUtils.java @@ -21,16 +21,16 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.maven.artifact.Artifact; import org.apache.maven.caching.ProjectUtils; -import org.apache.maven.caching.jaxb.ArtifactType; -import org.apache.maven.caching.jaxb.CompletedExecutionType; -import org.apache.maven.caching.jaxb.DigestItemType; -import org.apache.maven.caching.jaxb.PropertyValueType; -import org.apache.maven.caching.jaxb.TrackedPropertyType; +import org.apache.maven.caching.xml.build.Artifact; +import org.apache.maven.caching.xml.build.CompletedExecution; +import org.apache.maven.caching.xml.build.DigestItem; +import org.apache.maven.caching.xml.build.PropertyValue; +import org.apache.maven.caching.xml.config.TrackedProperty; import org.apache.maven.model.Dependency; import javax.annotation.Nonnull; + import java.util.List; import static org.apache.maven.caching.checksum.KeyUtils.getArtifactKey; @@ -41,15 +41,14 @@ public class DtoUtils { - public static String findPropertyValue( String propertyName, CompletedExecutionType completedExecution ) + public static String findPropertyValue( String propertyName, CompletedExecution completedExecution ) { - final CompletedExecutionType.Configuration configuration = completedExecution.getConfiguration(); - if ( configuration == null ) + final List properties = completedExecution.getProperties(); + if ( properties == null ) { return null; } - final List properties = configuration.getProperty(); - for ( PropertyValueType property : properties ) + for ( PropertyValue property : properties ) { if ( StringUtils.equals( propertyName, property.getName() ) ) { @@ -59,9 +58,9 @@ public static String findPropertyValue( String propertyName, CompletedExecutionT return null; } - public static ArtifactType createDto( Artifact artifact ) + public static Artifact createDto( org.apache.maven.artifact.Artifact artifact ) { - ArtifactType dto = new ArtifactType(); + Artifact dto = new Artifact(); dto.setArtifactId( artifact.getArtifactId() ); dto.setGroupId( artifact.getGroupId() ); dto.setVersion( artifact.getVersion() ); @@ -72,9 +71,9 @@ public static ArtifactType createDto( Artifact artifact ) return dto; } - public static DigestItemType createdDigestedByProjectChecksum( ArtifactType artifact, String projectChecksum ) + public static DigestItem createdDigestedByProjectChecksum( Artifact artifact, String projectChecksum ) { - DigestItemType dit = new DigestItemType(); + DigestItem dit = new DigestItem(); dit.setType( "module" ); dit.setHash( projectChecksum ); dit.setFileChecksum( artifact.getFileHash() ); @@ -82,9 +81,9 @@ public static DigestItemType createdDigestedByProjectChecksum( ArtifactType arti return dit; } - public static DigestItemType createDigestedFile( Artifact artifact, String fileHash ) + public static DigestItem createDigestedFile( org.apache.maven.artifact.Artifact artifact, String fileHash ) { - DigestItemType dit = new DigestItemType(); + DigestItem dit = new DigestItem(); dit.setType( "artifact" ); dit.setHash( fileHash ); dit.setFileChecksum( fileHash ); @@ -92,7 +91,7 @@ public static DigestItemType createDigestedFile( Artifact artifact, String fileH return dit; } - public static Dependency createDependency( ArtifactType artifact ) + public static Dependency createDependency( org.apache.maven.artifact.Artifact artifact ) { final Dependency dependency = new Dependency(); dependency.setArtifactId( artifact.getArtifactId() ); @@ -116,17 +115,13 @@ public static Dependency createDependency( Artifact artifact ) return dependency; } - public static void addProperty( CompletedExecutionType execution, + public static void addProperty( CompletedExecution execution, String propertyName, Object value, String baseDirPath, boolean tracked ) { - if ( execution.getConfiguration() == null ) - { - execution.setConfiguration( new CompletedExecutionType.Configuration() ); - } - final PropertyValueType valueType = new PropertyValueType(); + final PropertyValue valueType = new PropertyValue(); valueType.setName( propertyName ); if ( value != null && value.getClass().isArray() ) { @@ -135,11 +130,11 @@ public static void addProperty( CompletedExecutionType execution, final String valueText = String.valueOf( value ); valueType.setValue( StringUtils.remove( valueText, baseDirPath ) ); valueType.setTracked( tracked ); - execution.getConfiguration().getProperty().add( valueType ); + execution.addProperty( valueType ); } public static boolean containsAllProperties( - @Nonnull CompletedExecutionType cachedExecution, List trackedProperties ) + @Nonnull CompletedExecution cachedExecution, List trackedProperties ) { if ( trackedProperties == null || trackedProperties.isEmpty() ) @@ -147,13 +142,13 @@ public static boolean containsAllProperties( return true; } - if ( !cachedExecution.isSetConfiguration() ) + if ( cachedExecution.getProperties() == null ) { return false; } - final List executionProperties = cachedExecution.getConfiguration().getProperty(); - for ( TrackedPropertyType trackedProperty : trackedProperties ) + final List executionProperties = cachedExecution.getProperties(); + for ( TrackedProperty trackedProperty : trackedProperties ) { if ( !contains( executionProperties, trackedProperty.getPropertyName() ) ) { @@ -163,9 +158,9 @@ public static boolean containsAllProperties( return true; } - public static boolean contains( List executionProperties, String propertyName ) + public static boolean contains( List executionProperties, String propertyName ) { - for ( PropertyValueType executionProperty : executionProperties ) + for ( PropertyValue executionProperty : executionProperties ) { if ( StringUtils.equals( executionProperty.getName(), propertyName ) ) { @@ -175,45 +170,18 @@ public static boolean contains( List executionProperties, Str return false; } - public static ArtifactType copy( ArtifactType artifact ) + public static Artifact copy( Artifact artifact ) { - ArtifactType copy = new ArtifactType(); - if ( artifact.isSetArtifactId() ) - { - copy.setArtifactId( artifact.getArtifactId() ); - } - if ( artifact.isSetGroupId() ) - { - copy.setGroupId( artifact.getGroupId() ); - } - if ( artifact.isSetVersion() ) - { - copy.setVersion( artifact.getVersion() ); - } - if ( artifact.isSetType() ) - { - copy.setType( artifact.getType() ); - } - if ( artifact.isSetClassifier() ) - { - copy.setClassifier( artifact.getClassifier() ); - } - if ( artifact.isSetScope() ) - { - copy.setScope( artifact.getScope() ); - } - if ( artifact.isSetFileName() ) - { - copy.setFileName( artifact.getFileName() ); - } - if ( artifact.isSetFileHash() ) - { - copy.setFileHash( artifact.getFileHash() ); - } - if ( artifact.isSetFileSize() ) - { - copy.setFileSize( artifact.getFileSize() ); - } + Artifact copy = new Artifact(); + copy.setArtifactId( artifact.getArtifactId() ); + copy.setGroupId( artifact.getGroupId() ); + copy.setVersion( artifact.getVersion() ); + copy.setType( artifact.getType() ); + copy.setClassifier( artifact.getClassifier() ); + copy.setScope( artifact.getScope() ); + copy.setFileName( artifact.getFileName() ); + copy.setFileHash( artifact.getFileHash() ); + copy.setFileSize( artifact.getFileSize() ); return copy; } } diff --git a/maven-core/src/main/java/org/apache/maven/caching/xml/SentinelVersionStartegy.java b/maven-caching/src/main/java/org/apache/maven/caching/xml/SentinelVersionStartegy.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/caching/xml/SentinelVersionStartegy.java rename to maven-caching/src/main/java/org/apache/maven/caching/xml/SentinelVersionStartegy.java diff --git a/maven-caching/src/main/java/org/apache/maven/caching/xml/XmlService.java b/maven-caching/src/main/java/org/apache/maven/caching/xml/XmlService.java new file mode 100644 index 000000000000..cde63c1a49ec --- /dev/null +++ b/maven-caching/src/main/java/org/apache/maven/caching/xml/XmlService.java @@ -0,0 +1,190 @@ +package org.apache.maven.caching.xml; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.apache.maven.caching.xml.build.Build; +import org.apache.maven.caching.xml.build.io.xpp3.CacheBuildXpp3Reader; +import org.apache.maven.caching.xml.build.io.xpp3.CacheBuildXpp3Writer; +import org.apache.maven.caching.xml.diff.Diff; +import org.apache.maven.caching.xml.diff.io.xpp3.CacheDiffXpp3Reader; +import org.apache.maven.caching.xml.diff.io.xpp3.CacheDiffXpp3Writer; +import org.apache.maven.caching.xml.config.CacheConfig; +import org.apache.maven.caching.xml.config.io.xpp3.CacheConfigXpp3Reader; +import org.apache.maven.caching.xml.config.io.xpp3.CacheConfigXpp3Writer; +import org.apache.maven.caching.xml.report.CacheReport; +import org.apache.maven.caching.xml.report.io.xpp3.CacheReportXpp3Reader; +import org.apache.maven.caching.xml.report.io.xpp3.CacheReportXpp3Writer; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +/** + * XmlService + */ +@Singleton +@Named +public class XmlService +{ + + public byte[] toBytes( CacheConfig cache ) throws IOException + { + try ( ByteArrayOutputStream baos = new ByteArrayOutputStream() ) + { + new CacheConfigXpp3Writer().write( baos, cache ); + return baos.toByteArray(); + } + } + + public byte[] toBytes( Build build ) throws IOException + { + try ( ByteArrayOutputStream baos = new ByteArrayOutputStream() ) + { + new CacheBuildXpp3Writer().write( baos, build ); + return baos.toByteArray(); + } + } + + public byte[] toBytes( Diff diff ) throws IOException + { + try ( ByteArrayOutputStream baos = new ByteArrayOutputStream() ) + { + new CacheDiffXpp3Writer().write( baos, diff ); + return baos.toByteArray(); + } + } + + public byte[] toBytes( CacheReport cacheReportType ) throws IOException + { + try ( ByteArrayOutputStream baos = new ByteArrayOutputStream() ) + { + new CacheReportXpp3Writer().write( baos, cacheReportType ); + return baos.toByteArray(); + } + } + + public Build loadBuild( File file ) throws IOException + { + return fromFile( Build.class, file ); + } + + public Build loadBuild( byte[] bytes ) + { + return fromBytes( Build.class, bytes ); + } + + public Build loadBuild( InputStream inputStream ) + { + return fromInputStream( Build.class, inputStream ); + } + + public CacheConfig loadCacheConfig( File file ) throws IOException + { + return fromFile( CacheConfig.class, file ); + } + + public CacheConfig loadCacheConfig( byte[] bytes ) + { + return fromBytes( CacheConfig.class, bytes ); + } + + public CacheConfig loadCacheConfig( InputStream inputStream ) + { + return fromInputStream( CacheConfig.class, inputStream ); + } + + public CacheReport loadCacheReport( File file ) throws IOException + { + return fromFile( CacheReport.class, file ); + } + + public CacheReport loadCacheReport( byte[] bytes ) + { + return fromBytes( CacheReport.class, bytes ); + } + + public CacheReport loadCacheReport( InputStream inputStream ) + { + return fromInputStream( CacheReport.class, inputStream ); + } + + public Diff loadDiff( File file ) throws IOException + { + return fromFile( Diff.class, file ); + } + + public Diff loadDiff( byte[] bytes ) + { + return fromBytes( Diff.class, bytes ); + } + + public Diff loadDiff( InputStream inputStream ) + { + return fromInputStream( Diff.class, inputStream ); + } + + private T fromFile( Class clazz, File file ) throws IOException + { + return fromInputStream( clazz, Files.newInputStream( file.toPath() ) ); + } + + private T fromBytes( Class clazz, byte[] bytes ) + { + return fromInputStream( clazz, new ByteArrayInputStream( bytes ) ); + } + + private T fromInputStream( Class clazz, InputStream inputStream ) + { + try + { + if ( clazz == Build.class ) + { + return clazz.cast( new CacheBuildXpp3Reader().read( inputStream ) ); + } + else if ( clazz == CacheConfig.class ) + { + return clazz.cast( new CacheConfigXpp3Reader().read( inputStream ) ); + } + else if ( clazz == Diff.class ) + { + return clazz.cast( new CacheDiffXpp3Reader().read( inputStream ) ); + } + else if ( clazz == CacheReport.class ) + { + return clazz.cast( new CacheReportXpp3Reader().read( inputStream ) ); + } + else + { + throw new IllegalArgumentException( "Unsupported type " + clazz ); + } + } + catch ( IOException | XmlPullParserException e ) + { + throw new RuntimeException( "Unable to parse cache xml element", e ); + } + } +} diff --git a/maven-caching/src/main/mdo/cache-build.mdo b/maven-caching/src/main/mdo/cache-build.mdo new file mode 100644 index 000000000000..b1d720332bcd --- /dev/null +++ b/maven-caching/src/main/mdo/cache-build.mdo @@ -0,0 +1,386 @@ + + + + cache-build + CacheBuild + lookupinfo.xml or remote buildinfo.xml + ]]> + + + package + org.apache.maven.caching.xml.build + + + + + + Build + 1.0.0+ + + + + + + cacheImplementationVersion + 1.0.0+ + String + + + + _final + 1.0.0+ + Boolean + final + + + + hashFunction + 1.0.0+ + String + + + + buildTime + 1.0.0+ + Date + + + + buildServer + 1.0.0+ + String + + + + scm + 1.0.0+ + + Scm + + + + + goals + 1.0.0+ + + String + * + + + + + + artifact + 1.0.0+ + + Artifact + + + + + + attachedArtifacts + + Artifact + * + + + + + + executions + + CompletedExecution + * + + + + + projectsInputInfo + + ProjectsInputInfo + + + + + + + + Scm + + + sourceBranch + String + + + revision + String + + + + + + + Artifact + + + + + groupId + String + + + + artifactId + String + + + + version + String + + + + classifier + String + + + + type + String + + + + scope + String + + + + fileName + String + + + + fileHash + String + + + + + fileSize + long + + + + + + + + + CompletedExecution + + + executionKey + String + + + mojoClassName + String + + + properties + + PropertyValue + * + + + + + + + + + PropertyValue + + + value + String + + + name + String + + + tracked + Boolean + + + + + + + + ProjectsInputInfo + + + checksum + String + + + items + + DigestItem + * + + + + + + + + + DigestItem + + + value + String + + + type + String + + + hash + String + + + fileChecksum + String + + + content + String + + + isText + String + + + charset + String + + + eol + String + + + + + + diff --git a/maven-caching/src/main/mdo/cache-config.mdo b/maven-caching/src/main/mdo/cache-config.mdo new file mode 100644 index 000000000000..6f3c3398f8b4 --- /dev/null +++ b/maven-caching/src/main/mdo/cache-config.mdo @@ -0,0 +1,1342 @@ + + + + cache-config + CacheConfig + .mvn/maven-cache-config.xml + ]]> + + + + package + org.apache.maven.caching.xml.config + + + + + + + CacheConfig + + + configuration + + Configuration + + Configuration of main cache properties + + + input + + Input + + Configuration for source code input files participating in checksum calculation + + + output + + Output + + Configuration for output artifacts, it's needed if you want to explicitly include/exclude something from caching + + + executionControl + + ExecutionControl + + Execution rules for plugins in cached mode. Defines which plugins should run always + + + Cache build metadata + + + + Remote + + + url + String + Address of remote cache + + + enabled + boolean + true + + + saveToRemote + boolean + false + Save output to remote cache. Recommended to enable on CI agents only. + + + + + + + Configuration + + + enabled + boolean + + + hashAlgorithm + String + One of XX, XXMM, SHA-1, SHA-256, SHA-384, SHA-512 + + + validateXml + boolean + true + Validate cache config and builds metadata against xsd. + + + projectDiscoveryStrategy + + ProjectDiscoveryStrategy + + Specifies how to identify belonging to a cached project then submodule is being build. + + + remote + + Remote + + + + attachedOutputs + + AttachedOutputs + + + + local + + Local + + + + debugs + + String + * + + FileHash (causes file hash is saved in build metadata) or + EffectivePom (causes effective pom info is saved in build metadata) + + + + + + + ProjectDiscoveryStrategy + + + specificVersion + String + + Any project dependency this this version will be considered cache eligible and will + be processed cache aware + + + + + + + + AttachedOutputs + + + dirNames + + String + * + + Directory name in build output directory to attach to cached artifacts + + + + + + + Local + + + maxBuildsCached + int + 3 + Maximum number of cached build per artifact in local cache. First created cache (the + oldest) is evicted if breached. + + + + + + + Input + + + global + + PathSet + + Global input calculation rules applicable to all projects and plugins in the build + + + plugins + + PluginConfigurationScan + * + + Plugin specific input calculation rules + + + + + + + PluginConfigurationScan + CoordinatesBase + + + effectivePom + + EffectivePom + + Effective pom calculation rules + + + dirScan + + DirScanConfig + + Specifies plugin level rules of configuration processing in search of referenced source files + + + executions + + ExecutionConfigurationScan + * + + Specifies execution specific configuration processing in search of referenced source files + + + + + + + EffectivePom + + + excludeProperties + + String + * + + Plugin configuration property should be excluded from effective pom calculation + + + + + + + ExecutionConfigurationScan + + + execIds + + String + * + + + + dirScan + + DirScanConfig + + Specifies rules of configuration processing in search of referenced source files + + + ignoreParentConfig + boolean + ignore parent config or inherit/merge + + + + + + + TagScanConfig + TagExclude + + + recursive + boolean + true + + + glob + String + * + + + + + + + DirScanConfig + + + includes + + TagScanConfig + * + + Forces cache to treat property value as input and include in calculation. If set, only included + properties will be takein in calculation (whitelist) + + + excludes + + TagExclude + * + + Tag to exclude when scanning plugin configuration for input files (blacklist) + + + tagScanConfigs + + TagScanConfig + * + + Additional processing rules for non-blacklisted tags + + + ignoreParent + boolean + false + Ignore parent settings or inherit and merge + + + mode + String + + Either 'auto' (scan directory accordingly to cache implementation) or 'skip' (skip directory). + + + + + + + + Output + + + exclude + + OutputExclude + + Patterns to exclude output artifacts applicable to all projects in the build + + + + + + OutputExclude + + + patterns + + String + * + + + + + + + + PathSet + + + glob + String + * + + + includes + + Include + * + + + + excludes + + Exclude + * + + + + + + Exclude + + + value + String + + + + + Include + + + value + String + + + recursive + boolean + true + + + glob + String + * + + + + + + + + + + GoalReconciliation + GoalId + + + reconciles + + TrackedProperty + * + + + + logs + + PropertyName + * + + Specify property which should be logged to build metadata for exploration + + + nologs + + PropertyName + * + + Specify property which should not be logged + + + logAll + boolean + true + Controls if all plugin properties to be logged (true is default). All the properties logged + with respect to log/nolog children: + * true: logged all if no blacklists (<nolog/>) and whitelists (<log/>) specified on plugin + level + * false: logged only tracked and included by whitelists (<log/>) on plugin level + + + + + + + + + ExecutionControl + + + runAlways + + Executables + + Specify which plugin should run always if present in build regardless of cached status + + + ignoreMissing + + Executables + + + Specify which executions/plugins/goals do not affect generated artifacts and do not affect build correctness. + If cached build lacks of ignorable executions only, it still could be reused. + Typically case is then cached build is produced with 'verify' and you locally you run 'install'. + Strictly speaking these are different builds but in most of cases you want this difference to be ignored + + + + reconcile + + Reconcile + + Specify which plugin should run always if present in build regardless of cached status + + + + + + + + Reconcile + + + plugins + + GoalReconciliation + * + + Reconciliation rules for plugin properties which might be affected by command line flags, etc + + + logAllProperties + boolean + true + + Controls if all plugin properties to be logged (true is default). All the properties + logged with respect to children: + * logAll on plugin level overrides global value + * true: logged all if no blacklists (<nolog/>) and whitelists (<log/>) specified on + plugin level + * false: logged only tracked and included by whitelists (<log/>) on plugin level + <log/> + + + + + + + + + Executables + + + plugins + + PluginSet + * + + Specify which executions should run always if present in build regardless of cached status + + + executions + + ExecutionIdsList + * + + Specify which executions should run always if present in build regardless of cached status + + + goalsLists + + GoalsList + * + + Specify which goals should run always if present in build regardless of cached status + + + + + + + + GoalsList + CoordinatesBase + + + goals + + String + * + + Goals identification + + + + + + + + GoalId + CoordinatesBase + + + goal + String + true + + + + + + + + ExecutionIdsList + CoordinatesBase + + + execIds + + String + * + + Executions ids list with plugin identifier + + + + + + + + PluginSet + CoordinatesBase + + + + + + CoordinatesBase + + + groupId + String + + + artifactId + String + + + + + + + + TagExclude + + + tagName + String + true + + + + + + + + PropertyName + + + value + String + + + propertyName + String + + + + + + + + TrackedProperty + + + value + String + + + propertyName + String + + + skipValue + String + + + defaultValue + String + + + + + + + + diff --git a/maven-caching/src/main/mdo/cache-diff.mdo b/maven-caching/src/main/mdo/cache-diff.mdo new file mode 100644 index 000000000000..9d837362b663 --- /dev/null +++ b/maven-caching/src/main/mdo/cache-diff.mdo @@ -0,0 +1,110 @@ + + + + cache-diff + CacheDiff + diff-${checksum}.xml + ]]> + + + package + org.apache.maven.caching.xml.diff + + + + + + + + Diff + + + mismatches + + Mismatch + * + + + + + + + + + Mismatch + + + detail + + MismatchDetail + * + + + + item + String + + + current + String + + + baseline + String + + + reason + String + + + resolution + String + + + context + String + + + + + + + MismatchDetail + + + + diff --git a/maven-caching/src/main/mdo/cache-report.mdo b/maven-caching/src/main/mdo/cache-report.mdo new file mode 100644 index 000000000000..d77ba5655cdd --- /dev/null +++ b/maven-caching/src/main/mdo/cache-report.mdo @@ -0,0 +1,109 @@ + + + + cache-report + CacheReport + cache-report.xml + ]]> + + + package + org.apache.maven.caching.xml.report + + + + + + CacheReport + + + projects + + ProjectReport + * + + + + + + + + + + + + + + ProjectReport + + + groupId + String + + + artifactId + String + + + checksum + String + + + checksumMatched + Boolean + + + lifecycleMatched + Boolean + + + pluginsMatched + Boolean + + + source + String + + + sharedToRemote + Boolean + + + url + String + + + + + + diff --git a/maven-core/src/test/java/org/apache/maven/caching/BuildInfoTest.java b/maven-caching/src/test/java/org/apache/maven/caching/BuildInfoTest.java similarity index 53% rename from maven-core/src/test/java/org/apache/maven/caching/BuildInfoTest.java rename to maven-caching/src/test/java/org/apache/maven/caching/BuildInfoTest.java index 6c9b14c418aa..f99934686949 100644 --- a/maven-core/src/test/java/org/apache/maven/caching/BuildInfoTest.java +++ b/maven-caching/src/test/java/org/apache/maven/caching/BuildInfoTest.java @@ -20,62 +20,60 @@ */ -import com.google.common.collect.Lists; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.DefaultArtifact; -import org.apache.maven.artifact.handler.DefaultArtifactHandler; -import org.apache.maven.caching.hash.HashFactory; -import org.apache.maven.caching.jaxb.ArtifactType; -import org.apache.maven.caching.jaxb.BuildInfoType; -import org.apache.maven.caching.jaxb.CompletedExecutionType; -import org.apache.maven.caching.jaxb.DigestItemType; -import org.apache.maven.caching.jaxb.ProjectsInputInfoType; -import org.apache.maven.caching.jaxb.PropertyValueType; -import org.apache.maven.caching.xml.BuildInfo; -import org.apache.maven.caching.xml.XmlService; - -import javax.xml.datatype.DatatypeFactory; import java.io.File; -import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.GregorianCalendar; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; -import static org.apache.maven.caching.xml.BuildInfo.createGoals; +import com.google.common.collect.Lists; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.DefaultArtifactHandler; +import org.apache.maven.caching.hash.HashFactory; +import org.apache.maven.caching.xml.Build; +import org.apache.maven.caching.xml.build.Artifact; +import org.apache.maven.caching.xml.build.CompletedExecution; +import org.apache.maven.caching.xml.build.DigestItem; +import org.apache.maven.caching.xml.build.ProjectsInputInfo; +import org.apache.maven.caching.xml.build.PropertyValue; +import org.apache.maven.caching.xml.XmlService; +import org.junit.Test; public class BuildInfoTest { - // @Test + @Test public void name() throws Exception { XmlService xmlService = new XmlService(); - ProjectsInputInfoType main = new ProjectsInputInfoType(); + ProjectsInputInfo main = new ProjectsInputInfo(); main.setChecksum("dependencyChecksum"); - main.getItem().add(createItem("pom", "4.0.0", "hash1")); - main.getItem().add(createItem("file", Paths.get(".").toString(), "hash2")); + main.addItem(createItem("pom", "4.0.0", "hash1")); + main.addItem(createItem("file", Paths.get(".").toString(), "hash2")); - ArtifactType artifact = new ArtifactType(); + Artifact artifact = new Artifact(); artifact.setGroupId("g"); artifact.setArtifactId("a"); artifact.setType("t"); artifact.setClassifier("c"); artifact.setScope("s"); artifact.setFileName("f"); - artifact.setFileSize(BigInteger.valueOf(123456)); + artifact.setFileSize(123456); artifact.setFileHash("456L"); - BuildInfoType buildInfo = new BuildInfoType(); + org.apache.maven.caching.xml.build.Build buildInfo = new org.apache.maven.caching.xml.build.Build(); buildInfo.setCacheImplementationVersion("cacheImplementationVersion"); buildInfo.setBuildServer("server"); - buildInfo.setBuildTime(DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar())); + buildInfo.setBuildTime(new Date()); buildInfo.setArtifact(artifact); buildInfo.setHashFunction("SHA-256"); - buildInfo.setGoals(createGoals(Lists.newArrayList("install"))); - final Artifact attachedArtifact = new DefaultArtifact("ag", "aa", "av", "as", "at", "ac", new DefaultArtifactHandler()); - buildInfo.setAttachedArtifacts(BuildInfo.createAttachedArtifacts(Lists.newArrayList(attachedArtifact), HashFactory.XX.createAlgorithm())); + buildInfo.setGoals(Lists.newArrayList("install")); + final org.apache.maven.artifact.Artifact attachedArtifact = new DefaultArtifact("ag", "aa", "av", "as", "at", "ac", new DefaultArtifactHandler()); + buildInfo.setAttachedArtifacts(Build.createAttachedArtifacts(Lists.newArrayList(attachedArtifact), HashFactory.XX.createAlgorithm())); buildInfo.setProjectsInputInfo(main); buildInfo.setExecutions(createExecutions()); @@ -86,25 +84,22 @@ public void name() throws Exception { file.deleteOnExit(); Files.write(tempFilePath, bytes); - BuildInfoType buildInfo1 = xmlService.fromFile(BuildInfoType.class, file); + org.apache.maven.caching.xml.build.Build buildInfo1 = xmlService.loadBuild(file); System.out.println(buildInfo1); } - private BuildInfoType.Executions createExecutions() { - CompletedExecutionType execution = new CompletedExecutionType(); + private List createExecutions() { + CompletedExecution execution = new CompletedExecution(); execution.setExecutionKey("execkey"); - execution.setConfiguration(new CompletedExecutionType.Configuration()); - PropertyValueType property = new PropertyValueType(); + PropertyValue property = new PropertyValue(); property.setValue("value"); property.setName("key"); - execution.getConfiguration().getProperty().add(property); - BuildInfoType.Executions executions = new BuildInfoType.Executions(); - executions.getExecution().add(execution); - return executions; + execution.addProperty(property); + return new ArrayList<>(Arrays.asList(execution)); } - private DigestItemType createItem(String pom, String s, String hash1) { - final DigestItemType d1 = new DigestItemType(); + private DigestItem createItem(String pom, String s, String hash1) { + final DigestItem d1 = new DigestItem(); d1.setType(pom); d1.setHash(s); d1.setValue(hash1); diff --git a/maven-core/src/test/java/org/apache/maven/caching/checksum/MavenProjectInputTest.java b/maven-caching/src/test/java/org/apache/maven/caching/checksum/MavenProjectInputTest.java similarity index 94% rename from maven-core/src/test/java/org/apache/maven/caching/checksum/MavenProjectInputTest.java rename to maven-caching/src/test/java/org/apache/maven/caching/checksum/MavenProjectInputTest.java index d420134e6746..6366d9269459 100644 --- a/maven-core/src/test/java/org/apache/maven/caching/checksum/MavenProjectInputTest.java +++ b/maven-caching/src/test/java/org/apache/maven/caching/checksum/MavenProjectInputTest.java @@ -19,15 +19,15 @@ * under the License. */ -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + import static org.junit.Assert.assertEquals; public class MavenProjectInputTest { @@ -72,14 +72,14 @@ public void testGlobInput() { @Test public void testGetDirectoryFiles() { List directoryFiles = new ArrayList<>(); - MavenProjectInput.walkDirectoryFiles(Paths.get("src/test/resources"), directoryFiles, MavenProjectInput.DEFAULT_GLOB); + MavenProjectInput.walkDirectoryFiles(Paths.get("src/test/resources/test-folder"), directoryFiles, MavenProjectInput.DEFAULT_GLOB); assertEquals(0, directoryFiles.size()); // pom is filtered out by hardcoded if } @Test public void testGetDirectoryFiles2() { List directoryFiles = new ArrayList<>(); - MavenProjectInput.walkDirectoryFiles(Paths.get("src/test/resources"), directoryFiles, GLOB); - assertEquals(4, directoryFiles.size()); // pom is filtered out by hardcoded if + MavenProjectInput.walkDirectoryFiles(Paths.get("src/test/resources/test-folder"), directoryFiles, GLOB); + assertEquals(1, directoryFiles.size()); // pom is filtered out by hardcoded if } } diff --git a/maven-core/src/test/java/org/apache/maven/caching/checksum/SHAHashTest.java b/maven-caching/src/test/java/org/apache/maven/caching/checksum/SHAHashTest.java similarity index 100% rename from maven-core/src/test/java/org/apache/maven/caching/checksum/SHAHashTest.java rename to maven-caching/src/test/java/org/apache/maven/caching/checksum/SHAHashTest.java index 9cf5bb405f91..c3782e1a75fc 100644 --- a/maven-core/src/test/java/org/apache/maven/caching/checksum/SHAHashTest.java +++ b/maven-caching/src/test/java/org/apache/maven/caching/checksum/SHAHashTest.java @@ -19,12 +19,12 @@ * under the License. */ +import java.nio.charset.StandardCharsets; + import org.apache.maven.caching.hash.HashAlgorithm; import org.apache.maven.caching.hash.HashChecksum; import org.junit.Test; -import java.nio.charset.StandardCharsets; - import static org.apache.maven.caching.hash.HashFactory.SHA256; import static org.junit.Assert.assertEquals; diff --git a/maven-core/src/test/java/org/apache/maven/caching/checksum/XXHashTest.java b/maven-caching/src/test/java/org/apache/maven/caching/checksum/XXHashTest.java similarity index 100% rename from maven-core/src/test/java/org/apache/maven/caching/checksum/XXHashTest.java rename to maven-caching/src/test/java/org/apache/maven/caching/checksum/XXHashTest.java index 3a1a46ecf492..164f2b2966ac 100644 --- a/maven-core/src/test/java/org/apache/maven/caching/checksum/XXHashTest.java +++ b/maven-caching/src/test/java/org/apache/maven/caching/checksum/XXHashTest.java @@ -19,13 +19,13 @@ * under the License. */ +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + import org.apache.maven.caching.hash.HashAlgorithm; import org.apache.maven.caching.hash.HashChecksum; import org.junit.Test; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; - import static org.apache.maven.caching.hash.HashFactory.XX; import static org.apache.maven.caching.hash.HashFactory.XXMM; import static org.junit.Assert.assertEquals; diff --git a/maven-core/src/test/java/org/apache/maven/caching/hash/HexUtilsTest.java b/maven-caching/src/test/java/org/apache/maven/caching/hash/HexUtilsTest.java similarity index 100% rename from maven-core/src/test/java/org/apache/maven/caching/hash/HexUtilsTest.java rename to maven-caching/src/test/java/org/apache/maven/caching/hash/HexUtilsTest.java diff --git a/maven-caching/src/test/java/org/apache/maven/caching/xml/XmlServiceTest.java b/maven-caching/src/test/java/org/apache/maven/caching/xml/XmlServiceTest.java new file mode 100644 index 000000000000..9415d10ab58f --- /dev/null +++ b/maven-caching/src/test/java/org/apache/maven/caching/xml/XmlServiceTest.java @@ -0,0 +1,95 @@ +package org.apache.maven.caching.xml; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.caching.xml.build.Build; +import org.apache.maven.caching.xml.diff.Diff; +import org.apache.maven.caching.xml.config.CacheConfig; +import org.apache.maven.caching.xml.report.CacheReport; +import org.junit.Test; + +import java.io.InputStream; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.w3c.dom.Document; + +public class XmlServiceTest { + + @Test + public void testConfig() throws Exception { + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = sf.newSchema(getClass().getResource("/cache-config-1.0.0.xsd")); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setSchema(schema); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse( getClass().getResource( "cache-config-instance.xml" ).toString() ); + + InputStream is = getClass().getResourceAsStream( "cache-config-instance.xml" ); + final CacheConfig cache = new XmlService().loadCacheConfig( is ); + } + + @Test + public void testReport() throws Exception { + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = sf.newSchema(getClass().getResource("/cache-report-1.0.0.xsd")); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setSchema(schema); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse( getClass().getResource( "cache-report-instance.xml" ).toString() ); + + InputStream is = getClass().getResourceAsStream( "cache-report-instance.xml" ); + final CacheReport cacheReport = new XmlService().loadCacheReport( is ); + } + + @Test + public void testBuild() throws Exception { + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = sf.newSchema(getClass().getResource("/cache-build-1.0.0.xsd")); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setSchema(schema); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse( getClass().getResource( "cache-build-instance.xml" ).toString() ); + + InputStream is = getClass().getResourceAsStream( "cache-build-instance.xml" ); + final Build build = new XmlService().loadBuild( is ); + } + + @Test + public void testDiff() throws Exception { + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = sf.newSchema(getClass().getResource("/cache-diff-1.0.0.xsd")); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setSchema(schema); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse( getClass().getResource( "cache-diff-instance.xml" ).toString() ); + + InputStream is = getClass().getResourceAsStream( "cache-diff-instance.xml" ); + final Diff buildDiff = new XmlService().loadDiff( is ); + } +} \ No newline at end of file diff --git a/maven-core/src/main/resources/cache-domain-instance.xml b/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-build-instance.xml similarity index 80% rename from maven-core/src/main/resources/cache-domain-instance.xml rename to maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-build-instance.xml index 101a011430e0..c80e922425e9 100644 --- a/maven-core/src/main/resources/cache-domain-instance.xml +++ b/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-build-instance.xml @@ -19,11 +19,11 @@ specific language governing permissions and limitations under the License. --> - + xsi:schemaLocation="http://maven.apache.org/CACHE-BUILD/1.0.0 ../../../../../../../../target/generated-sources/modello/cache-build-1.0.0.xsd"> v3 - 1980-03-23T10:20:15 + 1980-03-23T10:20:15.000 my-server.com SHA-256 @@ -39,26 +39,28 @@ under the License. 123456 - + com.my.shared my-server java-source sources my-server-sources.jar - + default:check:verify:duplicate-finder-maven-plugin:org.basepom.maven:1.3.0 org.basepom.mojo.duplicatefinder.DuplicateFinderMojo - + true false - + 0136171ac2c9d9b066805bd09904a25318cfb2037189b20c48e79b20b63b81ed - src/main/conf/my-context.xml + + src/main/conf/my-context.xml + diff --git a/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-config-instance.xml b/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-config-instance.xml new file mode 100644 index 000000000000..8451304e6606 --- /dev/null +++ b/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-config-instance.xml @@ -0,0 +1,160 @@ + + + + + + + + true + SHA-256 + true + + http://host:port + + + 3 + + + + + + + {*.java,*.groovy,*.yaml,*.svcd,*.proto,*assembly.xml,assembly*.xml,*logback.xml,*.vm,*.ini,*.jks,*.properties,*.sh,*.bat} + + + src/ + + + pom.xml + + + + + + + 111 + + + + + + + + + + + + + + + 1 + 2 + + + + + + + + + + + + + + + .*-processes.*\.zip + + + + + + + + + + + + aaa + + + + + + + install + + + + + deploy + + + + + deploy-local + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-diff-instance.xml b/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-diff-instance.xml new file mode 100644 index 000000000000..e549ef940756 --- /dev/null +++ b/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-diff-instance.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + diff --git a/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-report-instance.xml b/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-report-instance.xml new file mode 100644 index 000000000000..af1f64d1f63d --- /dev/null +++ b/maven-caching/src/test/resources/org/apache/maven/caching/xml/cache-report-instance.xml @@ -0,0 +1,32 @@ + + + + + + + + + org.apache.maven + + + + diff --git a/maven-caching/src/test/resources/test-folder/test-pom.xml b/maven-caching/src/test/resources/test-folder/test-pom.xml new file mode 100644 index 000000000000..b5e89715a9cd --- /dev/null +++ b/maven-caching/src/test/resources/test-folder/test-pom.xml @@ -0,0 +1,52 @@ + + + + 4.0.0 + + org.apache.maven + maven-core + 2.0-SNAPSHOT + jar + + Maven + 2001 + + + + org.apache.maven + maven-model + 2.0-SNAPSHOT + jar + compile + + + org.apache.maven + maven-plugin + 2.0-SNAPSHOT + jar + compile + + + + + scm-connection + + diff --git a/maven-core/pom.xml b/maven-core/pom.xml index 9dd0250754e4..80a90aa8ba60 100644 --- a/maven-core/pom.xml +++ b/maven-core/pom.xml @@ -156,17 +156,6 @@ under the License. zero-allocation-hashing 0.9
- - jakarta.xml.bind - jakarta.xml.bind-api - 2.3.3 - - - com.sun.xml.bind - jaxb-impl - 2.3.3 - runtime - com.github.albfernandez juniversalchardet @@ -216,8 +205,8 @@ under the License.
- - modello-site-doc + + modello-site-docs-extension pre-site xdoc @@ -248,26 +237,6 @@ under the License. - - org.codehaus.mojo - jaxb2-maven-plugin - 2.5.0 - - - xjc - - xjc - - - - - org.apache.maven.caching.jaxb - - src/main/resources/cache-config.xsd - src/main/resources/cache-domain.xsd - - - diff --git a/maven-core/src/main/java/org/apache/maven/caching/xml/XmlService.java b/maven-core/src/main/java/org/apache/maven/caching/xml/XmlService.java deleted file mode 100644 index 658c9d0dd3b1..000000000000 --- a/maven-core/src/main/java/org/apache/maven/caching/xml/XmlService.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.apache.maven.caching.xml; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.apache.maven.caching.jaxb.BuildDiffType; -import org.apache.maven.caching.jaxb.BuildInfoType; -import org.apache.maven.caching.jaxb.CacheReportType; -import org.apache.maven.caching.jaxb.ObjectFactory; -import org.codehaus.plexus.component.annotations.Component; -import org.xml.sax.SAXException; - -import javax.xml.XMLConstants; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.transform.Source; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.InputStream; - -/** - * XmlService - */ -@Component( role = XmlService.class ) -public class XmlService -{ - - private final ObjectFactory objectFactory; - private final JAXBContext jaxbContext; - private final Schema schema; - - public XmlService() throws JAXBException, SAXException - { - objectFactory = new ObjectFactory(); - jaxbContext = JAXBContext.newInstance( "org.apache.maven.caching.jaxb", XmlService.class.getClassLoader() ); - - SchemaFactory sf = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI ); - final InputStream domainSchemaStream = getResourceAsStream( "cache-domain.xsd" ); - final Source domainSchema = new StreamSource( domainSchemaStream ); - final InputStream configSchemaStream = getResourceAsStream( "cache-config.xsd" ); - final Source configSchema = new StreamSource( configSchemaStream ); - schema = sf.newSchema( new Source[] {domainSchema, configSchema} ); - } - - public byte[] toBytes( BuildInfoType buildInfo ) - { - return serializeXml( objectFactory.createBuild( buildInfo ) ); - } - - public byte[] toBytes( BuildDiffType diff ) - { - return serializeXml( objectFactory.createDiff( diff ) ); - } - - public byte[] toBytes( CacheReportType cacheReportType ) - { - - return serializeXml( objectFactory.createReport( cacheReportType ) ); - } - - private byte[] serializeXml( JAXBElement element ) - { - try - { - Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); - jaxbMarshaller.setSchema( schema ); - // output pretty printed - jaxbMarshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true ); - jaxbMarshaller.setProperty( Marshaller.JAXB_ENCODING, "UTF-8" ); - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - jaxbMarshaller.marshal( element, baos ); - return baos.toByteArray(); - } - catch ( Exception e ) - { - throw new RuntimeException( "Errors in jaxb serialization: " + e.toString(), e ); - } - } - - public T fromFile( Class clazz, File file ) - { - - try - { - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - unmarshaller.setSchema( schema ); - JAXBElement result = (JAXBElement) unmarshaller.unmarshal( file ); - return result.getValue(); - } - catch ( Exception e ) - { - throw new RuntimeException( "Errors in jaxb serialization: " + e.toString(), e ); - } - } - - public static InputStream getResourceAsStream( String name ) - { - ClassLoader cl = XmlService.class.getClassLoader(); - if ( cl == null ) - { - // A system class. - return ClassLoader.getSystemResourceAsStream( name ); - } - return cl.getResourceAsStream( name ); - } - - public T fromBytes( Class clazz, byte[] bytes ) - { - try - { - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - unmarshaller.setSchema( schema ); - JAXBElement result = (JAXBElement) unmarshaller.unmarshal( new ByteArrayInputStream( bytes ) ); - return result.getValue(); - - } - catch ( Exception e ) - { - throw new RuntimeException( "Errors in jaxb serialization: " + e.toString(), e ); - } - } -} diff --git a/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java b/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java index 5a7db543f80b..fb7a9f45064d 100644 --- a/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java @@ -34,11 +34,9 @@ import org.apache.maven.MavenExecutionException; import org.apache.maven.ProjectCycleException; import org.apache.maven.artifact.ArtifactUtils; -import org.apache.maven.caching.checksum.KeyUtils; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.ProjectDependencyGraph; -import org.apache.maven.model.Dependency; import org.apache.maven.model.Plugin; import org.apache.maven.model.building.DefaultModelProblem; import org.apache.maven.model.building.ModelProblem; @@ -58,8 +56,6 @@ import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.dag.CycleDetectedException; -import static org.apache.maven.artifact.versioning.VersionRange.createFromVersion; - /** * Builds the {@link ProjectDependencyGraph inter-dependencies graph} between projects in the reactor. */ @@ -68,8 +64,6 @@ public class DefaultGraphBuilder implements GraphBuilder { - public static final String PROJECT_VERSION_PROP_NAME = "org.maven.project.version"; - @Requirement private Logger logger; @@ -87,11 +81,6 @@ public Result build( MavenSession session ) { final List projects = getProjectsForMavenReactor( session ); validateProjects( projects ); - - if ( System.getProperties().containsKey( PROJECT_VERSION_PROP_NAME ) ) - { - overrideReactorVersions( projects, session ); - } result = reactorDependencyGraph( session, projects ); } @@ -111,68 +100,6 @@ public Result build( MavenSession session ) } } - private void overrideReactorVersions( List projects, MavenSession session ) - { - String injectedVersion = System.getProperty( PROJECT_VERSION_PROP_NAME ); - logger.info( "Overriding reactor projects version to " + injectedVersion ); - - Map reactorProjects = new HashMap<>( projects.size() ); - - for ( MavenProject project : projects ) - { - String projectKey = KeyUtils.getVersionlessProjectKey( project ); - logger.debug( - "[" + projectKey + "] Overriding version from " + project.getVersion() + " to " + injectedVersion ); - reactorProjects.put( projectKey, project.getVersion() ); - project.setVersion( injectedVersion ); - project.getArtifact().setVersionRange( createFromVersion( injectedVersion ) ); - project.getArtifact().updateVersion( injectedVersion, session.getLocalRepository() ); - } - - for ( MavenProject project : projects ) - { - String projectKey = KeyUtils.getVersionlessProjectKey( project ); - MavenProject parent = project.getParent(); - String parentKey = KeyUtils.getVersionlessProjectKey( parent ); - String overriddenParentVersion = reactorProjects.get( parentKey ); - if ( overriddenParentVersion != null && overriddenParentVersion.equals( - project.getParentArtifact().getVersion() ) ) - { - logger.debug( - "[" + projectKey + "] Parent " + parentKey + " overriding artefact version from " - + parent.getVersion() + " to " + injectedVersion ); - project.getParentArtifact().setVersionRange( createFromVersion( injectedVersion ) ); - project.getParentArtifact().updateVersion( injectedVersion, session.getLocalRepository() ); - } - - for ( Dependency dependency : project.getDependencies() ) - { - String dependencyKey = KeyUtils.getVersionlessDependencyKey( dependency ); - String overriddenReactorVersion = reactorProjects.get( dependencyKey ); - if ( overriddenReactorVersion != null && overriddenReactorVersion.equals( dependency.getVersion() ) ) - { - logger.debug( - "[" + projectKey + "] Dependency " + dependencyKey + " overriding version from " - + dependency.getVersion() + " to " + injectedVersion ); - dependency.setVersion( injectedVersion ); - } - } - - for ( Dependency dependency : project.getDependencyManagement().getDependencies() ) - { - String dependencyKey = KeyUtils.getVersionlessDependencyKey( dependency ); - String overriddenReactorVersion = reactorProjects.get( dependencyKey ); - if ( overriddenReactorVersion != null && overriddenReactorVersion.equals( dependency.getVersion() ) ) - { - logger.debug( - "[" + projectKey + "] Dependency management " + dependencyKey - + " overriding version from " + dependency.getVersion() + " to " + injectedVersion ); - dependency.setVersion( injectedVersion ); - } - } - } - } - private Result sessionDependencyGraph( final MavenSession session ) throws CycleDetectedException, DuplicateProjectException { diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultMojoExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultMojoExecutor.java new file mode 100644 index 000000000000..16af887fbd14 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultMojoExecutor.java @@ -0,0 +1,385 @@ +package org.apache.maven.lifecycle.internal; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.artifact.resolver.filter.CumulativeScopeArtifactFilter; +import org.apache.maven.execution.ExecutionEvent; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.lifecycle.LifecycleExecutionException; +import org.apache.maven.lifecycle.MissingProjectException; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.plugin.MavenPluginManager; +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.PluginConfigurationException; +import org.apache.maven.plugin.PluginIncompatibleException; +import org.apache.maven.plugin.PluginManagerException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.util.StringUtils; + +/** + *

+ * Executes an individual mojo + *

+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice. + * + * @author Jason van Zyl + * @author Benjamin Bentmann + * @author Kristian Rosenvold + * @since 3.0 + */ +@Component( role = MojoExecutor.class ) +public class DefaultMojoExecutor implements MojoExecutor +{ + + @Requirement + private BuildPluginManager pluginManager; + + @Requirement + private MavenPluginManager mavenPluginManager; + + @Requirement + private LifecycleDependencyResolver lifeCycleDependencyResolver; + + @Requirement + private ExecutionEventCatapult eventCatapult; + + public DefaultMojoExecutor() + { + } + + public DependencyContext newDependencyContext( MavenSession session, List mojoExecutions ) + { + Set scopesToCollect = new TreeSet<>(); + Set scopesToResolve = new TreeSet<>(); + + collectDependencyRequirements( scopesToResolve, scopesToCollect, mojoExecutions ); + + return new DependencyContext( session.getCurrentProject(), scopesToCollect, scopesToResolve ); + } + + private void collectDependencyRequirements( Set scopesToResolve, Set scopesToCollect, + Collection mojoExecutions ) + { + for ( MojoExecution mojoExecution : mojoExecutions ) + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + scopesToResolve.addAll( toScopes( mojoDescriptor.getDependencyResolutionRequired() ) ); + + scopesToCollect.addAll( toScopes( mojoDescriptor.getDependencyCollectionRequired() ) ); + } + } + + private Collection toScopes( String classpath ) + { + Collection scopes = Collections.emptyList(); + + if ( StringUtils.isNotEmpty( classpath ) ) + { + if ( Artifact.SCOPE_COMPILE.equals( classpath ) ) + { + scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED ); + } + else if ( Artifact.SCOPE_RUNTIME.equals( classpath ) ) + { + scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME ); + } + else if ( Artifact.SCOPE_COMPILE_PLUS_RUNTIME.equals( classpath ) ) + { + scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, + Artifact.SCOPE_RUNTIME ); + } + else if ( Artifact.SCOPE_RUNTIME_PLUS_SYSTEM.equals( classpath ) ) + { + scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME ); + } + else if ( Artifact.SCOPE_TEST.equals( classpath ) ) + { + scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, + Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST ); + } + } + return Collections.unmodifiableCollection( scopes ); + } + + public void execute( MavenSession session, List mojoExecutions, ProjectIndex projectIndex ) + throws LifecycleExecutionException + + { + DependencyContext dependencyContext = newDependencyContext( session, mojoExecutions ); + + PhaseRecorder phaseRecorder = new PhaseRecorder( session.getCurrentProject() ); + + for ( MojoExecution mojoExecution : mojoExecutions ) + { + execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); + } + } + + public void execute( MavenSession session, MojoExecution mojoExecution, ProjectIndex projectIndex, + DependencyContext dependencyContext, PhaseRecorder phaseRecorder ) + throws LifecycleExecutionException + { + execute( session, mojoExecution, projectIndex, dependencyContext ); + phaseRecorder.observeExecution( mojoExecution ); + } + + private void execute( MavenSession session, MojoExecution mojoExecution, ProjectIndex projectIndex, + DependencyContext dependencyContext ) + throws LifecycleExecutionException + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + try + { + mavenPluginManager.checkRequiredMavenVersion( mojoDescriptor.getPluginDescriptor() ); + } + catch ( PluginIncompatibleException e ) + { + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e ); + } + + if ( mojoDescriptor.isProjectRequired() && !session.getRequest().isProjectPresent() ) + { + Throwable cause = new MissingProjectException( + "Goal requires a project to execute" + " but there is no POM in this directory (" + + session.getExecutionRootDirectory() + ")." + + " Please verify you invoked Maven from the correct directory." ); + throw new LifecycleExecutionException( mojoExecution, null, cause ); + } + + if ( mojoDescriptor.isOnlineRequired() && session.isOffline() ) + { + if ( MojoExecution.Source.CLI.equals( mojoExecution.getSource() ) ) + { + Throwable cause = new IllegalStateException( + "Goal requires online mode for execution" + " but Maven is currently offline." ); + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), cause ); + } + else + { + eventCatapult.fire( ExecutionEvent.Type.MojoSkipped, session, mojoExecution ); + + return; + } + } + + List forkedProjects = executeForkedExecutions( mojoExecution, session, projectIndex ); + + ensureDependenciesAreResolved( mojoDescriptor, session, dependencyContext ); + + eventCatapult.fire( ExecutionEvent.Type.MojoStarted, session, mojoExecution ); + + try + { + try + { + pluginManager.executeMojo( session, mojoExecution ); + } + catch ( MojoFailureException | PluginManagerException | PluginConfigurationException + | MojoExecutionException e ) + { + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e ); + } + + eventCatapult.fire( ExecutionEvent.Type.MojoSucceeded, session, mojoExecution ); + } + catch ( LifecycleExecutionException e ) + { + eventCatapult.fire( ExecutionEvent.Type.MojoFailed, session, mojoExecution, e ); + + throw e; + } + finally + { + for ( MavenProject forkedProject : forkedProjects ) + { + forkedProject.setExecutionProject( null ); + } + } + } + + public void ensureDependenciesAreResolved( MojoDescriptor mojoDescriptor, MavenSession session, + DependencyContext dependencyContext ) + throws LifecycleExecutionException + + { + MavenProject project = dependencyContext.getProject(); + boolean aggregating = mojoDescriptor.isAggregator(); + + if ( dependencyContext.isResolutionRequiredForCurrentProject() ) + { + Collection scopesToCollect = dependencyContext.getScopesToCollectForCurrentProject(); + Collection scopesToResolve = dependencyContext.getScopesToResolveForCurrentProject(); + + lifeCycleDependencyResolver.resolveProjectDependencies( project, scopesToCollect, scopesToResolve, session, + aggregating, Collections.emptySet() ); + + dependencyContext.synchronizeWithProjectState(); + } + + if ( aggregating ) + { + Collection scopesToCollect = toScopes( mojoDescriptor.getDependencyCollectionRequired() ); + Collection scopesToResolve = toScopes( mojoDescriptor.getDependencyResolutionRequired() ); + + if ( dependencyContext.isResolutionRequiredForAggregatedProjects( scopesToCollect, scopesToResolve ) ) + { + for ( MavenProject aggregatedProject : session.getProjects() ) + { + if ( aggregatedProject != project ) + { + lifeCycleDependencyResolver.resolveProjectDependencies( aggregatedProject, scopesToCollect, + scopesToResolve, session, aggregating, + Collections.emptySet() ); + } + } + } + } + + ArtifactFilter artifactFilter = getArtifactFilter( mojoDescriptor ); + List projectsToResolve = + LifecycleDependencyResolver.getProjects( session.getCurrentProject(), session, + mojoDescriptor.isAggregator() ); + for ( MavenProject projectToResolve : projectsToResolve ) + { + projectToResolve.setArtifactFilter( artifactFilter ); + } + } + + private ArtifactFilter getArtifactFilter( MojoDescriptor mojoDescriptor ) + { + String scopeToResolve = mojoDescriptor.getDependencyResolutionRequired(); + String scopeToCollect = mojoDescriptor.getDependencyCollectionRequired(); + + List scopes = new ArrayList<>( 2 ); + if ( StringUtils.isNotEmpty( scopeToCollect ) ) + { + scopes.add( scopeToCollect ); + } + if ( StringUtils.isNotEmpty( scopeToResolve ) ) + { + scopes.add( scopeToResolve ); + } + + if ( scopes.isEmpty() ) + { + return null; + } + else + { + return new CumulativeScopeArtifactFilter( scopes ); + } + } + + public List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session, + ProjectIndex projectIndex ) + throws LifecycleExecutionException + { + List forkedProjects = Collections.emptyList(); + + Map> forkedExecutions = mojoExecution.getForkedExecutions(); + + if ( !forkedExecutions.isEmpty() ) + { + eventCatapult.fire( ExecutionEvent.Type.ForkStarted, session, mojoExecution ); + + MavenProject project = session.getCurrentProject(); + + forkedProjects = new ArrayList<>( forkedExecutions.size() ); + + try + { + for ( Map.Entry> fork : forkedExecutions.entrySet() ) + { + String projectId = fork.getKey(); + + int index = projectIndex.getIndices().get( projectId ); + + MavenProject forkedProject = projectIndex.getProjects().get( projectId ); + + forkedProjects.add( forkedProject ); + + MavenProject executedProject = forkedProject.clone(); + + forkedProject.setExecutionProject( executedProject ); + + List mojoExecutions = fork.getValue(); + + if ( mojoExecutions.isEmpty() ) + { + continue; + } + + try + { + session.setCurrentProject( executedProject ); + session.getProjects().set( index, executedProject ); + projectIndex.getProjects().put( projectId, executedProject ); + + eventCatapult.fire( ExecutionEvent.Type.ForkedProjectStarted, session, mojoExecution ); + + execute( session, mojoExecutions, projectIndex ); + + eventCatapult.fire( ExecutionEvent.Type.ForkedProjectSucceeded, session, mojoExecution ); + } + catch ( LifecycleExecutionException e ) + { + eventCatapult.fire( ExecutionEvent.Type.ForkedProjectFailed, session, mojoExecution, e ); + + throw e; + } + finally + { + projectIndex.getProjects().put( projectId, forkedProject ); + session.getProjects().set( index, forkedProject ); + session.setCurrentProject( project ); + } + } + + eventCatapult.fire( ExecutionEvent.Type.ForkSucceeded, session, mojoExecution ); + } + catch ( LifecycleExecutionException e ) + { + eventCatapult.fire( ExecutionEvent.Type.ForkFailed, session, mojoExecution, e ); + + throw e; + } + } + + return forkedProjects; + } +} \ No newline at end of file diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java index 59f384983d9e..78aaedd3b298 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java @@ -19,575 +19,26 @@ * under the License. */ -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.artifact.resolver.filter.CumulativeScopeArtifactFilter; -import org.apache.maven.caching.CacheController; -import org.apache.maven.caching.CacheResult; -import org.apache.maven.caching.MojoExecutionManager; -import org.apache.maven.caching.MojoParametersListener; -import org.apache.maven.caching.xml.BuildInfo; -import org.apache.maven.caching.xml.CacheConfig; -import org.apache.maven.caching.xml.CacheState; -import org.apache.maven.execution.ExecutionEvent; +import java.util.List; + import org.apache.maven.execution.MavenSession; -import org.apache.maven.execution.MojoExecutionEvent; -import org.apache.maven.execution.MojoExecutionListener; import org.apache.maven.lifecycle.LifecycleExecutionException; -import org.apache.maven.lifecycle.MissingProjectException; -import org.apache.maven.plugin.BuildPluginManager; -import org.apache.maven.plugin.MavenPluginManager; import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.plugin.MojoExecution.Source; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugin.PluginConfigurationException; -import org.apache.maven.plugin.PluginIncompatibleException; -import org.apache.maven.plugin.PluginManagerException; -import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; -import org.codehaus.plexus.logging.Logger; -import org.codehaus.plexus.util.StringUtils; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.atomic.AtomicBoolean; - -import static org.apache.maven.caching.ProjectUtils.isLaterPhase; -import static org.apache.maven.caching.checksum.KeyUtils.getVersionlessProjectKey; -import static org.apache.maven.caching.xml.CacheState.DISABLED; -import static org.apache.maven.caching.xml.CacheState.INITIALIZED; - /** *

* Executes an individual mojo *

- * NOTE: This class is not part of any public api and can be changed or deleted without prior notice. - * - * @author Jason van Zyl - * @author Benjamin Bentmann - * @author Kristian Rosenvold - * @since 3.0 */ -@Component( role = MojoExecutor.class ) -public class MojoExecutor +public interface MojoExecutor { - @Requirement - private Logger logger; - - @Requirement - private BuildPluginManager pluginManager; - - @Requirement - private MavenPluginManager mavenPluginManager; - - @Requirement - private LifecycleDependencyResolver lifeCycleDependencyResolver; - - @Requirement - private ExecutionEventCatapult eventCatapult; - - @Requirement - private CacheController cacheController; - - @Requirement - private CacheConfig cacheConfig; - - @Requirement( role = MojoExecutionListener.class, hint = "MojoParametersListener" ) - private MojoParametersListener mojoListener; - - public MojoExecutor() - { - } - - public DependencyContext newDependencyContext( MavenSession session, List mojoExecutions ) - { - Set scopesToCollect = new TreeSet<>(); - Set scopesToResolve = new TreeSet<>(); - - collectDependencyRequirements( scopesToResolve, scopesToCollect, mojoExecutions ); - - return new DependencyContext( session.getCurrentProject(), scopesToCollect, scopesToResolve ); - } - - private void collectDependencyRequirements( Set scopesToResolve, Set scopesToCollect, - Collection mojoExecutions ) - { - for ( MojoExecution mojoExecution : mojoExecutions ) - { - MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); - - scopesToResolve.addAll( toScopes( mojoDescriptor.getDependencyResolutionRequired() ) ); - - scopesToCollect.addAll( toScopes( mojoDescriptor.getDependencyCollectionRequired() ) ); - } - } - - private Collection toScopes( String classpath ) - { - Collection scopes = Collections.emptyList(); - - if ( StringUtils.isNotEmpty( classpath ) ) - { - if ( Artifact.SCOPE_COMPILE.equals( classpath ) ) - { - scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED ); - } - else if ( Artifact.SCOPE_RUNTIME.equals( classpath ) ) - { - scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME ); - } - else if ( Artifact.SCOPE_COMPILE_PLUS_RUNTIME.equals( classpath ) ) - { - scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, - Artifact.SCOPE_RUNTIME ); - } - else if ( Artifact.SCOPE_RUNTIME_PLUS_SYSTEM.equals( classpath ) ) - { - scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME ); - } - else if ( Artifact.SCOPE_TEST.equals( classpath ) ) - { - scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, - Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST ); - } - } - return Collections.unmodifiableCollection( scopes ); - } - - public void execute( MavenSession session, List mojoExecutions, ProjectIndex projectIndex ) - throws LifecycleExecutionException - { - DependencyContext dependencyContext = newDependencyContext( session, mojoExecutions ); - - PhaseRecorder phaseRecorder = new PhaseRecorder( session.getCurrentProject() ); - - final MavenProject project = session.getCurrentProject(); - final Source source = getSource( mojoExecutions ); - - // execute clean bound goals before restoring to not interfere/slowdown clean - CacheState cacheState = DISABLED; - CacheResult result = CacheResult.empty(); - if ( source == Source.LIFECYCLE ) - { - List cleanPhase = getCleanPhase( mojoExecutions ); - for ( MojoExecution mojoExecution : cleanPhase ) - { - execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); - } - cacheState = cacheConfig.initialize( project, session ); - if ( cacheState == INITIALIZED ) - { - result = cacheController.findCachedBuild( session, project, projectIndex, mojoExecutions ); - } - } - - boolean restorable = result.isSuccess() || result.isPartialSuccess(); - boolean restored = result.isSuccess(); // if partially restored need to save increment - if ( restorable ) - { - restored &= restoreProject( result, mojoExecutions, projectIndex, dependencyContext, phaseRecorder ); - } - else - { - for ( MojoExecution mojoExecution : mojoExecutions ) - { - if ( source == Source.CLI || isLaterPhase( mojoExecution.getLifecyclePhase(), "post-clean" ) ) - { - execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); - } - } - } - - if ( cacheState == INITIALIZED && ( !restorable || !restored ) ) - { - final Map executionEvents = mojoListener.getProjectExecutions( project ); - cacheController.save( result, mojoExecutions, executionEvents ); - } - - if ( cacheConfig.isFailFast() && !result.isSuccess() ) - { - throw new LifecycleExecutionException( - "Failed to restore project[" + getVersionlessProjectKey( project ) + "] from cache, failing build.", - project ); - } - } - - private Source getSource( List mojoExecutions ) - { - if ( mojoExecutions == null || mojoExecutions.isEmpty() ) - { - return null; - } - for ( MojoExecution mojoExecution : mojoExecutions ) - { - if ( mojoExecution.getSource() == Source.CLI ) - { - return Source.CLI; - } - } - return Source.LIFECYCLE; - } - - private boolean restoreProject( CacheResult cacheResult, - List mojoExecutions, - ProjectIndex projectIndex, - DependencyContext dependencyContext, - PhaseRecorder phaseRecorder ) throws LifecycleExecutionException - { - - final BuildInfo buildInfo = cacheResult.getBuildInfo(); - final MavenProject project = cacheResult.getContext().getProject(); - final MavenSession session = cacheResult.getContext().getSession(); - final List cachedSegment = buildInfo.getCachedSegment( mojoExecutions ); - - boolean restored = cacheController.restoreProjectArtifacts( cacheResult ); - if ( !restored ) - { - logger.info( - "[CACHE][" + project.getArtifactId() - + "] Cannot restore project artifacts, continuing with non cached build" ); - return false; - } - - for ( MojoExecution cacheCandidate : cachedSegment ) - { - - if ( cacheController.isForcedExecution( project, cacheCandidate ) ) - { - logger.info( - "[CACHE][" + project.getArtifactId() + "] Mojo execution is forced by project property: " - + cacheCandidate.getMojoDescriptor().getFullGoalName() ); - execute( session, cacheCandidate, projectIndex, dependencyContext, phaseRecorder ); - } - else - { - restored = verifyCacheConsistency( cacheCandidate, buildInfo, project, session, projectIndex, - dependencyContext, phaseRecorder ); - if ( !restored ) - { - break; - } - } - } - - if ( !restored ) - { - // cleanup partial state - project.getArtifact().setFile( null ); - project.getArtifact().setResolved( false ); - project.getAttachedArtifacts().clear(); - mojoListener.remove( project ); - // build as usual - for ( MojoExecution mojoExecution : cachedSegment ) - { - execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); - } - } - - for ( MojoExecution mojoExecution : buildInfo.getPostCachedSegment( mojoExecutions ) ) - { - execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); - } - return restored; - } - - private boolean verifyCacheConsistency( MojoExecution cacheCandidate, - BuildInfo cachedBuildInfo, - MavenProject project, - MavenSession session, - ProjectIndex projectIndex, - DependencyContext dependencyContext, - PhaseRecorder phaseRecorder ) throws LifecycleExecutionException - { - - AtomicBoolean consistent = new AtomicBoolean( true ); - final MojoExecutionManager mojoChecker = new MojoExecutionManager( project, cacheController, cachedBuildInfo, - consistent, logger, cacheConfig ); - - if ( mojoChecker.needCheck( cacheCandidate, session ) ) - { - try - { - // actual execution will not happen (if not forced). decision delayed to execution time - // then all properties are resolved. - cacheCandidate.setMojoExecutionManager( mojoChecker ); - IDependencyContext nop = new NoResolutionContext( dependencyContext ); - execute( session, cacheCandidate, projectIndex, nop, phaseRecorder ); - } - finally - { - cacheCandidate.setMojoExecutionManager( null ); - } - } - else - { - logger.info( - "[CACHE][" + project.getArtifactId() + "] Skipping plugin execution (cached): " - + cacheCandidate.getMojoDescriptor().getFullGoalName() ); - } - - return consistent.get(); - } - - private List getCleanPhase( List mojoExecutions ) - { - List list = new ArrayList<>(); - for ( MojoExecution mojoExecution : mojoExecutions ) - { - if ( isLaterPhase( mojoExecution.getLifecyclePhase(), "post-clean" ) ) - { - break; - } - list.add( mojoExecution ); - } - return list; - } - - public void execute( MavenSession session, - MojoExecution mojoExecution, - ProjectIndex projectIndex, - IDependencyContext dependencyContext, - PhaseRecorder phaseRecorder ) throws LifecycleExecutionException - { - execute( session, mojoExecution, projectIndex, dependencyContext ); - phaseRecorder.observeExecution( mojoExecution ); - } - - private void execute( MavenSession session, - MojoExecution mojoExecution, - ProjectIndex projectIndex, - IDependencyContext dependencyContext ) throws LifecycleExecutionException - { - MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); - - try - { - mavenPluginManager.checkRequiredMavenVersion( mojoDescriptor.getPluginDescriptor() ); - } - catch ( PluginIncompatibleException e ) - { - throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e ); - } - - if ( mojoDescriptor.isProjectRequired() && !session.getRequest().isProjectPresent() ) - { - Throwable cause = new MissingProjectException( - "Goal requires a project to execute" + " but there is no POM in this directory (" - + session.getExecutionRootDirectory() + ")." - + " Please verify you invoked Maven from the correct directory." ); - throw new LifecycleExecutionException( mojoExecution, null, cause ); - } - - if ( mojoDescriptor.isOnlineRequired() && session.isOffline() ) - { - if ( Source.CLI.equals( mojoExecution.getSource() ) ) - { - Throwable cause = new IllegalStateException( - "Goal requires online mode for execution" + " but Maven is currently offline." ); - throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), cause ); - } - else - { - eventCatapult.fire( ExecutionEvent.Type.MojoSkipped, session, mojoExecution ); - - return; - } - } - - List forkedProjects = executeForkedExecutions( mojoExecution, session, projectIndex ); - - ensureDependenciesAreResolved( mojoDescriptor, session, dependencyContext ); - - eventCatapult.fire( ExecutionEvent.Type.MojoStarted, session, mojoExecution ); - - try - { - try - { - pluginManager.executeMojo( session, mojoExecution ); - } - catch ( MojoFailureException - | PluginManagerException - | PluginConfigurationException - | MojoExecutionException e ) - { - throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e ); - } - - eventCatapult.fire( ExecutionEvent.Type.MojoSucceeded, session, mojoExecution ); - } - catch ( LifecycleExecutionException e ) - { - eventCatapult.fire( ExecutionEvent.Type.MojoFailed, session, mojoExecution, e ); - - throw e; - } - finally - { - for ( MavenProject forkedProject : forkedProjects ) - { - forkedProject.setExecutionProject( null ); - } - } - } - - public void ensureDependenciesAreResolved( MojoDescriptor mojoDescriptor, - MavenSession session, - IDependencyContext dependencyContext ) throws LifecycleExecutionException - - { - MavenProject project = dependencyContext.getProject(); - boolean aggregating = mojoDescriptor.isAggregator(); - - if ( dependencyContext.isResolutionRequiredForCurrentProject() ) - { - Collection scopesToCollect = dependencyContext.getScopesToCollectForCurrentProject(); - Collection scopesToResolve = dependencyContext.getScopesToResolveForCurrentProject(); - - lifeCycleDependencyResolver.resolveProjectDependencies( project, scopesToCollect, scopesToResolve, session, - aggregating, Collections.emptySet() ); - - dependencyContext.synchronizeWithProjectState(); - } - - if ( aggregating ) - { - Collection scopesToCollect = toScopes( mojoDescriptor.getDependencyCollectionRequired() ); - Collection scopesToResolve = toScopes( mojoDescriptor.getDependencyResolutionRequired() ); - - if ( dependencyContext.isResolutionRequiredForAggregatedProjects( scopesToCollect, scopesToResolve ) ) - { - for ( MavenProject aggregatedProject : session.getProjects() ) - { - if ( aggregatedProject != project ) - { - lifeCycleDependencyResolver.resolveProjectDependencies( aggregatedProject, scopesToCollect, - scopesToResolve, session, aggregating, Collections.emptySet() ); - } - } - } - } - - ArtifactFilter artifactFilter = getArtifactFilter( mojoDescriptor ); - List projectsToResolve = LifecycleDependencyResolver.getProjects( session.getCurrentProject(), - session, mojoDescriptor.isAggregator() ); - for ( MavenProject projectToResolve : projectsToResolve ) - { - projectToResolve.setArtifactFilter( artifactFilter ); - } - } - - private ArtifactFilter getArtifactFilter( MojoDescriptor mojoDescriptor ) - { - String scopeToResolve = mojoDescriptor.getDependencyResolutionRequired(); - String scopeToCollect = mojoDescriptor.getDependencyCollectionRequired(); - - List scopes = new ArrayList<>( 2 ); - if ( StringUtils.isNotEmpty( scopeToCollect ) ) - { - scopes.add( scopeToCollect ); - } - if ( StringUtils.isNotEmpty( scopeToResolve ) ) - { - scopes.add( scopeToResolve ); - } - - if ( scopes.isEmpty() ) - { - return null; - } - else - { - return new CumulativeScopeArtifactFilter( scopes ); - } - } - - public List executeForkedExecutions( MojoExecution mojoExecution, - MavenSession session, - ProjectIndex projectIndex ) throws LifecycleExecutionException - { - List forkedProjects = Collections.emptyList(); - - Map> forkedExecutions = mojoExecution.getForkedExecutions(); - - if ( !forkedExecutions.isEmpty() ) - { - eventCatapult.fire( ExecutionEvent.Type.ForkStarted, session, mojoExecution ); - - MavenProject project = session.getCurrentProject(); - - forkedProjects = new ArrayList<>( forkedExecutions.size() ); - - try - { - for ( Map.Entry> fork : forkedExecutions.entrySet() ) - { - String projectId = fork.getKey(); - - int index = projectIndex.getIndices().get( projectId ); - - MavenProject forkedProject = projectIndex.getProjects().get( projectId ); - - forkedProjects.add( forkedProject ); - - MavenProject executedProject = forkedProject.clone(); - - forkedProject.setExecutionProject( executedProject ); - - List mojoExecutions = fork.getValue(); - - if ( mojoExecutions.isEmpty() ) - { - continue; - } - - try - { - session.setCurrentProject( executedProject ); - session.getProjects().set( index, executedProject ); - projectIndex.getProjects().put( projectId, executedProject ); - - eventCatapult.fire( ExecutionEvent.Type.ForkedProjectStarted, session, mojoExecution ); - - execute( session, mojoExecutions, projectIndex ); - - eventCatapult.fire( ExecutionEvent.Type.ForkedProjectSucceeded, session, mojoExecution ); - } - catch ( LifecycleExecutionException e ) - { - eventCatapult.fire( ExecutionEvent.Type.ForkedProjectFailed, session, mojoExecution, e ); - - throw e; - } - finally - { - projectIndex.getProjects().put( projectId, forkedProject ); - session.getProjects().set( index, forkedProject ); - session.setCurrentProject( project ); - } - } - - eventCatapult.fire( ExecutionEvent.Type.ForkSucceeded, session, mojoExecution ); - } - catch ( LifecycleExecutionException e ) - { - eventCatapult.fire( ExecutionEvent.Type.ForkFailed, session, mojoExecution, e ); + void execute( MavenSession session, List mojoExecutions, ProjectIndex projectIndex ) + throws LifecycleExecutionException; - throw e; - } - } + List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session, + ProjectIndex projectIndex ) + throws LifecycleExecutionException; - return forkedProjects; - } -} +} \ No newline at end of file diff --git a/maven-core/src/main/resources/cache-config-instance.xml b/maven-core/src/main/resources/cache-config-instance.xml deleted file mode 100644 index 68555927800a..000000000000 --- a/maven-core/src/main/resources/cache-config-instance.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - true - SHA-256 - true - - http://host:port - - - 3 - - - - - - - {*.java,*.groovy,*.yaml,*.svcd,*.proto,*assembly.xml,assembly*.xml,*logback.xml,*.vm,*.ini,*.jks,*.properties,*.sh,*.bat} - - src/ - pom.xml - - - - 111 - - - - - - - - 1 - 2 - - - - - - - - - .*-processes.*\.zip - - - - - - - aaa - - - install - - - deploy - - - deploy-local - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/maven-core/src/main/resources/cache-config.xsd b/maven-core/src/main/resources/cache-config.xsd deleted file mode 100644 index 69437d993300..000000000000 --- a/maven-core/src/main/resources/cache-config.xsd +++ /dev/null @@ -1,640 +0,0 @@ - - - - - - - - - - - - - - - - - - - Cached build metadata - - - - - - - - - - Configuration of major cache properties - - - - - - - Configuration for source code input files participating in checksum calculation - - - - - - - Configuration for output artifacts, it's needed if you want to explicitly include/exclude something from caching - - - - - - - Execution rules for plugins in cached mode. Defines which plugins should run always - - - - - - - - - - - - - - - - 64 bit XX family hashing. Fast, but higher probability of collisions - - - - - - - 64 bit XX family hashing, with usage of Memory Mapped Buffer - - - - - - - - - - - - - - Validate cache config and builds metadata against xsd. - - - - - - - Specifies how to identify belonging to a cached project then submodule is being build. - - - - - - - - Any project dependency this this version will be considered cache eligible and will - be processed cache aware - - - - - - - - - - - - - address of remote cache - - - - - - - - - Save output to remote cache. Recommended to enable on CI agents only. - - - - - - - - - - - - Directory name in build output directory to attach to cached artifacts - - - - - - - - - - - - - Maximum number of cached build per artifact in local cache. First created cache (the - oldest) is - evicted if breached. - - - - - - - - - - - - - Causes file hash is saved in build metadata - - - - - - - Causes effective pom info is saved in build metadata - - - - - - - - - - - - - - - Global input calculation rules applicable to all projects and plugins in the build - - - - - - - Plugin specific input calculation rules - - - - - - - - - - - - - - Effective pom calculation rules - - - - - - - - Plugin configuration property should be excluded from effective pom - calculation - - - - - - - - - - Specifies plugin level rules of configuration processing in search of referenced source - files - - - - - - - Specifies execution specific configuration processing in search of referenced source - files - - - - - - - - - - - - - - - Specifies rules of configuration processing in search of referenced source files - - - - - - - - ignore parent config or inherit/merge - - - - - - - - - Common attributes for scanning paths - - - - - - Should walk directory specified in property recursively or not - - - - - - - Glob to apply when scanning dir denoted by this property - - - - - - - - - - - - - - - - - - - Forces cache to treat property value as input and include in calculation. If set, only included - properties will be takein in calculation (whitelist) - - - - - - - - Tag to exclude when scanning plugin configuration for input files (blacklist) - - - - - - - Additional processing rules for non-blacklisted tags - - - - - - - - - - Ignore parent settings or inherit and merge - - - - - - - - - - - Scan directory accordingly to cache implementation - - - - - - - Skip directory - - - - - - - - - - - - - - Patterns to exclude output artifacts applicable to all projects in the build - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Specify property which should be reconciled against running build - - - - - - - Specify property which should be logged to build metadata for exploration - - - - - - - Specify property which should not be logged - - - - - - - - Controls if all plugin properties to be logged (true is default). All the properties logged - with respect to log/nolog children: - * true: logged all if no blacklists () and whitelists () specified on plugin - level - * false: logged only tracked and included by whitelists () on plugin level - - - - - - - - - - - - - Specify which plugin should run always if present in build regardless of cached status - - - - - - - Specify which executions/plugins/goals do not affect generated artifacts and do not affect build correctness. - If cached build lacks of ignorable executions only, it still could be reused. - Typically case is then cached build is produced with 'verify' and you locally you run 'install'. - Strictly speaking these are different builds but in most of cases you want this difference to be ignored - - - - - - - Specify which plugin should run always if present in build regardless of cached status - - - - - - - - Reconciliation rules for plugin properties which might be affected by command line - flags, etc - - - - - - - - Controls if all plugin properties to be logged (true is default). All the properties - logged with respect to children: - * logAll on plugin level overrides global value - * true: logged all if no blacklists () and whitelists () specified on - plugin level - * false: logged only tracked and included by whitelists () on plugin level - - - - - - - - - - - - - - - Specify which plugin should run always if present in build regardless of cached status - - - - - - - Specify which executions should run always if present in build regardless of cached status - - - - - - - Specify which goals should run always if present in build regardless of cached status - - - - - - - - - - - - - - Goals identification - - - - - - - - - - - - - - - - - - - - - - - - - Executions ids list with plugin identifier - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Specify which value denotes skipped execution in plugin config. - If active build skips execution (property set to skipValue) cache will allow such - discrepancy. - - - - - - - Manual value for reconciliation. Required to reconcile runtime only properties - - - - - - - - diff --git a/maven-core/src/main/resources/cache-domain.xsd b/maven-core/src/main/resources/cache-domain.xsd deleted file mode 100644 index c233ed46e463..000000000000 --- a/maven-core/src/main/resources/cache-domain.xsd +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/maven-core/src/test/java/org/apache/maven/caching/xml/CacheConfigTest.java b/maven-core/src/test/java/org/apache/maven/caching/xml/CacheConfigTest.java deleted file mode 100644 index b18752fd0594..000000000000 --- a/maven-core/src/test/java/org/apache/maven/caching/xml/CacheConfigTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.apache.maven.caching.xml; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.junit.Test; - -import java.nio.file.Path; -import java.nio.file.Paths; - -public class CacheConfigTest { - - @Test - public void testMU() { -// final Path path = Paths.get("W:\\dev\\abfx\\maven-cache-config.xml"); -// final CacheConfig cacheConfig = CacheConfig.fromFile(path.toFile()); -// System.out.println(cacheConfig.toString()); - } -} \ No newline at end of file diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java index 1650e24eb681..a9cdb4a301db 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java @@ -21,6 +21,7 @@ import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; import java.util.ArrayList; import java.util.Collections; @@ -30,12 +31,11 @@ * @author Kristian Rosenvold */ public class MojoExecutorStub - extends MojoExecutor + implements MojoExecutor { // This is being lazy instead of making interface public List executions = Collections.synchronizedList( new ArrayList() ); - @Override public void execute(MavenSession session, MojoExecution mojoExecution, ProjectIndex projectIndex, IDependencyContext dependencyContext, PhaseRecorder phaseRecorder ) throws LifecycleExecutionException @@ -50,8 +50,13 @@ public void execute( MavenSession session, List mojoExecutions, P executions.addAll(mojoExecutions); } + @Override + public List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session, ProjectIndex projectIndex ) throws LifecycleExecutionException + { + return null; + } - public static MojoDescriptor createMojoDescriptor( String mojoDescription ) + public static MojoDescriptor createMojoDescriptor(String mojoDescription ) { final PluginDescriptor descriptor = new PluginDescriptor(); descriptor.setArtifactId( mojoDescription ); diff --git a/pom.xml b/pom.xml index f76757ba9fc6..44a61b887f3f 100644 --- a/pom.xml +++ b/pom.xml @@ -86,6 +86,7 @@ under the License. maven-model maven-model-builder maven-core + maven-caching maven-settings maven-settings-builder maven-artifact @@ -197,6 +198,11 @@ under the License. maven-core ${project.version} + + org.apache.maven + maven-caching + ${project.version} + org.apache.maven maven-model-builder @@ -555,7 +561,6 @@ under the License. --> src/main/appended-resources/licenses/CDDL-1.0.txt src/main/appended-resources/licenses/EPL-1.0.txt - src/main/appended-resources/licenses/EDL-1.0.txt src/main/appended-resources/licenses/MPL-1.1.txt src/main/appended-resources/licenses/LGPL-3.0.txt .editorconfig