Repository: conan-io/conan

Issue:
[bug] Conan 2.3.2 detects incorrect version of mingw-w64-x86_64-gcc 14.1.0-3
### Describe the bug

Summary:
Running `conan profile detect` on `MSYS2` version `3.5.3` with gcc package `mingw-w64-x86_64-gcc` version `14.1.0-3` detects `compiler.version=3` instead of `14`.  I think conan is getting confused by the `Rev3` in the `cc` version string.

Note that you shouldn't rely solely on detected profiles, but this seems like a bug.

```
# conan profile detect -v -f
detect_api: Found cc=gcc-3
detect_api: gcc C++ standard library: libstdc++11

Detected profile:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu98
compiler.libcxx=libstdc++11
compiler.version=3
os=Windows
```

Other details:
```
# pacman -Q mingw-w64-x86_64-gcc -v
Root      : /
Conf File : /etc/pacman.conf
DB Path   : /var/lib/pacman/
Cache Dirs: /var/cache/pacman/pkg/
Hook Dirs : /usr/share/libalpm/hooks/  /etc/pacman.d/hooks/
Lock File : /var/lib/pacman/db.lck
Log File  : /var/log/pacman.log
GPG Dir   : /etc/pacman.d/gnupg/
Targets   : mingw-w64-x86_64-gcc

# which cc
/mingw64/bin/cc

# cc --version
cc.exe (Rev3, Built by MSYS2 project) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

# conan --version
Conan version 2.3.2

# uname -a
MSYS_NT-10.0-17763 EC2AMAZ-XXXXXXX 3.5.3.x86_64 2024-05-06 06:45 UTC x86_64 Msys
```

### How to reproduce it

- Install MSYS2
- Install gcc version `14.1.0-3`
    `pacman -S mingw-w64-x86_64-gcc=14.1.0-3`
- Run `conan profile detect`
- Examine created default profile


Discussion:
Hi @jwatson0 thanks a lot for taking the time to report this issue. We can reproduce this (And it in fact is getting confused with the Rev3 number), and we'll try to target a fix for this  for 2.4 release.

The issue here comes from us failing to parse --version for gcc when we dont expect gcc to be called :)
Note this looks to have appeared in `2.3.0`.
Conan `2.2.3` detects this correctly.
```
# conan --version
Conan version 2.2.3

# conan profile detect -v -f
detect_api: Found gcc 14.1
detect_api: gcc>=5, using the major as version
detect_api: gcc C++ standard library: libstdc++11

Detected profile:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=14
os=Windows

# cc --version
cc.exe (Rev3, Built by MSYS2 project) 14.1.0
```



Patch:
diff --git a/conan/internal/api/detect_api.py b/conan/internal/api/detect_api.py
index e90894b297f..7fefd209d0b 100644
--- a/conan/internal/api/detect_api.py
+++ b/conan/internal/api/detect_api.py
@@ -438,8 +438,15 @@ def _cc_compiler(compiler_exe="cc"):
         if ret != 0:
             return None, None, None
         compiler = "clang" if "clang" in out else "gcc"
-        installed_version = re.search(r"([0-9]+(\.[0-9])?)", out).group()
-        if installed_version:
+        # clang and gcc have version after a space, first try to find that to skip extra numbers
+        # that might appear in the first line of the output before the version
+        installed_version = re.search(r" ([0-9]+(\.[0-9])+)", out)
+        # Try only major but with spaces next
+        installed_version = installed_version or re.search(r" ([0-9]+(\.[0-9])?)", out)
+        # Fallback to the first number we find optionally followed by other version fields
+        installed_version = installed_version or re.search(r"([0-9]+(\.[0-9])?)", out)
+        if installed_version and installed_version.group():
+            installed_version = installed_version.group()
             ConanOutput(scope="detect_api").info("Found cc=%s-%s" % (compiler, installed_version))
             return compiler, Version(installed_version), compiler_exe
     except (Exception,):  # to disable broad-except


Test patch:
diff --git a/test/unittests/util/detect_test.py b/test/unittests/util/detect_test.py
index 28b004230c7..1ac0e59a94f 100644
--- a/test/unittests/util/detect_test.py
+++ b/test/unittests/util/detect_test.py
@@ -1,8 +1,11 @@
 import unittest
 
 import mock
+from unittest.mock import patch
+import pytest
 from parameterized import parameterized
 
+from conan.internal.api.detect_api import _cc_compiler
 from conans.client.conf.detect import detect_defaults_settings
 from conans.model.version import Version
 from conan.test.utils.mocks import RedirectedTestOutput
@@ -56,3 +59,18 @@ def test_detect_clang_gcc_toolchain(self, _):
             with environment_update({"CC": "clang-9 --gcc-toolchain=/usr/lib/gcc/x86_64-linux-gnu/9"}):
                 detect_defaults_settings()
                 self.assertIn("CC and CXX: clang-9 --gcc-toolchain", output)
+
+
+@pytest.mark.parametrize("version_return,expected_version", [
+    ["cc.exe (Rev3, Built by MSYS2 project) 14.1.0", "14.1.0"],
+    ["g++ (Conan-Build-gcc--binutils-2.42) 14.1.0", "14.1.0"],
+    ["clang version 18.1.0rc (https://github.com/llvm/llvm-project.git 461274b81d8641eab64d494accddc81d7db8a09e)", "18.1.0"],
+    ["cc.exe (Rev3, Built by MSYS2 project) 14.0", "14.0"],
+    ["clang version 18 (https://github.com/llvm/llvm-project.git 461274b81d8641eab64d494accddc81d7db8a09e)", "18"],
+    ["cc.exe (Rev3, Built by MSYS2 project) 14", "14"],
+])
+@patch("conan.internal.api.detect_api.detect_runner")
+def test_detect_cc_versionings(detect_runner_mock, version_return, expected_version):
+    detect_runner_mock.return_value = 0, version_return
+    compiler, installed_version, compiler_exe = _cc_compiler()
+    assert installed_version == Version(expected_version)