Repository: quarkusio/quarkus
Issue: [native] Quarkus not able to parse GraalVM version in upcoming 21.1

## Describe the bug
Quakus fails to parse the GraalVM version from `native-image --version` in upcoming GraalVM 21.1.

This is because in the upcoming GraalVM the version is:
```
GraalVM Version 21.0.0 (Java Version 11.0.10+8-jvmci-21.0-b06)
```
while in previous versions it used to be:
```
GraalVM 21.1.0 Java 11 CE (Java Version 11.0.11+5-jvmci-21.1-b02)
```
Note the removal of "Version" and the addition of "Java 11 CE".

### Expected behavior
Quarkus should be able to get the version without any warning or error.

### Actual behavior
Quarkus prints:
```
[io.quarkus.deployment.pkg.steps.NativeImageBuildStep] Unable to get GraalVM version from the native-image binary.
```

## To Reproduce

1. Grab GraalVM from https://github.com/graalvm/graalvm-ce-dev-builds/releases/tag/21.1.0-dev-20210330_0726
2. Build a Quarkus app or test with `-Dnative` and `GRAALVM_HOME` pointing to GraalVM 21.1.0-dev


Changed files:
core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java
core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStepTest.java

diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java
index 345cc3f8cd6..063d3daeafd 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java
@@ -8,14 +8,9 @@
 final class GraalVM {
     static final class Version implements Comparable<Version> {
         private static final Pattern PATTERN = Pattern.compile(
-                "GraalVM Version (([1-9][0-9]*)\\\\.([0-9]+)\\\\.[0-9]+|\\\\p{XDigit}*)[^(\\n$]*(\\\\(Mandrel Distribution\\\\))?\\\\s*");
+                "(GraalVM|native-image)( Version)? ([1-9][0-9]*)\\\\.([0-9]+)\\\\.[0-9]+(-dev\\\\p{XDigit}*)?([^\\n$]*)\\\\s*");
 
         static final Version UNVERSIONED = new Version("Undefined", -1, -1, Distribution.ORACLE);
-        static final Version SNAPSHOT_ORACLE = new Version("Snapshot", Integer.MAX_VALUE, Integer.MAX_VALUE,
-                Distribution.ORACLE);
-        static final Version SNAPSHOT_MANDREL = new Version("Snapshot", Integer.MAX_VALUE, Integer.MAX_VALUE,
-                Distribution.MANDREL);
-
         static final Version VERSION_20_3 = new Version("GraalVM 20.3", 20, 3, Distribution.ORACLE);
         static final Version VERSION_21_0 = new Version("GraalVM 21.0", 21, 0, Distribution.ORACLE);
 
@@ -50,10 +45,6 @@ boolean isMandrel() {
             return distribution == Distribution.MANDREL;
         }
 
-        boolean isSnapshot() {
-            return this == SNAPSHOT_ORACLE || this == SNAPSHOT_MANDREL;
-        }
-
         boolean isNewerThan(Version version) {
             return this.compareTo(version) > 0;
         }
@@ -81,27 +72,21 @@ static Version of(Stream<String> lines) {
                 final String line = it.next();
                 final Matcher matcher = PATTERN.matcher(line);
                 if (matcher.find() && matcher.groupCount() >= 3) {
-                    final String distro = matcher.group(4);
-                    if (isSnapshot(matcher.group(2))) {
-                        return isMandrel(distro) ? SNAPSHOT_MANDREL : SNAPSHOT_ORACLE;
-                    } else {
-                        return new Version(
-                                line,
-                                Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3)),
-                                isMandrel(distro) ? Distribution.MANDREL : Distribution.ORACLE);
-                    }
+                    final String major = matcher.group(3);
+                    final String minor = matcher.group(4);
+                    final String distro = matcher.group(6);
+                    return new Version(
+                            line,
+                            Integer.parseInt(major), Integer.parseInt(minor),
+                            isMandrel(distro) ? Distribution.MANDREL : Distribution.ORACLE);
                 }
             }
 
             return UNVERSIONED;
         }
 
-        private static boolean isSnapshot(String s) {
-            return s == null;
-        }
-
         private static boolean isMandrel(String s) {
-            return "(Mandrel Distribution)".equals(s);
+            return s.contains("Mandrel Distribution");
         }
 
         @Override
diff --git a/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStepTest.java b/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStepTest.java
index d953271b887..d93d78cba6e 100644
--- a/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStepTest.java
+++ b/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStepTest.java
@@ -15,10 +15,6 @@ public class NativeImageBuildStepTest {
 
     @Test
     public void testGraalVMVersionDetected() {
-        assertVersion(1, 0, ORACLE, Version.of(Stream.of("GraalVM Version 1.0.0")));
-        assertVersion(19, 3, ORACLE, Version.of(Stream.of("GraalVM Version 19.3.0")));
-        assertVersion(19, 3, ORACLE, Version.of(Stream.of("GraalVM Version 19.3.3")));
-        assertVersion(20, 0, ORACLE, Version.of(Stream.of("GraalVM Version 20.0.0")));
         assertVersion(20, 1, ORACLE, Version.of(Stream.of("GraalVM Version 20.1.0 (Java Version 11.0.7)")));
         assertVersion(20, 1, MANDREL, Version
                 .of(Stream.of("GraalVM Version 20.1.0.1.Alpha2 56d4ee1b28 (Mandrel Distribution) (Java Version 11.0.8)")));
@@ -28,6 +24,14 @@ public void testGraalVMVersionDetected() {
                 .of(Stream.of("GraalVM Version 21.0.0.0-0b3 (Mandrel Distribution) (Java Version 11.0.8)")));
         assertVersion(20, 3, MANDREL, Version
                 .of(Stream.of("GraalVM Version 20.3.1.2-dev (Mandrel Distribution) (Java Version 11.0.8)")));
+        assertVersion(21, 1, MANDREL, Version
+                .of(Stream.of("native-image 21.1.0.0 Java 11 Mandrel Distribution (Java Version 11.0.11)")));
+        assertVersion(21, 1, MANDREL, Version
+                .of(Stream.of("GraalVM 21.1.0.0 Java 11 Mandrel Distribution (Java Version 11.0.11)")));
+        assertVersion(21, 1, ORACLE, Version
+                .of(Stream.of("GraalVM 21.1.0 Java 11 CE (Java Version 11.0.11+5-jvmci-21.1-b02)")));
+        assertVersion(21, 1, ORACLE, Version
+                .of(Stream.of("native-image 21.1.0.0 Java 11 CE (Java Version 11.0.11+5-jvmci-21.1-b02)")));
     }
 
     static void assertVersion(int major, int minor, Distribution distro, Version version) {
@@ -46,21 +50,9 @@ public void testGraalVMVersionUndetected() {
         assertThat(Version.of(Stream.of("foo bar")).isDetected()).isFalse();
     }
 
-    @Test
-    public void testGraalVMVersionSnapshot() {
-        assertSnapshot(MANDREL,
-                Version.of(Stream.of("GraalVM Version beb2fd6 (Mandrel Distribution) (Java Version 11.0.9-internal)")));
-    }
-
-    static void assertSnapshot(Distribution distro, Version version) {
-        assertThat(version.distribution).isEqualTo(distro);
-        assertThat(version.isDetected()).isEqualTo(true);
-        assertThat(version.isSnapshot()).isEqualTo(true);
-    }
-
     @Test
     public void testGraalVMVersionsOlderThan() {
-        assertOlderThan("GraalVM Version 1.0.0", "GraalVM Version 19.3.0");
+        assertOlderThan("GraalVM Version 19.3.0", "GraalVM Version 20.2.0");
         assertOlderThan("GraalVM Version 20.0.0", "GraalVM Version 20.1.0");
     }