Repository: conan-io/conan
Pull request #11939 (2022-08-23 11:31:22)

change conan.tools.files.get/download default checksums to None
Changelog: Fix: Change conan.tools.files.get/download default checksums to None, instead of empty string.
Docs: Omit

Close https://github.com/conan-io/conan/issues/11843


Patch:
diff --git a/conan/tools/cmake/presets.py b/conan/tools/cmake/presets.py
index 03449a059..2b710d190 100644
--- a/conan/tools/cmake/presets.py
+++ b/conan/tools/cmake/presets.py
@@ -133,7 +133,8 @@ def write_cmake_presets(conanfile, toolchain_file, generator, cache_variables):
         if "CMAKE_SH" not in cache_variables:
             cache_variables["CMAKE_SH"] = "CMAKE_SH-NOTFOUND"
 
-        cmake_make_program = conanfile.conf.get("tools.gnu:make_program", default=cache_variables.get("CMAKE_MAKE_PROGRAM"))
+        cmake_make_program = conanfile.conf.get("tools.gnu:make_program",
+                                                default=cache_variables.get("CMAKE_MAKE_PROGRAM"))
         if cmake_make_program:
             cmake_make_program = cmake_make_program.replace("\\", "/")
             cache_variables["CMAKE_MAKE_PROGRAM"] = cmake_make_program
@@ -141,6 +142,10 @@ def write_cmake_presets(conanfile, toolchain_file, generator, cache_variables):
     if "CMAKE_POLICY_DEFAULT_CMP0091" not in cache_variables:
         cache_variables["CMAKE_POLICY_DEFAULT_CMP0091"] = "NEW"
 
+    if "BUILD_TESTING" not in cache_variables:
+        if conanfile.conf.get("tools.build:skip_test", check_type=bool):
+            cache_variables["BUILD_TESTING"] = "OFF"
+
     preset_path = os.path.join(conanfile.generators_folder, "CMakePresets.json")
     multiconfig = is_multi_configuration(generator)
 
diff --git a/conan/tools/files/files.py b/conan/tools/files/files.py
index e8eac166d..e46e02b2f 100644
--- a/conan/tools/files/files.py
+++ b/conan/tools/files/files.py
@@ -78,7 +78,7 @@ def rm(conanfile, pattern, folder, recursive=False):
             break
 
 
-def get(conanfile, url, md5='', sha1='', sha256='', destination=".", filename="",
+def get(conanfile, url, md5=None, sha1=None, sha256=None, destination=".", filename="",
         keep_permissions=False, pattern=None, verify=True, retry=None, retry_wait=None,
         auth=None, headers=None, strip_root=False):
     """ high level downloader + unzipper + (optional hash checker) + delete temporary zip
@@ -124,7 +124,7 @@ def ftp_download(conanfile, ip, filename, login='', password=''):
 
 
 def download(conanfile, url, filename, verify=True, retry=None, retry_wait=None,
-             auth=None, headers=None, md5='', sha1='', sha256=''):
+             auth=None, headers=None, md5=None, sha1=None, sha256=None):
     """Retrieves a file from a given URL into a file with a given filename.
        It uses certificates from a list of known verifiers for https downloads,
        but this can be optionally disabled.
@@ -167,7 +167,8 @@ def download(conanfile, url, filename, verify=True, retry=None, retry_wait=None,
     def _download_file(file_url):
         # The download cache is only used if a checksum is provided, otherwise, a normal download
         if file_url.startswith("file:"):
-            _copy_local_file_from_uri(conanfile, url=file_url, file_path=filename, md5=md5, sha1=sha1, sha256=sha256)
+            _copy_local_file_from_uri(conanfile, url=file_url, file_path=filename, md5=md5,
+                                      sha1=sha1, sha256=sha256)
         else:
             run_downloader(requester=requester, output=out, verify=verify, download_cache=download_cache,
                         user_download=True, url=file_url,
@@ -188,17 +189,19 @@ def download(conanfile, url, filename, verify=True, retry=None, retry_wait=None,
         else:
             raise ConanException("All downloads from ({}) URLs have failed.".format(len(url)))
 
+
 def _copy_local_file_from_uri(conanfile, url, file_path, md5=None, sha1=None, sha256=None):
     file_origin = _path_from_file_uri(url)
     shutil.copyfile(file_origin, file_path)
 
-    if md5:
+    if md5 is not None:
         check_md5(conanfile, file_path, md5)
-    if sha1:
+    if sha1 is not None:
         check_sha1(conanfile, file_path, sha1)
-    if sha256:
+    if sha256 is not None:
         check_sha256(conanfile, file_path, sha256)
 
+
 def _path_from_file_uri(uri):
     path = urlparse(uri).path
     return url2pathname(path)
diff --git a/conans/client/conf/config_installer.py b/conans/client/conf/config_installer.py
index 4e54c6b9b..434868531 100644
--- a/conans/client/conf/config_installer.py
+++ b/conans/client/conf/config_installer.py
@@ -108,9 +108,10 @@ def _process_file(directory, filename, config, cache, output, folder):
         finally:
             _filecopy(directory, filename, cache.cache_folder)
             migrate_registry_file(cache, output)
+    # FIXME: remove in 2.0
     elif filename == "remotes.json":
-        # Fix for Conan 2.0
-        raise ConanException("remotes.json install is not supported yet. Use 'remotes.txt'")
+        output.info("Defining remotes from remotes.json")
+        _filecopy(directory, filename, cache.cache_folder)
     else:
         # This is ugly, should be removed in Conan 2.0
         if filename in ("README.md", "LICENSE.txt") and not directory.startswith("templates"):
@@ -137,6 +138,7 @@ def _process_folder(config, folder, cache, output):
         raise ConanException("No such directory: '%s'" % str(folder))
     if config.source_folder:
         folder = os.path.join(folder, config.source_folder)
+
     for root, dirs, files in walk(folder):
         dirs[:] = [d for d in dirs if d != ".git"]
         for f in files:
diff --git a/conans/client/downloaders/file_downloader.py b/conans/client/downloaders/file_downloader.py
index 659461810..0611d73af 100644
--- a/conans/client/downloaders/file_downloader.py
+++ b/conans/client/downloaders/file_downloader.py
@@ -16,11 +16,11 @@ from conans.util.tracer import log_download
 
 
 def check_checksum(file_path, md5, sha1, sha256):
-    if md5:
+    if md5 is not None:
         check_md5(file_path, md5)
-    if sha1:
+    if sha1 is not None:
         check_sha1(file_path, sha1)
-    if sha256:
+    if sha256 is not None:
         check_sha256(file_path, sha256)
 
 
diff --git a/conans/client/tools/net.py b/conans/client/tools/net.py
index c11bb9961..f6ba4c562 100644
--- a/conans/client/tools/net.py
+++ b/conans/client/tools/net.py
@@ -6,7 +6,7 @@ from conans.errors import ConanException
 from conans.util.fallbacks import default_output, default_requester
 
 
-def get(url, md5='', sha1='', sha256='', destination=".", filename="", keep_permissions=False,
+def get(url, md5=None, sha1=None, sha256=None, destination=".", filename="", keep_permissions=False,
         pattern=None, requester=None, output=None, verify=True, retry=None, retry_wait=None,
         overwrite=False, auth=None, headers=None, strip_root=False):
     """ high level downloader + unzipper + (optional hash checker) + delete temporary zip
@@ -51,7 +51,7 @@ def ftp_download(ip, filename, login='', password=''):
 
 
 def download(url, filename, verify=True, out=None, retry=None, retry_wait=None, overwrite=False,
-             auth=None, headers=None, requester=None, md5='', sha1='', sha256=''):
+             auth=None, headers=None, requester=None, md5=None, sha1=None, sha256=None):
     """Retrieves a file from a given URL into a file with a given filename.
        It uses certificates from a list of known verifiers for https downloads,
        but this can be optionally disabled.


Test patch:
diff --git a/conans/test/conftest.py b/conans/test/conftest.py
index be571fd11..a3e45cfd7 100644
--- a/conans/test/conftest.py
+++ b/conans/test/conftest.py
@@ -34,6 +34,9 @@ tools_locations = {
 }
 """
 
+MacOS_arm = all([platform.system() == "Darwin", platform.machine() == "arm64"])
+homebrew_root = "/opt/homebrew" if MacOS_arm else "/usr/local"
+
 
 tools_locations = {
     "clang": {"disabled": True},
@@ -47,7 +50,9 @@ tools_locations = {
         "0.28": {
             "path": {
                 # Using chocolatey in Windows -> choco install pkgconfiglite --version 0.28
-                'Windows': "C:/ProgramData/chocolatey/lib/pkgconfiglite/tools/pkg-config-lite-0.28-1/bin"
+                'Windows': "C:/ProgramData/chocolatey/lib/pkgconfiglite/tools/pkg-config-lite-0.28-1/bin",
+                'Darwin': f"{homebrew_root}/bin/pkg-config",
+                'Linux': "/usr/bin/pkg-config"
             }
         }},
     'autotools': {"exe": "autoconf"},
@@ -174,16 +179,13 @@ try:
 except ImportError as e:
     user_tool_locations = None
 
-if platform.machine() == "arm64":
-    android_ndk_path = "/opt/homebrew/share/android-ndk"
-else:
-    android_ndk_path = "/usr/local/share/android-ndk"
+
 tools_environments = {
     'mingw32': {'Windows': {'MSYSTEM': 'MINGW32'}},
     'mingw64': {'Windows': {'MSYSTEM': 'MINGW64'}},
     'ucrt64': {'Windows': {'MSYSTEM': 'UCRT64'}},
     'msys2_clang64': {"Windows": {"MSYSTEM": "CLANG64"}},
-    'android_ndk': {'Darwin': {'TEST_CONAN_ANDROID_NDK': android_ndk_path}}
+    'android_ndk': {'Darwin': {'TEST_CONAN_ANDROID_NDK': f"{homebrew_root}/share/android-ndk"}}
 }
 
 
diff --git a/conans/test/functional/command/config_install_test.py b/conans/test/functional/command/config_install_test.py
index 7d438307e..400ea596d 100644
--- a/conans/test/functional/command/config_install_test.py
+++ b/conans/test/functional/command/config_install_test.py
@@ -333,13 +333,56 @@ class Pkg(ConanFile):
         self.client.run("remote list")
         self.assertEqual("conan.io: https://server.conan.io [Verify SSL: True]\n", self.client.out)
 
-    def test_install_remotes_json_error(self):
+    def test_install_remotes_json(self):
         folder = temp_folder()
-        save_files(folder, {"remotes.json": ""})
-        self.client.run('config install "%s"' % folder, assert_error=True)
-        self.assertIn("ERROR: Failed conan config install: "
-                      "remotes.json install is not supported yet. Use 'remotes.txt'",
-                      self.client.out)
+
+        remotes_json = textwrap.dedent("""
+            {
+                "remotes": [
+                    { "name": "repojson1", "url": "https://repojson1.net", "verify_ssl": false },
+                    { "name": "repojson2", "url": "https://repojson2.com", "verify_ssl": true }
+                ]
+            }
+        """)
+
+        remotes_txt = textwrap.dedent("""\
+            repotxt1 https://repotxt1.net False
+            repotxt2 https://repotxt2.com True
+        """)
+
+        # remotes.txt and json try to define both the remotes,
+        # could lead to unpredictable results
+        save_files(folder, {"remotes.json": remotes_json,
+                            "remotes.txt": remotes_txt})
+
+        self.client.run(f'config install "{folder}"')
+        assert "Defining remotes from remotes.json" in self.client.out
+        assert "Defining remotes from remotes.txt" in self.client.out
+
+        # If there's only a remotes.txt it's the one installed
+        folder = temp_folder()
+        save_files(folder, {"remotes.txt": remotes_txt})
+
+        self.client.run(f'config install "{folder}"')
+
+        assert "Defining remotes from remotes.txt" in self.client.out
+
+        self.client.run('remote list')
+
+        assert "repotxt1: https://repotxt1.net [Verify SSL: False]" in self.client.out
+        assert "repotxt2: https://repotxt2.com [Verify SSL: True]" in self.client.out
+
+        # If there's only a remotes.json it's the one installed
+        folder = temp_folder()
+        save_files(folder, {"remotes.json": remotes_json})
+
+        self.client.run(f'config install "{folder}"')
+        assert "Defining remotes from remotes.json" in self.client.out
+
+        self.client.run('remote list')
+
+        assert "repojson1: https://repojson1.net [Verify SSL: False]" in self.client.out
+        assert "repojson2: https://repojson2.com [Verify SSL: True]" in self.client.out
 
     def test_without_profile_folder(self):
         shutil.rmtree(self.client.cache.profiles_path)
diff --git a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
index d22ee397a..8b6f35791 100644
--- a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -466,7 +466,7 @@ def test_toolchain_cache_variables():
     client.save({"conanfile.py": conanfile})
     with mock.patch("platform.system", mock.MagicMock(return_value="Windows")):
         client.run("install . mylib/1.0@ -c tools.cmake.cmaketoolchain:generator='MinGW Makefiles' "
-                   "-c tools.gnu:make_program='MyMake'")
+                   "-c tools.gnu:make_program='MyMake' -c tools.build:skip_test=True")
     presets = json.loads(client.load("CMakePresets.json"))
     cache_variables = presets["configurePresets"][0]["cacheVariables"]
     assert cache_variables["foo"] == 'ON'
@@ -475,6 +475,7 @@ def test_toolchain_cache_variables():
     assert cache_variables["CMAKE_SH"] == "THIS VALUE HAS PRIORITY"
     assert cache_variables["CMAKE_POLICY_DEFAULT_CMP0091"] == "THIS VALUE HAS PRIORITY"
     assert cache_variables["CMAKE_MAKE_PROGRAM"] == "MyMake"
+    assert cache_variables["BUILD_TESTING"] == 'OFF'
 
 
 def test_android_c_library():