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

kwin pushed a commit to branch maven-3.9.x
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/maven-3.9.x by this push:
     new f860a8693d [MNG-5726] Support regular expression matching in profile 
activation for (#1431)
f860a8693d is described below

commit f860a8693d38292c8ce9ee3b6a883559e7a94796
Author: Konrad Windszus <k...@apache.org>
AuthorDate: Thu Mar 7 16:14:20 2024 +0100

    [MNG-5726] Support regular expression matching in profile activation for 
(#1431)
    
    OS version
    
    This requires using the reserved prefix "regex:" in the version element.
---
 maven-model-builder/pom.xml                        |   4 -
 .../OperatingSystemProfileActivator.java           |  55 +++--
 .../src/main/java/org/apache/maven/utils/Os.java   | 233 +++++++++++++++++++++
 .../OperatingSystemProfileActivatorTest.java       | 144 +++++++++++++
 4 files changed, 410 insertions(+), 26 deletions(-)

diff --git a/maven-model-builder/pom.xml b/maven-model-builder/pom.xml
index 8357f7ec38..97347635c9 100644
--- a/maven-model-builder/pom.xml
+++ b/maven-model-builder/pom.xml
@@ -32,10 +32,6 @@ under the License.
   <description>The effective model builder, with inheritance, profile 
activation, interpolation, ...</description>
 
   <dependencies>
-    <dependency>
-      <groupId>org.codehaus.plexus</groupId>
-      <artifactId>plexus-utils</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.codehaus.plexus</groupId>
       <artifactId>plexus-interpolation</artifactId>
diff --git 
a/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java
 
b/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java
index f7445199ff..a9c2c76a88 100644
--- 
a/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java
+++ 
b/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java
@@ -21,12 +21,14 @@ package org.apache.maven.model.profile.activation;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
+import java.util.Locale;
+
 import org.apache.maven.model.Activation;
 import org.apache.maven.model.ActivationOS;
 import org.apache.maven.model.Profile;
 import org.apache.maven.model.building.ModelProblemCollector;
 import org.apache.maven.model.profile.ProfileActivationContext;
-import org.codehaus.plexus.util.Os;
+import org.apache.maven.utils.Os;
 
 /**
  * Determines profile activation based on the operating system of the current 
runtime platform.
@@ -38,6 +40,8 @@ import org.codehaus.plexus.util.Os;
 @Singleton
 public class OperatingSystemProfileActivator implements ProfileActivator {
 
+    private static final String REGEX_PREFIX = "regex:";
+
     @Override
     public boolean isActive(Profile profile, ProfileActivationContext context, 
ModelProblemCollector problems) {
         Activation activation = profile.getActivation();
@@ -54,17 +58,21 @@ public class OperatingSystemProfileActivator implements 
ProfileActivator {
 
         boolean active = ensureAtLeastOneNonNull(os);
 
+        String actualOsName = 
context.getSystemProperties().get("os.name").toLowerCase(Locale.ENGLISH);
+        String actualOsArch = 
context.getSystemProperties().get("os.arch").toLowerCase(Locale.ENGLISH);
+        String actualOsVersion = 
context.getSystemProperties().get("os.version").toLowerCase(Locale.ENGLISH);
+
         if (active && os.getFamily() != null) {
-            active = determineFamilyMatch(os.getFamily());
+            active = determineFamilyMatch(os.getFamily(), actualOsName);
         }
         if (active && os.getName() != null) {
-            active = determineNameMatch(os.getName());
+            active = determineNameMatch(os.getName(), actualOsName);
         }
         if (active && os.getArch() != null) {
-            active = determineArchMatch(os.getArch());
+            active = determineArchMatch(os.getArch(), actualOsArch);
         }
         if (active && os.getVersion() != null) {
-            active = determineVersionMatch(os.getVersion());
+            active = determineVersionMatch(os.getVersion(), actualOsVersion);
         }
 
         return active;
@@ -90,22 +98,25 @@ public class OperatingSystemProfileActivator implements 
ProfileActivator {
         return os.getArch() != null || os.getFamily() != null || os.getName() 
!= null || os.getVersion() != null;
     }
 
-    private boolean determineVersionMatch(String version) {
-        String test = version;
+    private boolean determineVersionMatch(String expectedVersion, String 
actualVersion) {
+        String test = expectedVersion;
         boolean reverse = false;
-
-        if (test.startsWith("!")) {
-            reverse = true;
-            test = test.substring(1);
+        final boolean result;
+        if (test.startsWith(REGEX_PREFIX)) {
+            result = 
actualVersion.matches(test.substring(REGEX_PREFIX.length()));
+        } else {
+            if (test.startsWith("!")) {
+                reverse = true;
+                test = test.substring(1);
+            }
+            result = actualVersion.equals(test);
         }
 
-        boolean result = Os.isVersion(test);
-
-        return reverse ? !result : result;
+        return reverse != result;
     }
 
-    private boolean determineArchMatch(String arch) {
-        String test = arch;
+    private boolean determineArchMatch(String expectedArch, String actualArch) 
{
+        String test = expectedArch;
         boolean reverse = false;
 
         if (test.startsWith("!")) {
@@ -113,13 +124,13 @@ public class OperatingSystemProfileActivator implements 
ProfileActivator {
             test = test.substring(1);
         }
 
-        boolean result = Os.isArch(test);
+        boolean result = actualArch.equals(test);
 
         return reverse ? !result : result;
     }
 
-    private boolean determineNameMatch(String name) {
-        String test = name;
+    private boolean determineNameMatch(String expectedName, String actualName) 
{
+        String test = expectedName;
         boolean reverse = false;
 
         if (test.startsWith("!")) {
@@ -127,12 +138,12 @@ public class OperatingSystemProfileActivator implements 
ProfileActivator {
             test = test.substring(1);
         }
 
-        boolean result = Os.isName(test);
+        boolean result = actualName.equals(test);
 
         return reverse ? !result : result;
     }
 
-    private boolean determineFamilyMatch(String family) {
+    private boolean determineFamilyMatch(String family, String actualName) {
         String test = family;
         boolean reverse = false;
 
@@ -141,7 +152,7 @@ public class OperatingSystemProfileActivator implements 
ProfileActivator {
             test = test.substring(1);
         }
 
-        boolean result = Os.isFamily(test);
+        boolean result = Os.isFamily(test, actualName);
 
         return reverse ? !result : result;
     }
diff --git a/maven-model-builder/src/main/java/org/apache/maven/utils/Os.java 
b/maven-model-builder/src/main/java/org/apache/maven/utils/Os.java
new file mode 100644
index 0000000000..3bc84fcec1
--- /dev/null
+++ b/maven-model-builder/src/main/java/org/apache/maven/utils/Os.java
@@ -0,0 +1,233 @@
+/*
+ * 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.utils;
+
+import java.util.Locale;
+import java.util.stream.Stream;
+
+/**
+ * OS support
+ */
+public class Os {
+
+    /**
+     * The OS Name.
+     */
+    public static final String OS_NAME = 
System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
+
+    /**
+     * The OA architecture.
+     */
+    public static final String OS_ARCH = 
System.getProperty("os.arch").toLowerCase(Locale.ENGLISH);
+
+    /**
+     * The OS version.
+     */
+    public static final String OS_VERSION = 
System.getProperty("os.version").toLowerCase(Locale.ENGLISH);
+
+    /**
+     * OS Family
+     */
+    public static final String OS_FAMILY;
+
+    /**
+     * Boolean indicating if the running OS is a Windows system.
+     */
+    public static final boolean IS_WINDOWS;
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_WINDOWS = "windows";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_WIN9X = "win9x";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    public static final String FAMILY_NT = "winnt";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_OS2 = "os/2";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_NETWARE = "netware";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_DOS = "dos";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_MAC = "mac";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_TANDEM = "tandem";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_UNIX = "unix";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_OPENVMS = "openvms";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_ZOS = "z/os";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_OS390 = "os/390";
+
+    /**
+     * OS family that can be tested for. {@value}
+     */
+    private static final String FAMILY_OS400 = "os/400";
+
+    /**
+     * OpenJDK is reported to call MacOS X "Darwin"
+     *
+     * @see <a 
href="https://issues.apache.org/bugzilla/show_bug.cgi?id=44889";>bugzilla 
issue</a>
+     * @see <a 
href="https://issues.apache.org/jira/browse/HADOOP-3318";>HADOOP-3318</a>
+     */
+    private static final String DARWIN = "darwin";
+
+    /**
+     * The path separator.
+     */
+    private static final String PATH_SEP = 
System.getProperty("path.separator");
+
+    static {
+        // Those two public constants are initialized here, as they need all 
the private constants
+        // above to be initialized first, but the code style imposes the 
public constants to be
+        // defined above the private ones...
+        OS_FAMILY = getOsFamily();
+        IS_WINDOWS = isFamily(FAMILY_WINDOWS);
+    }
+
+    private Os() {}
+
+    /**
+     * Determines if the OS on which Maven is executing matches the
+     * given OS family.
+     *
+     * @param family the family to check for
+     * @return true if the OS matches
+     *
+     */
+    public static boolean isFamily(String family) {
+        return isFamily(family, OS_NAME);
+    }
+
+    /**
+     * Determines if the OS on which Maven is executing matches the
+     * given OS family derived from the given OS name
+     *
+     * @param family the family to check for
+     * @param actualOsName the OS name to check against
+     * @return true if the OS matches
+     *
+     */
+    public static boolean isFamily(String family, String actualOsName) {
+        // windows probing logic relies on the word 'windows' in the OS
+        boolean isWindows = actualOsName.contains(FAMILY_WINDOWS);
+        boolean is9x = false;
+        boolean isNT = false;
+        if (isWindows) {
+            // there are only four 9x platforms that we look for
+            is9x = (actualOsName.contains("95")
+                    || actualOsName.contains("98")
+                    || actualOsName.contains("me")
+                    // wince isn't really 9x, but crippled enough to
+                    // be a muchness. Maven doesnt run on CE, anyway.
+                    || actualOsName.contains("ce"));
+            isNT = !is9x;
+        }
+        switch (family) {
+            case FAMILY_WINDOWS:
+                return isWindows;
+            case FAMILY_WIN9X:
+                return isWindows && is9x;
+            case FAMILY_NT:
+                return isWindows && isNT;
+            case FAMILY_OS2:
+                return actualOsName.contains(FAMILY_OS2);
+            case FAMILY_NETWARE:
+                return actualOsName.contains(FAMILY_NETWARE);
+            case FAMILY_DOS:
+                return PATH_SEP.equals(";") && !isFamily(FAMILY_NETWARE, 
actualOsName) && !isWindows;
+            case FAMILY_MAC:
+                return actualOsName.contains(FAMILY_MAC) || 
actualOsName.contains(DARWIN);
+            case FAMILY_TANDEM:
+                return actualOsName.contains("nonstop_kernel");
+            case FAMILY_UNIX:
+                return PATH_SEP.equals(":")
+                        && !isFamily(FAMILY_OPENVMS, actualOsName)
+                        && (!isFamily(FAMILY_MAC, actualOsName) || 
actualOsName.endsWith("x"));
+            case FAMILY_ZOS:
+                return actualOsName.contains(FAMILY_ZOS) || 
actualOsName.contains(FAMILY_OS390);
+            case FAMILY_OS400:
+                return actualOsName.contains(FAMILY_OS400);
+            case FAMILY_OPENVMS:
+                return actualOsName.contains(FAMILY_OPENVMS);
+            default:
+                return actualOsName.contains(family.toLowerCase(Locale.US));
+        }
+    }
+
+    /**
+     * Helper method to determine the current OS family.
+     *
+     * @return name of current OS family.
+     */
+    private static String getOsFamily() {
+        return Stream.of(
+                        FAMILY_DOS,
+                        FAMILY_MAC,
+                        FAMILY_NETWARE,
+                        FAMILY_NT,
+                        FAMILY_OPENVMS,
+                        FAMILY_OS2,
+                        FAMILY_OS400,
+                        FAMILY_TANDEM,
+                        FAMILY_UNIX,
+                        FAMILY_WIN9X,
+                        FAMILY_WINDOWS,
+                        FAMILY_ZOS)
+                .filter(Os::isFamily)
+                .findFirst()
+                .orElse(null);
+    }
+}
diff --git 
a/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivatorTest.java
 
b/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivatorTest.java
new file mode 100644
index 0000000000..7944e25503
--- /dev/null
+++ 
b/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivatorTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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.model.profile.activation;
+
+import java.util.Properties;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationOS;
+import org.apache.maven.model.Profile;
+
+/**
+ * Tests {@link OperatingSystemProfileActivator}.
+ *
+ */
+public class OperatingSystemProfileActivatorTest extends 
AbstractProfileActivatorTest<OperatingSystemProfileActivator> {
+
+    public OperatingSystemProfileActivatorTest() throws Exception {
+        super(OperatingSystemProfileActivator.class);
+    }
+
+    private Profile newProfile(ActivationOS os) {
+        org.apache.maven.model.Activation a = new Activation();
+        a.setOs(os);
+
+        Profile p = new Profile();
+        p.setActivation(a);
+
+        return p;
+    }
+
+    private Properties newProperties(String osName, String osVersion, String 
osArch) {
+        Properties props = new Properties();
+        props.setProperty("os.name", osName);
+        props.setProperty("os.version", osVersion);
+        props.setProperty("os.arch", osArch);
+        return props;
+    }
+
+    public void testVersionStringComparison() throws Exception {
+        ActivationOS os = new ActivationOS();
+        os.setVersion("6.5.0-1014-aws");
+        Profile profile = newProfile(os);
+
+        assertActivation(true, profile, newContext(null, 
newProperties("linux", "6.5.0-1014-aws", "amd64")));
+        assertActivation(true, profile, newContext(null, 
newProperties("windows", "6.5.0-1014-aws", "aarch64")));
+
+        assertActivation(false, profile, newContext(null, 
newProperties("linux", "3.1.0", "amd64")));
+    }
+
+    public void testVersionRegexMatching() throws Exception {
+        ActivationOS os = new ActivationOS();
+        os.setVersion("regex:.*aws");
+        Profile profile = newProfile(os);
+
+        assertActivation(true, profile, newContext(null, 
newProperties("linux", "6.5.0-1014-aws", "amd64")));
+        assertActivation(true, profile, newContext(null, 
newProperties("windows", "6.5.0-1014-aws", "aarch64")));
+
+        assertActivation(false, profile, newContext(null, 
newProperties("linux", "3.1.0", "amd64")));
+    }
+
+    public void testName() {
+        ActivationOS os = new ActivationOS();
+        os.setName("windows");
+        Profile profile = newProfile(os);
+
+        assertActivation(false, profile, newContext(null, 
newProperties("linux", "6.5.0-1014-aws", "amd64")));
+        assertActivation(true, profile, newContext(null, 
newProperties("windows", "6.5.0-1014-aws", "aarch64")));
+    }
+
+    public void testNegatedName() {
+        ActivationOS os = new ActivationOS();
+        os.setName("!windows");
+        Profile profile = newProfile(os);
+
+        assertActivation(true, profile, newContext(null, 
newProperties("linux", "6.5.0-1014-aws", "amd64")));
+        assertActivation(false, profile, newContext(null, 
newProperties("windows", "6.5.0-1014-aws", "aarch64")));
+    }
+
+    public void testArch() {
+        ActivationOS os = new ActivationOS();
+        os.setArch("amd64");
+        Profile profile = newProfile(os);
+
+        assertActivation(true, profile, newContext(null, 
newProperties("linux", "6.5.0-1014-aws", "amd64")));
+        assertActivation(false, profile, newContext(null, 
newProperties("windows", "6.5.0-1014-aws", "aarch64")));
+    }
+
+    public void testNegatedArch() {
+        ActivationOS os = new ActivationOS();
+        os.setArch("!amd64");
+        Profile profile = newProfile(os);
+
+        assertActivation(false, profile, newContext(null, 
newProperties("linux", "6.5.0-1014-aws", "amd64")));
+        assertActivation(true, profile, newContext(null, 
newProperties("windows", "6.5.0-1014-aws", "aarch64")));
+    }
+
+    public void testFamily() {
+        ActivationOS os = new ActivationOS();
+        os.setFamily("windows");
+        Profile profile = newProfile(os);
+
+        assertActivation(false, profile, newContext(null, 
newProperties("linux", "6.5.0-1014-aws", "amd64")));
+        assertActivation(true, profile, newContext(null, 
newProperties("windows", "6.5.0-1014-aws", "aarch64")));
+    }
+
+    public void testNegatedFamily() {
+        ActivationOS os = new ActivationOS();
+        os.setFamily("!windows");
+        Profile profile = newProfile(os);
+
+        assertActivation(true, profile, newContext(null, 
newProperties("linux", "6.5.0-1014-aws", "amd64")));
+        assertActivation(false, profile, newContext(null, 
newProperties("windows", "6.5.0-1014-aws", "aarch64")));
+    }
+
+    public void testAllOsConditions() {
+        ActivationOS os = new ActivationOS();
+        os.setFamily("windows");
+        os.setName("windows");
+        os.setArch("aarch64");
+        os.setVersion("99");
+        Profile profile = newProfile(os);
+
+        assertActivation(false, profile, newContext(null, 
newProperties("linux", "6.5.0-1014-aws", "amd64")));
+        assertActivation(false, profile, newContext(null, 
newProperties("windows", "1", "aarch64")));
+        assertActivation(false, profile, newContext(null, 
newProperties("windows", "99", "amd64")));
+        assertActivation(true, profile, newContext(null, 
newProperties("windows", "99", "aarch64")));
+    }
+}

Reply via email to