Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move most of git out of VcpkgPaths #1381

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/vcpkg/base/git.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vcpkg/base/expected.h>
#include <vcpkg/base/path.h>
#include <vcpkg/base/stringview.h>
#include <vcpkg/base/system.process.h>

#include <set>
#include <string>
Expand Down Expand Up @@ -42,6 +43,8 @@ namespace vcpkg
std::string old_path;
};

Command git_cmd_builder(const GitConfig& config);

// Try to extract a port name from a path.
// The path should start with the "ports/" prefix
std::string try_extract_port_name_from_path(StringView path);
Expand All @@ -58,4 +61,9 @@ namespace vcpkg

// Check whether a repository is a shallow clone
ExpectedL<bool> is_shallow_clone(const GitConfig& config);

// runs git ref-parse for a given refname, e.g. HEAD
ExpectedL<std::string> git_ref_sha(const GitConfig& config, StringView refname = "HEAD");
// runs `git fetch {uri} {treeish}`
ExpectedL<Unit> git_fetch(const Filesystem& fs, const GitConfig& config, StringView repo, StringView treeish);
}
3 changes: 1 addition & 2 deletions include/vcpkg/vcpkgpaths.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ namespace vcpkg
// Git manipulation for remote registries
// runs `git fetch {uri} {treeish}`, and returns the hash of FETCH_HEAD.
// Use {treeish} of "HEAD" for the default branch
GitConfig git_registries_config() const;
ExpectedL<std::string> git_fetch_from_remote_registry(StringView uri, StringView treeish) const;
// runs `git fetch {uri} {treeish}`
ExpectedL<Unit> git_fetch(StringView uri, StringView treeish) const;
ExpectedL<std::string> git_show_from_remote_registry(StringView hash, const Path& relative_path_to_file) const;
ExpectedL<std::string> git_find_object_id_for_remote_registry_path(StringView hash,
const Path& relative_path_to_file) const;
Expand Down
68 changes: 59 additions & 9 deletions src/vcpkg/base/git.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
#include <vcpkg/base/expected.h>
#include <vcpkg/base/fwd/message_sinks.h>

#include <vcpkg/base/files.h>
#include <vcpkg/base/git.h>
#include <vcpkg/base/messages.h>
#include <vcpkg/base/parse.h>
#include <vcpkg/base/strings.h>
#include <vcpkg/base/stringview.h>
#include <vcpkg/base/system.process.h>

#include <vcpkg/tools.h>

namespace
namespace vcpkg
{
using namespace vcpkg;

Command git_cmd_builder(const GitConfig& config)
{
auto cmd = Command(config.git_exe);
Expand All @@ -26,10 +24,7 @@ namespace
}
return cmd;
}
}

namespace vcpkg
{
std::string try_extract_port_name_from_path(StringView path)
{
static constexpr StringLiteral prefix = "ports/";
Expand Down Expand Up @@ -199,4 +194,59 @@ namespace vcpkg
Tools::GIT)
.map([](std::string&& output) { return "true" == Strings::trim(std::move(output)); });
}

ExpectedL<std::string> git_ref_sha(const GitConfig& config, StringView refname)
{
const auto cmd_line = git_cmd_builder(config).string_arg("rev-parse").string_arg(refname);
return flatten_out(cmd_execute_and_capture_output(cmd_line), Tools::GIT)
.map([](std::string&& output) {
Strings::inplace_trim(output);
return std::move(output);
})
.map_error([&](LocalizedString&& err) {
return msg::format(msgGitCommandFailed, msg::command_line = cmd_line.command_line())
.append_raw('\n')
.append(std::move(err));
});
}

ExpectedL<Unit> git_fetch(const Filesystem& fs, const GitConfig& config, StringView repo, StringView treeish)
{
const auto& work_tree = config.git_work_tree;
fs.create_directories(work_tree, VCPKG_LINE_INFO);

auto lock_file = work_tree / ".vcpkg-lock";

auto guard = fs.take_exclusive_file_lock(lock_file, stderr_sink, IgnoreErrors{});

auto init_registries_git_dir = git_cmd_builder(config).string_arg("init");
auto maybe_init_output = flatten(cmd_execute_and_capture_output(init_registries_git_dir), Tools::GIT);
if (!maybe_init_output)
{
Comment on lines +222 to +224
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does not appear to be well described either if it's potentially doing init.

return msg::format(msgGitFailedToInitializeLocalRepository, msg::path = work_tree)
.append_raw('\n')
.append(msgGitCommandFailed, msg::command_line = init_registries_git_dir.command_line())
.append_raw('\n')
.append(std::move(maybe_init_output).error());
}

auto fetch_git_ref = git_cmd_builder(config)
.string_arg("fetch")
.string_arg("--update-shallow")
.string_arg("--")
.string_arg(repo)
.string_arg(treeish);

auto maybe_fetch_output = flatten(cmd_execute_and_capture_output(fetch_git_ref), Tools::GIT);
if (!maybe_fetch_output)
{
return msg::format(msgGitFailedToFetch, msg::value = treeish, msg::url = repo)
.append_raw('\n')
.append(msgGitCommandFailed, msg::command_line = fetch_git_ref.command_line())
.append_raw('\n')
.append(std::move(maybe_fetch_output).error());
}

return {Unit{}};
}
}
3 changes: 2 additions & 1 deletion src/vcpkg/commands.portsdiff.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <vcpkg/base/files.h>
#include <vcpkg/base/git.h>
#include <vcpkg/base/system.process.h>
#include <vcpkg/base/util.h>

Expand Down Expand Up @@ -73,7 +74,7 @@ namespace
{
static constexpr StringLiteral VALID_COMMIT_OUTPUT = "commit\n";
Checks::msg_check_exit(VCPKG_LINE_INFO,
cmd_execute_and_capture_output(paths.git_cmd_builder(paths.root / ".git", paths.root)
cmd_execute_and_capture_output(git_cmd_builder(paths.git_builtin_config())
.string_arg("cat-file")
.string_arg("-t")
.string_arg(git_commit_id))
Expand Down
8 changes: 4 additions & 4 deletions src/vcpkg/registries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <vcpkg/base/contractual-constants.h>
#include <vcpkg/base/delayed-init.h>
#include <vcpkg/base/files.h>
#include <vcpkg/base/git.h>
#include <vcpkg/base/json.h>
#include <vcpkg/base/jsonreader.h>
#include <vcpkg/base/messages.h>
Expand Down Expand Up @@ -1012,13 +1013,12 @@ namespace
if (!maybe_contents)
{
msg::println(msgFetchingBaselineInfo, msg::package_name = m_repo);
auto maybe_err = m_paths.git_fetch(m_repo, m_baseline_identifier);
auto maybe_err =
git_fetch(m_paths.get_filesystem(), m_paths.git_registries_config(), m_repo, m_baseline_identifier);
if (!maybe_err)
{
get_global_metrics_collector().track_define(DefineMetric::RegistriesErrorCouldNotFindBaseline);
return msg::format_error(msgFailedToFetchRepo, msg::url = m_repo)
.append_raw('\n')
.append(maybe_err.error());
return msg::format_error(maybe_err.error());
}

maybe_contents = m_paths.git_show_from_remote_registry(m_baseline_identifier, path_to_baseline);
Expand Down
136 changes: 20 additions & 116 deletions src/vcpkg/vcpkgpaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -841,8 +841,8 @@ namespace vcpkg
if (m_pimpl->m_bundle.read_only)
{
Strings::append(ret, " vcpkg-readonly: true\n");
const auto sha = get_current_git_sha();
Strings::append(ret, " vcpkg-scripts version: ", sha ? StringView(*sha.get()) : "unknown", "\n");
const auto sha = get_current_git_sha().value_or("unknown");
Strings::append(ret, " vcpkg-scripts version: ", StringView{sha}, "\n");
}
else
{
Expand Down Expand Up @@ -890,17 +890,8 @@ namespace vcpkg

Command VcpkgPaths::git_cmd_builder(const Path& dot_git_dir, const Path& work_tree) const
{
Command ret(get_tool_exe(Tools::GIT, out_sink));
if (!dot_git_dir.empty())
{
ret.string_arg(Strings::concat("--git-dir=", dot_git_dir));
}
if (!work_tree.empty())
{
ret.string_arg(Strings::concat("--work-tree=", work_tree));
}
ret.string_arg("-c").string_arg("core.autocrlf=false");
return ret;
const GitConfig config{get_tool_exe(Tools::GIT, out_sink), dot_git_dir, work_tree};
return vcpkg::git_cmd_builder(config);
}

ExpectedL<std::string> VcpkgPaths::get_current_git_sha() const
Expand All @@ -910,19 +901,12 @@ namespace vcpkg
return {*sha, expected_left_tag};
}

return flatten_out(
cmd_execute_and_capture_output(
git_cmd_builder(this->root / ".git", this->root).string_arg("rev-parse").string_arg("HEAD")),
Tools::GIT)
.map([](std::string&& output) {
Strings::inplace_trim(output);
return std::move(output);
});
return git_ref_sha(git_builtin_config());
}

LocalizedString VcpkgPaths::get_current_git_sha_baseline_message() const
{
const auto& git_config = git_builtin_config();
const auto git_config = git_builtin_config();
if (is_shallow_clone(git_config).value_or(false))
{
return msg::format(msgShallowRepositoryDetected, msg::path = git_config.git_dir);
Expand Down Expand Up @@ -1027,95 +1011,25 @@ namespace vcpkg
.append(msgWhileGettingLocalTreeIshObjectsForPorts);
}

ExpectedL<std::string> VcpkgPaths::git_fetch_from_remote_registry(StringView repo, StringView treeish) const
GitConfig VcpkgPaths::git_registries_config() const
{
auto& fs = get_filesystem();

const auto& work_tree = m_pimpl->m_registries_work_tree_dir;
fs.create_directories(work_tree, VCPKG_LINE_INFO);
const auto& dot_git_dir = m_pimpl->m_registries_dot_git_dir;

auto init_cmd = git_cmd_builder(dot_git_dir, work_tree).string_arg("init");
auto maybe_init_output = flatten(cmd_execute_and_capture_output(init_cmd), Tools::GIT);
if (!maybe_init_output)
{
return msg::format_error(msgGitCommandFailed, msg::command_line = init_cmd.command_line())
.append_raw('\n')
.append(maybe_init_output.error());
}

auto lock_file = work_tree / ".vcpkg-lock";

auto guard = fs.take_exclusive_file_lock(lock_file, stderr_sink, IgnoreErrors{});
auto fetch_git_ref = git_cmd_builder(dot_git_dir, work_tree)
.string_arg("fetch")
.string_arg("--update-shallow")
.string_arg("--")
.string_arg(repo)
.string_arg(treeish);

auto maybe_fetch_output = flatten(cmd_execute_and_capture_output(fetch_git_ref), Tools::GIT);
if (!maybe_fetch_output)
{
return msg::format_error(msgGitFailedToFetch, msg::value = treeish, msg::url = repo)
.append_raw('\n')
.append(msgGitCommandFailed, msg::command_line = fetch_git_ref.command_line())
.append_raw('\n')
.append(std::move(maybe_fetch_output).error());
}

auto get_fetch_head = git_cmd_builder(dot_git_dir, work_tree).string_arg("rev-parse").string_arg("FETCH_HEAD");
return flatten_out(cmd_execute_and_capture_output(get_fetch_head), Tools::GIT)
.map([](std::string&& output) { return Strings::trim(output).to_string(); })
.map_error([&](LocalizedString&& err) {
return msg::format_error(msgGitCommandFailed, msg::command_line = get_fetch_head.command_line())
.append_raw('\n')
.append(std::move(err));
});
GitConfig conf;
conf.git_exe = get_tool_exe(Tools::GIT, out_sink);
conf.git_dir = m_pimpl->m_registries_dot_git_dir;
conf.git_work_tree = m_pimpl->m_registries_work_tree_dir;
return conf;
}

ExpectedL<Unit> VcpkgPaths::git_fetch(StringView repo, StringView treeish) const
ExpectedL<std::string> VcpkgPaths::git_fetch_from_remote_registry(StringView repo, StringView treeish) const
{
auto& fs = get_filesystem();

const auto& work_tree = m_pimpl->m_registries_work_tree_dir;
fs.create_directories(work_tree, VCPKG_LINE_INFO);

auto lock_file = work_tree / ".vcpkg-lock";
auto git_config = git_registries_config();
auto maybe_fetch_result = vcpkg::git_fetch(get_filesystem(), git_config, repo, treeish);

auto guard = fs.take_exclusive_file_lock(lock_file, stderr_sink, IgnoreErrors{});

const auto& dot_git_dir = m_pimpl->m_registries_dot_git_dir;

auto init_registries_git_dir = git_cmd_builder(dot_git_dir, work_tree).string_arg("init");
auto maybe_init_output = flatten(cmd_execute_and_capture_output(init_registries_git_dir), Tools::GIT);
if (!maybe_init_output)
{
return msg::format_error(msgGitFailedToInitializeLocalRepository, msg::path = work_tree)
.append_raw('\n')
.append(msgGitCommandFailed, msg::command_line = init_registries_git_dir.command_line())
.append_raw('\n')
.append(std::move(maybe_init_output).error());
}

auto fetch_git_ref = git_cmd_builder(dot_git_dir, work_tree)
.string_arg("fetch")
.string_arg("--update-shallow")
.string_arg("--")
.string_arg(repo)
.string_arg(treeish);

auto maybe_fetch_output = flatten(cmd_execute_and_capture_output(fetch_git_ref), Tools::GIT);
if (!maybe_fetch_output)
if (!maybe_fetch_result)
{
return msg::format_error(msgGitFailedToFetch, msg::value = treeish, msg::url = repo)
.append_raw('\n')
.append(msgGitCommandFailed, msg::command_line = fetch_git_ref.command_line())
.append_raw('\n')
.append(std::move(maybe_fetch_output).error());
return msg::format_error(maybe_fetch_result.error());
}

return {Unit{}};
return git_ref_sha(git_config, "FETCH_HEAD");
}

// returns an error if there was an unexpected error; returns nullopt if the file doesn't exist at the specified
Expand All @@ -1124,24 +1038,14 @@ namespace vcpkg
{
auto revision = fmt::format("{}:{}", hash, relative_path.generic_u8string());
return flatten_out(cmd_execute_and_capture_output(
git_cmd_builder(m_pimpl->m_registries_dot_git_dir, m_pimpl->m_registries_work_tree_dir)
.string_arg("show")
.string_arg(revision)),
vcpkg::git_cmd_builder(git_registries_config()).string_arg("show").string_arg(revision)),
Tools::GIT);
}
ExpectedL<std::string> VcpkgPaths::git_find_object_id_for_remote_registry_path(StringView hash,
const Path& relative_path) const
{
auto revision = fmt::format("{}:{}", hash, relative_path.generic_u8string());
return flatten_out(cmd_execute_and_capture_output(
git_cmd_builder(m_pimpl->m_registries_dot_git_dir, m_pimpl->m_registries_work_tree_dir)
.string_arg("rev-parse")
.string_arg(revision)),
Tools::GIT)
.map([](std::string&& output) {
Strings::inplace_trim(output);
return std::move(output);
});
return git_ref_sha(git_registries_config(), revision);
}

ExpectedL<Unit> VcpkgPaths::git_read_tree(const Path& destination, StringView tree, const Path& dot_git_dir) const
Expand Down
Loading