You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by cs...@apache.org on 2024/09/24 15:07:19 UTC

(maven) branch maven-cling updated (cddb2349d1 -> ce42df4f81)

This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a change to branch maven-cling
in repository https://gitbox.apache.org/repos/asf/maven.git


 discard cddb2349d1 WIP
 discard cb594479a2 Merge remote-tracking branch 'upstream/master' into maven-cling
 discard 649d20794a Merge remote-tracking branch 'origin/master' into maven-cling
 discard f85b7e0f60 WIP
 discard fb7c484d83 Merge remote-tracking branch 'origin/master' into maven-cling
 discard a7f0f8da12 Fixes
 discard c198232caf WIP
 discard 664bc2b47f Make it Tool from root
 discard 3b18c30f00 Pull our CLworld
 discard a25d04ee59 WIP
 discard 43f498377b WIP
 discard aa8951c6d9 WIP
 discard c7aa324936 WIP
 discard 65024f20a9 Add more options
 discard 18d99b365a Add picocli to picture
 discard 44428b9974 CLIng
     add 40fe1dc167 [MNG-8220] Fix loading DI-powered beans from extensions (#1683)
     add 57082737d8 [MNG-7897] Support ${project.rootDirectory} in file profile activation (#1687)
     add 3f430bbd07 [MNG-8228] Enable Sisu Plexus strict classpath scanning (#1688)
     add c948b26484 [MNG-8218] Always normalize Path in PathSource (#1684)
     add e11b475e8b [MNG-8052] Concurrently lifecycle executor (#1429)
     add b370e5e929 [MNG-8210] Replace Maven "module" term by "subproject" (#1651)
     add c0813a2b53 [MNG-7838] Fix usage of older packaged artifacts from project local repository (#1199)
     add cdaf86cfe9 [MNG-8229] Fix interpolation of CI friendly versions
     add 0c311e3da1 [MNG-8090] Fix missing repositories during parent artifact resolution
     add 697c543b4e [maven-release-plugin] prepare release maven-4.0.0-beta-4
     add a98d530e33 [maven-release-plugin] prepare for next development iteration
     add c166bd1382 Disable automated JIRA comments from GitHub
     add f67402a0b1 [MNG-8255] Bump ch.qos.logback:logback-classic from 1.5.7 to 1.5.8 (#1709)
     add 7d3a8f260f Bump org.apache.commons:commons-lang3 from 3.16.0 to 3.17.0 (#1691)
     add 2d0e307318 Bump net.bytebuddy:byte-buddy from 1.15.0 to 1.15.1 (#1692)
     add 96b12394bf Bump org.codehaus.mojo:buildnumber-maven-plugin from 3.2.0 to 3.2.1 (#1698)
     add 8a61f7d20a [MNG-8249] Provide an annotation processor for DI (#1704)
     add 0c7e73335d Fix broken circular references detection
     add bb99857f34 Enhance DiIndexProcessor
     add e0b01fb5a4 [MNG-8210] Fix broken inference of version when using -f option (#1720)
     add e6d038ac07 [MNG-8252] Fully infer the parent coordinates if the location points to a valid model (#1706)
     add f137c13877 [MNG-8190] Restrict build pom feature to 4.1.0 model version (#1707)
     add 237eeba760 [MNG-8252] Fully infer the parent coordinates if the location points to a valid model (#1706) (#1721)
     add 36de1c6e51 [MNG-8237] Option deprecation notices cleanup (#1713)
     add bcd5d9c9f9 DI improvements (#1717)
     add 625b4561f0 [MNG-8232] Introduce ModelTransformer (#1702)
     add 85f5dca4a6 [MNG-8234] Revert the addition of the priority tag (#1711)
     add 2b13a43c09 [MNG-8235] Move remote repositories into requests (#1712)
     add 7ea795b789 [MNG-8256] FilteredProjectDependencyGraph fix for non-transitive case (#1723)
     add 30f52651a7 [MNG-8249] Fix annotation processor to correctly handle inner-inner classes
     add deb15be3b6 [MNG-8259] Improve Sisu / DI bridge (#1722)
     add 8d9f8da444 [MNG-8239] Add missing ModelCacheFactory (#1728)
     add 9811df363b [MNG-8260] Fix warning on latest JDK 24.ea (#1718)
     add 2f5f61a043 [MNG-7255] Infer groupId for intra-reactor dependencies (#1696)
     add e1e23d9e26 [MNG-8242] Cache flattened parents during model building (#1703)
     add 368ddec0e4 [MNG-8233] Client should handle modelIds as "opaque" (#1701)
     add 45f9b81b4a Simple typo bugfix (NPE) (#1731)
     add 034ef155da [MNG-8263] Remove last remnants of wrapper integration (#1736)
     new ce42df4f81 CLIng

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (cddb2349d1)
            \
             N -- N -- N   refs/heads/maven-cling (ce42df4f81)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .asf.yaml                                          |   2 +-
 apache-maven/pom.xml                               |   2 +-
 apache-maven/src/assembly/maven/bin/mvn            |   1 +
 apache-maven/src/assembly/maven/bin/mvn.cmd        |   2 +-
 api/maven-api-core/pom.xml                         |   2 +-
 .../main/java/org/apache/maven/api/Constants.java  |   8 +
 .../main/java/org/apache/maven/api/Lifecycle.java  |   2 +-
 .../main/java/org/apache/maven/api/Session.java    |  59 +-
 .../org/apache/maven/api/feature/Features.java     |  24 +-
 .../apache/maven/api/plugin/annotations/Mojo.java  |   4 +-
 .../maven/api/services/ArtifactResolver.java       |  20 +
 .../api/services/ArtifactResolverRequest.java      |  41 +-
 .../api/services/DependencyResolverRequest.java    |  24 +-
 .../apache/maven/api/services/ModelBuilder.java    |   6 +-
 .../maven/api/services/ModelBuilderRequest.java    |  43 +-
 .../maven/api/services/ModelBuilderResult.java     |  16 +-
 .../apache/maven/api/services/ModelProblem.java    |   9 +-
 .../apache/maven/api/services/ModelResolver.java   |  18 +-
 .../org/apache/maven/api/services/ModelSource.java |   2 +-
 .../api/services/ModelTransformerException.java    |   4 +
 .../org/apache/maven/api/services/PathSource.java  |   8 +-
 .../maven/api/services/ProjectBuilderRequest.java  |  24 +-
 .../maven/api/services/VersionRangeResolver.java   |  27 +
 .../api/services/VersionRangeResolverRequest.java  |  37 +-
 .../maven/api/services/VersionResolverRequest.java |  40 +-
 api/maven-api-di/pom.xml                           |   5 +-
 .../apache/maven/api/di/MojoExecutionScoped.java   |   7 +
 .../org/apache/maven/api/di/SessionScoped.java     |   2 +
 .../org/apache/maven/di/tool/DiIndexProcessor.java | 156 ++++
 .../services/javax.annotation.processing.Processor |   1 +
 api/maven-api-meta/pom.xml                         |   2 +-
 .../org/apache/maven/api/annotations/Nullable.java |   2 +-
 api/maven-api-metadata/pom.xml                     |   2 +-
 api/maven-api-model/pom.xml                        |   2 +-
 api/maven-api-model/src/main/mdo/maven.mdo         |  43 +-
 api/maven-api-plugin/pom.xml                       |   2 +-
 api/maven-api-settings/pom.xml                     |   2 +-
 api/maven-api-spi/pom.xml                          |   6 +-
 .../org/apache/maven/api/spi/LanguageProvider.java |   2 +
 .../apache/maven/api/spi/LifecycleProvider.java    |   2 +
 .../java/org/apache/maven/api/spi/ModelParser.java |   2 +
 .../org/apache/maven/api/spi/ModelTransformer.java |  82 ++
 .../maven/api/spi/ModelTransformerException.java}  |  27 +-
 .../apache/maven/api/spi/PackagingProvider.java    |   2 +
 .../apache/maven/api/spi/PathScopeProvider.java    |   2 +
 .../apache/maven/api/spi/ProjectScopeProvider.java |   2 +
 .../apache/maven/api/spi/PropertyContributor.java  |   2 +
 .../org/apache/maven/api/spi/TypeProvider.java     |   2 +
 api/maven-api-toolchain/pom.xml                    |   2 +-
 api/maven-api-xml/pom.xml                          |   2 +-
 api/pom.xml                                        |   2 +-
 maven-api-impl/pom.xml                             |  16 +-
 .../maven/api/services/model}/ModelCache.java      |  20 +-
 .../api/services/model/ModelCacheFactory.java      |  28 +-
 .../maven/internal/impl/AbstractSession.java       |  49 ++
 .../internal/impl/DefaultArtifactResolver.java     |   3 +-
 .../internal/impl/DefaultDependencyResolver.java   |  11 +-
 .../internal/impl/DefaultModelXmlFactory.java      |   2 +-
 .../internal/impl/DefaultVersionRangeResolver.java |   5 +-
 .../internal/impl/DefaultVersionResolver.java      |   5 +-
 .../maven/internal/impl/di/MojoExecutionScope.java | 124 +++
 .../internal/impl/di/OutOfScopeException.java      |  12 +-
 .../maven/internal/impl/di}/SessionScope.java      | 101 +--
 .../internal/impl/model/BuildModelTransformer.java |  56 +-
 .../internal/impl/model/DefaultModelBuilder.java   | 171 +++-
 .../{resolver => model}/DefaultModelCache.java     |  30 +-
 .../impl/model}/DefaultModelCacheFactory.java      |  20 +-
 .../DefaultModelTransformerContextBuilder.java     |  32 +-
 .../internal/impl/model/DefaultModelValidator.java | 135 ++-
 .../internal/impl/model/MavenModelMerger.java      |  31 +
 .../ProfileActivationFilePathInterpolator.java     |   2 +-
 .../resolver/DefaultArtifactDescriptorReader.java  |  43 +-
 .../impl/resolver/DefaultModelResolver.java        |  99 ++-
 .../impl/resolver/DefaultModelResolverTest.java    |  20 +-
 .../maven/internal/impl/standalone/ApiRunner.java  | 124 +--
 .../impl/standalone/RepositorySystemSupplier.java  |   5 +-
 maven-artifact/pom.xml                             |   2 +-
 maven-bom/pom.xml                                  |   2 +-
 maven-builder-support/pom.xml                      |   2 +-
 maven-compat/pom.xml                               |   2 +-
 maven-core/pom.xml                                 |  10 +-
 .../main/java/org/apache/maven/ReactorReader.java  |  26 +-
 .../org/apache/maven/execution/BuildFailure.java   |  14 +-
 .../org/apache/maven/execution/BuildSuccess.java   |  13 +-
 .../org/apache/maven/execution/BuildSummary.java   |  36 +-
 .../scope/internal/MojoExecutionScope.java         | 105 +--
 .../scope/internal/MojoExecutionScopeModule.java   |  12 +-
 .../apache/maven/graph/DefaultGraphBuilder.java    |   6 +-
 .../graph/FilteredProjectDependencyGraph.java      |  40 +-
 .../internal/impl/DefaultLifecycleRegistry.java    |  39 +-
 .../maven/internal/impl/DefaultProjectBuilder.java |   7 +-
 .../maven/internal/impl/SisuDiBridgeModule.java    | 332 +++++---
 .../DefaultConsumerPomArtifactTransformer.java     |   6 +-
 .../impl/DefaultConsumerPomBuilder.java            |  29 +-
 .../apache/maven/lifecycle/DefaultLifecycles.java  |   2 +-
 .../internal/CompoundProjectExecutionListener.java |   4 +-
 .../maven/lifecycle/internal/MojoExecutor.java     |  91 +-
 .../lifecycle/internal/concurrent/BuildPlan.java   | 166 ++++
 .../internal/concurrent/BuildPlanExecutor.java     | 939 +++++++++++++++++++++
 .../internal/concurrent/BuildPlanLogger.java       | 177 ++++
 .../lifecycle/internal/concurrent/BuildStep.java   | 133 +++
 .../concurrent/ConcurrentLifecycleStarter.java     | 191 +++++
 .../internal/concurrent/ConcurrentLogOutput.java   |  81 ++
 .../internal/concurrent/MojoExecutor.java}         |  52 +-
 .../internal/concurrent/PhasingExecutor.java       |  47 +-
 .../internal/concurrent/PluginLifecycle.java       |  94 +++
 .../plugin/internal/DefaultMavenPluginManager.java |   5 -
 .../maven/project/DefaultProjectBuilder.java       | 365 +++++---
 .../org/apache/maven/project/MavenProject.java     |   3 +
 .../maven/session/scope/internal/SessionScope.java | 181 +---
 .../META-INF/maven/org.apache.maven.api.di.Inject  |  70 --
 .../src/test/java/org/apache/maven/di/DiTest.java  | 271 ++++++
 .../scope/internal/MojoExecutionScopeTest.java     |   6 +-
 .../graph/DefaultProjectDependencyGraphTest.java   |  17 +
 .../impl/ConsumerPomArtifactTransformerTest.java   |   2 +-
 .../impl/ConsumerPomBuilderTest.java               |   9 +-
 .../maven/lifecycle/DefaultLifecyclesTest.java     |  14 +-
 .../maven/lifecycle/LifecycleExecutorTest.java     |   2 +-
 .../internal/concurrent/BuildPlanCreatorTest.java  | 144 ++++
 .../internal/concurrent/PhasingExecutorTest.java   |  34 +-
 .../internal/stub/DefaultLifecyclesStub.java       |   7 +-
 .../stub/LifecycleExecutionPlanCalculatorStub.java |   4 -
 .../project/DefaultMavenProjectBuilderTest.java    |  23 +
 .../apache/maven/project/ProjectBuilderTest.java   |   8 +
 .../maven/session/scope/SessionScopeProxyTest.java |   2 +-
 .../src/test/resources/consumer/simple/pom.xml     |   8 +-
 .../consumer/simple/simple-parent/pom.xml          |  14 +-
 .../simple/simple-parent/simple-testutils/pom.xml  |   2 +-
 .../simple/simple-parent/simple-weather/pom.xml    |   2 +-
 .../simple/simple-parent/utils-parent/pom.xml      |   2 +-
 .../src/test/resources/consumer/trivial/pom.xml    |   6 +-
 .../projects/subprojects-discover/child/pom.xml    |   8 +
 .../pom.xml                                        |   5 +-
 .../test/resources/projects/transform/before.pom   |   8 +-
 maven-di/pom.xml                                   |   2 +-
 .../main/java/org/apache/maven/di/Injector.java    |  25 +-
 .../src/main/java/org/apache/maven/di/Key.java     |  15 +-
 .../src/main/java/org/apache/maven/di/Scope.java   |  28 +-
 .../java/org/apache/maven/di/impl/Binding.java     |  43 +-
 .../apache/maven/di/impl/BindingInitializer.java   |  16 +-
 .../java/org/apache/maven/di/impl/DIException.java |   2 +-
 .../java/org/apache/maven/di/impl/Dependency.java  |  19 +-
 .../org/apache/maven/di/impl/InjectorImpl.java     |  76 +-
 .../org/apache/maven/di/impl/ReflectionUtils.java  |  46 +-
 .../main/java/org/apache/maven/di/impl/Types.java  |  37 +-
 .../org/apache/maven/di/impl/InjectorImplTest.java |  47 ++
 maven-docgen/pom.xml                               |   4 +-
 .../apache/maven/tools/CollectConfiguration.java   |   1 +
 maven-embedder/pom.xml                             |   2 +-
 .../main/java/org/apache/maven/cli/CLIManager.java |  60 +-
 .../main/java/org/apache/maven/cli/MavenCli.java   |  62 +-
 maven-jline/pom.xml                                |   2 +-
 maven-model-builder/pom.xml                        |   2 +-
 .../maven/model/building/DefaultModelBuilder.java  |  30 +-
 .../maven/model/building/ModelBuildingResult.java  |  14 +-
 .../apache/maven/model/building/ModelProblem.java  |  13 +-
 .../ProfileActivationFilePathInterpolator.java     |   2 +-
 .../activation/FileProfileActivatorTest.java       |  35 +-
 maven-model/pom.xml                                |   2 +-
 .../maven/model/v4/MavenModelVersionTest.java      |   2 +-
 maven-plugin-api/pom.xml                           |   2 +-
 maven-repository-metadata/pom.xml                  |   2 +-
 maven-resolver-provider/pom.xml                    |   2 +-
 .../internal/MavenRepositorySystemSupplier.java    |   5 +-
 maven-settings-builder/pom.xml                     |   2 +-
 maven-settings/pom.xml                             |   2 +-
 maven-slf4j-provider/pom.xml                       |   2 +-
 maven-slf4j-wrapper/pom.xml                        |   2 +-
 maven-toolchain-builder/pom.xml                    |   2 +-
 maven-toolchain-model/pom.xml                      |   2 +-
 maven-xml-impl/pom.xml                             |   2 +-
 pom.xml                                            |  11 +-
 src/mdo/model.vm                                   |  12 +
 src/site/markdown/configuration.md                 |  51 +-
 174 files changed, 4854 insertions(+), 1646 deletions(-)
 create mode 100644 api/maven-api-di/src/main/java/org/apache/maven/di/tool/DiIndexProcessor.java
 create mode 100644 api/maven-api-di/src/main/resources/META-INF/services/javax.annotation.processing.Processor
 create mode 100644 api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelTransformer.java
 copy api/{maven-api-core/src/main/java/org/apache/maven/api/services/MavenException.java => maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelTransformerException.java} (66%)
 rename {api/maven-api-core/src/main/java/org/apache/maven/api/services => maven-api-impl/src/main/java/org/apache/maven/api/services/model}/ModelCache.java (63%)
 copy api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactResolverResult.java => maven-api-impl/src/main/java/org/apache/maven/api/services/model/ModelCacheFactory.java (59%)
 create mode 100644 maven-api-impl/src/main/java/org/apache/maven/internal/impl/di/MojoExecutionScope.java
 copy maven-core/src/main/java/org/apache/maven/BuildAbort.java => maven-api-impl/src/main/java/org/apache/maven/internal/impl/di/OutOfScopeException.java (77%)
 copy {maven-core/src/main/java/org/apache/maven/session/scope/internal => maven-api-impl/src/main/java/org/apache/maven/internal/impl/di}/SessionScope.java (63%)
 rename maven-api-impl/src/main/java/org/apache/maven/internal/impl/{resolver => model}/DefaultModelCache.java (85%)
 copy {maven-resolver-provider/src/main/java/org/apache/maven/repository/internal => maven-api-impl/src/main/java/org/apache/maven/internal/impl/model}/DefaultModelCacheFactory.java (69%)
 create mode 100644 maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlan.java
 create mode 100644 maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java
 create mode 100644 maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanLogger.java
 create mode 100644 maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildStep.java
 create mode 100644 maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/ConcurrentLifecycleStarter.java
 create mode 100644 maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/ConcurrentLogOutput.java
 copy maven-core/src/{test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java => main/java/org/apache/maven/lifecycle/internal/concurrent/MojoExecutor.java} (52%)
 copy maven-api-impl/src/main/java/org/apache/maven/internal/impl/MappedCollection.java => maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/PhasingExecutor.java (51%)
 create mode 100644 maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/PluginLifecycle.java
 delete mode 100644 maven-core/src/main/resources/META-INF/maven/org.apache.maven.api.di.Inject
 create mode 100644 maven-core/src/test/java/org/apache/maven/di/DiTest.java
 create mode 100644 maven-core/src/test/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanCreatorTest.java
 copy api/maven-api-settings/src/test/java/org/apache/maven/api/settings/SettingsTest.java => maven-core/src/test/java/org/apache/maven/lifecycle/internal/concurrent/PhasingExecutorTest.java (56%)
 create mode 100644 maven-core/src/test/resources/projects/subprojects-discover/child/pom.xml
 copy maven-core/src/test/resources/projects/{parent-version-range-local-child-without-version => subprojects-discover}/pom.xml (50%)
 copy maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataUtils.java => maven-di/src/main/java/org/apache/maven/di/impl/Dependency.java (74%)


(maven) 01/01: CLIng

Posted by cs...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a commit to branch maven-cling
in repository https://gitbox.apache.org/repos/asf/maven.git

commit ce42df4f816b192285ccf85f098435d75ba263ec
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Tue Aug 27 11:26:16 2024 +0200

    CLIng
---
 apache-maven/pom.xml                               |   4 +
 maven-cli/pom.xml                                  | 245 +++++++++
 .../java/org/apache/maven/cling/MavenCling.java    | 158 ++++++
 .../org/apache/maven/cling/basedir/Basedir.java    |  74 +++
 .../maven/cling/basedir/InstallationBasedir.java   | 127 +++++
 .../maven/cling/basedir/SessionRootBasedir.java    | 119 +++++
 .../apache/maven/cling/basedir/UserBasedir.java    | 137 +++++
 .../apache/maven/cling/support/MavenOptions.java   | 557 +++++++++++++++++++++
 maven-cli/src/main/mdo/core-extensions.mdo         | 158 ++++++
 .../META-INF/maven/slf4j-configuration.properties  |  23 +
 maven-cli/src/site/site.xml                        |  35 ++
 pom.xml                                            |  13 +
 12 files changed, 1650 insertions(+)

diff --git a/apache-maven/pom.xml b/apache-maven/pom.xml
index 22395d9ef6..6a2baa4d83 100644
--- a/apache-maven/pom.xml
+++ b/apache-maven/pom.xml
@@ -37,6 +37,10 @@ under the License.
   </properties>
 
   <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-cli</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-embedder</artifactId>
diff --git a/maven-cli/pom.xml b/maven-cli/pom.xml
new file mode 100644
index 0000000000..2793a22bb5
--- /dev/null
+++ b/maven-cli/pom.xml
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.maven</groupId>
+    <artifactId>maven</artifactId>
+    <version>4.0.0-beta-4-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>maven-cli</artifactId>
+
+  <name>Maven CLI</name>
+  <description>Maven CLI component, with CLI and logging support.</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-settings</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-settings-builder</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-toolchain-builder</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-embedder</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-jline</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-model</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-model-builder</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-builder-support</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-slf4j-wrapper</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.resolver</groupId>
+      <artifactId>maven-resolver-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.resolver</groupId>
+      <artifactId>maven-resolver-util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-sec-dispatcher</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-cipher</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-interpolation</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-interactivity-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>info.picocli</groupId>
+      <artifactId>picocli</artifactId>
+      <version>4.7.6</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.jline</groupId>
+      <artifactId>jline</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.sisu</groupId>
+      <artifactId>org.eclipse.sisu.plexus</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.sisu</groupId>
+      <artifactId>org.eclipse.sisu.inject</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.inject</groupId>
+      <artifactId>guice</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-params</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.jimfs</groupId>
+      <artifactId>jimfs</artifactId>
+      <version>1.3.0</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.sisu</groupId>
+        <artifactId>sisu-maven-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <annotationProcessorPaths>
+            <path>
+              <groupId>info.picocli</groupId>
+              <artifactId>picocli-codegen</artifactId>
+              <version>${picocliVersion}</version>
+            </path>
+          </annotationProcessorPaths>
+          <compilerArgs>
+            <arg>-Aproject=${project.groupId}/${project.artifactId}</arg>
+          </compilerArgs>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifest>
+              <mainClass>org.apache.maven.cling.MavenCling</mainClass>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.modello</groupId>
+        <artifactId>modello-maven-plugin</artifactId>
+        <configuration>
+          <version>1.3.0</version>
+          <models>
+            <model>src/main/mdo/core-extensions.mdo</model>
+          </models>
+          <templates>
+            <template>model.vm</template>
+            <template>reader-stax.vm</template>
+            <template>writer-stax.vm</template>
+          </templates>
+          <params>
+            <param>packageModelV4=org.apache.maven.cling.internal.extension.model</param>
+            <param>packageToolV4=org.apache.maven.cling.internal.extension.io</param>
+          </params>
+          <velocityBasedir>${project.basedir}/../src/mdo</velocityBasedir>
+        </configuration>
+        <executions>
+          <execution>
+            <id>modello</id>
+            <goals>
+              <goal>velocity</goal>
+              <goal>xsd</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java b/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java
new file mode 100644
index 0000000000..1c16b819a7
--- /dev/null
+++ b/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+package org.apache.maven.cling;
+
+import javax.lang.model.SourceVersion;
+import javax.tools.Tool;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.apache.maven.cli.CLIReportingUtils;
+import org.apache.maven.cli.MavenCli;
+import org.apache.maven.cling.support.MavenOptions;
+import org.apache.maven.jline.MessageUtils;
+import org.codehaus.plexus.classworlds.ClassWorld;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Maven CLI "new-gen".
+ */
+public class MavenCling implements Tool {
+    protected static final String CORE_CLASS_REALM_ID = "plexus.core";
+
+    /**
+     * "Normal" Java entry point. Note: Maven uses ClassWorld Launcher and this entry point is NOT used under normal
+     * circumstances.
+     */
+    public static void main(String[] args) {
+        System.exit(new MavenCling().run(null, null, null, args));
+    }
+
+    /**
+     * ClassWorld Launcher "enhanced" entry point: returning exitCode and accepts Class World.
+     */
+    public static int main(String[] args, ClassWorld world) {
+        return new MavenCling(world).run(null, null, null, args);
+    }
+
+    /**
+     * Helper method for ad-hoc ClassWorld creation. Note: IF you invoke this, you must properly close it as well.
+     */
+    private static ClassWorld createClassWorld() {
+        return new ClassWorld(CORE_CLASS_REALM_ID, Thread.currentThread().getContextClassLoader());
+    }
+
+    private final ClassWorld classWorld;
+    private final boolean classWorldManaged;
+
+    public MavenCling() {
+        this.classWorld = createClassWorld();
+        this.classWorldManaged = true;
+    }
+
+    public MavenCling(ClassWorld classWorld) {
+        this.classWorld = requireNonNull(classWorld);
+        this.classWorldManaged = false;
+    }
+
+    @Override
+    public String name() {
+        return "mvn";
+    }
+
+    @Override
+    public Set<SourceVersion> getSourceVersions() {
+        return EnumSet.range(SourceVersion.RELEASE_17, SourceVersion.latestSupported());
+    }
+
+    /**
+     * Override this method to introduce new options (by extending {@link MavenOptions}).
+     */
+    protected MavenOptions createMavenOptions(String[] args) {
+        return new MavenOptions(name(), args);
+    }
+
+    @Override
+    public int run(InputStream in, OutputStream out, OutputStream err, String... args) {
+        // TODO: in/out/err?
+        MavenOptions mavenOptions = createMavenOptions(args);
+        if (mavenOptions.failed()) {
+            mavenOptions.printParsingError(System.err);
+            mavenOptions.printUsage(System.out);
+            return 1;
+        }
+        return doRun(mavenOptions);
+    }
+
+    protected int doRun(MavenOptions mavenOptions) {
+        if (mavenOptions.isLegacyCli()) {
+            // just delegate it: but filter out one command legacy does not know
+            // TODO: how to not duplicate string literal here?
+            return MavenCli.main(
+                    mavenOptions.getArgs().stream()
+                            .filter(a -> !a.equals("--legacy-cli"))
+                            .toArray(String[]::new),
+                    classWorld);
+        } else {
+            if (mavenOptions.isShowVersionAndExit()) {
+                if (mavenOptions.isQuiet()) {
+                    System.out.println(CLIReportingUtils.showVersionMinimal());
+                } else {
+                    System.out.println(CLIReportingUtils.showVersion());
+                }
+                return 0;
+            } else if (mavenOptions.getGoals().orElseGet(Collections::emptyList).isEmpty()) {
+                System.err.println("No goals specified!");
+                mavenOptions.printUsage(System.out);
+                return 1;
+            }
+            return executeMaven(mavenOptions);
+        }
+    }
+
+    protected int executeMaven(MavenOptions mavenOptions) {
+        MessageUtils.systemInstall();
+        MessageUtils.registerShutdownHook();
+        try {
+            System.out.println("Hello World!");
+            return 0;
+            //            initialize(cliRequest);
+            //            cli(cliRequest);
+            //            properties(cliRequest);
+            //            logging(cliRequest);
+            //            informativeCommands(cliRequest);
+            //            version(cliRequest);
+            //            localContainer = container(cliRequest);
+            //            commands(cliRequest);
+            //            configure(cliRequest);
+            //            toolchains(cliRequest);
+            //            populateRequest(cliRequest);
+            //            encryption(cliRequest);
+            //            return execute(cliRequest);
+
+        } finally {
+            MessageUtils.systemUninstall();
+        }
+    }
+}
diff --git a/maven-cli/src/main/java/org/apache/maven/cling/basedir/Basedir.java b/maven-cli/src/main/java/org/apache/maven/cling/basedir/Basedir.java
new file mode 100644
index 0000000000..e7a9ddb1d1
--- /dev/null
+++ b/maven-cli/src/main/java/org/apache/maven/cling/basedir/Basedir.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+package org.apache.maven.cling.basedir;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.apache.maven.api.annotations.Nonnull;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Basedir represents a base directory of some structure or layout, like "user home" or "maven home" is.
+ * Creating these instances is possible only with not yet existing path, or if path is existing, it is enforced
+ * it is a directory (maybe a symlink, but then it should point to a directory).
+ */
+public abstract class Basedir {
+    private final Path basedir;
+
+    public Basedir(Path basedir) {
+        this.basedir = validateDirectory(requireNonNull(basedir));
+    }
+
+    /**
+     * A directory path is valid if:
+     * <ul>
+     *     <li>is {@code null}</li>
+     *     <li>is not {@code null} and does not exists</li>
+     *     <li>is not {@code null} and is an existing directory</li>
+     * </ul>
+     */
+    protected Path validateDirectory(Path path) {
+        if (path != null && Files.exists(path) && !Files.isDirectory(path)) {
+            throw new IllegalArgumentException("The path exists but is not a directory: " + path);
+        }
+        return path;
+    }
+
+    /**
+     * A file path is valid if:
+     * <ul>
+     *     <li>is {@code null}</li>
+     *     <li>is not {@code null} and does not exists</li>
+     *     <li>is not {@code null} and is an existing file</li>
+     * </ul>
+     */
+    protected Path validateFile(Path path) {
+        if (path != null && Files.exists(path) && !Files.isRegularFile(path)) {
+            throw new IllegalArgumentException("The path exists but is not a file: " + path);
+        }
+        return path;
+    }
+
+    @Nonnull
+    public Path basedir() {
+        return basedir;
+    }
+}
diff --git a/maven-cli/src/main/java/org/apache/maven/cling/basedir/InstallationBasedir.java b/maven-cli/src/main/java/org/apache/maven/cling/basedir/InstallationBasedir.java
new file mode 100644
index 0000000000..2bc1086f8a
--- /dev/null
+++ b/maven-cli/src/main/java/org/apache/maven/cling/basedir/InstallationBasedir.java
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+package org.apache.maven.cling.basedir;
+
+import java.nio.file.Path;
+
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * Maven Installation (former "maven home") base directory.
+ */
+public class InstallationBasedir extends Basedir {
+    public static class Builder {
+        private final Path basedir;
+        private Path settingsXml;
+        private Path toolchainsXml;
+        private Path extensionsXml;
+
+        private Builder(Path basedir) {
+            this.basedir = basedir;
+        }
+
+        @Nonnull
+        public InstallationBasedir build() {
+            return new InstallationBasedir(basedir, settingsXml, toolchainsXml, extensionsXml);
+        }
+
+        @Nonnull
+        public Builder settingsXml(final Path settingsXml) {
+            this.settingsXml = settingsXml;
+            return this;
+        }
+
+        @Nonnull
+        public Builder toolchainsXml(final Path toolchainsXml) {
+            this.toolchainsXml = toolchainsXml;
+            return this;
+        }
+
+        @Nonnull
+        public Builder extensionsXml(final Path extensionsXml) {
+            this.extensionsXml = extensionsXml;
+            return this;
+        }
+    }
+
+    @Nonnull
+    public static Builder builder(Path basedir) {
+        return new Builder(basedir);
+    }
+
+    private final Path settingsXml;
+    private final Path toolchainsXml;
+    private final Path extensionsXml;
+
+    private InstallationBasedir(Path basedir, Path settingsXml, Path toolchainsXml, Path extensionsXml) {
+        super(basedir);
+        this.settingsXml = validateFile(settingsXml);
+        this.toolchainsXml = validateFile(toolchainsXml);
+        this.extensionsXml = validateFile(extensionsXml);
+    }
+
+    @Nonnull
+    public Path bin() {
+        return basedir().resolve("bin");
+    }
+
+    @Nonnull
+    public Path boot() {
+        return basedir().resolve("boot");
+    }
+
+    @Nonnull
+    public Path conf() {
+        return basedir().resolve("conf");
+    }
+
+    @Nonnull
+    public Path lib() {
+        return basedir().resolve("lib");
+    }
+
+    @Nonnull
+    public Path libExt() {
+        return lib().resolve("ext");
+    }
+
+    @Nonnull
+    public Path settingsXml() {
+        if (settingsXml != null) {
+            return settingsXml;
+        }
+        return conf().resolve("settings.xml");
+    }
+
+    @Nonnull
+    public Path toolchainsXml() {
+        if (toolchainsXml != null) {
+            return toolchainsXml;
+        }
+        return conf().resolve("toolchains.xml");
+    }
+
+    @Nonnull
+    public Path extensionsXml() {
+        if (extensionsXml != null) {
+            return extensionsXml;
+        }
+        return conf().resolve("extensions.xml");
+    }
+}
diff --git a/maven-cli/src/main/java/org/apache/maven/cling/basedir/SessionRootBasedir.java b/maven-cli/src/main/java/org/apache/maven/cling/basedir/SessionRootBasedir.java
new file mode 100644
index 0000000000..c99a1a7471
--- /dev/null
+++ b/maven-cli/src/main/java/org/apache/maven/cling/basedir/SessionRootBasedir.java
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+package org.apache.maven.cling.basedir;
+
+import java.nio.file.Path;
+
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * Maven Session Root base directory.
+ */
+public class SessionRootBasedir extends Basedir {
+    public static class Builder {
+        private final Path basedir;
+        private Path conf;
+        private Path settingsXml;
+        private Path extensionsXml;
+        private Path mavenProperties;
+
+        private Builder(Path basedir) {
+            this.basedir = basedir;
+        }
+
+        @Nonnull
+        public SessionRootBasedir build() {
+            return new SessionRootBasedir(basedir, conf, settingsXml, extensionsXml, mavenProperties);
+        }
+
+        @Nonnull
+        public Builder conf(final Path conf) {
+            this.conf = conf;
+            return this;
+        }
+
+        @Nonnull
+        public Builder settingsXml(final Path settingsXml) {
+            this.settingsXml = settingsXml;
+            return this;
+        }
+
+        @Nonnull
+        public Builder extensionsXml(final Path extensionsXml) {
+            this.extensionsXml = extensionsXml;
+            return this;
+        }
+
+        @Nonnull
+        public Builder mavenProperties(final Path mavenProperties) {
+            this.mavenProperties = mavenProperties;
+            return this;
+        }
+    }
+
+    @Nonnull
+    public static Builder builder(Path basedir) {
+        return new Builder(basedir);
+    }
+
+    private final Path conf;
+    private final Path settingsXml;
+    private final Path extensionsXml;
+    private final Path mavenProperties;
+
+    private SessionRootBasedir(Path basedir, Path conf, Path settingsXml, Path extensionsXml, Path mavenProperties) {
+        super(basedir);
+        this.conf = validateDirectory(conf);
+        this.settingsXml = validateFile(settingsXml);
+        this.extensionsXml = validateFile(extensionsXml);
+        this.mavenProperties = validateFile(mavenProperties);
+    }
+
+    @Nonnull
+    public Path conf() {
+        if (conf != null) {
+            return conf;
+        }
+        return basedir().resolve(".mvn");
+    }
+
+    @Nonnull
+    public Path settingsXml() {
+        if (settingsXml != null) {
+            return settingsXml;
+        }
+        return conf().resolve("settings.xml");
+    }
+
+    @Nonnull
+    public Path extensionsXml() {
+        if (extensionsXml != null) {
+            return extensionsXml;
+        }
+        return conf().resolve("extensions.xml");
+    }
+
+    @Nonnull
+    public Path mavenProperties() {
+        if (mavenProperties != null) {
+            return mavenProperties;
+        }
+        return conf().resolve("maven.properties");
+    }
+}
diff --git a/maven-cli/src/main/java/org/apache/maven/cling/basedir/UserBasedir.java b/maven-cli/src/main/java/org/apache/maven/cling/basedir/UserBasedir.java
new file mode 100644
index 0000000000..29dda95f35
--- /dev/null
+++ b/maven-cli/src/main/java/org/apache/maven/cling/basedir/UserBasedir.java
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+package org.apache.maven.cling.basedir;
+
+import java.nio.file.Path;
+
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * Maven User base directory.
+ */
+public class UserBasedir extends Basedir {
+    public static class Builder {
+        private final Path basedir;
+        private Path conf;
+        private Path settingsXml;
+        private Path toolchainsXml;
+        private Path extensionsXml;
+        private Path mavenProperties;
+
+        private Builder(Path basedir) {
+            this.basedir = basedir;
+        }
+
+        @Nonnull
+        public UserBasedir build() {
+            return new UserBasedir(basedir, conf, settingsXml, toolchainsXml, extensionsXml, mavenProperties);
+        }
+
+        @Nonnull
+        public Builder conf(final Path conf) {
+            this.conf = conf;
+            return this;
+        }
+
+        @Nonnull
+        public Builder settingsXml(final Path settingsXml) {
+            this.settingsXml = settingsXml;
+            return this;
+        }
+
+        @Nonnull
+        public Builder toolchainsXml(final Path toolchainsXml) {
+            this.toolchainsXml = toolchainsXml;
+            return this;
+        }
+
+        @Nonnull
+        public Builder extensionsXml(final Path extensionsXml) {
+            this.extensionsXml = extensionsXml;
+            return this;
+        }
+
+        @Nonnull
+        public Builder mavenProperties(final Path mavenProperties) {
+            this.mavenProperties = mavenProperties;
+            return this;
+        }
+    }
+
+    @Nonnull
+    public static Builder builder(Path basedir) {
+        return new Builder(basedir);
+    }
+
+    private final Path conf;
+    private final Path settingsXml;
+    private final Path toolchainsXml;
+    private final Path extensionsXml;
+    private final Path mavenProperties;
+
+    private UserBasedir(
+            Path basedir, Path conf, Path settingsXml, Path toolchainsXml, Path extensionsXml, Path mavenProperties) {
+        super(basedir);
+        this.conf = validateDirectory(conf);
+        this.settingsXml = validateFile(settingsXml);
+        this.toolchainsXml = validateFile(toolchainsXml);
+        this.extensionsXml = validateFile(extensionsXml);
+        this.mavenProperties = validateFile(mavenProperties);
+    }
+
+    @Nonnull
+    public Path conf() {
+        if (conf != null) {
+            return conf;
+        }
+        return basedir().resolve(".m2");
+    }
+
+    @Nonnull
+    public Path settingsXml() {
+        if (settingsXml != null) {
+            return settingsXml;
+        }
+        return conf().resolve("settings.xml");
+    }
+
+    @Nonnull
+    public Path toolchainsXml() {
+        if (toolchainsXml != null) {
+            return toolchainsXml;
+        }
+        return conf().resolve("toolchains.xml");
+    }
+
+    @Nonnull
+    public Path extensionsXml() {
+        if (extensionsXml != null) {
+            return extensionsXml;
+        }
+        return conf().resolve("extensions.xml");
+    }
+
+    @Nonnull
+    public Path mavenProperties() {
+        if (mavenProperties != null) {
+            return mavenProperties;
+        }
+        return conf().resolve("maven.properties");
+    }
+}
diff --git a/maven-cli/src/main/java/org/apache/maven/cling/support/MavenOptions.java b/maven-cli/src/main/java/org/apache/maven/cling/support/MavenOptions.java
new file mode 100644
index 0000000000..cde3f910e4
--- /dev/null
+++ b/maven-cli/src/main/java/org/apache/maven/cling/support/MavenOptions.java
@@ -0,0 +1,557 @@
+/*
+ * 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.
+ */
+package org.apache.maven.cling.support;
+
+import java.io.PrintStream;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Nonnull;
+import picocli.CommandLine;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.Parameters;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Generic Apache Maven CLI options.
+ */
+public class MavenOptions {
+    private final String commandName;
+    private final List<String> args;
+    private final CommandLine commandLine;
+    private final CommandLine.ParameterException parsingException;
+
+    public MavenOptions(String commandName, String... args) {
+        this.commandName = requireNonNull(commandName);
+        this.args = Arrays.asList(args);
+        this.commandLine = new CommandLine(this).setCommandName(commandName);
+        CommandLine.ParameterException ex = null;
+        try {
+            this.commandLine.parseArgs(args);
+        } catch (CommandLine.ParameterException e) {
+            ex = e;
+        }
+        this.parsingException = ex;
+    }
+
+    @Nonnull
+    public String getCommandName() {
+        return commandName;
+    }
+
+    @Nonnull
+    public List<String> getArgs() {
+        return args;
+    }
+
+    public boolean failed() {
+        return parsingException != null;
+    }
+
+    public void printParsingError(PrintStream out) {
+        if (parsingException != null) {
+            out.println("Bad CLI arguments: " + parsingException.getMessage());
+        }
+    }
+
+    public void printUsage(PrintStream out) {
+        commandLine.usage(out);
+    }
+
+    // Options
+
+    @Option(
+            names = {"-h", "--help"},
+            arity = "0",
+            description = "Display help information")
+    protected boolean help;
+
+    @Option(
+            names = {"-f", "--file"},
+            arity = "1",
+            paramLabel = "<file>",
+            description = "Force the use of an alternate POM file (or directory with pom.xml)")
+    protected Path alternatePomFile;
+
+    @Option(
+            names = {"-D", "--define"},
+            arity = "1",
+            paramLabel = "<property>",
+            description = "Define a user property in form of key=value, if no value set it becomes 'true'")
+    protected List<String> userProperties;
+
+    @Option(
+            names = {"-o", "--offline"},
+            arity = "0",
+            description = "Work offline")
+    protected boolean offline;
+
+    @Option(
+            names = {"-v", "--version"},
+            arity = "0",
+            description = "Display version information and exit")
+    protected boolean showVersionAndExit;
+
+    @Option(
+            names = {"-q", "--quiet"},
+            arity = "0",
+            description = "Quiet execution output - only show errors")
+    protected boolean quiet;
+
+    @Option(
+            names = {"-X", "--verbose"},
+            arity = "0",
+            description = "Verbose execution output")
+    protected boolean verbose;
+
+    @Option(
+            names = {"-e", "--errors"},
+            arity = "0",
+            description = "Produce execution error messages and stack traces")
+    protected boolean errors;
+
+    @Option(
+            names = {"-N", "--non-recursive"},
+            arity = "0",
+            description =
+                    "Do not recurse into sub-projects. When used together with -pl, do not recurse into sub-projects of selected aggregators")
+    protected boolean nonRecursive;
+
+    @Option(
+            names = {"-U", "--update-snapshots"},
+            arity = "0",
+            description = "Forces a check for missing releases and updated snapshots on remote repositories")
+    protected boolean updateSnapshots;
+
+    @Option(
+            names = {"-P", "--activate-profiles"},
+            arity = "1",
+            split = ",",
+            paramLabel = "<profile>",
+            description =
+                    "Comma-delimited list of profiles to activate. Prefixing a profile with ! excludes it, and ? marks it as optional")
+    protected List<String> activatedProfiles;
+
+    @Option(
+            names = {"-B", "--batch-mode", "--non-interactive"},
+            arity = "0",
+            description = "Run in non-interactive (batch) mode")
+    protected boolean nonInteractive;
+
+    @Option(
+            names = {"--force-interactive"},
+            arity = "0",
+            description =
+                    "Run in interactive mode. Overrides, if applicable, the CI environment variable and --non-interactive/--batch-mode options")
+    protected boolean forceInteractive;
+
+    @Option(
+            names = {"-nsu", "--no-snapshot-updates"},
+            arity = "0",
+            description = "Suppress SNAPSHOT updates")
+    protected boolean suppressSnapshotUpdates;
+
+    @Option(
+            names = {"-C", "--strict-checksums"},
+            arity = "0",
+            description = "Fail the build if checksums don't match")
+    protected boolean strictChecksums;
+
+    @Option(
+            names = {"-c", "--lax-checksums"},
+            arity = "0",
+            description = "Warn if checksums don't match")
+    protected boolean relaxedChecksums;
+
+    @Option(
+            names = {"-s", "--settings"},
+            arity = "1",
+            paramLabel = "<file>",
+            description = "Alternate path for the user settings file")
+    protected Path altUserSettings;
+
+    @Option(
+            names = {"-ps", "--project-settings"},
+            arity = "1",
+            paramLabel = "<file>",
+            description = "Alternate path for the project settings file")
+    protected Path altProjectSettings;
+
+    @Deprecated
+    @Option(
+            names = {"-gs", "--global-settings"},
+            arity = "1",
+            paramLabel = "<file>",
+            description = "Alternate path for the global settings file")
+    protected Path altGlobalSettings;
+
+    @Option(
+            names = {"-is", "--install-settings"},
+            arity = "1",
+            paramLabel = "<file>",
+            description = "Alternate path for the installation settings file")
+    protected Path altInstallationSettings;
+
+    @Option(
+            names = {"-t", "--toolchains"},
+            arity = "1",
+            paramLabel = "<file>",
+            description = "Alternate path for the user toolchains file")
+    protected Path altUserToolchains;
+
+    @Deprecated
+    @Option(
+            names = {"-gt", "--global-toolchains"},
+            arity = "1",
+            paramLabel = "<file>",
+            description = "Alternate path for the global toolchains file")
+    protected Path altGlobalToolchains;
+
+    @Option(
+            names = {"-it", "--install-toolchains"},
+            arity = "1",
+            paramLabel = "<file>",
+            description = "Alternate path for the installation toolchains file")
+    protected Path altInstallationToolchains;
+
+    public enum FailOnSeverityOption {
+        warn,
+        error
+    }
+
+    @Option(
+            names = {"-fos", "--fail-on-severity"},
+            arity = "1",
+            paramLabel = "<severity>",
+            description =
+                    "Configure which severity of logging should cause the build to fail. Supported values are 'warn' and 'error'")
+    protected FailOnSeverityOption failOnSeverity;
+
+    @Option(
+            names = {"-ff", "--fail-fast"},
+            arity = "0",
+            description = "Stop at first failure in build")
+    protected boolean failFast;
+
+    @Option(
+            names = {"-fae", "--fail-at-end"},
+            arity = "0",
+            description = "Only fail the build afterwards; allow all non-impacted builds to continue")
+    protected boolean failAtEnd;
+
+    @Option(
+            names = {"-fn", "--fail-never"},
+            arity = "0",
+            description = "Never fail the build, regardless of project result")
+    protected boolean failNever;
+
+    @Option(
+            names = {"-r", "--resume"},
+            arity = "0",
+            description =
+                    "Resume reactor from the last failed project, using the resume.properties file in the build directory")
+    protected boolean resume;
+
+    @Option(
+            names = {"-rf", "--resume-from"},
+            arity = "1",
+            paramLabel = "<project>",
+            description = "Resume reactor from specified project")
+    protected String resumeFrom;
+
+    @Option(
+            names = {"-pl", "--projects"},
+            arity = "1..*",
+            split = ",",
+            paramLabel = "<project>",
+            description =
+                    "Comma-delimited list of specified reactor projects to build instead of all projects. A project can be specified by [groupId]:artifactId or by its relative path. Prefixing a project with ! excludes it, and ? marks it as optional")
+    protected List<String> projects;
+
+    @Option(
+            names = {"-am", "--also-make"},
+            arity = "1..*",
+            split = ",",
+            paramLabel = "<project>",
+            description = "If project list is specified, also build projects required by this list")
+    protected List<String> alsoMake;
+
+    @Option(
+            names = {"-amd", "--also-make-dependents"},
+            arity = "0",
+            description = "If project list is specified, also build projects that depend on projects on the list")
+    protected boolean alsoMakeDependents;
+
+    @Option(
+            names = {"-l", "--log-file"},
+            arity = "1",
+            paramLabel = "<file>",
+            description = "Log file where all build output will go (disables output color)")
+    protected Path logFile;
+
+    @Option(
+            names = {"-V", "--show-version"},
+            arity = "0",
+            description = "Display version information without exiting")
+    protected boolean showVersion;
+
+    @Option(
+            names = {"-T", "--threads"},
+            arity = "1",
+            description = "Thread count, for instance 4 (int) or 2C/2.5C (int/float) where C is core multiplied")
+    protected String threads;
+
+    @Option(
+            names = {"-b", "--builder"},
+            arity = "1",
+            description = "The id of the build strategy to use")
+    protected String builder;
+
+    @Option(
+            names = {"-ntp", "--no-transfer-progress"},
+            arity = "0",
+            description = "Do not display transfer progress when downloading or uploading")
+    protected boolean noTransferProgress;
+
+    public enum ColorOption {
+        auto,
+        always,
+        never
+    }
+
+    @Option(
+            names = {"--color"},
+            arity = "1",
+            description = "Defines the color mode of the output. Supported are 'auto', 'always', 'never'")
+    protected ColorOption color = ColorOption.auto;
+
+    @Option(
+            names = {"-canf", "--cache-artifact-not-found"},
+            arity = "0..1",
+            paramLabel = "<bool>",
+            description =
+                    "Defines caching behaviour for 'not found' artifacts. Supported values are 'true' (default), 'false'")
+    protected boolean cacheArtifactNotFound = true;
+
+    @Option(
+            names = {"-sadp", "--strict-artifact-descriptor-policy"},
+            arity = "0..1",
+            paramLabel = "<bool>",
+            description = "Defines 'strict' artifact descriptor policy. Supported values are 'true', 'false' (default)")
+    protected boolean strictArtifactDescriptorPolicy;
+
+    @Option(
+            names = {"-itr", "--ignore-transitive-repositories"},
+            arity = "0",
+            description = "If set, Maven will ignore remote repositories introduced by transitive dependencies")
+    protected boolean ignoreTransitiveRepositories;
+
+    @Parameters(paramLabel = "GOALS", arity = "0..*", description = "List of phases and/or goals")
+    protected List<String> goals;
+
+    public boolean isHelp() {
+        return help;
+    }
+
+    public Optional<Path> getAlternatePomFile() {
+        return Optional.ofNullable(alternatePomFile);
+    }
+
+    public Optional<List<String>> getUserProperties() {
+        return Optional.ofNullable(userProperties);
+    }
+
+    public boolean isOffline() {
+        return offline;
+    }
+
+    public boolean isShowVersionAndExit() {
+        return showVersionAndExit;
+    }
+
+    public boolean isQuiet() {
+        return quiet;
+    }
+
+    public boolean isVerbose() {
+        return verbose;
+    }
+
+    public boolean isErrors() {
+        return errors;
+    }
+
+    public boolean isNonRecursive() {
+        return nonRecursive;
+    }
+
+    public boolean isUpdateSnapshots() {
+        return updateSnapshots;
+    }
+
+    public Optional<List<String>> getActivatedProfiles() {
+        return Optional.ofNullable(activatedProfiles);
+    }
+
+    public boolean isNonInteractive() {
+        return nonInteractive;
+    }
+
+    public boolean isForceInteractive() {
+        return forceInteractive;
+    }
+
+    public boolean isSuppressSnapshotUpdates() {
+        return suppressSnapshotUpdates;
+    }
+
+    public boolean isStrictChecksums() {
+        return strictChecksums;
+    }
+
+    public boolean isRelaxedChecksums() {
+        return relaxedChecksums;
+    }
+
+    public Optional<Path> getAltUserSettings() {
+        return Optional.ofNullable(altUserSettings);
+    }
+
+    public Optional<Path> getAltProjectSettings() {
+        return Optional.ofNullable(altProjectSettings);
+    }
+
+    @Deprecated
+    public Optional<Path> getAltGlobalSettings() {
+        return Optional.ofNullable(altGlobalSettings);
+    }
+
+    public Optional<Path> getAltInstallationSettings() {
+        return Optional.ofNullable(altInstallationSettings);
+    }
+
+    public Optional<Path> getAltUserToolchains() {
+        return Optional.ofNullable(altUserToolchains);
+    }
+
+    @Deprecated
+    public Optional<Path> getAltGlobalToolchains() {
+        return Optional.ofNullable(altGlobalToolchains);
+    }
+
+    public Optional<Path> getAltInstallationToolchains() {
+        return Optional.ofNullable(altInstallationToolchains);
+    }
+
+    public Optional<FailOnSeverityOption> getFailOnSeverity() {
+        return Optional.ofNullable(failOnSeverity);
+    }
+
+    public boolean isFailFast() {
+        return failFast;
+    }
+
+    public boolean isFailAtEnd() {
+        return failAtEnd;
+    }
+
+    public boolean isFailNever() {
+        return failNever;
+    }
+
+    public boolean isResume() {
+        return resume;
+    }
+
+    public Optional<String> getResumeFrom() {
+        return Optional.ofNullable(resumeFrom);
+    }
+
+    public Optional<List<String>> getProjects() {
+        return Optional.ofNullable(projects);
+    }
+
+    public Optional<List<String>> getAlsoMake() {
+        return Optional.ofNullable(alsoMake);
+    }
+
+    public boolean isAlsoMakeDependents() {
+        return alsoMakeDependents;
+    }
+
+    public Optional<Path> getLogFile() {
+        return Optional.ofNullable(logFile);
+    }
+
+    public boolean isShowVersion() {
+        return showVersion;
+    }
+
+    public Optional<String> getThreads() {
+        return Optional.ofNullable(threads);
+    }
+
+    public Optional<String> getBuilder() {
+        return Optional.ofNullable(builder);
+    }
+
+    public boolean isNoTransferProgress() {
+        return noTransferProgress;
+    }
+
+    public Optional<ColorOption> getColor() {
+        return Optional.ofNullable(color);
+    }
+
+    public boolean isCacheArtifactNotFound() {
+        return cacheArtifactNotFound;
+    }
+
+    public boolean isStrictArtifactDescriptorPolicy() {
+        return strictArtifactDescriptorPolicy;
+    }
+
+    public boolean isIgnoreTransitiveRepositories() {
+        return ignoreTransitiveRepositories;
+    }
+
+    public Optional<List<String>> getGoals() {
+        return Optional.ofNullable(goals);
+    }
+
+    // Extras
+
+    /**
+     * Experimental: CLIng own option, to delegate CLI to (legacy) MavenCli as is.
+     */
+    @Experimental
+    @Option(
+            names = {"--legacy-cli"},
+            arity = "0",
+            description = "Use legacy CLI")
+    protected boolean legacyCli;
+
+    public boolean isLegacyCli() {
+        return legacyCli;
+    }
+}
diff --git a/maven-cli/src/main/mdo/core-extensions.mdo b/maven-cli/src/main/mdo/core-extensions.mdo
new file mode 100644
index 0000000000..4ab0eca9c7
--- /dev/null
+++ b/maven-cli/src/main/mdo/core-extensions.mdo
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+
+-->
+
+<model xmlns="http://codehaus-plexus.github.io/MODELLO/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://codehaus-plexus.github.io/MODELLO/2.0.0 https://codehaus-plexus.github.io/modello/xsd/modello-2.0.0.xsd"
+  xml.namespace="http://maven.apache.org/EXTENSIONS/${version}"
+  xml.schemaLocation="http://maven.apache.org/xsd/core-extensions-${version}.xsd">
+
+  <id>core-extensions</id>
+  <name>CoreExtensions</name>
+  <description><![CDATA[
+  <p>This is a reference for the Core Extensions descriptor.</p>
+  <p>The default location for the Core Extensions descriptor file is <code>${maven.projectBasedir}/.mvn/extensions.xml</code></p>
+  ]]></description>
+
+  <defaults>
+    <default>
+      <key>package</key>
+      <value>org.apache.maven.cling.internal.extension.model</value>
+    </default>
+  </defaults>
+
+  <classes>
+    <class rootElement="true" xml.tagName="extensions" xsd.compositor="sequence">
+      <name>CoreExtensions</name>
+      <description>Extensions to load.</description>
+      <version>1.0.0+</version>
+      <fields>
+        <field>
+          <name>extensions</name>
+          <description>A set of build extensions to use from this project.</description>
+          <version>1.0.0+</version>
+          <association xml.itemsStyle="flat">
+            <type>CoreExtension</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+      </fields>
+    </class>
+    <class xml.tagName="extension">
+      <name>CoreExtension</name>
+      <description>Describes a build extension to utilise.</description>
+      <version>1.0.0+</version>
+      <fields>
+        <field>
+          <name>groupId</name>
+          <description>The group ID of the extension's artifact.</description>
+          <version>1.0.0+</version>
+          <required>true</required>
+          <type>String</type>
+        </field>
+        <field>
+          <name>artifactId</name>
+          <description>The artifact ID of the extension.</description>
+          <version>1.0.0+</version>
+          <required>true</required>
+          <type>String</type>
+        </field>
+        <field>
+          <name>version</name>
+          <description>The version of the extension.</description>
+          <version>1.0.0+</version>
+          <required>true</required>
+          <type>String</type>
+        </field>
+        <field>
+          <name>classLoadingStrategy</name>
+          <description>The class loading strategy: 'self-first' (the default), 'parent-first' (loads classes from the parent, then from the extension) or 'plugin' (follows the rules from extensions defined as plugins).</description>
+          <version>1.1.0+</version>
+          <defaultValue>self-first</defaultValue>
+          <required>false</required>
+          <type>String</type>
+        </field>
+        <field>
+          <name>configuration</name>
+          <version>1.2.0+</version>
+          <required>false</required>
+          <type>DOM</type>
+        </field>
+        <field>
+          <name>dependencies</name>
+          <description>A set of build extension dependencies to add to this extension classpath.</description>
+          <version>1.3.0+</version>
+          <association>
+            <type>CoreExtensionDependency</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+      </fields>
+      <codeSegments>
+        <codeSegment>
+          <version>1.0.0+</version>
+          <code>
+            <![CDATA[
+    /**
+     * Gets the identifier of the extension.
+     *
+     * @return The extension id in the form {@code <groupId>:<artifactId>:<version>}, never {@code null}.
+     */
+    public String getId() {
+        return (getGroupId() == null ? "[unknown-group-id]" : getGroupId())
+            + ":" + (getArtifactId() == null ? "[unknown-artifact-id]" : getArtifactId())
+            + ":" + (getVersion() == null ? "[unknown-version]" : getVersion());
+    }
+            ]]>
+          </code>
+        </codeSegment>
+      </codeSegments>
+    </class>
+    <class xml.tagName="dependency">
+      <name>CoreExtensionDependency</name>
+      <description>Describes a build extension dependency JAR to added to extension classloader.</description>
+      <version>1.3.0+</version>
+      <fields>
+        <field>
+          <name>groupId</name>
+          <description>The group ID of the dependency JAR artifact.</description>
+          <version>1.3.0+</version>
+          <required>true</required>
+          <type>String</type>
+        </field>
+        <field>
+          <name>artifactId</name>
+          <description>The artifact ID of the dependency JAR artifact.</description>
+          <version>1.3.0+</version>
+          <required>true</required>
+          <type>String</type>
+        </field>
+        <field>
+          <name>version</name>
+          <description>The version of the dependency JAR artifact.</description>
+          <version>1.3.0+</version>
+          <required>true</required>
+          <type>String</type>
+        </field>
+      </fields>
+    </class>
+  </classes>
+</model>
diff --git a/maven-cli/src/main/resources/META-INF/maven/slf4j-configuration.properties b/maven-cli/src/main/resources/META-INF/maven/slf4j-configuration.properties
new file mode 100644
index 0000000000..4798c87267
--- /dev/null
+++ b/maven-cli/src/main/resources/META-INF/maven/slf4j-configuration.properties
@@ -0,0 +1,23 @@
+# 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.
+
+# key = Slf4j effective logger factory implementation
+# value = corresponding o.a.m.cli.logging.Slf4jConfiguration class
+org.slf4j.impl.SimpleLoggerFactory org.apache.maven.cli.logging.impl.Slf4jSimpleConfiguration
+org.apache.maven.slf4j.MavenLoggerFactory org.apache.maven.cli.logging.impl.Slf4jSimpleConfiguration
+org.apache.logging.slf4j.Log4jLoggerFactory org.apache.maven.cli.logging.impl.Log4j2Configuration
+ch.qos.logback.classic.LoggerContext org.apache.maven.cli.logging.impl.LogbackConfiguration
diff --git a/maven-cli/src/site/site.xml b/maven-cli/src/site/site.xml
new file mode 100644
index 0000000000..4eb2879fad
--- /dev/null
+++ b/maven-cli/src/site/site.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+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.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.8.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/DECORATION/1.8.1 https://maven.apache.org/xsd/decoration-1.8.1.xsd">
+
+  <edit>${project.scm.url}</edit>
+
+  <body>
+    <menu name="Overview">
+      <item name="Introduction" href="index.html"/>
+      <item name="Javadocs" href="apidocs/index.html"/>
+      <item name="Source Xref" href="xref/index.html"/>
+      <!--item name="FAQ" href="faq.html"/-->
+    </menu>
+  </body>
+</project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 586b859116..0ccc02654a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -118,6 +118,7 @@ under the License.
     <module>maven-slf4j-provider</module>
     <module>maven-slf4j-wrapper</module>
     <module>maven-embedder</module>
+    <module>maven-cli</module>
     <module>maven-compat</module>
     <module>apache-maven</module>
     <module>maven-toolchain-model</module>
@@ -180,6 +181,7 @@ under the License.
     <jxpathVersion>1.3</jxpathVersion>
     <logbackClassicVersion>1.5.8</logbackClassicVersion>
     <mockitoVersion>5.13.0</mockitoVersion>
+    <picocliVersion>4.7.6</picocliVersion>
     <plexusInteractivityVersion>1.3</plexusInteractivityVersion>
     <plexusInterpolationVersion>1.27</plexusInterpolationVersion>
     <plexusTestingVersion>1.4.0</plexusTestingVersion>
@@ -230,6 +232,11 @@ under the License.
         <artifactId>maven-embedder</artifactId>
         <version>${project.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-cli</artifactId>
+        <version>${project.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.maven</groupId>
         <artifactId>maven-model</artifactId>
@@ -548,6 +555,12 @@ under the License.
         <artifactId>maven-resolver-transport-wagon</artifactId>
         <version>${resolverVersion}</version>
       </dependency>
+      <!-- CLIng -->
+      <dependency>
+        <groupId>info.picocli</groupId>
+        <artifactId>picocli</artifactId>
+        <version>${picocliVersion}</version>
+      </dependency>
       <!--  Commons -->
       <dependency>
         <groupId>commons-cli</groupId>