Skip to content

Commit

Permalink
Upload backup source even when the recipe has been exported (#13846)
Browse files Browse the repository at this point in the history
Changelog: Bugfix: Ensure backup sources are uploaded in more cases
Docs: Omit
  • Loading branch information
AbrilRBS authored May 9, 2023
2 parents f4fdb78 + 0efdda0 commit d01221b
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
12 changes: 11 additions & 1 deletion conans/client/downloaders/download_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,18 @@ def get_backup_sources_files_to_upload(self, package_list):
""" from a package_list of packages to upload, collect from the backup-sources cache
the matching references to upload those backups too
"""
def should_upload_sources(package):
return any(prev["upload"] for prev in package["revisions"].values())

files_to_upload = []
path_backups = os.path.join(self._path, self._SOURCE_BACKUP)

if not os.path.exists(path_backups):
return []
all_refs = {str(k) for k, v in package_list.refs() if v.get("upload")}

all_refs = {str(k) for k, ref in package_list.refs()
if ref.get("upload") or any(should_upload_sources(p)
for p in ref["packages"].values())}
for f in os.listdir(path_backups):
if f.endswith(".json"):
f = os.path.join(path_backups, f)
Expand Down Expand Up @@ -85,4 +92,7 @@ def update_backup_sources_json(cached_path, conanfile, urls):
urls = [urls]
existing_urls = summary["references"].setdefault(summary_key, [])
existing_urls.extend(url for url in urls if url not in existing_urls)
conanfile.output.verbose(f"Updating ${summary_path} summary file")
summary_dump = json.dumps(summary)
conanfile.output.debug(f"New summary: ${summary_dump}")
save(summary_path, json.dumps(summary))
2 changes: 1 addition & 1 deletion conans/client/downloaders/file_downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def get_total_length():
total_length = get_total_length()
if total_length > 100000:
action = "Downloading" if range_start == 0 else "Continuing download of"
description = "{} {}".format(action, os.path.basename(file_path))
description = f"${action} {os.path.basename(file_path)} from {url}"
self._output.info(description)

chunk_size = 1024 * 100
Expand Down
48 changes: 44 additions & 4 deletions conans/test/integration/cache/backup_sources_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,14 +628,54 @@ def source(self):
assert f"Sources for http://localhost:{http_server.port}/internet/myfile.txt found in remote backup http://localhost:{http_server.port}/downloader2/" in client.out
assert "sha256 signature failed for" in client.out

def test_upload_after_export(self):
def test_export_then_upload_workflow(self):
client = TestClient(default_server_user=True)
download_cache_folder = temp_folder()
client.save({"global.conf": "core.sources:upload_url=foo"},
http_server = StoppableThreadBottle()

http_server_base_folder_internet = temp_folder()
http_server_base_folder_backup1 = temp_folder()

sha256 = "315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3"
save(os.path.join(http_server_base_folder_internet, "myfile.txt"), "Hello, world!")

@http_server.server.get("/internet/<file>")
def get_internet_file(file):
return static_file(file, http_server_base_folder_internet)

@http_server.server.get("/downloader1/<file>")
def get_file(file):
return static_file(file, http_server_base_folder_backup1)

@http_server.server.put("/uploader/<file>")
def put_file(file):
dest = os.path.join(http_server_base_folder_backup1, file)
with open(dest, 'wb') as f:
f.write(request.body.read())

http_server.run_server()

conanfile = textwrap.dedent(f"""
from conan import ConanFile
from conan.tools.files import download
class Pkg2(ConanFile):
name = "pkg"
version = "1.0"
def source(self):
download(self, "http://localhost:{http_server.port}/internet/myfile.txt", "myfile.txt",
sha256="{sha256}")
""")

client.save({"global.conf": f"core.sources:download_cache={download_cache_folder}\n"
f"core.sources:download_urls=['http://localhost:{http_server.port}/downloader1/', 'origin']\n"
f"core.sources:upload_url=http://localhost:{http_server.port}/uploader/"},
path=client.cache.cache_folder)

client.save({"conanfile.py": GenConanfile("pkg", "1.0")})
client.save({"conanfile.py": conanfile})
client.run("export .")
# This used to crash because we were trying to list a missing dir if only exports were made
client.run("upload * -c -r=default")
# This used to crash because we were trying to list a missing dir if only exports were made
assert "[Errno 2] No such file or directory" not in client.out
client.run("create .")
client.run("upload * -c -r=default")
assert sha256 in os.listdir(http_server_base_folder_backup1)

0 comments on commit d01221b

Please sign in to comment.