2626#include < vcpkg/vcpkgcmdarguments.h>
2727#include < vcpkg/vcpkgpaths.h>
2828
29+ #include < algorithm>
2930#include < memory>
3031#include < utility>
3132
@@ -213,6 +214,17 @@ 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 = std::find_if_not (file_stem.rbegin (), file_stem.rend (), std::isxdigit);
221+ if (reverse_it != file_stem.rend () && (*reverse_it) == ' _' )
222+ {
223+ return {reverse_it.base () + 1 , file_stem.end ()};
224+ }
225+ return {};
226+ }
227+
216228 struct FilesWriteBinaryProvider : IWriteBinaryProvider
217229 {
218230 FilesWriteBinaryProvider (const Filesystem& fs, std::vector<Path>&& dirs) : m_fs(fs), m_dirs(std::move(dirs)) { }
@@ -293,7 +305,10 @@ namespace
293305 // - IReadBinaryProvider::precheck()
294306 struct ZipReadBinaryProvider : IReadBinaryProvider
295307 {
296- ZipReadBinaryProvider (ZipTool zip, const Filesystem& fs) : m_zip(std::move(zip)), m_fs(fs) { }
308+ ZipReadBinaryProvider (ZipTool zip, const Filesystem& fs, Optional<Path> local_cache_folder = {})
309+ : m_zip(std::move(zip)), m_fs(fs), m_local_cache_folder(std::move(local_cache_folder))
310+ {
311+ }
297312
298313 void fetch (View<const InstallPlanAction*> actions, Span<RestoreResult> out_status) const override
299314 {
@@ -336,8 +351,41 @@ namespace
336351 {
337352 if (r.to_remove == RemoveWhen::always)
338353 {
339- m_fs.remove (r.path , IgnoreErrors{});
354+ if (auto new_path = try_write_back_zip_file (r.path ))
355+ {
356+ Debug::print (" Renamed " , r.path , " to " , *(new_path.get ()), " \n " );
357+ }
358+ else
359+ {
360+ m_fs.remove (r.path , IgnoreErrors{});
361+ Debug::print (" Removed " , r.path , ' \n ' );
362+ }
363+ }
364+ }
365+
366+ [[nodiscard]] Optional<Path> try_write_back_zip_file (const Path& zip_file) const
367+ {
368+ if (!m_local_cache_folder)
369+ {
370+ return {};
371+ }
372+
373+ const StringView abi = try_extract_abi_from_zip_file (zip_file);
374+ if (abi.empty ())
375+ {
376+ return {};
377+ }
378+
379+ const Path& local_cache_folder = *m_local_cache_folder.get ();
380+ Path new_path = local_cache_folder / files_archive_subpath (std::string (abi));
381+ if (m_fs.exists (new_path, IgnoreErrors{}))
382+ {
383+ return {};
340384 }
385+
386+ m_fs.create_directories (new_path.parent_path (), IgnoreErrors{});
387+ m_fs.rename (zip_file, new_path, IgnoreErrors{});
388+ return new_path;
341389 }
342390
343391 // For every action denoted by actions, at corresponding indicies in out_zips, stores a ZipResource indicating
@@ -350,6 +398,7 @@ namespace
350398 protected:
351399 ZipTool m_zip;
352400 const Filesystem& m_fs;
401+ Optional<Path> m_local_cache_folder;
353402 };
354403
355404 struct FilesReadBinaryProvider : ZipReadBinaryProvider
@@ -857,8 +906,9 @@ namespace
857906 const Filesystem& fs,
858907 const Path& buildtrees,
859908 std::string&& prefix,
860- const std::shared_ptr<const IObjectStorageTool>& tool)
861- : ZipReadBinaryProvider(std::move(zip), fs)
909+ const std::shared_ptr<const IObjectStorageTool>& tool,
910+ Optional<Path> local_cache_folder)
911+ : ZipReadBinaryProvider(std::move(zip), fs, std::move(local_cache_folder))
862912 , m_buildtrees(buildtrees)
863913 , m_prefix(std::move(prefix))
864914 , m_tool(tool)
@@ -2253,22 +2303,28 @@ namespace vcpkg
22532303 std::make_unique<HttpGetBinaryProvider>(zip_tool, fs, buildtrees, std::move (url), s.secrets ));
22542304 }
22552305
2306+ Optional<Path> local_cache_folder;
2307+ if (!s.archives_to_write .empty ())
2308+ {
2309+ local_cache_folder = s.archives_to_write .front ();
2310+ }
2311+
22562312 for (auto && prefix : s.gcs_read_prefixes )
22572313 {
2258- m_config.read .push_back (
2259- std::make_unique<ObjectStorageProvider>( zip_tool, fs, buildtrees, std::move (prefix), gcs_tool));
2314+ m_config.read .push_back (std::make_unique<ObjectStorageProvider>(
2315+ zip_tool, fs, buildtrees, std::move (prefix), gcs_tool, local_cache_folder ));
22602316 }
22612317
22622318 for (auto && prefix : s.aws_read_prefixes )
22632319 {
2264- m_config.read .push_back (
2265- std::make_unique<ObjectStorageProvider>( zip_tool, fs, buildtrees, std::move (prefix), aws_tool));
2320+ m_config.read .push_back (std::make_unique<ObjectStorageProvider>(
2321+ zip_tool, fs, buildtrees, std::move (prefix), aws_tool, local_cache_folder ));
22662322 }
22672323
22682324 for (auto && prefix : s.cos_read_prefixes )
22692325 {
2270- m_config.read .push_back (
2271- std::make_unique<ObjectStorageProvider>( zip_tool, fs, buildtrees, std::move (prefix), cos_tool));
2326+ m_config.read .push_back (std::make_unique<ObjectStorageProvider>(
2327+ zip_tool, fs, buildtrees, std::move (prefix), cos_tool, local_cache_folder ));
22722328 }
22732329
22742330 for (auto && src : s.upkg_templates_to_get )
0 commit comments