Repository: conan-io/conan-center-index

Issue:
[package] rapidcheck/cci.20220514: cannot enable enable_gmock option
### Description

If I enable the `enable_gmock` option in `rapidcheck` the verification step always fails despite `gtest:build_gmock` is already enabled.

### Package and Environment Details

* Package Name/Version: **rapidcheck/cci.20220514**
* Conan version: **conan 1.55**
* Python version: **Python 3.10.8**


### Conan profile

```ini
[settings]
os=Macos
os_build=Macos
arch=x86_64
arch_build=x86_64
compiler=apple-clang
compiler.version=14
compiler.libcxx=libc++
build_type=Release
[options]
[conf]
[build_requires]
[env]
```

### Steps to reproduce

```ini
[requires]
gtest/1.12.1
rapidcheck/cci.20220514

[options]
rapidcheck:enable_gtest=True
rapidcheck:enable_gmock=True
gtest:build_gmock=True
```

Results in
```
ERROR: rapidcheck/cci.20220514: Error in validate() method, line 74
	if self.options.enable_gmock and not self.deps_cpp_info["gtest"].build_gmock:
	KeyError: 'gtest'
```

### Logs

<details><summary>Click to expand log</summary>

```
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=apple-clang
compiler.libcxx=libc++
compiler.version=14
os=Macos
os_build=Macos
[options]
[build_requires]
[env]

WARN: rapidcheck/cci.20220514: requirement gtest/1.11.0 overridden by your conanfile to gtest/1.12.1 
ERROR: rapidcheck/cci.20220514: Error in validate() method, line 74
	if self.options.enable_gmock and not self.deps_cpp_info["gtest"].build_gmock:
	KeyError: 'gtest'
```

</details>



Discussion:

Resolving patch:
diff --git a/recipes/rapidcheck/all/conanfile.py b/recipes/rapidcheck/all/conanfile.py
--- a/recipes/rapidcheck/all/conanfile.py
+++ b/recipes/rapidcheck/all/conanfile.py
@@ -1,10 +1,14 @@
-from conans import CMake, ConanFile, tools
-from conans.errors import ConanInvalidConfiguration
-import os
-import functools
+from conan import ConanFile
+from conan.errors import ConanInvalidConfiguration
+from conan.tools.build import check_min_cppstd
+from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
+from conan.tools.files import apply_conandata_patches, export_conandata_patches, get, copy, rmdir, save
+from conan.tools.microsoft import is_msvc
+from conan.tools.scm import Version
+from os.path import join
 import textwrap
 
-required_conan_version = ">=1.43.0"
+required_conan_version = ">=1.53.0"
 
 
 class RapidcheckConan(ConanFile):
@@ -14,7 +18,7 @@ class RapidcheckConan(ConanFile):
     homepage = "https://github.com/emil-e/rapidcheck"
     license = "BSD-2-Clause"
     topics = ("quickcheck", "testing", "property-testing")
-
+    package_type = "library"
     settings = "os", "arch", "compiler", "build_type"
     options = {
         "shared": [True, False],
@@ -33,24 +37,12 @@ class RapidcheckConan(ConanFile):
         "enable_gtest": False,
     }
 
-    generators = "cmake", "cmake_find_package"
-
-    @property
-    def _source_subfolder(self):
-        return "source_subfolder"
-
     @property
-    def _build_subfolder(self):
-        return "build_subfolder"
-
-    @property
-    def _is_msvc(self):
-        return str(self.settings.compiler) in ["Visual Studio", "msvc"]
+    def _min_cppstd(self):
+        return 11
 
     def export_sources(self):
-        self.copy("CMakeLists.txt")
-        for patch in self.conan_data.get("patches", {}).get(self.version, []):
-            self.copy(patch["patch_file"])
+        export_conandata_patches(self)
 
     def config_options(self):
         if self.settings.os == "Windows":
@@ -58,53 +50,57 @@ def config_options(self):
 
     def configure(self):
         if self.options.shared:
-            del self.options.fPIC
+            self.options.rm_safe("fPIC")
+
+    def layout(self):
+        cmake_layout(self, src_folder="src")
 
     def requirements(self):
         if self.options.enable_catch:
-            self.requires("catch2/2.13.9")
+            self.requires("catch2/2.13.10")
         if self.options.enable_gmock or self.options.enable_gtest:
-            self.requires("gtest/1.11.0")
+            self.requires("gtest/1.12.1")
 
     def validate(self):
-        if self.settings.compiler.get_safe("cppstd"):
-            tools.check_min_cppstd(self, 11)
-        if self._is_msvc and self.options.shared:
-            raise ConanInvalidConfiguration("shared is not supported using Visual Studio")
-        if self.options.enable_gmock and not self.deps_cpp_info["gtest"].build_gmock:
-            raise ConanInvalidConfiguration("The option `rapidcheck:enable_gmock` requires gtest:build_gmock=True`")
+        if self.settings.compiler.cppstd:
+            check_min_cppstd(self, self._min_cppstd)
+        if is_msvc(self) and self.options.shared:
+            raise ConanInvalidConfiguration(f"{self.ref} can not be built as shared on Visual Studio and msvc.")
+        if self.options.enable_gmock and not self.dependencies["gtest"].options.build_gmock:
+            raise ConanInvalidConfiguration("The option `rapidcheck:enable_gmock` requires `gtest/*:build_gmock=True`")
 
     def source(self):
-        tools.get(**self.conan_data["sources"][self.version],
-                  destination=self._source_subfolder, strip_root=True)
+        get(self, **self.conan_data["sources"][self.version], strip_root=True)
 
-    @functools.lru_cache(1)
-    def _configure_cmake(self):
-        cmake = CMake(self)
-        cmake.definitions["RC_ENABLE_RTTI"] = self.options.enable_rtti
-        cmake.definitions["RC_ENABLE_TESTS"] = False
-        cmake.definitions["RC_ENABLE_EXAMPLES"] = False
-        cmake.definitions["RC_ENABLE_CATCH"] = self.options.enable_catch
-        cmake.definitions["RC_ENABLE_GMOCK"] = self.options.enable_gmock
-        cmake.definitions["RC_ENABLE_GTEST"] = self.options.enable_gtest
-        cmake.configure(build_folder=self._build_subfolder)
-        return cmake
+    def generate(self):
+        tc = CMakeToolchain(self)
+        tc.variables["RC_ENABLE_RTTI"] = self.options.enable_rtti
+        tc.variables["RC_ENABLE_TESTS"] = False
+        tc.variables["RC_ENABLE_EXAMPLES"] = False
+        tc.variables["RC_ENABLE_CATCH"] = self.options.enable_catch
+        tc.variables["RC_ENABLE_GMOCK"] = self.options.enable_gmock
+        tc.variables["RC_ENABLE_GTEST"] = self.options.enable_gtest
+        tc.generate()
+
+        tc = CMakeDeps(self)
+        tc.generate()
 
     def build(self):
-        for patch in self.conan_data.get("patches", {}).get(self.version, []):
-            tools.patch(**patch)
-        cmake = self._configure_cmake()
+        apply_conandata_patches(self)
+        cmake = CMake(self)
+        cmake.configure()
         cmake.build()
 
     def package(self):
-        self.copy(pattern="LICENSE*", src=self._source_subfolder, dst="licenses")
-        cmake = self._configure_cmake()
+        copy(self, pattern="LICENSE*", dst=join(self.package_folder, "licenses"), src=self.source_folder)
+        cmake = CMake(self)
         cmake.install()
-        tools.rmdir(os.path.join(self.package_folder, "share"))
+
+        rmdir(self, join(self.package_folder, "share"))
 
         # TODO: to remove in conan v2 once cmake_find_package* generators removed
         self._create_cmake_module_alias_targets(
-            os.path.join(self.package_folder, self._module_file_rel_path),
+            join(self.package_folder, self._module_file_rel_path),
             {
                 "rapidcheck": "rapidcheck::rapidcheck_rapidcheck",
                 "rapidcheck_catch":"rapidcheck::rapidcheck_catch",
@@ -113,8 +109,7 @@ def package(self):
             }
         )
 
-    @staticmethod
-    def _create_cmake_module_alias_targets(module_file, targets):
+    def _create_cmake_module_alias_targets(self, module_file, targets):
         content = ""
         for alias, aliased in targets.items():
             content += textwrap.dedent("""\
@@ -123,11 +118,11 @@ def _create_cmake_module_alias_targets(module_file, targets):
                     set_property(TARGET {alias} PROPERTY INTERFACE_LINK_LIBRARIES {aliased})
                 endif()
             """.format(alias=alias, aliased=aliased))
-        tools.save(module_file, content)
+        save(self, module_file, content)
 
     @property
     def _module_file_rel_path(self):
-        return os.path.join("lib", "cmake", "conan-official-{}-targets.cmake".format(self.name))
+        return join("lib", "cmake", f"conan-official-{self.name}-targets.cmake")
 
     def package_info(self):
         self.cpp_info.set_property("cmake_file_name", "rapidcheck")
@@ -135,7 +130,7 @@ def package_info(self):
         self.cpp_info.components["rapidcheck_rapidcheck"].set_property("cmake_target_name", "rapidcheck")
         self.cpp_info.components["rapidcheck_rapidcheck"].libs = ["rapidcheck"]
         version = str(self.version)[4:]
-        if tools.Version(version) < "20201218":
+        if Version(version) < "20201218":
             if self.options.enable_rtti:
                 self.cpp_info.components["rapidcheck_rapidcheck"].defines.append("RC_USE_RTTI")
         else:
@@ -152,6 +147,9 @@ def package_info(self):
             self.cpp_info.components["rapidcheck_gtest"].set_property("cmake_target_name", "rapidcheck_gtest")
             self.cpp_info.components["rapidcheck_gtest"].requires = ["rapidcheck_rapidcheck", "gtest::gtest"]
 
+        if self.settings.os in ["Linux", "FreeBSD"]:
+            self.cpp_info.system_libs.append("m")
+
         # TODO: to remove in conan v2 once cmake_find_package* generators removed
         self.cpp_info.components["rapidcheck_rapidcheck"].build_modules["cmake_find_package"] = [self._module_file_rel_path]
         self.cpp_info.components["rapidcheck_rapidcheck"].build_modules["cmake_find_package_multi"] = [self._module_file_rel_path]


Test patch:
diff --git a/recipes/rapidcheck/all/test_package/CMakeLists.txt b/recipes/rapidcheck/all/test_package/CMakeLists.txt
--- a/recipes/rapidcheck/all/test_package/CMakeLists.txt
+++ b/recipes/rapidcheck/all/test_package/CMakeLists.txt
@@ -1,11 +1,9 @@
-cmake_minimum_required(VERSION 3.1)
-project(test_package)
+cmake_minimum_required(VERSION 3.8)
 
-include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
-conan_basic_setup(TARGETS)
+project(test_package CXX)
 
 find_package(rapidcheck REQUIRED CONFIG)
 
 add_executable(${PROJECT_NAME} test_package.cpp)
-target_link_libraries(${PROJECT_NAME} rapidcheck)
-set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)
+target_link_libraries(${PROJECT_NAME} PRIVATE rapidcheck::rapidcheck)
+target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)
diff --git a/recipes/rapidcheck/all/test_package/conanfile.py b/recipes/rapidcheck/all/test_package/conanfile.py
--- a/recipes/rapidcheck/all/test_package/conanfile.py
+++ b/recipes/rapidcheck/all/test_package/conanfile.py
@@ -1,10 +1,19 @@
-from conans import ConanFile, CMake, tools
+from conan import ConanFile
+from conan.tools.build import can_run
+from conan.tools.cmake import cmake_layout, CMake
 import os
 
 
 class TestPackageConan(ConanFile):
-    settings = "os", "compiler", "build_type", "arch"
-    generators = "cmake", "cmake_find_package_multi"
+    settings = "os", "arch", "compiler", "build_type"
+    generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
+    test_type = "explicit"
+
+    def requirements(self):
+        self.requires(self.tested_reference_str)
+
+    def layout(self):
+        cmake_layout(self)
 
     def build(self):
         cmake = CMake(self)
@@ -12,6 +21,6 @@ def build(self):
         cmake.build()
 
     def test(self):
-        if not tools.cross_building(self):
-            bin_path = os.path.join("bin", "test_package")
-            self.run(bin_path, run_environment=True)
+        if can_run(self):
+            bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
+            self.run(bin_path, env="conanrun")
diff --git a/recipes/rapidcheck/all/test_v1_package/CMakeLists.txt b/recipes/rapidcheck/all/test_v1_package/CMakeLists.txt
new file mode 100644
--- /dev/null
+++ b/recipes/rapidcheck/all/test_v1_package/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.1)
+project(test_package)
+
+include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+conan_basic_setup(TARGETS)
+
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../test_package/
+                 ${CMAKE_CURRENT_BINARY_DIR}/test_package/)
diff --git a/recipes/rapidcheck/all/test_v1_package/conanfile.py b/recipes/rapidcheck/all/test_v1_package/conanfile.py
new file mode 100644
--- /dev/null
+++ b/recipes/rapidcheck/all/test_v1_package/conanfile.py
@@ -0,0 +1,18 @@
+from conans import ConanFile, CMake
+from conan.tools.build import cross_building
+import os
+
+
+class TestPackageConan(ConanFile):
+    settings = "os", "compiler", "build_type", "arch"
+    generators = "cmake", "cmake_find_package_multi"
+
+    def build(self):
+        cmake = CMake(self)
+        cmake.configure()
+        cmake.build()
+
+    def test(self):
+        if not cross_building(self):
+            bin_path = os.path.join("bin", "test_package")
+            self.run(bin_path, run_environment=True)