From 986f59683e2271ee6d4c611321f258a8892fc771 Mon Sep 17 00:00:00 2001
From: Guillaume Nodet
Date: Wed, 20 Nov 2024 21:36:48 +0100
Subject: [PATCH] [MNG-8286] Add a condition profile based on a simple
expressions (#1771)
---
api/maven-api-model/src/main/mdo/maven.mdo | 83 +-
.../src/main/mdo/settings.mdo | 8 +
.../MavenRepositorySystemSupplier.java | 1104 -----------------
.../model/ProfileActivationContext.java | 31 +-
.../internal/impl/DefaultSettingsBuilder.java | 17 +-
.../maven/internal/impl/SettingsUtilsV4.java | 4 +
.../impl/model/DefaultModelBuilder.java | 21 +-
.../impl/model/DefaultModelValidator.java | 13 +
.../DefaultProfileActivationContext.java | 36 +-
...ProfileActivationFilePathInterpolator.java | 4 +-
.../model/profile/ConditionFunctions.java | 296 +++++
.../impl/model/profile/ConditionParser.java | 636 ++++++++++
.../profile/ConditionProfileActivator.java | 213 ++++
.../OperatingSystemProfileActivator.java | 8 +-
.../profile/PackagingProfileActivator.java | 2 +-
.../profile/PropertyProfileActivator.java | 3 +
.../profile/AbstractProfileActivatorTest.java | 64 +
.../model/profile/ConditionParserTest.java | 300 +++++
.../ConditionProfileActivatorTest.java | 503 ++++++++
.../profile/FileProfileActivatorTest.java | 145 +++
.../JdkVersionProfileActivatorTest.java | 198 +++
.../OperatingSystemProfileActivatorTest.java | 152 +++
.../profile/PropertyProfileActivatorTest.java | 168 +++
.../model/profile/SimpleProblemCollector.java | 121 ++
24 files changed, 2957 insertions(+), 1173 deletions(-)
delete mode 100644 compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemSupplier.java
create mode 100644 impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/profile/ConditionFunctions.java
create mode 100644 impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/profile/ConditionParser.java
create mode 100644 impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/profile/ConditionProfileActivator.java
create mode 100644 maven-api-impl/src/test/java/org/apache/maven/internal/impl/model/profile/AbstractProfileActivatorTest.java
create mode 100644 maven-api-impl/src/test/java/org/apache/maven/internal/impl/model/profile/ConditionParserTest.java
create mode 100644 maven-api-impl/src/test/java/org/apache/maven/internal/impl/model/profile/ConditionProfileActivatorTest.java
create mode 100644 maven-api-impl/src/test/java/org/apache/maven/internal/impl/model/profile/FileProfileActivatorTest.java
create mode 100644 maven-api-impl/src/test/java/org/apache/maven/internal/impl/model/profile/JdkVersionProfileActivatorTest.java
create mode 100644 maven-api-impl/src/test/java/org/apache/maven/internal/impl/model/profile/OperatingSystemProfileActivatorTest.java
create mode 100644 maven-api-impl/src/test/java/org/apache/maven/internal/impl/model/profile/PropertyProfileActivatorTest.java
create mode 100644 maven-api-impl/src/test/java/org/apache/maven/internal/impl/model/profile/SimpleProblemCollector.java
diff --git a/api/maven-api-model/src/main/mdo/maven.mdo b/api/maven-api-model/src/main/mdo/maven.mdo
index 4e29c4ffaf..2829ffdc22 100644
--- a/api/maven-api-model/src/main/mdo/maven.mdo
+++ b/api/maven-api-model/src/main/mdo/maven.mdo
@@ -2742,10 +2742,79 @@
Activation
4.0.0+
- The conditions within the build runtime environment which will trigger the
- automatic inclusion of the build profile. Multiple conditions can be defined, which must
- be all satisfied to activate the profile.
-
+ In addition to the traditional activation mechanisms (JDK version, OS properties,
+ file existence, etc.), Maven now supports a powerful condition-based activation
+ through the {@code condition} field. This new mechanism allows for more flexible
+ and expressive profile activation rules.
+
+ Condition Syntax
+
+ The condition is specified as a string expression that can include various
+ functions, comparisons, and logical operators. Some key features include:
+
+
+ - Property access: {@code ${property.name}}
+ - Comparison operators: {@code ==}, {@code !=}, {@code <}, {@code >}, {@code <=}, {@code >=}
+ - Logical operators: {@code &&} (AND), {@code ||} (OR), {@code not(...)}
+ - Functions: {@code exists(...)}, {@code missing(...)}, {@code matches(...)}, {@code inrange(...)}, and more
+
+
+ Supported Functions
+
+ The following functions are supported in condition expressions:
+
+
+ - {@code length(string)}: Returns the length of the given string.
+ - {@code upper(string)}: Converts the string to uppercase.
+ - {@code lower(string)}: Converts the string to lowercase.
+ - {@code substring(string, start, [end])}: Returns a substring of the given string.
+ - {@code indexOf(string, substring)}: Returns the index of the first occurrence of substring in string, or -1 if not found.
+ - {@code contains(string, substring)}: Checks if the string contains the substring.
+ - {@code matches(string, regex)}: Checks if the string matches the given regular expression.
+ - {@code not(condition)}: Negates the given condition.
+ - {@code if(condition, trueValue, falseValue)}: Returns trueValue if the condition is true, falseValue otherwise.
+ - {@code exists(path)}: Checks if a file matching the given glob pattern exists.
+ - {@code missing(path)}: Checks if a file matching the given glob pattern does not exist.
+ - {@code inrange(version, range)}: Checks if the given version is within the specified version range.
+
+
+ Supported properties
+
+ The following properties are supported in expressions:
+
+
+ - `project.basedir`: The project directory
+ - `project.rootDirectory`: The root directory of the project
+ - `project.artifactId`: The artifactId of the project
+ - `project.packaging`: The packaging of the project
+ - user properties
+ - system properties (including environment variables prefixed with `env.`)
+
+
+ Examples
+
+
+ - JDK version range: {@code inrange(${java.version}, '[11,)')} (JDK 11 or higher)
+ - OS check: {@code ${os.name} == 'windows'}
+ - File existence: {@code exists('${project.basedir}/src/**}{@code /*.xsd')}
+ - Property check: {@code ${my.property} != 'some-value'}
+ - Regex matching: {@code matches(${os.version}, '.*aws')}
+ - Complex condition: {@code ${os.name} == 'windows' && ${os.arch} != 'amd64' && inrange(${os.version}, '[10,)')}
+ - String length check: {@code length(${user.name}) > 5}
+ - Substring with version: {@code substring(${java.version}, 0, 3) == '1.8'}
+ - Using indexOf: {@code indexOf(${java.version}, '-') > 0}
+ - Conditional logic: {@code if(contains(${java.version}, '-'), substring(${java.version}, 0, indexOf(${java.version}, '-')), ${java.version})}
+
+
+ This flexible condition mechanism allows for more precise control over profile
+ activation, enabling developers to create profiles that respond to a wide range of
+ environmental factors and project states.
+ ]]>
activeByDefault
@@ -2798,6 +2867,12 @@
String
Specifies that this profile will be activated based on the project's packaging.
+
+ condition
+ 4.1.0+
+ String
+ The condition which must be satisfied to activate the profile.
+