This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch MNG-7129-maven-caching
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/MNG-7129-maven-caching by this
push:
new f5557a7 [MNG-7129] Maven cache docs updates (#631)
f5557a7 is described below
commit f5557a7596330dc1179eccb22f89a20166bd3300
Author: Alexander Ashitkin <[email protected]>
AuthorDate: Fri Dec 10 03:21:24 2021 -0500
[MNG-7129] Maven cache docs updates (#631)
---
.../src/site/markdown/CACHE-REMOTE.md | 249 ---------------------
maven-caching-extension/src/site/markdown/CACHE.md | 170 --------------
maven-caching-extension/src/site/markdown/cache.md | 131 +++++++++++
.../src/site/markdown/getting-started.md | 69 ++++++
.../site/markdown/{CACHE-HOWTO.md => how-to.md} | 6 +-
.../src/site/markdown/maven-cache-config.xml | 5 +
.../{CACHE-PARAMETERS.md => parameters.md} | 15 +-
.../src/site/markdown/performance.md | 103 +++++++++
.../src/site/markdown/remote-cache.md | 242 ++++++++++++++++++++
maven-caching-extension/src/site/markdown/usage.md | 57 +++++
10 files changed, 618 insertions(+), 429 deletions(-)
diff --git a/maven-caching-extension/src/site/markdown/CACHE-REMOTE.md
b/maven-caching-extension/src/site/markdown/CACHE-REMOTE.md
deleted file mode 100644
index c89e5de..0000000
--- a/maven-caching-extension/src/site/markdown/CACHE-REMOTE.md
+++ /dev/null
@@ -1,249 +0,0 @@
-<!---
- 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.
--->
-
-# Overview
-
-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.
-
-# Step-By-Step
-
-## Fork branch for cache setup purposes
-
-It is recommended to fork branch for cache setup purposes as you might need to
do changes to project build as long as
-you go.
-
-## Setup http server to store artifacts
-
-In order to share build results you need shared storage. Basically any http
server which supports http PUT/GET/HEAD
-operations will work. In our case it is a Nginx OSS with file system module.
Add the url to config and
-change `remote@enabled` to true:
-
-```xml
-
-<remote enabled="true">
- <url>http://your-buildcache-url</url>
-</remote>
-```
-
-Known limitations: auth is not supported yet
-
-## Build selection
-
-In order to share build results, you need a golden source of builds. Build
stored in cache ideally should be a build
-assembled in the most correct, comprehensive and complete way. In such a case
you can make sure that whoever reuses such
-build doesn't compromise quality of own build. Often per pull requests builds
are the best candidates to populate cache
-because they seed cache fast and provide sufficient quality safeguards.
-
-## CI Build setup to seed shared cache
-
-In order to share build results, you need to store builds in the shared
storage. Default scheme is to configure
-designated CI nodes only to push in cache and prohibit elsewhere. In order to
allow writes in remote cache add jvm
-property to designated CI builds.
-
-```
--Dremote.cache.save.enabled=true
-```
-
-Run your branch, review log and ensure that artifacts are uploaded to remote
cache. Now, rerun build and ensure that it
-completes almost instantly because it is fully cached. Hint: consider limiting
first attempts to single agent/node to
-simplify troubleshooting.
-
-## Normalize local builds to reuse CI build cache
-
-As practice shows, developers often don't realize that builds they run in
local and CI environments are different. So
-straightforward attempt to reuse remote cache in local build usually results
in cache misses because of difference in
-plugins, parameters, profiles, environment, etc. In order to reuse results you
might need to change poms, cache config,
-CI jobs and the project itself. This part is usually most challenging and
time-consuming. Follow steps below to
-iteratively achieve working configuration.
-
-### Before you start
-
-Before you start, please keep in mind basic principles:
-
-* Cache is checksum based, it is a complex hash function essentially. In order
to to produce the same hash the source
- code, effective poms and dependencies should match.
-* There is no built-in normalization of line endings in this implementation,
file checksum calculation is raw bytes
- based. The most obvious implication could be illustrated by a simple Git
checkout. By default git will check out
- source code with CRLF line endings on win and LF on Linux. Because of that
builds over same commit on a Linux agent
- and local build on Windows workstation will yield different checksums.
-* Parameters of plugins are manually tracked ony. For example to avoid of
accidentally reusing builds which never run
- tests ensure that critical surfire parameters are tracked (`skipTests` and
similar) in config. The same applies for
- all over plugins.
-
-### Configure local build in debug mode
-
-To minimize distractions and simplify understanding of discrepancies following
is recommended:
-
-* Run build with single threaded builder to make sure logs from different
modules do not interfere
-* Enable cache fail fast mode to focus on the blocking failure
-* Provide reference to the CI build as a baseline for comparison between your
local and remote builds. Go to the
- reference CI build and one of the final lines of the build should be
-
-```
-[INFO] [CACHE][artifactId] Saved to remote cache
https://your-cache-url/<...>/915296a3-4596-4eb5-bf37-f6e13ebe087e/cache-report.xml.
-```
-
-followed by a link to a `cache-report.xml` file. The `cache-report.xml`
contains aggregated information about the
-produced cache and could be used as a baseline for comparison.
-
-* Run local build. Command line should look similar to this:
-
-```bash
-mvnw verify -Dremote.cache.failFast=true
-Dremote.cache.baselineUrl=https://url-from-ci-build-to-cache-report.xml
-```
-
-Once discrepancy between remote and local builds detected cache will fail with
diagnostic info
-in `target/incremental-maven` directory:
-
-```
-* 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
-```
-
-Review `buildsdiff.xml` file and eliminate detected discrepancies.You can also
diff build-info files directly to get low
-level insights. See techniques to configure cache in [How-To](CACHE-HOWTO.md)
and troubleshooting of typical issues in
-the section below.
-
-# Common issues
-
-## Issue 1: Local checkout is with different line endings
-
-Solution: normalise line endings. Current implementation doesn't have built-in
line endings normalization, it has to be
-done externally. In git it is recommended to use `.gitattributes` file to
establish consistent line endings across all
-envs for file types specific to this project
-
-## Issue 2: Effective poms mismatch because of plugins filtering by profiles
-
-Different profiles between remote and local builds results in different text
of effective poms and break checksums.
-Solution: instead of adding/removing specific plugins from build altogether
with profiles use profile specific `skip`
-or `disabled` flags instead. Instead of:
-
- ```
- <profiles>
- <profile>
- <id>run-plugin-in-ci-only</id>
- <build>
- <plugins>
- <plugin>
- <artifactId>surefire-report-maven-plugin</artifactId>
- <configuration>
- <!-- my configuration -->
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
- ```
-
-Use:
-
- ```xml
-
-<properties>
- <!-- default value -->
- <skip.plugin.property>true</skip.plugin.property>
-</properties>
-<build>
-<plugins>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <!-- plugin behavior is controlled by property -->
- <skip>${skip.plugin.property}</skip>
- </configuration>
- </plugin>
-</plugins>
-</build>
-<profiles>
-<profile>
- <id>run-plugin-in-ci-only</id>
- <properties>
- <!-- override to run plugin in reference ci build -->
- <skip.plugin.property>false</skip.plugin.property>
- </properties>
-</profile>
-</profiles>
- ```
-
-Hint: effective poms could be found in `buildinfo` files under
`/build/projectsInputInfo/item[@type='pom']`
-xpath (`item type="pom"`).
-
-## Issue 3: Effective pom mismatch because of environment specific properties
-
-Potential reason: Sometimes it is not possible to avoid discrepancies in
different environments - for example if you
-need to invoke command line command, it will be likely different on win and
linux. Such commands will appear in
-effective pom as a different literal values and will result in checksum
mismatch Solution: filter out such properties
-from cache effective pom:
-
-```xml
-
-<input>
- <global>
- ...
- </global>
- <plugin artifactId="maven-surefire-plugin">
- <effectivePom>
- <excludeProperty>argLine</excludeProperty>
- </effectivePom>
- </plugin>
-</input>
-```
-
-## Issue 4: Unexpected or transient files in checksum calculation
-
-Potential reasons: plugins or tests emit temporary files (logs and similar) in
non-standard locations Solution: adjust
-global exclusions list to filter out unexpected files:
-
-```
-<global>
- <exclude>tempfile.out</exclude>
-</global>
-```
-
-see sample config for exact syntax
-
-## Issue 5: Difference in tracked plugin properties
-
-Tracked property in config means it is critical for determining is build up to
date or not. Discrepancies could happen
-for any plugin for a number of reasons. Example: local build is using java
target 1.6, remote: 1.8. `buildsdiff.xml`
-will produce something like
-
-```
-<mismatch item="target"
- current="1.8"
- baseline="1.6"
- reason="Plugin:
default-compile:compile:compile:maven-compiler-plugin:org.apache.maven.plugins:3.8.1
has mismatch in tracked property and cannot be reused"
- resolution="Align properties between remote and local build or
remove property from tracked list if mismatch could be tolerated. In some cases
it is possible to add skip value to ignore lax mismatch"/>
-```
-
-Solution is at your discretion. If the property is tracked, out-of-date status
is fair and expected. If you want to
-relax consistency rules in favor of compatibility, remove property from
tracked list
-
-## Issue 5: Version changes invalidate effective pom checksum
-
-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
-project (eg `<version>MY-PROJECT-LOCAL</version>`). Such approach simplifies
git branching workflow significantly.
-
-Deployment of artifacts with specific version from builds with cache is not
supported yet.
-
diff --git a/maven-caching-extension/src/site/markdown/CACHE.md
b/maven-caching-extension/src/site/markdown/CACHE.md
deleted file mode 100644
index 7449ef5..0000000
--- a/maven-caching-extension/src/site/markdown/CACHE.md
+++ /dev/null
@@ -1,170 +0,0 @@
-<!---
- 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.
--->
-
-## Overview
-
-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
-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
-projects that have significant number of small modules. Remote cache in
conjunction with precise input identification
-effectively enables "change once - build once" approach.
-
-### Maven insights
-
-The challenge of implementing build cache in Maven is that domain model is
overly generic and doesn't support well
-reproducible builds. You might have never thought of that, but it is a reality
that 2 different Maven builds from the
-same source code normally produce 2 different results. The question here is
tolerance level - can you accept particular
-discrepancies or not. For most of teams artifacts produced in the same build
environment from the same source code will
-be considered equivalent and technical differences between them (like
different timestamps in jar manifests) could be
-ignored. Now consider scenario when artifact is first produced with compiler X
and cached but later without touching a
-update compiler changes to Y and yields significantly different outcomes of
compilation. Ask yourself a question \- am I
-consider artifacts of such builds equivalent? Both Yes and No outcomes are
pretty possible and could be even desirable
-in different scenarios. When productivity and performance are the primary
concerns it could be desirable to tolerate
-insignificant discrepancies and maximise reuse of cached builds. As long as
correctness in focus there could be demand
-to comply with the exact release process. In the same way as with classic
Maven, decision stays with you - what is
-acceptable difference between builds. In the same way as with classic Maven
the previous build is just an approximation
-of today build with some tolerance (implementation, configuration and
environment driven).
-
-### Implementation insights
-
-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
-in different runs - resulting in cache miss. The ultimate target is to achieve
desired balance between collisions (
-sufficient correctness) and stability (sufficient reuse). In current
implementation this is achieved by configuring
-project specific processing rules in static configuration file. To avoid
unintentional collisions and achieve better
-correctness need to ensure that every critical file and plugin parameter
accounted in build inputs. In order to achieve
-better reuse need to ensure that non-critical files (test logs, readme and
similar) and non-critical plugin parameters (
-like number of threads in build) are filtered out from build inputs.
Essentially cache configuration is a process of
-inspecting build, taking these decision and reflect them in the cache
configuration.
-
-Please notice though idea of perfectly matching builds might be tempting, but
it is not practical with regard to
-caching. Perfect correctness means that not a single build could be reused and
renders whole idea of builds caching
-useless. Whatever build tool you use, there will be always a tradeoff which
might be acceptable or not in particular
-situation. Incremental Maven provides flexible and transparent control over
caching policy and allows achieving desired
-outcomes - maximize reusability or maximize equivalence between pre-cached
candidates and requested builds.
-
-## Usage
-
-Cornerstone principle of using this tool is that it is delivered as is. Though
the tool went through thorough
-verification it's still consumer's responsibility to verify final product
quality.
-
-### Recommended Scenarios
-
-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
- 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.
-* Assemble artifacts faster. In some development models it might be critical
to have as fast build/deploy cycle as
- possible. Caching helps to cut down time drastically in such scenarios
because it doesn't require to build cached
- dependencies.
-
-For cases there correctness must be ensured (eg prod builds), it is
recommended to disable cache and do clean builds.
-This also allows you to validate cache correctness and reconcile cache
outcomes on CI process.
-
-## Getting Started
-
-To on-board incremental Maven you need to complete several steps:
-
-* 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
-
-### 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:
-
-```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:
-
-* simple distribution across workstations and CI envs
-* 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`)
-
-### Adding cache config
-
-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:
-
-* remote cache location
-* source code files glob
-* plugins reconciliation rules - add critical plugin parameters to
reconciliation
-* add non-standard source code locations (most of locations discovered
automatically from project and plugins config,
- but still there might be edge cases)
-
-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 `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
-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
- 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
- * expected source code files are present in build info
- * all critical plugins and their critical parameters are covered by config
-
-Notice - in configuration you should find best working trade-off between
fairness and cache efficiency. Adding
-unnecessary rules and checks could reduce both performance and cache
efficiency (hit rate).
-
-### Adding caching CI and remote cache
-
-To leverage remote cache feature you need web server which supports get/put
operations
-like [Nginx OSS](http://nginx.org/en/) (with fs module) or binary repo in
Artifactory. It is recommended to populate
-remote cache from CI build. Benefits are:
-
-* such scheme provides predictable and consistent artifacts in remote cache
-* usually CI builds project fast enough to populate cache for team members See
[Remote cache setup](CACHE-REMOTE.md) for
- detailed description of cache setup
-
-## Credits
-CacheConfigImpl
-* Maximilian Novikov - Project lead. Idea, design, coordination and
verification.
-* Alexander Ashitkin - Co-design and implementation of the majority of
functionality
-* Alexander Novoselov - Hashing module implementation
\ No newline at end of file
diff --git a/maven-caching-extension/src/site/markdown/cache.md
b/maven-caching-extension/src/site/markdown/cache.md
new file mode 100644
index 0000000..46c3f69
--- /dev/null
+++ b/maven-caching-extension/src/site/markdown/cache.md
@@ -0,0 +1,131 @@
+<!---
+ 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.
+-->
+
+## Overview
+
+Build cache is an extension targeted to simplify and make more efficient work
with large repositories in Maven. That is
+achieved by a combination of features:
+
+* Incremental builds over the changed project graph part only
+* Subtree support in multimodule projects (caches discovered from the larger
project)
+* Version normalization to support project version agnostic caches
+* Project state restoration (partial) to avoid expensive tasks (code
generation and similar)
+
+Large projects usually pose scalability challenges and work with such projects
require build tool which scales. Cache
+extension addresses that with incremental build execution and ability to
efficiently work on sub-parts of a larger
+project without building and installing dependencies from the larger project.
Though, features implemented in maven
+should give noticeable benefits in medium and small sized projects as well.
+
+### Cache concepts
+
+Idea of Incremental Maven is to calculate key from module inputs, store
outputs in cache and restore them later
+transparently to the standard Maven core. In order to calculate the key cache
engine analyzes source code, build flow,
+plugins and their parameters. This allows to deterministically associate each
project state with unique key and restore
+up-to-date (not changed) projects from cache and rebuild out-of-date(changed)
ones. Restoring artifacts associated with
+a particular project state improves build times by avoiding re-building
unnecessary modules. Cache does not make any
+interventions to actual build execution process and fully delegates build work
to Maven core. This ensures that
+artifacts produced in presence of cache are equivalent to result produced by a
standard Maven build.
+To achieve accurate key calculation incremental Maven combines automatic
introspection
+of [project object model](https://maven.apache.org/pom.html#What_is_the_POM)
and allows fine-grained tuning by means of
+configuration file and xml attributes. Source code content fingerprinting is
digests based which is more reliable over
+widely used file timestamps in tools like Make or Apache Ant. Deterministic
build state allows reliably cache outputs
+even of the build in progress 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
+projects that have significant number of small modules. Remote cache in
conjunction with relocatable inputs
+identification effectively enables "change once - build once" approach across
all environments.
+
+### Maven insights
+
+The challenge of implementing build cache in Maven is that domain model is
overly generic and doesn't have dedicated api
+for build inputs. Because of that, even 2 identically looking builds from the
same source code could normally produce 2
+different results. The question here is tolerance level - can you accept
particular discrepancies or not. For most of
+teams artifacts produced in the same build environment from the same source
code will be considered equivalent and
+technical differences between them (like different timestamps in jar
manifests) could be ignored. Now consider scenario
+when artifact is first produced with compiler X and cached. Later, without
touching source code, compiler changes to Y
+and build yields significantly different outcomes of compilation. Should the
produced artifacts be considered as
+equivalent? Both Yes and No answers are possible and could be even desirable
in different scenarios. When productivity
+and performance are the primary concerns it could be desirable to tolerate
insignificant discrepancies and maximise
+reuse of cached builds. As long as correctness is in focus there could be
demand to comply with the exact release
+process. In the same way as with classic Maven, correctness is ensured by
proper build configuration and controllable
+build environments. In the same way as with classic Maven the previous build
is just an approximation of today build
+with some tolerance (implementation, configuration and environment driven).
+
+### Implementation insights
+
+At very simple form, the incremental Maven is essentially a hash function
which takes Maven project and produces cache
+key for a project. Then the key is used to store and restore build results.
Because of different factors there could be
+collisions and instabilities in the produced key. Collision could happen if
the same key produced from the semantically
+different build states and will result in unintended reuse. Instability means
that same input yields different key in
+different runs resulting in cache misses. The ultimate target is to find
tradeoff between correctness and performance by
+means of configuration. In current implementation this is achieved by
configuring cache processing rules in xml file.
+
+In order to achieve better correctness need to:
+
+* Verify that every relevant file is selected as input to engine
+* Add critical plugin parameters to reconciliation (because they could be
overridden from command line)
+
+In order to achieve better reuse need to:
+
+* ensure that non-critical files (test logs, readme and similar) are filtered
out from build inputs.
+* non-critical plugin parameters (like number of threads in build) are
filtered out from build inputs
+* Source code is relocatable and build parameters are relocatable (not
environment specific)
+
+Essentially cache setup is a process of inspecting build, taking these
decision and reflect them in the cache
+configuration.
+
+Please notice though idea of perfectly matching builds might be tempting, but
it is not practical with regard to
+caching. Perfect correctness could lead to prevailing hit misses and render
caching useless when applied to real
+projects. In practice, configuring sufficient(good enough) correctness might
yield the best outcomes. Incremental Maven
+provides flexible and transparent control over caching policy and allows
achieving desired outcomes - maximize usability
+or maximize equivalence(correctness) between pre-cached candidates and
requested builds.
+
+## Usage
+
+Cache extension is an opt-in feature. It is delivered as is and though the
tool went through careful verification it's
+still build owner's responsibility to verify build outcomes.
+
+### Recommended Scenarios
+
+Given all the information above, the Incremental Maven is recommended to use
in scenarios when productivity and
+performance are in priority. Typical cases are:
+
+* Continuous integration. 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.
+* Assemble artifacts faster. In some development models it might be critical
to have as fast build/deploy cycle as
+ possible. Caching helps to cut down time drastically in such scenarios
because it doesn't require to build cached
+ dependencies.
+
+For cases there correctness must be ensured (eg prod builds), it is
recommended to disable cache and do clean builds.
+Such scheme allows to validate cache correctness by reconciling outcomes of
cached builds against the reference builds.
+
+## See also
+
+* [Getting started](getting-started.md) - getting starting with cache and
usage manual
+* [Usage](usage.md) - shared cache setup procedure
+* [Remote cache setup](remote-cache.md) - shared cache setup procedure
+* [How-To](how-to.md) - cookbook for typical scenarios
+* [Performance](performance.md) - performance tuning
+* [Cache Parameters](parameters.md) - description of supported parameters
+* [Sample config file](maven-cache-config.xml)
+
+
+* Maximilian Novikov - Project lead. Idea, design, coordination and
verification.
+* Alexander Ashitkin - Co-design and implementation of the majority of
functionality
+* Alexander Novoselov - Hashing module implementation
\ No newline at end of file
diff --git a/maven-caching-extension/src/site/markdown/getting-started.md
b/maven-caching-extension/src/site/markdown/getting-started.md
new file mode 100644
index 0000000..56fd82f
--- /dev/null
+++ b/maven-caching-extension/src/site/markdown/getting-started.md
@@ -0,0 +1,69 @@
+<!---
+ 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.
+-->
+
+## Getting Started
+
+To on-board incremental Maven you need to complete several steps:
+
+* Declare caching extension in your project
+* Add cache config in `.mvn` (optional) to customize default behavior
+* Validate build results and iteratively adjust config to properly reflect
project specifics
+* Setup remote cache (optional)
+
+### Declaring cache extension
+
+```xml
+<extension>
+ <groupId>org.apache.maven.caching</groupId>
+ <artifactId>maven-caching-extension</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+</extension>
+```
+
+### Adding cache config
+
+Copy [default config `maven-cache-config.xml`](maven-cache-config.xml)
+to [`.mvn/`](https://maven.apache.org/configure.html) directory 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:
+
+* Exclusions for unstable, temporary files or environment specific files
+* Plugins reconciliation rules – add critical plugins parameters to
reconciliation
+* Source code files selectors. Though source code locations discovered
automatically from project and plugins config,
+ there might be edge cases.
+* remote cache location (if remote cache is used)
+
+### Adjusting cache config
+
+Having extension run usual command, like `mvn package`. Verify the caching
engine is activated:
+
+* Check log output - there should be cache related output or initialization
error message.
+* Navigate to your local repo directory - there should be a sibling directory
`cache` next to the usual
+ local `repository`.
+* Find `buildinfo.xml` in the cache repository for typical module and review
it. Ensure that
+ * expected source code files are present in the build info
+ * all critical plugins and their critical parameters are covered by config
+
+It is recommended to find the best working trade-off between fairness and
cache efficiency. Adding unnecessary rules and
+checks could reduce both performance and cache efficiency (hit rate).
+
+### Adding caching CI and remote cache
+
+To leverage remote cache feature there should a shared storage provide. Any
technology supported
+by [Maven Wagon](https://maven.apache.org/wagon/) will suffice. In simplest
form it could be a http web server which
+supports get/put operations ([Nginx OSS](http://nginx.org/en/) with fs module
or any other equivalent).
+See [Remote cache setup](remote-cache.md) for detailed description of cache
setup
diff --git a/maven-caching-extension/src/site/markdown/CACHE-HOWTO.md
b/maven-caching-extension/src/site/markdown/how-to.md
similarity index 97%
rename from maven-caching-extension/src/site/markdown/CACHE-HOWTO.md
rename to maven-caching-extension/src/site/markdown/how-to.md
index c0877ac..3394ef1 100644
--- a/maven-caching-extension/src/site/markdown/CACHE-HOWTO.md
+++ b/maven-caching-extension/src/site/markdown/how-to.md
@@ -22,7 +22,7 @@ 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
```xml
<?xml version="1.0" encoding="UTF-8" ?>
@@ -87,7 +87,7 @@ add additional directories with `<include>`. Also you can
filter out undesirable
</input>
```
-### Plugin property is env specific (breaks checksum and caching)
+### Plugin property is env specific and yields different cache key in
different environments
Consider to exclude env specific properties:
@@ -108,7 +108,7 @@ Consider to exclude env specific properties:
</input>
```
-Implications - builds with different `argLine` will have identical checksum.
Validate that is semantically valid.
+Implications - builds with different `argLine` will have identical key.
Validate that is semantically valid.
### Plugin property points to directory where only subset of files is relevant
diff --git a/maven-caching-extension/src/site/markdown/maven-cache-config.xml
b/maven-caching-extension/src/site/markdown/maven-cache-config.xml
index 6119349..f39a59a 100644
--- a/maven-caching-extension/src/site/markdown/maven-cache-config.xml
+++ b/maven-caching-extension/src/site/markdown/maven-cache-config.xml
@@ -18,6 +18,10 @@
<cache xmlns="http://maven.apache.org/CACHE-CONFIG/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/CACHE-CONFIG/1.0.0
../maven-caching/target/generated-resources/modello/cache-config-1.0.0.xsd">
+ <!--
+ Template cache configuration
+ -->
+
<configuration>
<enabled>true</enabled>
<hashAlgorithm>SHA-256</hashAlgorithm>
@@ -31,6 +35,7 @@
<local>
<maxBuildsCached>3</maxBuildsCached>
</local>
+ <projectVersioning adjustMetaInf="true"/>
</configuration>
<input>
diff --git a/maven-caching-extension/src/site/markdown/CACHE-PARAMETERS.md
b/maven-caching-extension/src/site/markdown/parameters.md
similarity index 59%
rename from maven-caching-extension/src/site/markdown/CACHE-PARAMETERS.md
rename to maven-caching-extension/src/site/markdown/parameters.md
index 12042c6..476c046 100644
--- a/maven-caching-extension/src/site/markdown/CACHE-PARAMETERS.md
+++ b/maven-caching-extension/src/site/markdown/parameters.md
@@ -23,19 +23,20 @@ This documents contains various configuration parameters
supported by cache engi
| Parameter | Description | Usage Scenario |
| ----------- | ----------- | ----------- |
-| `-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 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=<http url>` | Location of baseline build for
comparison | Remote cache setup/tuning/troubleshooting |
+| `-Dremote.cache.configPath=path to file` | 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)` | Prohibit to override
remote 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=<http url>` | Location of baseline
build for comparison | Remote cache
setup/tuning/troubleshooting |
+| `-Dremote.cache.lazyRestore=(true/false)` | Restore artifacts
from remote cache lazily | Performance optimization |
+| `-Dremote.cache.restoreGeneratedSources=(true/false)` | Do not restore
generated sources and directly attached files | Performance optimization |
## Project level properties
Project level parameters allow overriding global parameters on project level
Must be specified as project properties:
```xml
-
<pom>
...
<properties>
diff --git a/maven-caching-extension/src/site/markdown/performance.md
b/maven-caching-extension/src/site/markdown/performance.md
new file mode 100644
index 0000000..03a8173
--- /dev/null
+++ b/maven-caching-extension/src/site/markdown/performance.md
@@ -0,0 +1,103 @@
+<!---
+ 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.
+-->
+
+# Performance Tuning
+
+Various setup options which affect cache performance.
+
+## General notes
+
+Tuning of cache performance could reduce both resources consumption and build
execution time but that is not guaranteed.
+In many scenarios build time of invalidated (changed) projects could be
dominating in overall build time. Performance
+wins achieved by a faster cache engine might not correlate with final build
times in straightforward way. As usual with
+performance, effect of performance optimizations should be carefully measured
in relevant scenarios.
+
+## Hash algorithm selection
+
+By default, cache uses SHA-256 algorithm which is sufficiently fast and
provides negligible probability of hash
+collisions. In projects with large codebase, performance of hash algorithms
becomes more important and in such
+scenarios [XX](https://cyan4973.github.io/xxHash/) or XXMM (memory mapped
files) hashing algorithms provide better
+performance.
+
+```xml
+<hashAlgorithm>XX</hashAlgorithm>
+```
+
+or
+```xml
+
+<hashAlgorithm>XXMM</hashAlgorithm>
+```
+
+## Filter out unnecessary/huge artifacts
+
+Price of uploading and downloading from cache of huge artifacts could be
significant. In many scenarios assembling WAR,
+EAR or ZIP archive could be done more efficiently locally from cached JARs
than storing bundles. In order to filter out
+artifacts add configuration section:
+
+```xml
+<cache>
+ <output>
+ <exclude>
+ <pattern>.*\.zip</pattern>
+ </exclude>
+ </output>
+</cache>
+```
+
+## Use lazy restore
+
+By default, cache tries to restore all artifacts for a project preemptively.
Lazy restore could give a significant time
+and resources wins for remote cache by avoiding requesting and downloading
unnecessary artifacts from cache. Use command
+line flag:
+
+```
+-Dremote.cache.lazyRestore=true";
+```
+
+Note: In case of cache corruption lazy cache cannot fallback to normal
execution, it will fail instead. To heal the
+corrupted cache need to force rewrite of the cache or remove corrupted cache
entries manually
+
+## Disable project files restoration
+
+By default, cache support partial restore of source code state from cached
generated sources (and potentially more,
+depending on configuration). This could be helpful in local environment, but
likely unnecessary and adds overhead in
+continuous integration. To disable add command line flag
+
+```
+-Dremote.cache.restoreGeneratedSources=false";
+```
+
+## Disable post-processing of archives(JARs, WARs, etc) META-INF
+
+Post-processing is disabled by default, but for some projects cache could be
configured to auto-correct metadata (most
+notably [MANIFEST.MF
`Implementation-Version`](https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Main_Attributes))
+. This could be rather expensive as it requires copying and repacking archive
entries. If metadata state is not relevant
+for the build (continuous integration, `verify` scenarios and similar)
consider disabling it:
+
+```xml
+<cache>
+ <configuration>
+ ...
+ <projectVersioning adadjustMetaInf="false"/>
+ ...
+ </configuration>
+ ...
+</cache>
+```
+
+
diff --git a/maven-caching-extension/src/site/markdown/remote-cache.md
b/maven-caching-extension/src/site/markdown/remote-cache.md
new file mode 100644
index 0000000..74b0bdc
--- /dev/null
+++ b/maven-caching-extension/src/site/markdown/remote-cache.md
@@ -0,0 +1,242 @@
+<!---
+ 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.
+-->
+
+# Overview
+
+This document describes generic approach to remote cache setup. The process
implies good knowledge of both Maven and the
+project. Due to Maven model limitation the process is semi-manual, but allows
you to achieve sufficient control and
+transparency over caching logic.
+
+## Before you start
+
+Before you start, please keep in mind basic principles:
+
+* Cache is key based, the key is produced by HashTree-like technique. The key
is produced by hashing every configured
+ source code file, every dependency and effective pom (including plugin
parameters). Every element's hash contributes
+ to the key. In order to produce the same key there engine must consume
exactly the same hashes.
+* There is no built-in normalization of line endings in this implementation,
file hash calculation is raw bytes
+ based. The most obvious implication could be illustrated by a simple Git
checkout. By default, git will check out
+ source code with CRLF line endings on win and LF on Linux. Because of that
builds over same commit on a Linux agent
+ and local build on Windows workstation will yield different hashes.
+* Parameters of plugins are reconciled in runtime. For example to avoid of
accidentally reusing builds which never run
+ tests ensure that critical surefire parameters are tracked (`skipTests` and
similar) in config. The same applies for
+ all over plugins.
+
+# Step-By-Step
+
+## Minimize number of moving parts
+
+* Run build with single threaded builder to make sure logs from different
modules do not interfere
+* Use the same branch which no-one else commits to
+* Designate single agent/node for CI builds
+* Preferably use the same OS between CI and local machine
+
+## Fork branch for cache setup purposes
+
+Fork stable code branch for cache setup purposes as you will need source code
which doesn't change over time of setup.
+Also, you likely will need to do code changes as long as you go.
+
+## Setup http server to store artifacts
+
+In order to share build results cache needs a shared storage. The simplest
option is to set up a http server which
+supports http PUT/GET/HEAD operations will suffice (Nginx, Apache or similar).
Add the url to config and
+change `remote@enabled` to true:
+
+```xml
+<remote enabled="true">
+ <url>http://your-buildcache-url</url>
+</remote>
+```
+
+If proxy or authentication is required to access remote cache, add server
record to settings.xml as described
+in [Servers](https://maven.apache.org/settings.html#Servers). The server
should be referenced from cache config:
+
+```
+TBD
+```
+
+Beside the http server, remote cache could be configured using any storage
which is supported
+by [Maven Wagon](https://maven.apache.org/wagon/). That includes a wide set of
options, including SSH, FTP and many
+others. See Wagon documentation for a full list of options and other details.
+
+## Build selection
+
+Build stored in cache ideally should be a build assembled in the most correct,
comprehensive and complete way. Pull
+requests builds are good candidates to populate cache usually because this is
there quality safeguards are applied
+normally.
+
+## CI Build setup to seed shared cache
+
+Allow writes in remote cache add jvm property to designated CI builds.
+
+```
+-Dremote.cache.save.enabled=true
+```
+
+Run the build, review log and ensure that artifacts are uploaded to remote
cache. Now, rerun build and ensure that it
+completes almost instantly because it is fully cached.
+
+## Remote cache relocation to local builds
+
+As practice shows, developers often don't realize that builds they run in
local and CI environments are different. So
+straightforward attempt to reuse remote cache in local build usually results
in cache misses because of difference in
+plugins, parameters, profiles, environment, etc. In order to reuse results you
might need to change poms, cache config,
+CI jobs and the project itself. This part is usually most challenging and
time-consuming. Follow steps below to
+iteratively achieve working configuration.
+
+* Enable fail fast mode to fail build on the first discrepancy between
+* Provide reference to the CI build as a baseline for comparison between your
local and remote builds. Go to the
+ reference CI build log and one of the final lines of the build should be a
line about saving `cache-report.xml`
+
+```
+[INFO] [CACHE] Saved to remote cache
https://your-cache-url/<...>/915296a3-4596-4eb5-bf37-f6e13ebe087e/cache-report.xml
+```
+
+Copy the link to a `cache-report.xml` and provide it to your local build as a
baseline for comparison.
+
+* Run local build. Command line should look similar to this:
+
+```bash
+mvn verify -Dremote.cache.failFast=true
-Dremote.cache.baselineUrl=https://your-cache-url/<...>/915296a3-4596-4eb5-bf37-f6e13ebe087e/cache-report.xml
+```
+
+Once discrepancy between remote and local builds detected cache will fail with
diagnostic info in
+project's `target/incremental-maven` directory:
+
+```
+* 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
+```
+
+Review `buildsdiff.xml` file and eliminate detected discrepancies. You can
also diff build-info files directly to get
+low level insights. See techniques to configure cache in [How-To](how-to.md)
and troubleshooting of typical issues
+in the section below.
+
+# Common issues
+
+## Issue 1: Local checkout is with different line endings
+
+Solution: normalise line endings. Current implementation doesn't have built-in
line endings normalization, it has to be
+done externally. In git it is recommended to use `.gitattributes` file to
establish consistent line endings across all
+envs for file types specific to this project
+
+## Issue 2: Effective poms mismatch because of plugins injection by profiles
+
+Different profiles between remote and local builds likely result in different
text of effective poms. As effective pom
+contributes hash value to the key that could lead to cache misses. Solution:
instead of adding/removing specific plugins
+by profiles, set default value of the plugin's `skip` or `disabled` flag in a
profile properties instead. Instead of:
+
+```xml
+<profiles>
+ <profile>
+ <id>run-plugin-in-ci-only</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>surefire-report-maven-plugin</artifactId>
+ <configuration>
+ <!-- my configuration -->
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+</profiles>
+```
+
+Use:
+
+```xml
+<properties>
+ <!-- default value -->
+ <skip.plugin.property>true</skip.plugin.property>
+</properties>
+<build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <!-- plugin behavior is controlled by property -->
+ <skip>${skip.plugin.property}</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+</build>
+<profiles>
+ <profile>
+ <id>run-plugin-in-ci-only</id>
+ <properties>
+ <!-- override to run plugin in reference ci build -->
+ <skip.plugin.property>false</skip.plugin.property>
+ </properties>
+ </profile>
+</profiles>
+```
+
+Hint: effective poms could be found in `buildinfo` files under
`/build/projectsInputInfo/item[@type='pom']`
+xpath (`item type="pom"`).
+
+## Issue 3: Effective pom mismatch because of environment specific properties
+
+Potential reason: Sometimes it is not possible to avoid discrepancies in
different environments - for example if plugin
+takes command line as parameter, it will be likely different on Win and linux.
Such commands will appear in effective
+pom as a different literal values and will result in a different effective pom
hash and cache key mismatch. Solution:
+filter out such properties from effective pom:
+
+```xml
+<input>
+ <global>
+ ...
+ </global>
+ <plugin artifactId="maven-surefire-plugin">
+ <effectivePom>
+ <excludeProperty>argLine</excludeProperty>
+ </effectivePom>
+ </plugin>
+</input>
+```
+
+## Issue 4: Unexpected or transient files in cache key calculation
+
+Potential reasons: plugins or tests emit temporary files (logs and similar) in
non-standard locations. Solution: adjust
+global exclusions list to filter out the unexpected files:
+
+```xml
+<global>
+ <exclude>tempfile.out</exclude>
+</global>
+```
+
+see sample config for exact syntax
+
+## Issue 5: Difference in tracked plugin properties
+
+Tracked property in config means it is critical for determining is build up to
date or not. Discrepancies could happen
+for any plugin for a number of reasons. Example: local build is using java
target 1.6, remote: 1.8. `buildsdiff.xml`
+will produce something like
+
+```xml
+<mismatch item="target"
+ current="1.8"
+ baseline="1.6"
+ reason="Plugin:
default-compile:compile:compile:maven-compiler-plugin:org.apache.maven.plugins:3.8.1
has mismatch in tracked property and cannot be reused"
+ resolution="Align properties between remote and local build or
remove property from tracked list if mismatch could be tolerated. In some cases
it is possible to add skip value to ignore lax mismatch"/>
+```
+
+Solution is at your discretion. If the property is tracked, out-of-date status
is fair and expected. If you want to
+relax consistency rules in favor of compatibility, remove property from the
reconciliations list
diff --git a/maven-caching-extension/src/site/markdown/usage.md
b/maven-caching-extension/src/site/markdown/usage.md
new file mode 100644
index 0000000..45c23c5
--- /dev/null
+++ b/maven-caching-extension/src/site/markdown/usage.md
@@ -0,0 +1,57 @@
+<!---
+ 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.
+-->
+
+## Normal usage
+
+Once extension is activated, cache will kick-in automatically on every
lifecycle build of phase `package` or higher.
+
+## Subtree builds
+
+Build could be invoked on any module in project and will try to discover cache
by introspecting dependencies. In order
+to identify which dependencies are part of cacheable project the cache engine
needs to know:
+
+* full project root location which must be passed with
`-Dmaven.multiModuleProjectDirectory`
+* Specify profiles which activate full graph in config:
+
+```
+TBD
+```
+
+## Disable cache
+
+Disable in config:
+```xml
+<cache>
+ <configuration>
+ <enabled>true</enabled>
+ </configuration>
+</cache>
+```
+On command line:
+```
+-Dremote.cache.enabled=false
+```
+
+## IDE support
+
+Cache extension is generally compatible with ides with one limitation:
+
+* The cache doesn't restore full project state. Compiled classes and other
output directories will not be restored from
+ cache if `clean` was invoked. In order to work efficiently, IDE should be
configured to not use maven
+ output (`target`) directories for compilation. In that case compilation
caches will be maintained by IDE leveraging
+ both fast builds and fast compilation
+