2626#include < vcpkg/vcpkgcmdarguments.h>
2727#include < vcpkg/vcpkgpaths.h>
2828
29+ #include < algorithm>
2930#include < memory>
3031#include < utility>
3132
@@ -213,6 +214,18 @@ namespace
213214 Path files_archive_parent_path (const std::string& abi) { return Path (abi.substr (0 , 2 )); }
214215 Path files_archive_subpath (const std::string& abi) { return files_archive_parent_path (abi) / (abi + " .zip" ); }
215216
217+ StringView try_extract_abi_from_zip_file (const Path& zip_file)
218+ {
219+ StringView file_stem = zip_file.stem ();
220+ auto reverse_it =
221+ std::find_if (file_stem.rbegin (), file_stem.rend (), [](char ch) { return !std::isxdigit (ch); });
222+ if (reverse_it != file_stem.rend () && (*reverse_it) == ' _' )
223+ {
224+ return {reverse_it.base (), file_stem.end ()};
225+ }
226+ return {};
227+ }
228+
216229 struct FilesWriteBinaryProvider : IWriteBinaryProvider
217230 {
218231 FilesWriteBinaryProvider (const Filesystem& fs, std::vector<Path>&& dirs) : m_fs(fs), m_dirs(std::move(dirs)) { }
@@ -293,7 +306,10 @@ namespace
293306 // - IReadBinaryProvider::precheck()
294307 struct ZipReadBinaryProvider : IReadBinaryProvider
295308 {
296- ZipReadBinaryProvider (ZipTool zip, const Filesystem& fs) : m_zip(std::move(zip)), m_fs(fs) { }
309+ ZipReadBinaryProvider (ZipTool zip, const Filesystem& fs, Optional<Path> local_cache_folder = {})
310+ : m_zip(std::move(zip)), m_fs(fs), m_local_cache_folder(std::move(local_cache_folder))
311+ {
312+ }
297313
298314 void fetch (View<const InstallPlanAction*> actions, Span<RestoreResult> out_status) const override
299315 {
@@ -336,8 +352,41 @@ namespace
336352 {
337353 if (r.to_remove == RemoveWhen::always)
338354 {
339- m_fs.remove (r.path , IgnoreErrors{});
355+ if (auto new_path = try_write_back_zip_file (r.path ))
356+ {
357+ Debug::print (" Renamed " , r.path , " to " , *(new_path.get ()), " \n " );
358+ }
359+ else
360+ {
361+ m_fs.remove (r.path , IgnoreErrors{});
362+ Debug::print (" Removed " , r.path , ' \n ' );
363+ }
364+ }
365+ }
366+
367+ [[nodiscard]] Optional<Path> try_write_back_zip_file (const Path& zip_file) const
368+ {
369+ if (!m_local_cache_folder)
370+ {
371+ return {};
372+ }
373+
374+ const StringView abi = try_extract_abi_from_zip_file (zip_file);
375+ if (abi.empty ())
376+ {
377+ return {};
378+ }
379+
380+ const Path& local_cache_folder = *m_local_cache_folder.get ();
381+ Path new_path = local_cache_folder / files_archive_subpath (std::string (abi));
382+ if (m_fs.exists (new_path, IgnoreErrors{}))
383+ {
384+ return {};
340385 }
386+
387+ m_fs.create_directories (new_path.parent_path (), IgnoreErrors{});
388+ m_fs.rename (zip_file, new_path, IgnoreErrors{});
389+ return new_path;
341390 }
342391
343392 // For every action denoted by actions, at corresponding indicies in out_zips, stores a ZipResource indicating
@@ -350,6 +399,7 @@ namespace
350399 protected:
351400 ZipTool m_zip;
352401 const Filesystem& m_fs;
402+ Optional<Path> m_local_cache_folder;
353403 };
354404
355405 struct FilesReadBinaryProvider : ZipReadBinaryProvider
@@ -857,8 +907,9 @@ namespace
857907 const Filesystem& fs,
858908 const Path& buildtrees,
859909 std::string&& prefix,
860- const std::shared_ptr<const IObjectStorageTool>& tool)
861- : ZipReadBinaryProvider(std::move(zip), fs)
910+ const std::shared_ptr<const IObjectStorageTool>& tool,
911+ Optional<Path> local_cache_folder)
912+ : ZipReadBinaryProvider(std::move(zip), fs, std::move(local_cache_folder))
862913 , m_buildtrees(buildtrees)
863914 , m_prefix(std::move(prefix))
864915 , m_tool(tool)
@@ -2253,22 +2304,28 @@ namespace vcpkg
22532304 std::make_unique<HttpGetBinaryProvider>(zip_tool, fs, buildtrees, std::move (url), s.secrets ));
22542305 }
22552306
2307+ Optional<Path> local_cache_folder;
2308+ if (!s.archives_to_write .empty ())
2309+ {
2310+ local_cache_folder = s.archives_to_write .front ();
2311+ }
2312+
22562313 for (auto && prefix : s.gcs_read_prefixes )
22572314 {
2258- m_config.read .push_back (
2259- std::make_unique<ObjectStorageProvider>( zip_tool, fs, buildtrees, std::move (prefix), gcs_tool));
2315+ m_config.read .push_back (std::make_unique<ObjectStorageProvider>(
2316+ zip_tool, fs, buildtrees, std::move (prefix), gcs_tool, local_cache_folder ));
22602317 }
22612318
22622319 for (auto && prefix : s.aws_read_prefixes )
22632320 {
2264- m_config.read .push_back (
2265- std::make_unique<ObjectStorageProvider>( zip_tool, fs, buildtrees, std::move (prefix), aws_tool));
2321+ m_config.read .push_back (std::make_unique<ObjectStorageProvider>(
2322+ zip_tool, fs, buildtrees, std::move (prefix), aws_tool, local_cache_folder ));
22662323 }
22672324
22682325 for (auto && prefix : s.cos_read_prefixes )
22692326 {
2270- m_config.read .push_back (
2271- std::make_unique<ObjectStorageProvider>( zip_tool, fs, buildtrees, std::move (prefix), cos_tool));
2327+ m_config.read .push_back (std::make_unique<ObjectStorageProvider>(
2328+ zip_tool, fs, buildtrees, std::move (prefix), cos_tool, local_cache_folder ));
22722329 }
22732330
22742331 for (auto && src : s.upkg_templates_to_get )
0 commit comments