Skip to content

Commit

Permalink
TgBot++: android_builder: Improve sync error matching
Browse files Browse the repository at this point in the history
  • Loading branch information
Royna2544 committed Jul 7, 2024
1 parent 9148aa9 commit 26e903e
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 17 deletions.
69 changes: 58 additions & 11 deletions src/android_builder/tasks/RepoSyncTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <thread>

#include "CStringLifetime.h"
#include "git2/types.h"
#include "tasks/PerBuildData.hpp"

namespace {
Expand All @@ -20,6 +21,25 @@ struct RAIIGit {
void addCleanup(std::function<void(void)> cleanupFn) {
cleanups.emplace_back(cleanupFn);
}
void add_repo_cleanup(git_repository* repo) {
addCleanup([repo] { git_repository_free(repo); });
}
void add_ref_cleanup(git_reference* ref) {
addCleanup([ref] { git_reference_free(ref); });
}
void add_commit_cleanup(git_commit* commit) {
addCleanup([commit] { git_commit_free(commit); });
}
void add_tree_cleanup(git_tree* tree) {
addCleanup([tree] { git_tree_free(tree); });
}
void add_object_cleanup(git_object* obj) {
addCleanup([obj] { git_object_free(obj); });
}
void add_remote_cleanup(git_remote* remote) {
addCleanup([remote] { git_remote_free(remote); });
}

RAIIGit() { git_libgit2_init(); }
~RAIIGit() {
for (auto& cleanup : cleanups) {
Expand Down Expand Up @@ -53,15 +73,15 @@ bool tryToMakeItMine(const PerBuildData& data) {
LOG(ERROR) << "Failed to open repository: " << git_error_last_str();
return false;
}
raii.addCleanup([repo] { git_repository_free(repo); });
raii.add_repo_cleanup(repo);

ret = git_remote_lookup(&remote, repo, kRemoteRepoName.data());
if (ret != 0) {
LOG(ERROR) << "Failed to lookup remote origin: "
<< git_error_last_str();
return false;
}
raii.addCleanup([remote] { git_remote_free(remote); });
raii.add_remote_cleanup(remote);

remote_url = git_remote_url(remote);
if (remote_url == nullptr) {
Expand All @@ -80,7 +100,7 @@ bool tryToMakeItMine(const PerBuildData& data) {
LOG(ERROR) << "Failed to get HEAD reference: " << git_error_last_str();
return false;
}
raii.addCleanup([head_ref] { git_reference_free(head_ref); });
raii.add_ref_cleanup(head_ref);

current_branch = git_reference_shorthand(head_ref);
LOG(INFO) << "Current branch: " << current_branch;
Expand Down Expand Up @@ -125,8 +145,7 @@ bool tryToMakeItMine(const PerBuildData& data) {
<< git_error_last_str();
return false;
}
raii.addCleanup(
[target_remote_ref] { git_reference_free(target_remote_ref); });
raii.add_ref_cleanup(target_remote_ref);

// Get the commit of the target branch ref
ret = git_commit_lookup(&commit, repo,
Expand All @@ -136,7 +155,7 @@ bool tryToMakeItMine(const PerBuildData& data) {
<< git_error_last_str();
return false;
}
raii.addCleanup([commit] { git_commit_free(commit); });
raii.add_commit_cleanup(commit);

// Create the local branch ref pointing to the commit
ret = git_branch_create(&target_ref, repo, branch_name.get(),
Expand All @@ -146,7 +165,7 @@ bool tryToMakeItMine(const PerBuildData& data) {
<< git_error_last_str();
return false;
}
raii.addCleanup([target_ref] { git_reference_free(target_ref); });
raii.add_ref_cleanup(target_ref);

// Checkout the local branch
ret = git_checkout_head(repo, &checkout_opts);
Expand All @@ -158,7 +177,8 @@ bool tryToMakeItMine(const PerBuildData& data) {

LOG(INFO) << "Success on checking out remote branch";
} else {
raii.addCleanup([target_ref] { git_reference_free(target_ref); });
// Switching to the branch directly
raii.add_ref_cleanup(target_ref);

// Get the object of the target branch ref
ret = git_reference_peel(&treeish, target_ref, GIT_OBJECT_TREE);
Expand All @@ -167,7 +187,7 @@ bool tryToMakeItMine(const PerBuildData& data) {
<< git_error_last_str();
return false;
}
raii.addCleanup([treeish] { git_object_free(treeish); });
raii.add_object_cleanup(treeish);

ret = git_checkout_tree(repo, treeish, nullptr);
if (ret != 0) {
Expand All @@ -189,6 +209,11 @@ bool tryToMakeItMine(const PerBuildData& data) {
} // namespace

bool RepoSyncLocalHook::process(const std::string& line) {
static const std::regex kRepoRemoveFail(
"error: ([a-zA-Z0-9_\\-\\/]+): Cannot remove project: "
"uncommitted changes are present\\.");
std::smatch smatch;

if (line.find(kUpdatingFiles) != std::string::npos) {
// Stop logspam
return true;
Expand All @@ -207,6 +232,25 @@ bool RepoSyncLocalHook::process(const std::string& line) {
return true;
}

if (std::regex_search(line, smatch, kRepoRemoveFail)) {
std::error_code ec;
errorAndLog("Repo sync failed due to local issue: RemoveFail");
hasRemoveIssues = true;
hadProblems = true;
if (smatch.size() > 1) {
std::string directory = smatch[1].str();
LOG(WARNING) << "Will remove directory: " << directory;
std::filesystem::remove_all(directory, ec);
if (ec) {
errorAndLog("Failed to remove: " + directory + ": " +
ec.message());
hadFatalProblems = true;
} else {
LOG(INFO) << "Successfully removed";
}
}
}

if (hasCheckoutIssues) {
std::error_code ec;
if (line.find(kRepoCheckoutFailEnd) != std::string::npos) {
Expand All @@ -229,7 +273,10 @@ bool RepoSyncLocalHook::process(const std::string& line) {
bool RepoSyncNetworkHook::process(const std::string& line) {
static const std::regex kSyncErrorNetworkRegex(
R"(^error:\s+Cannot\s+fetch\s+[^\s]+(?:/[^\s]+)*\s+from\s+https:\/\/.+$)");
if (std::regex_match(line, kSyncErrorNetworkRegex)) {
static const std::regex kSyncErrorNetworkRegex2(
R"(^Failed to connect to (github\.com|gitlab\.com) port \d+ after \d+ ms: Couldn't connect to server$)");
if (std::regex_match(line, kSyncErrorNetworkRegex) ||
std::regex_match(line, kSyncErrorNetworkRegex2)) {
LOG(INFO) << "Detected sync issue, caused by network";
hadProblems = true;
return true;
Expand Down Expand Up @@ -284,7 +331,7 @@ void RepoSyncTask::onNewStderrBuffer(ForkAndRun::BufferType& buffer) {
if (networkHook.process(line)) {
continue;
}
std::cerr << "Repo sync stderr: " << line << std::endl;
// std::cerr << "Repo sync stderr: " << line << std::endl;
}
}

Expand Down
17 changes: 11 additions & 6 deletions src/android_builder/tasks/RepoSyncTask.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <ConfigParsers.hpp>
#include <ForkAndRun.hpp>
#include <RepoUtils.hpp>

#include "PerBuildData.hpp"

class NewStdErrBufferHook {
Expand All @@ -9,7 +10,7 @@ class NewStdErrBufferHook {
protected:
bool hadProblems = false;
bool hadFatalProblems = false;

void errorAndLog(const std::string& message) {
LOG(ERROR) << message;
logMessage << message << std::endl;
Expand All @@ -36,9 +37,7 @@ class NewStdErrBufferHook {
[[nodiscard]] std::string getLogMessage() const noexcept {
return logMessage.str();
}
[[nodiscard]] bool hasProblems() const noexcept {
return hadProblems;
}
[[nodiscard]] bool hasProblems() const noexcept { return hadProblems; }
[[nodiscard]] bool hasFatalProblems() const noexcept {
return hadProblems && hadFatalProblems;
}
Expand All @@ -60,6 +59,8 @@ class RepoSyncLocalHook : public NewStdErrBufferHook {
"Try re-running with \"-j1 --fail-fast\" to exit at the first error.";

bool hasCheckoutIssues = false;
bool hasRemoveIssues = false;

public:
bool process(const std::string& line) override;
~RepoSyncLocalHook() override = default;
Expand All @@ -86,7 +87,7 @@ struct RepoSyncTask : ForkAndRun {
* otherwise.
*/
bool runFunction() override;

/**
* @brief Handles new standard error data.
*
Expand All @@ -98,6 +99,10 @@ struct RepoSyncTask : ForkAndRun {
*/
void onNewStderrBuffer(ForkAndRun::BufferType& buffer) override;

void onNewStdoutBuffer(ForkAndRun::BufferType& buffer) override {
onNewStderrBuffer(buffer);
}

/**
* @brief Handles the process exit event.
*
Expand Down Expand Up @@ -130,7 +135,7 @@ struct RepoSyncTask : ForkAndRun {

private:
PerBuildData data;

RepoSyncLocalHook localHook;
RepoSyncNetworkHook networkHook;
};

0 comments on commit 26e903e

Please sign in to comment.