mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-12-28 19:25:27 +08:00
Introduce archives.h/cpp
This commit is contained in:
parent
3e76baa163
commit
dbae3bfe56
9
toolsrc/include/vcpkg/base/archives.h
Normal file
9
toolsrc/include/vcpkg/base/archives.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/base/files.h>
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
namespace vcpkg::Archives
|
||||
{
|
||||
void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path);
|
||||
}
|
107
toolsrc/src/vcpkg/base/archives.cpp
Normal file
107
toolsrc/src/vcpkg/base/archives.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/archives.h>
|
||||
#include <vcpkg/commands.h>
|
||||
|
||||
namespace vcpkg::Archives
|
||||
{
|
||||
void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path)
|
||||
{
|
||||
Files::Filesystem& fs = paths.get_filesystem();
|
||||
const fs::path to_path_partial = to_path.u8string() + ".partial";
|
||||
|
||||
std::error_code ec;
|
||||
fs.remove_all(to_path, ec);
|
||||
fs.remove_all(to_path_partial, ec);
|
||||
fs.create_directories(to_path_partial, ec);
|
||||
const auto ext = archive.extension();
|
||||
#if defined(_WIN32)
|
||||
if (ext == ".nupkg")
|
||||
{
|
||||
static bool recursion_limiter_sevenzip_old = false;
|
||||
Checks::check_exit(VCPKG_LINE_INFO, !recursion_limiter_sevenzip_old);
|
||||
recursion_limiter_sevenzip_old = true;
|
||||
const auto nuget_exe = Commands::Fetch::get_tool_path(paths, Tools::NUGET);
|
||||
|
||||
const std::string stem = archive.stem().u8string();
|
||||
// assuming format of [name].[version in the form d.d.d]
|
||||
// This assumption may not always hold
|
||||
std::smatch match;
|
||||
const bool has_match = std::regex_match(stem, match, std::regex{R"###(^(.+)\.(\d+\.\d+\.\d+)$)###"});
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
has_match,
|
||||
"Could not deduce nuget id and version from filename: %s",
|
||||
archive.u8string());
|
||||
|
||||
const std::string nugetid = match[1];
|
||||
const std::string version = match[2];
|
||||
|
||||
const auto code_and_output = System::cmd_execute_and_capture_output(Strings::format(
|
||||
R"("%s" install %s -Version %s -OutputDirectory "%s" -Source "%s" -nocache -DirectDownload -NonInteractive -ForceEnglishOutput -PackageSaveMode nuspec)",
|
||||
nuget_exe.u8string(),
|
||||
nugetid,
|
||||
version,
|
||||
to_path_partial.u8string(),
|
||||
paths.downloads.u8string()));
|
||||
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
code_and_output.exit_code == 0,
|
||||
"Failed to extract '%s' with message:\n%s",
|
||||
archive.u8string(),
|
||||
code_and_output.output);
|
||||
recursion_limiter_sevenzip_old = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
static bool recursion_limiter_sevenzip = false;
|
||||
Checks::check_exit(VCPKG_LINE_INFO, !recursion_limiter_sevenzip);
|
||||
recursion_limiter_sevenzip = true;
|
||||
const auto seven_zip = Commands::Fetch::get_tool_path(paths, Tools::SEVEN_ZIP);
|
||||
const auto code_and_output = System::cmd_execute_and_capture_output(Strings::format(
|
||||
R"("%s" x "%s" -o"%s" -y)", seven_zip.u8string(), archive.u8string(), to_path_partial.u8string()));
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
code_and_output.exit_code == 0,
|
||||
"7zip failed while extracting '%s' with message:\n%s",
|
||||
archive.u8string(),
|
||||
code_and_output.output);
|
||||
recursion_limiter_sevenzip = false;
|
||||
}
|
||||
#else
|
||||
if (ext == ".gz" && ext.extension() != ".tar")
|
||||
{
|
||||
const auto code = System::cmd_execute(
|
||||
Strings::format(R"(cd '%s' && tar xzf '%s')", to_path_partial.u8string(), archive.u8string()));
|
||||
Checks::check_exit(VCPKG_LINE_INFO, code == 0, "tar failed while extracting %s", archive.u8string());
|
||||
}
|
||||
else if (ext == ".zip")
|
||||
{
|
||||
const auto code = System::cmd_execute(
|
||||
Strings::format(R"(cd '%s' && unzip -qqo '%s')", to_path_partial.u8string(), archive.u8string()));
|
||||
Checks::check_exit(VCPKG_LINE_INFO, code == 0, "unzip failed while extracting %s", archive.u8string());
|
||||
}
|
||||
else
|
||||
{
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Unexpected archive extension: %s", ext.u8string());
|
||||
}
|
||||
#endif
|
||||
|
||||
fs.rename(to_path_partial, to_path, ec);
|
||||
|
||||
for (int i = 0; i < 5 && ec; i++)
|
||||
{
|
||||
i++;
|
||||
using namespace std::chrono_literals;
|
||||
std::this_thread::sleep_for(i * 100ms);
|
||||
fs.rename(to_path_partial, to_path, ec);
|
||||
}
|
||||
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
!ec,
|
||||
"Failed to do post-extract rename-in-place.\n"
|
||||
"fs.rename(%s, %s, %s)",
|
||||
to_path_partial.u8string(),
|
||||
to_path.u8string(),
|
||||
ec.message());
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/archives.h>
|
||||
#include <vcpkg/base/checks.h>
|
||||
#include <vcpkg/base/downloads.h>
|
||||
#include <vcpkg/base/sortedvector.h>
|
||||
@ -236,106 +237,6 @@ namespace vcpkg::Commands::Fetch
|
||||
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
static void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path)
|
||||
{
|
||||
Files::Filesystem& fs = paths.get_filesystem();
|
||||
const fs::path to_path_partial = to_path.u8string() + ".partial";
|
||||
|
||||
std::error_code ec;
|
||||
fs.remove_all(to_path, ec);
|
||||
fs.remove_all(to_path_partial, ec);
|
||||
fs.create_directories(to_path_partial, ec);
|
||||
const auto ext = archive.extension();
|
||||
#if defined(_WIN32)
|
||||
if (ext == ".nupkg")
|
||||
{
|
||||
static bool recursion_limiter_sevenzip_old = false;
|
||||
Checks::check_exit(VCPKG_LINE_INFO, !recursion_limiter_sevenzip_old);
|
||||
recursion_limiter_sevenzip_old = true;
|
||||
const auto nuget_exe = get_tool_path(paths, Tools::NUGET);
|
||||
|
||||
const std::string stem = archive.stem().u8string();
|
||||
// assuming format of [name].[version in the form d.d.d]
|
||||
// This assumption may not always hold
|
||||
std::smatch match;
|
||||
const bool has_match = std::regex_match(stem, match, std::regex{R"###(^(.+)\.(\d+\.\d+\.\d+)$)###"});
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
has_match,
|
||||
"Could not deduce nuget id and version from filename: %s",
|
||||
archive.u8string());
|
||||
|
||||
const std::string nugetid = match[1];
|
||||
const std::string version = match[2];
|
||||
|
||||
const auto code_and_output = System::cmd_execute_and_capture_output(Strings::format(
|
||||
R"("%s" install %s -Version %s -OutputDirectory "%s" -Source "%s" -nocache -DirectDownload -NonInteractive -ForceEnglishOutput -PackageSaveMode nuspec)",
|
||||
nuget_exe.u8string(),
|
||||
nugetid,
|
||||
version,
|
||||
to_path_partial.u8string(),
|
||||
paths.downloads.u8string()));
|
||||
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
code_and_output.exit_code == 0,
|
||||
"Failed to extract '%s' with message:\n%s",
|
||||
archive.u8string(),
|
||||
code_and_output.output);
|
||||
recursion_limiter_sevenzip_old = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
static bool recursion_limiter_sevenzip = false;
|
||||
Checks::check_exit(VCPKG_LINE_INFO, !recursion_limiter_sevenzip);
|
||||
recursion_limiter_sevenzip = true;
|
||||
const auto seven_zip = get_tool_path(paths, Tools::SEVEN_ZIP);
|
||||
const auto code_and_output = System::cmd_execute_and_capture_output(Strings::format(
|
||||
R"("%s" x "%s" -o"%s" -y)", seven_zip.u8string(), archive.u8string(), to_path_partial.u8string()));
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
code_and_output.exit_code == 0,
|
||||
"7zip failed while extracting '%s' with message:\n%s",
|
||||
archive.u8string(),
|
||||
code_and_output.output);
|
||||
recursion_limiter_sevenzip = false;
|
||||
}
|
||||
#else
|
||||
if (ext == ".gz" && ext.extension() != ".tar")
|
||||
{
|
||||
const auto code = System::cmd_execute(
|
||||
Strings::format(R"(cd '%s' && tar xzf '%s')", to_path_partial.u8string(), archive.u8string()));
|
||||
Checks::check_exit(VCPKG_LINE_INFO, code == 0, "tar failed while extracting %s", archive.u8string());
|
||||
}
|
||||
else if (ext == ".zip")
|
||||
{
|
||||
const auto code = System::cmd_execute(
|
||||
Strings::format(R"(cd '%s' && unzip -qqo '%s')", to_path_partial.u8string(), archive.u8string()));
|
||||
Checks::check_exit(VCPKG_LINE_INFO, code == 0, "unzip failed while extracting %s", archive.u8string());
|
||||
}
|
||||
else
|
||||
{
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Unexpected archive extension: %s", ext.u8string());
|
||||
}
|
||||
#endif
|
||||
|
||||
fs.rename(to_path_partial, to_path, ec);
|
||||
|
||||
for (int i = 0; i < 5 && ec; i++)
|
||||
{
|
||||
i++;
|
||||
using namespace std::chrono_literals;
|
||||
std::this_thread::sleep_for(i * 100ms);
|
||||
fs.rename(to_path_partial, to_path, ec);
|
||||
}
|
||||
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
!ec,
|
||||
"Failed to do post-extract rename-in-place.\n"
|
||||
"fs.rename(%s, %s, %s)",
|
||||
to_path_partial.u8string(),
|
||||
to_path.u8string(),
|
||||
ec.message());
|
||||
}
|
||||
|
||||
static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data)
|
||||
{
|
||||
const std::array<int, 3>& version = tool_data.version;
|
||||
@ -367,7 +268,7 @@ namespace vcpkg::Commands::Fetch
|
||||
if (tool_data.is_archive)
|
||||
{
|
||||
System::println("Extracting %s...", tool_name);
|
||||
extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path);
|
||||
Archives::extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path);
|
||||
System::println("Extracting %s... done.", tool_name);
|
||||
}
|
||||
else
|
||||
|
@ -137,6 +137,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\pch.h" />
|
||||
<ClInclude Include="..\include\vcpkg\base\archives.h" />
|
||||
<ClInclude Include="..\include\vcpkg\base\checks.h" />
|
||||
<ClInclude Include="..\include\vcpkg\base\chrono.h" />
|
||||
<ClInclude Include="..\include\vcpkg\base\cofffilereader.h" />
|
||||
@ -193,6 +194,7 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\vcpkg\base\archives.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg\base\checks.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg\base\chrono.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg\base\cofffilereader.cpp" />
|
||||
|
@ -204,6 +204,9 @@
|
||||
<ClCompile Include="..\src\vcpkg\base\downloads.cpp">
|
||||
<Filter>Source Files\vcpkg\base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\vcpkg\base\archives.cpp">
|
||||
<Filter>Source Files\vcpkg\base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\pch.h">
|
||||
@ -353,5 +356,8 @@
|
||||
<ClInclude Include="..\include\vcpkg\base\downloads.h">
|
||||
<Filter>Header Files\vcpkg\base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\vcpkg\base\archives.h">
|
||||
<Filter>Header Files\vcpkg\base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user