mirror of
https://github.com/cemu-project/vcpkg.git
synced 2025-02-25 22:35:45 +00:00
get_versions should return all versions so the best match can be found (#4945)
* get_versions should return all versions so the best match can be found * [vcpkg] Consider more than one path when searching for system binaries
This commit is contained in:
parent
fcde2e64eb
commit
9cbdb33caf
@ -8,7 +8,11 @@ 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";
|
||||
const fs::path to_path_partial = to_path.u8string() + ".partial"
|
||||
#if defined(_WIN32)
|
||||
+ "." + std::to_string(GetCurrentProcessId())
|
||||
#endif
|
||||
;
|
||||
|
||||
std::error_code ec;
|
||||
fs.remove_all(to_path, ec);
|
||||
|
@ -44,7 +44,7 @@ namespace vcpkg
|
||||
return result;
|
||||
}
|
||||
|
||||
static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool)
|
||||
static ExpectedT<ToolData, std::string> parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
static constexpr StringLiteral OS_STRING = "windows";
|
||||
@ -53,13 +53,13 @@ namespace vcpkg
|
||||
#elif defined(__linux__)
|
||||
static constexpr StringLiteral OS_STRING = "linux";
|
||||
#else
|
||||
return ToolData{};
|
||||
return std::string("operating system is unknown");
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__)
|
||||
static const std::string XML_VERSION = "2";
|
||||
static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml";
|
||||
static const std::regex XML_VERSION_REGEX{R"###(<tools[\s]+version="([^"]+)">)###"};
|
||||
static const std::regex XML_VERSION_REGEX {R"###(<tools[\s]+version="([^"]+)">)###"};
|
||||
static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO);
|
||||
std::smatch match_xml_version;
|
||||
const bool has_xml_version = std::regex_search(XML.cbegin(), XML.cend(), match_xml_version, XML_VERSION_REGEX);
|
||||
@ -67,22 +67,22 @@ namespace vcpkg
|
||||
has_xml_version,
|
||||
R"(Could not find <tools version="%s"> in %s)",
|
||||
XML_VERSION,
|
||||
XML_PATH.generic_string());
|
||||
XML_PATH.u8string());
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
XML_VERSION == match_xml_version[1],
|
||||
"Expected %s version: [%s], but was [%s]. Please re-run bootstrap-vcpkg.",
|
||||
XML_PATH.generic_string(),
|
||||
XML_PATH.u8string(),
|
||||
XML_VERSION,
|
||||
match_xml_version[1]);
|
||||
|
||||
const std::regex tool_regex{Strings::format(R"###(<tool[\s]+name="%s"[\s]+os="%s">)###", tool, OS_STRING)};
|
||||
const std::regex tool_regex {Strings::format(R"###(<tool[\s]+name="%s"[\s]+os="%s">)###", tool, OS_STRING)};
|
||||
std::smatch match_tool_entry;
|
||||
const bool has_tool_entry = std::regex_search(XML.cbegin(), XML.cend(), match_tool_entry, tool_regex);
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
has_tool_entry,
|
||||
"Could not find entry for tool [%s] in %s",
|
||||
tool,
|
||||
XML_PATH.generic_string());
|
||||
if (!has_tool_entry)
|
||||
{
|
||||
return Strings::format(
|
||||
"Could not find entry for tool %s in %s for os=%s", tool, XML_PATH.u8string(), OS_STRING);
|
||||
}
|
||||
|
||||
const std::string tool_data =
|
||||
StringRange::find_exactly_one_enclosed(XML, match_tool_entry[0], "</tool>").to_string();
|
||||
@ -106,13 +106,13 @@ namespace vcpkg
|
||||
const fs::path tool_dir_path = paths.tools / tool_dir_name;
|
||||
const fs::path exe_path = tool_dir_path / exe_relative_path;
|
||||
|
||||
return ToolData{*version.get(),
|
||||
exe_path,
|
||||
url,
|
||||
paths.downloads / archive_name.value_or(exe_relative_path).to_string(),
|
||||
archive_name.has_value(),
|
||||
tool_dir_path,
|
||||
sha512};
|
||||
return ToolData {*version.get(),
|
||||
exe_path,
|
||||
url,
|
||||
paths.downloads / archive_name.value_or(exe_relative_path).to_string(),
|
||||
archive_name.has_value(),
|
||||
tool_dir_path,
|
||||
sha512};
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -122,55 +122,43 @@ namespace vcpkg
|
||||
std::string version;
|
||||
};
|
||||
|
||||
static Optional<PathAndVersion> find_first_with_sufficient_version(const std::vector<PathAndVersion>& candidates,
|
||||
struct ToolProvider
|
||||
{
|
||||
virtual const std::string& tool_data_name() const = 0;
|
||||
virtual const std::string& exe_stem() const = 0;
|
||||
virtual std::array<int, 3> default_min_version() const = 0;
|
||||
|
||||
virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const {}
|
||||
virtual Optional<std::string> get_version(const fs::path& path_to_exe) const = 0;
|
||||
};
|
||||
|
||||
static Optional<PathAndVersion> find_first_with_sufficient_version(const Files::Filesystem& fs,
|
||||
const ToolProvider& tool_provider,
|
||||
const std::vector<fs::path>& candidates,
|
||||
const std::array<int, 3>& expected_version)
|
||||
{
|
||||
const auto it = Util::find_if(candidates, [&](const PathAndVersion& candidate) {
|
||||
const auto parsed_version = parse_version_string(candidate.version);
|
||||
if (!parsed_version.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::array<int, 3> actual_version = *parsed_version.get();
|
||||
return actual_version[0] > expected_version[0] ||
|
||||
(actual_version[0] == expected_version[0] && actual_version[1] > expected_version[1]) ||
|
||||
(actual_version[0] == expected_version[0] && actual_version[1] == expected_version[1] &&
|
||||
actual_version[2] >= expected_version[2]);
|
||||
});
|
||||
|
||||
if (it == candidates.cend())
|
||||
for (auto&& candidate : candidates)
|
||||
{
|
||||
return nullopt;
|
||||
if (!fs.exists(candidate)) continue;
|
||||
auto maybe_version = tool_provider.get_version(candidate);
|
||||
const auto version = maybe_version.get();
|
||||
if (!version) continue;
|
||||
const auto parsed_version = parse_version_string(*version);
|
||||
if (!parsed_version) continue;
|
||||
auto& actual_version = *parsed_version.get();
|
||||
const auto version_acceptable =
|
||||
actual_version[0] > expected_version[0] ||
|
||||
(actual_version[0] == expected_version[0] && actual_version[1] > expected_version[1]) ||
|
||||
(actual_version[0] == expected_version[0] && actual_version[1] == expected_version[1] &&
|
||||
actual_version[2] >= expected_version[2]);
|
||||
if (!version_acceptable) continue;
|
||||
|
||||
return PathAndVersion {candidate, *version};
|
||||
}
|
||||
|
||||
return *it;
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
struct VersionProvider
|
||||
{
|
||||
virtual Optional<std::string> get_version(const fs::path& path_to_exe) const = 0;
|
||||
|
||||
std::vector<PathAndVersion> get_versions(const std::vector<fs::path>& candidate_paths) const
|
||||
{
|
||||
auto&& fs = Files::get_real_filesystem();
|
||||
|
||||
std::vector<PathAndVersion> output;
|
||||
for (auto&& p : candidate_paths)
|
||||
{
|
||||
if (!fs.exists(p)) continue;
|
||||
auto maybe_version = this->get_version(p);
|
||||
if (const auto version = maybe_version.get())
|
||||
{
|
||||
output.emplace_back(PathAndVersion{p, *version});
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
@ -220,76 +208,90 @@ namespace vcpkg
|
||||
}
|
||||
|
||||
static PathAndVersion fetch_tool(const VcpkgPaths& paths,
|
||||
const std::string& tool_name,
|
||||
const ToolData& tool_data,
|
||||
const VersionProvider& version_provider)
|
||||
const ToolProvider& tool_provider,
|
||||
const ToolData& tool_data)
|
||||
{
|
||||
const auto downloaded_path = fetch_tool(paths, tool_name, tool_data);
|
||||
const auto downloaded_version = version_provider.get_version(downloaded_path).value_or_exit(VCPKG_LINE_INFO);
|
||||
const auto downloaded_path = fetch_tool(paths, tool_provider.tool_data_name(), tool_data);
|
||||
const auto downloaded_version = tool_provider.get_version(downloaded_path).value_or_exit(VCPKG_LINE_INFO);
|
||||
return {downloaded_path, downloaded_version};
|
||||
}
|
||||
|
||||
namespace CMake
|
||||
static PathAndVersion get_path(const VcpkgPaths& paths, const ToolProvider& tool)
|
||||
{
|
||||
struct CmakeVersionProvider : VersionProvider
|
||||
auto& fs = paths.get_filesystem();
|
||||
|
||||
std::array<int, 3> min_version = tool.default_min_version();
|
||||
|
||||
std::vector<fs::path> candidate_paths;
|
||||
auto maybe_tool_data = parse_tool_data_from_xml(paths, tool.tool_data_name());
|
||||
if (auto tool_data = maybe_tool_data.get())
|
||||
{
|
||||
Optional<std::string> get_version(const fs::path& path_to_exe) const override
|
||||
{
|
||||
const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string());
|
||||
const auto rc = System::cmd_execute_and_capture_output(cmd);
|
||||
if (rc.exit_code != 0)
|
||||
{
|
||||
return nullopt;
|
||||
}
|
||||
candidate_paths.push_back(tool_data->exe_path);
|
||||
min_version = tool_data->version;
|
||||
}
|
||||
|
||||
/* Sample output:
|
||||
cmake version 3.10.2
|
||||
|
||||
CMake suite maintained and supported by Kitware (kitware.com/cmake).
|
||||
*/
|
||||
return StringRange::find_exactly_one_enclosed(rc.output, "cmake version ", "\n").to_string();
|
||||
}
|
||||
};
|
||||
|
||||
static PathAndVersion get_path(const VcpkgPaths& paths)
|
||||
auto& exe_stem = tool.exe_stem();
|
||||
if (!exe_stem.empty())
|
||||
{
|
||||
if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
|
||||
{
|
||||
return {"cmake", "0"};
|
||||
}
|
||||
auto paths_from_path = fs.find_from_PATH(exe_stem);
|
||||
candidate_paths.insert(candidate_paths.end(), paths_from_path.cbegin(), paths_from_path.cend());
|
||||
}
|
||||
|
||||
std::vector<fs::path> candidate_paths;
|
||||
#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__)
|
||||
static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "cmake");
|
||||
candidate_paths.push_back(TOOL_DATA.exe_path);
|
||||
#else
|
||||
static const ToolData TOOL_DATA = ToolData{{3, 5, 1}, ""};
|
||||
#endif
|
||||
const std::vector<fs::path> from_path = paths.get_filesystem().find_from_PATH("cmake");
|
||||
candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
|
||||
tool.add_special_paths(candidate_paths);
|
||||
|
||||
const auto maybe_path = find_first_with_sufficient_version(fs, tool, candidate_paths, min_version);
|
||||
if (const auto p = maybe_path.get())
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
if (auto tool_data = maybe_tool_data.get())
|
||||
{
|
||||
return fetch_tool(paths, tool, *tool_data);
|
||||
}
|
||||
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, maybe_tool_data.error());
|
||||
}
|
||||
|
||||
struct CMakeProvider : ToolProvider
|
||||
{
|
||||
std::string m_exe = "cmake";
|
||||
|
||||
virtual const std::string& tool_data_name() const override { return m_exe; }
|
||||
virtual const std::string& exe_stem() const override { return m_exe; }
|
||||
virtual std::array<int, 3> default_min_version() const override { return {3, 5, 1}; }
|
||||
|
||||
virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const override
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
const auto& program_files = System::get_program_files_platform_bitness();
|
||||
if (const auto pf = program_files.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe");
|
||||
if (const auto pf = program_files.get()) out_candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe");
|
||||
const auto& program_files_32_bit = System::get_program_files_32_bit();
|
||||
if (const auto pf = program_files_32_bit.get())
|
||||
candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe");
|
||||
|
||||
const CmakeVersionProvider version_provider{};
|
||||
const std::vector<PathAndVersion> candidates_with_versions = version_provider.get_versions(candidate_paths);
|
||||
const auto maybe_path = find_first_with_sufficient_version(candidates_with_versions, TOOL_DATA.version);
|
||||
if (const auto p = maybe_path.get())
|
||||
out_candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe");
|
||||
#endif
|
||||
}
|
||||
virtual Optional<std::string> get_version(const fs::path& path_to_exe) const override
|
||||
{
|
||||
const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string());
|
||||
const auto rc = System::cmd_execute_and_capture_output(cmd);
|
||||
if (rc.exit_code != 0)
|
||||
{
|
||||
return *p;
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
return fetch_tool(paths, Tools::CMAKE, TOOL_DATA, version_provider);
|
||||
/* Sample output:
|
||||
cmake version 3.10.2
|
||||
|
||||
CMake suite maintained and supported by Kitware (kitware.com/cmake).
|
||||
*/
|
||||
return StringRange::find_exactly_one_enclosed(rc.output, "cmake version ", "\n").to_string();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static fs::path get_7za_path(const VcpkgPaths& paths)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "7zip");
|
||||
static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "7zip").value_or_exit(VCPKG_LINE_INFO);
|
||||
if (!paths.get_filesystem().exists(TOOL_DATA.exe_path))
|
||||
{
|
||||
return fetch_tool(paths, "7zip", TOOL_DATA);
|
||||
@ -300,195 +302,131 @@ namespace vcpkg
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace Ninja
|
||||
struct NinjaProvider : ToolProvider
|
||||
{
|
||||
struct NinjaVersionProvider : VersionProvider
|
||||
std::string m_exe = "ninja";
|
||||
|
||||
virtual const std::string& tool_data_name() const override { return m_exe; }
|
||||
virtual const std::string& exe_stem() const override { return m_exe; }
|
||||
virtual std::array<int, 3> default_min_version() const override { return {3, 5, 1}; }
|
||||
|
||||
virtual Optional<std::string> get_version(const fs::path& path_to_exe) const override
|
||||
{
|
||||
Optional<std::string> get_version(const fs::path& path_to_exe) const override
|
||||
const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string());
|
||||
const auto rc = System::cmd_execute_and_capture_output(cmd);
|
||||
if (rc.exit_code != 0)
|
||||
{
|
||||
const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string());
|
||||
const auto rc = System::cmd_execute_and_capture_output(cmd);
|
||||
if (rc.exit_code != 0)
|
||||
{
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
/* Sample output:
|
||||
1.8.2
|
||||
*/
|
||||
return rc.output;
|
||||
}
|
||||
};
|
||||
|
||||
static PathAndVersion get_path(const VcpkgPaths& paths)
|
||||
{
|
||||
if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
|
||||
{
|
||||
return {"ninja", "0"};
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "ninja");
|
||||
|
||||
std::vector<fs::path> candidate_paths;
|
||||
candidate_paths.push_back(TOOL_DATA.exe_path);
|
||||
const std::vector<fs::path> from_path = paths.get_filesystem().find_from_PATH("ninja");
|
||||
candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
|
||||
|
||||
const NinjaVersionProvider version_provider{};
|
||||
const std::vector<PathAndVersion> candidates_with_versions = version_provider.get_versions(candidate_paths);
|
||||
const auto maybe_path = find_first_with_sufficient_version(candidates_with_versions, TOOL_DATA.version);
|
||||
if (const auto p = maybe_path.get())
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
|
||||
return fetch_tool(paths, Tools::NINJA, TOOL_DATA, version_provider);
|
||||
/* Sample output:
|
||||
1.8.2
|
||||
*/
|
||||
return rc.output;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
namespace Nuget
|
||||
struct NuGetProvider : ToolProvider
|
||||
{
|
||||
struct NugetVersionProvider : VersionProvider
|
||||
std::string m_exe = "nuget";
|
||||
|
||||
virtual const std::string& tool_data_name() const override { return m_exe; }
|
||||
virtual const std::string& exe_stem() const override { return m_exe; }
|
||||
virtual std::array<int, 3> default_min_version() const override { return {4, 6, 2}; }
|
||||
|
||||
virtual Optional<std::string> get_version(const fs::path& path_to_exe) const override
|
||||
{
|
||||
Optional<std::string> get_version(const fs::path& path_to_exe) const override
|
||||
const std::string cmd = Strings::format(R"("%s")", path_to_exe.u8string());
|
||||
const auto rc = System::cmd_execute_and_capture_output(cmd);
|
||||
if (rc.exit_code != 0)
|
||||
{
|
||||
const std::string cmd = Strings::format(R"("%s")", path_to_exe.u8string());
|
||||
const auto rc = System::cmd_execute_and_capture_output(cmd);
|
||||
if (rc.exit_code != 0)
|
||||
{
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
/* Sample output:
|
||||
NuGet Version: 4.6.2.5055
|
||||
usage: NuGet <command> [args] [options]
|
||||
Type 'NuGet help <command>' for help on a specific command.
|
||||
|
||||
[[[List of available commands follows]]]
|
||||
*/
|
||||
return StringRange::find_exactly_one_enclosed(rc.output, "NuGet Version: ", "\n").to_string();
|
||||
}
|
||||
};
|
||||
|
||||
static PathAndVersion get_path(const VcpkgPaths& paths)
|
||||
{
|
||||
static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "nuget");
|
||||
|
||||
std::vector<fs::path> candidate_paths;
|
||||
candidate_paths.push_back(TOOL_DATA.exe_path);
|
||||
const std::vector<fs::path> from_path = paths.get_filesystem().find_from_PATH("nuget");
|
||||
candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
|
||||
|
||||
const NugetVersionProvider version_provider{};
|
||||
const std::vector<PathAndVersion> candidates_with_versions = version_provider.get_versions(candidate_paths);
|
||||
const auto maybe_path = find_first_with_sufficient_version(candidates_with_versions, TOOL_DATA.version);
|
||||
if (const auto p = maybe_path.get())
|
||||
{
|
||||
return *p;
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
return fetch_tool(paths, Tools::NUGET, TOOL_DATA, version_provider);
|
||||
/* Sample output:
|
||||
NuGet Version: 4.6.2.5055
|
||||
usage: NuGet <command> [args] [options]
|
||||
Type 'NuGet help <command>' for help on a specific command.
|
||||
|
||||
[[[List of available commands follows]]]
|
||||
*/
|
||||
return StringRange::find_exactly_one_enclosed(rc.output, "NuGet Version: ", "\n").to_string();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
namespace Git
|
||||
struct GitProvider : ToolProvider
|
||||
{
|
||||
struct GitVersionProvider : VersionProvider
|
||||
std::string m_exe = "git";
|
||||
|
||||
virtual const std::string& tool_data_name() const override { return m_exe; }
|
||||
virtual const std::string& exe_stem() const override { return m_exe; }
|
||||
virtual std::array<int, 3> default_min_version() const override { return {2, 7, 4}; }
|
||||
|
||||
virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const
|
||||
{
|
||||
Optional<std::string> get_version(const fs::path& path_to_exe) const override
|
||||
{
|
||||
const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string());
|
||||
const auto rc = System::cmd_execute_and_capture_output(cmd);
|
||||
if (rc.exit_code != 0)
|
||||
{
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
/* Sample output:
|
||||
git version 2.17.1.windows.2
|
||||
*/
|
||||
const auto idx = rc.output.find("git version ");
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
idx != std::string::npos,
|
||||
"Unexpected format of git version string: %s",
|
||||
rc.output);
|
||||
return rc.output.substr(idx);
|
||||
}
|
||||
};
|
||||
|
||||
static PathAndVersion get_path(const VcpkgPaths& paths)
|
||||
{
|
||||
static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "git");
|
||||
|
||||
std::vector<fs::path> candidate_paths;
|
||||
#if defined(_WIN32)
|
||||
candidate_paths.push_back(TOOL_DATA.exe_path);
|
||||
#endif
|
||||
const std::vector<fs::path> from_path = paths.get_filesystem().find_from_PATH("git");
|
||||
candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
|
||||
|
||||
const auto& program_files = System::get_program_files_platform_bitness();
|
||||
if (const auto pf = program_files.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe");
|
||||
if (const auto pf = program_files.get()) out_candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe");
|
||||
const auto& program_files_32_bit = System::get_program_files_32_bit();
|
||||
if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe");
|
||||
|
||||
const GitVersionProvider version_provider{};
|
||||
const std::vector<PathAndVersion> candidates_with_versions = version_provider.get_versions(candidate_paths);
|
||||
const auto maybe_path = find_first_with_sufficient_version(candidates_with_versions, TOOL_DATA.version);
|
||||
if (const auto p = maybe_path.get())
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
|
||||
return fetch_tool(paths, Tools::GIT, TOOL_DATA, version_provider);
|
||||
if (const auto pf = program_files_32_bit.get())
|
||||
out_candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
namespace IfwInstallerBase
|
||||
{
|
||||
struct IfwInstallerBaseVersionProvider : VersionProvider
|
||||
virtual Optional<std::string> get_version(const fs::path& path_to_exe) const override
|
||||
{
|
||||
Optional<std::string> get_version(const fs::path& path_to_exe) const override
|
||||
const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string());
|
||||
const auto rc = System::cmd_execute_and_capture_output(cmd);
|
||||
if (rc.exit_code != 0)
|
||||
{
|
||||
const std::string cmd = Strings::format(R"("%s" --framework-version)", path_to_exe.u8string());
|
||||
const auto rc = System::cmd_execute_and_capture_output(cmd);
|
||||
if (rc.exit_code != 0)
|
||||
{
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
/* Sample output:
|
||||
3.1.81
|
||||
*/
|
||||
return rc.output;
|
||||
return nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
static PathAndVersion get_path(const VcpkgPaths& paths)
|
||||
/* Sample output:
|
||||
git version 2.17.1.windows.2
|
||||
*/
|
||||
const auto idx = rc.output.find("git version ");
|
||||
Checks::check_exit(
|
||||
VCPKG_LINE_INFO, idx != std::string::npos, "Unexpected format of git version string: %s", rc.output);
|
||||
return rc.output.substr(idx);
|
||||
}
|
||||
};
|
||||
|
||||
struct IfwInstallerBaseProvider : ToolProvider
|
||||
{
|
||||
std::string m_exe = "";
|
||||
std::string m_toolname = "installerbase";
|
||||
|
||||
virtual const std::string& tool_data_name() const override { return m_toolname; }
|
||||
virtual const std::string& exe_stem() const override { return m_exe; }
|
||||
virtual std::array<int, 3> default_min_version() const override { return {0, 0, 0}; }
|
||||
|
||||
virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const
|
||||
{
|
||||
static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "installerbase");
|
||||
|
||||
std::vector<fs::path> candidate_paths;
|
||||
candidate_paths.push_back(TOOL_DATA.exe_path);
|
||||
// TODO: Uncomment later
|
||||
// const std::vector<fs::path> from_path = Files::find_from_PATH("installerbase");
|
||||
// candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
|
||||
// candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" /
|
||||
// "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe");
|
||||
// candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" /
|
||||
// "QtIFW-3.1.0" / "bin" / "installerbase.exe");
|
||||
// candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) /
|
||||
// "Qt" / "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe");
|
||||
// candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) /
|
||||
// "Qt" / "QtIFW-3.1.0" / "bin" / "installerbase.exe");
|
||||
}
|
||||
|
||||
const IfwInstallerBaseVersionProvider version_provider{};
|
||||
const std::vector<PathAndVersion> candidates_with_versions = version_provider.get_versions(candidate_paths);
|
||||
const auto maybe_path = find_first_with_sufficient_version(candidates_with_versions, TOOL_DATA.version);
|
||||
if (const auto p = maybe_path.get())
|
||||
virtual Optional<std::string> get_version(const fs::path& path_to_exe) const override
|
||||
{
|
||||
const std::string cmd = Strings::format(R"("%s" --framework-version)", path_to_exe.u8string());
|
||||
const auto rc = System::cmd_execute_and_capture_output(cmd);
|
||||
if (rc.exit_code != 0)
|
||||
{
|
||||
return *p;
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
return fetch_tool(paths, Tools::IFW_INSTALLER_BASE, TOOL_DATA, version_provider);
|
||||
/* Sample output:
|
||||
3.1.81
|
||||
*/
|
||||
return rc.output;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ToolCacheImpl final : ToolCache
|
||||
{
|
||||
@ -506,12 +444,12 @@ namespace vcpkg
|
||||
tool == Tools::IFW_INSTALLER_BASE)
|
||||
return get_tool_pathversion(paths, tool).path;
|
||||
if (tool == Tools::IFW_BINARYCREATOR)
|
||||
return IfwInstallerBase::get_path(paths).path.parent_path() / "binarycreator.exe";
|
||||
return get_tool_path(paths, Tools::IFW_INSTALLER_BASE).parent_path() / "binarycreator.exe";
|
||||
if (tool == Tools::IFW_REPOGEN)
|
||||
return IfwInstallerBase::get_path(paths).path.parent_path() / "repogen.exe";
|
||||
return get_tool_path(paths, Tools::IFW_INSTALLER_BASE).parent_path() / "repogen.exe";
|
||||
|
||||
// For other tools, we simply always auto-download them.
|
||||
const ToolData tool_data = parse_tool_data_from_xml(paths, tool);
|
||||
const ToolData tool_data = parse_tool_data_from_xml(paths, tool).value_or_exit(VCPKG_LINE_INFO);
|
||||
if (paths.get_filesystem().exists(tool_data.exe_path))
|
||||
{
|
||||
return tool_data.exe_path;
|
||||
@ -522,12 +460,33 @@ namespace vcpkg
|
||||
|
||||
const PathAndVersion& get_tool_pathversion(const VcpkgPaths& paths, const std::string& tool) const
|
||||
{
|
||||
return path_version_cache.get_lazy(tool, [&]() {
|
||||
if (tool == Tools::CMAKE) return CMake::get_path(paths);
|
||||
if (tool == Tools::GIT) return Git::get_path(paths);
|
||||
if (tool == Tools::NINJA) return Ninja::get_path(paths);
|
||||
if (tool == Tools::NUGET) return Nuget::get_path(paths);
|
||||
if (tool == Tools::IFW_INSTALLER_BASE) return IfwInstallerBase::get_path(paths);
|
||||
return path_version_cache.get_lazy(tool, [&]() -> PathAndVersion {
|
||||
if (tool == Tools::CMAKE)
|
||||
{
|
||||
if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
|
||||
{
|
||||
return {"cmake", "0"};
|
||||
}
|
||||
return get_path(paths, CMakeProvider());
|
||||
}
|
||||
if (tool == Tools::GIT)
|
||||
{
|
||||
if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
|
||||
{
|
||||
return {"git", "0"};
|
||||
}
|
||||
return get_path(paths, GitProvider());
|
||||
}
|
||||
if (tool == Tools::NINJA)
|
||||
{
|
||||
if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
|
||||
{
|
||||
return {"ninja", "0"};
|
||||
}
|
||||
return get_path(paths, NinjaProvider());
|
||||
}
|
||||
if (tool == Tools::NUGET) return get_path(paths, NuGetProvider());
|
||||
if (tool == Tools::IFW_INSTALLER_BASE) return get_path(paths, IfwInstallerBaseProvider());
|
||||
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Finding version for %s is not implemented yet.", tool);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user