From c84550cac6237ff4fb97fa21f9d9b0361b07daef Mon Sep 17 00:00:00 2001 From: Uilian Ries Date: Wed, 25 Oct 2023 10:27:55 +0200 Subject: [PATCH] [upload] Ignore metadata when passing empty string (#15007) * Validate upload when ignoring metadata Signed-off-by: Uilian Ries * ignore metadata upload in case passing empty string Signed-off-by: Uilian Ries * Do not accept mixed metadata pattern Signed-off-by: Uilian Ries * Move validation to upload sub api Signed-off-by: Uilian Ries * Revert gather metadata Signed-off-by: Uilian Ries * Improve metadata upload test Signed-off-by: Uilian Ries * Update test description Signed-off-by: Uilian Ries * Simplify test for mixed metadata args Signed-off-by: Uilian Ries --------- Signed-off-by: Uilian Ries --- conan/api/subapi/upload.py | 8 +- .../metadata/test_metadata_commands.py | 115 +++++++++--------- 2 files changed, 65 insertions(+), 58 deletions(-) diff --git a/conan/api/subapi/upload.py b/conan/api/subapi/upload.py index 75fc7756762..eb437a9d999 100644 --- a/conan/api/subapi/upload.py +++ b/conan/api/subapi/upload.py @@ -38,11 +38,15 @@ def prepare(self, package_list, enabled_remotes, metadata=None): :param package_list: :param enabled_remotes: :param metadata: A list of patterns of metadata that should be uploaded. Default None - means all metadata will be uploaded together with the pkg artifacts""" + means all metadata will be uploaded together with the pkg artifacts. If metadata is empty + string (""), it means that no metadata files should be uploaded.""" + if metadata and metadata != [''] and '' in metadata: + raise ConanException("Empty string and patterns can not be mixed for metadata.") app = ConanApp(self.conan_api.cache_folder) preparator = PackagePreparator(app) preparator.prepare(package_list, enabled_remotes) - gather_metadata(package_list, app.cache, metadata) + if metadata != ['']: + gather_metadata(package_list, app.cache, metadata) signer = PkgSignaturesPlugin(app.cache) # This might add files entries to package_list with signatures signer.sign(package_list) diff --git a/conans/test/integration/metadata/test_metadata_commands.py b/conans/test/integration/metadata/test_metadata_commands.py index aacea1d7c70..32278907f31 100644 --- a/conans/test/integration/metadata/test_metadata_commands.py +++ b/conans/test/integration/metadata/test_metadata_commands.py @@ -1,4 +1,5 @@ import os +import pytest from conans.test.assets.genconanfile import GenConanfile from conans.test.utils.test_files import temp_folder @@ -8,22 +9,27 @@ class TestMetadataCommands: - def test_upload(self): - c = TestClient(default_server_user=True) - c.save({"conanfile.py": GenConanfile("pkg", "0.1")}) - c.run("create .") - pid = c.created_package_id("pkg/0.1") + @pytest.fixture + def create_conan_pkg(self): + client = TestClient(default_server_user=True) + client.save({"conanfile.py": GenConanfile("pkg", "0.1")}) + client.run("create .") + pid = client.created_package_id("pkg/0.1") + return client, pid - # Add some metadata - c.run("cache path pkg/0.1 --folder=metadata") - metadata_path = str(c.stdout).strip() - myfile = os.path.join(metadata_path, "logs", "mylogs.txt") - save(myfile, "mylogs!!!!") + def save_metadata_file(self, client, pkg_ref, filename="somefile.log"): + client.run(f"cache path {pkg_ref} --folder=metadata") + metadata_path = str(client.stdout).strip() + myfile = os.path.join(metadata_path, "logs", filename) + save(myfile, f"{pkg_ref}!!!!") + return metadata_path, myfile - c.run(f"cache path pkg/0.1:{pid} --folder=metadata") - pkg_metadata_path = str(c.stdout).strip() - myfile = os.path.join(pkg_metadata_path, "logs", "mybuildlogs.txt") - save(myfile, "mybuildlogs!!!!") + def test_upload(self, create_conan_pkg): + c, pid = create_conan_pkg + + # Add some metadata + self.save_metadata_file(c, "pkg/0.1", "mylogs.txt") + self.save_metadata_file(c, f"pkg/0.1:{pid}", "mybuildlogs.txt") # Now upload everything c.run("upload * -c -r=default") @@ -31,10 +37,8 @@ def test_upload(self): assert "pkg/0.1:da39a3ee5e6b4b0d3255bfef95601890afd80709: Package metadata: 1 files" in c.out # Add new files to the metadata - myfile = os.path.join(metadata_path, "logs", "mylogs2.txt") - save(myfile, "mylogs2!!!!") - myfile = os.path.join(pkg_metadata_path, "logs", "mybuildlogs2.txt") - save(myfile, "mybuildlogs2!!!!") + self.save_metadata_file(c, "pkg/0.1", "mylogs2.txt") + self.save_metadata_file(c, f"pkg/0.1:{pid}", "mybuildlogs2.txt") # Upload the metadata, even if the revisions exist in the server # adding the new metadata logs files c.run("upload * -c -r=default --metadata=*") @@ -63,10 +67,7 @@ def test_update_contents(self): c.run("export .") # Add some metadata - c.run("cache path pkg/0.1 --folder=metadata") - metadata_path = str(c.stdout).strip() - myfile = os.path.join(metadata_path, "logs", "mylogs.txt") - save(myfile, "mylogs!!!!") + _, myfile = self.save_metadata_file(c, "pkg/0.1", "mylogs.txt") # Now upload everything c.run("upload * -c -r=default") @@ -87,13 +88,11 @@ def test_update_contents(self): content = load(os.path.join(metadata_path, "logs", "mylogs.txt")) assert "mylogs2!!!!" in content - def test_folder_exist(self): + def test_folder_exist(self, create_conan_pkg): """ so we can cp -R to the metadata folder, having to create the folder in the cache is weird """ - c = TestClient(default_server_user=True) - c.save({"conanfile.py": GenConanfile("pkg", "0.1")}) - c.run("create .") + c, _ = create_conan_pkg c.run("cache path pkg/0.1 --folder=metadata") metadata_path = str(c.stdout).strip() assert os.path.isdir(metadata_path) @@ -101,27 +100,17 @@ def test_folder_exist(self): pkg_metadata_path = str(c.stdout).strip() assert os.path.isdir(pkg_metadata_path) - def test_direct_download_redownload(self): + def test_direct_download_redownload(self, create_conan_pkg): """ When we directly download things, without "conan install" first, it is also able to fetch the requested metadata Also, re-downloading same thing shouldn't fail """ - c = TestClient(default_server_user=True) - c.save({"conanfile.py": GenConanfile("pkg", "0.1")}) - c.run("create .") - pid = c.created_package_id("pkg/0.1") + c, pid = create_conan_pkg # Add some metadata - c.run("cache path pkg/0.1 --folder=metadata") - metadata_path = str(c.stdout).strip() - myfile = os.path.join(metadata_path, "logs", "mylogs.txt") - save(myfile, "mylogs!!!!") - - c.run(f"cache path pkg/0.1:{pid} --folder=metadata") - pkg_metadata_path = str(c.stdout).strip() - myfile = os.path.join(pkg_metadata_path, "logs", "mybuildlogs.txt") - save(myfile, "mybuildlogs!!!!") + metadata_path, _ = self.save_metadata_file(c, "pkg/0.1", "mylogs.txt") + self.save_metadata_file(c, f"pkg/0.1:{pid}", "mybuildlogs.txt") # Now upload everything c.run("upload * -c -r=default") @@ -144,24 +133,14 @@ def test_direct_download_redownload(self): pkg_metadata_path = str(c.stdout).strip() assert os.path.isfile(os.path.join(pkg_metadata_path, "logs", "mybuildlogs.txt")) - def test_no_download_cached(self): + def test_no_download_cached(self, create_conan_pkg): """ as the metadata can change, no checksum, no revision, cannot be cached """ - c = TestClient(default_server_user=True) - c.save({"conanfile.py": GenConanfile("pkg", "0.1")}) - c.run("create .") - pid = c.created_package_id("pkg/0.1") + c, pid = create_conan_pkg # Add some metadata - c.run("cache path pkg/0.1 --folder=metadata") - metadata_path = str(c.stdout).strip() - myrecipefile = os.path.join(metadata_path, "logs", "mylogs.txt") - save(myrecipefile, "mylogs!!!!") - - c.run(f"cache path pkg/0.1:{pid} --folder=metadata") - pkg_metadata_path = str(c.stdout).strip() - mypkgfile = os.path.join(pkg_metadata_path, "logs", "mybuildlogs.txt") - save(mypkgfile, "mybuildlogs!!!!") + _, myrecipefile = self.save_metadata_file(c, "pkg/0.1", "mylogs.txt") + _, mypkgfile = self.save_metadata_file(c, f"pkg/0.1:{pid}", "mybuildlogs.txt") # Now upload everything c.run("upload * -c -r=default") @@ -178,11 +157,11 @@ def test_no_download_cached(self): c2.run("cache path pkg/0.1 --folder=metadata") c2_metadata_path = str(c2.stdout).strip() mylogs = load(os.path.join(c2_metadata_path, "logs", "mylogs.txt")) - assert "mylogs!!!!" in mylogs + assert "pkg/0.1!!!!" in mylogs c2.run(f"cache path pkg/0.1:{pid} --folder=metadata") c2_pkg_metadata_path = str(c2.stdout).strip() mybuildlogs = load(os.path.join(c2_pkg_metadata_path, "logs", "mybuildlogs.txt")) - assert "mybuildlogs!!!!" in mybuildlogs + assert f"pkg/0.1:{pid}!!!!" in mybuildlogs # Now the other client will update the metadata save(myrecipefile, "mylogs2!!!!") @@ -198,3 +177,27 @@ def test_no_download_cached(self): assert "mylogs2!!!!" in mylogs mybuildlogs = load(os.path.join(c2_pkg_metadata_path, "logs", "mybuildlogs.txt")) assert "mybuildlogs2!!!!" in mybuildlogs + + def test_upload_ignored_metadata(self, create_conan_pkg): + """ + Upload command should ignore metadata files when passing --metadata="" + """ + client, pid = create_conan_pkg + + self.save_metadata_file(client, "pkg/0.1") + self.save_metadata_file(client, f"pkg/0.1:{pid}") + + client.run('upload * --confirm --remote=default --metadata=""') + assert "Recipe metadata" not in client.out + assert "Package metadata" not in client.out + + def test_upload_ignored_metadata_with_pattern(self, create_conan_pkg): + """ + Upload command should fail when passing --metadata="" and a pattern + """ + client = TestClient(default_server_user=True) + client.save({"conanfile.py": GenConanfile("pkg", "0.1")}) + client.run("export .") + + client.run('upload * --confirm --remote=default --metadata="" --metadata="logs/*"', assert_error=True) + assert "ERROR: Empty string and patterns can not be mixed for metadata." in client.out