Skip to content

Commit

Permalink
TgBot++: android_builder: Fix the following problems
Browse files Browse the repository at this point in the history
- Cannot checkout local manifest repo
- Upload should not send stderr
- Path shouldn't be relative to make sql loadable
  • Loading branch information
Royna2544 committed Jul 7, 2024
1 parent 7b353ca commit 9148aa9
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 38 deletions.
6 changes: 3 additions & 3 deletions src/android_builder/ForkAndRun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,13 @@ bool ForkAndRun::execute() {
Selector::Mode::READ);
selector.add(
python_pipe.readEnd(),
[python_pipe] {
[python_pipe, this] {
BufferType buf{};
ssize_t bytes_read =
read(python_pipe.readEnd(), buf.data(), buf.size() - 1);
if (bytes_read >= 0) {
printf("Python output: ");
fputs(buf.data(), stdout);
onNewStdoutBuffer(buf);
buf.fill(0);
}
},
Selector::Mode::READ);
Expand Down
34 changes: 29 additions & 5 deletions src/android_builder/scripts/build_rom_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,47 @@ def find_vendor_str() -> str:

def build_rom(device: str, variant: str, target: str, jobs: int) -> bool:
vendor = find_vendor_str()
success = False

if vendor is None:
print('Couldn\'t find vendor')
return False

shell_process = subprocess.Popen(['bash'], stdin=subprocess.PIPE, text=True)
shell_process = subprocess.Popen(['bash'], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print('Writing . build/envsetup.sh')
shell_process.stdin.write('. build/envsetup.sh\n')
if os.getenv('USE_CCACHE') is not None:
print('ccache is useless, unset USE_CCACHE')
os.unsetenv('USE_CCACHE')
print(f'Writing lunch {vendor}_{device}-{variant}')
shell_process.stdin.write(f'lunch {vendor}_{device}-{variant}\n')
shell_process.stdin.write('echo "exit code: $?\n')
shell_process.stdin.flush()
print('Waiting for lunch command result...')
while True:
line = process.stdout.readline()
if line.startswith("exit code:"):
# Extract the exit code from the line
exit_code = int(line.strip().split()[-1])
break
print(line)

if exit_code != 0:
print(f'Error: lunch command failed with exit code {exit_code}')
print(shell_process.stderr.read())
return False

# Remap to original stdout/stderr
shell_process.stdout.close()
shell_process.stderr.close()
shell_process.stdout = os.fdopen(os.dup(1), 'w')
shell_process.stderr = os.fdopen(os.dup(2), 'w')

# Start the build process
print(f'Writing m {target} -j{jobs}')
shell_process.stdin.write(f'm {target} -j{jobs}\n')
shell_process.stdin.flush()
shell_process.stdin.close()
print('Now waiting...')
shell_process.wait()
success = shell_process.returncode == 0

return success
return shell_process.returncode == 0
9 changes: 5 additions & 4 deletions src/android_builder/scripts/upload_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ def upload_to_gofile(device_name, file_prefix) -> str:
print(f"SSL certificate verification failed: {e}")
dir_path = os.path.dirname(os.path.realpath(__file__))
out, err = subprocess_utils.run_command_with_output(f'bash {dir_path}/upload_file.bash {file_to_upload}')
return f"""
STDOUT: {out}
STDERR: {err}
"""
if out is None:
with open('upload_err.txt', 'w') as f:
f.write(err)
return f"An error occurred while uploading the file. See upload_err.txt for details."
return out

# Check the response from GoFile
if response.status_code == 200:
Expand Down
16 changes: 11 additions & 5 deletions src/android_builder/tasks/ROMBuildTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <ArgumentBuilder.hpp>
#include <mutex>
#include <regex>

bool ROMBuildTask::runFunction() {
auto dataShmem =
Expand Down Expand Up @@ -62,15 +63,19 @@ bool ROMBuildTask::runFunction() {
LOG(ERROR) << "ROM build failed";
std::ifstream errorLog(kErrorLogFile.data());
if (errorLog.is_open()) {
static std::regex ansi_escape_code_pattern(
R"(\x1B\[[0-9;]*[A-Za-z])");

std::string errorLogContent(
(std::istreambuf_iterator<char>(errorLog)),
std::istreambuf_iterator<char>());
if (errorLogContent.find("FAILED:") != std::string::npos) {
const auto commandIdx = errorLogContent.find("Command:");
if (commandIdx != std::string::npos) {
// Ninja error
resultdata->setMessage(errorLogContent.substr(0,
errorLogContent.find_first_of("Command:")));
resultdata->setMessage(errorLogContent.substr(0, commandIdx));
} else {
// Probably makefile?
std::regex_replace(errorLogContent, ansi_escape_code_pattern, "");
resultdata->setMessage(errorLogContent);
}
} else {
Expand All @@ -93,7 +98,7 @@ int ROMBuildTask::guessJobCount() {
}
total_memory /= Multiplier; // Convert to GB
LOG(INFO) << "Total memory: " << total_memory << "GB";
jobCount = static_cast<int>(sqrt(total_memory) * 2);
jobCount = static_cast<int>(sqrt(total_memory));
LOG(INFO) << "Using job count: " << jobCount;
});
return jobCount;
Expand All @@ -111,7 +116,8 @@ void ROMBuildTask::onNewStdoutBuffer(ForkAndRun::BufferType& buffer) {
buildInfoBuffer << "Last updated on: " << fromTP(now) << std::endl;
buildInfoBuffer << "Target ROM: " << data.rConfig.name
<< ", branch: " << data.rConfig.branch << std::endl;
buildInfoBuffer << "Target device: " << data.bConfig.device << std::endl;
buildInfoBuffer << "Target device: " << data.bConfig.device
<< std::endl;
buildInfoBuffer << "Job count: " << guessJobCount();
if (_get_used_mem->call(nullptr, &memUsage)) {
buildInfoBuffer << ", memory usage: " << memUsage << "%";
Expand Down
119 changes: 99 additions & 20 deletions src/android_builder/tasks/RepoSyncTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,37 @@ bool tryToMakeItMine(const PerBuildData& data) {
RAIIGit raii;
const auto git_error_last_str = [] { return git_error_last()->message; };
int ret = 0;
constexpr std::string_view kRemoteRepoName = "origin";

git_repository* repo = nullptr;
git_reference* head_ref = nullptr;
git_reference* target_ref = nullptr;
git_reference* target_remote_ref = nullptr;
const char* current_branch = nullptr;
const char* remote_url = nullptr;
git_object* treeish = nullptr;
git_remote* remote = nullptr;
const char* remote_url = nullptr;
git_commit* commit = nullptr;
git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;

ret = git_repository_open(&repo, RepoSyncTask::kLocalManifestPath.data());
if (ret != 0) {
LOG(ERROR) << "Failed to open repository";
LOG(ERROR) << "Failed to open repository: " << git_error_last_str();
return false;
}
raii.addCleanup([repo] { git_repository_free(repo); });

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

remote_url = git_remote_url(remote);
if (remote_url == nullptr) {
LOG(ERROR) << "Remote origin URL is null";
LOG(ERROR) << "Remote origin URL is null: " << git_error_last_str();
return false;
}
LOG(INFO) << "Remote origin URL: " << remote_url;
Expand All @@ -71,7 +77,7 @@ bool tryToMakeItMine(const PerBuildData& data) {

ret = git_repository_head(&head_ref, repo);
if (ret != 0) {
LOG(ERROR) << "Failed to get HEAD reference";
LOG(ERROR) << "Failed to get HEAD reference: " << git_error_last_str();
return false;
}
raii.addCleanup([head_ref] { git_reference_free(head_ref); });
Expand All @@ -80,26 +86,99 @@ bool tryToMakeItMine(const PerBuildData& data) {
LOG(INFO) << "Current branch: " << current_branch;
CStringLifetime branch_name = data.bConfig.local_manifest.branch;

// Check if the branch is the one we're interested in
if (data.bConfig.local_manifest.branch != current_branch) {
LOG(INFO) << "Switching to branch: "
<< data.bConfig.local_manifest.branch;
LOG(INFO) << "Switching to branch: " << branch_name.get();
struct {
// refs/heads/*branch*
std::string local;
std::string remote;
} target_ref_name;
target_ref_name.local += "refs/heads/";
target_ref_name.local += branch_name.get();
target_ref_name.remote += "refs/remotes/";
target_ref_name.remote += kRemoteRepoName.data();
target_ref_name.remote += "/";
target_ref_name.remote += branch_name.get();

ret = git_revparse_single(&treeish, repo, branch_name);
// Try to find the branch ref in the repository
ret = git_reference_lookup(&target_ref, repo,
target_ref_name.local.c_str());
if (ret != 0) {
LOG(ERROR) << "Failed to find the branch";
return false;
}
raii.addCleanup([treeish] { git_object_free(treeish); });
LOG(ERROR) << "Failed to find the branch ref: "
<< git_error_last_str();

ret = git_checkout_tree(repo, treeish, nullptr);
if (ret != 0) {
LOG(ERROR) << "Failed to checkout tree";
return false;
// Maybe remote has it?
ret = git_remote_fetch(remote, nullptr, nullptr, nullptr);
if (ret != 0) {
LOG(ERROR) << "Failed to fetch remote: "
<< git_error_last_str();
return false;
}

// Now try to find the branch in the remote
ret = git_reference_lookup(&target_remote_ref, repo,
target_ref_name.remote.c_str());
if (ret != 0) {
LOG(ERROR) << "Failed to find the branch "
"in the remote: "
<< git_error_last_str();
return false;
}
raii.addCleanup(
[target_remote_ref] { git_reference_free(target_remote_ref); });

// Get the commit of the target branch ref
ret = git_commit_lookup(&commit, repo,
git_reference_target(target_remote_ref));
if (ret != 0) {
LOG(ERROR) << "Failed to find the commit: "
<< git_error_last_str();
return false;
}
raii.addCleanup([commit] { git_commit_free(commit); });

// Create the local branch ref pointing to the commit
ret = git_branch_create(&target_ref, repo, branch_name.get(),
commit, 0);
if (ret != 0) {
LOG(ERROR) << "Failed to create branch: "
<< git_error_last_str();
return false;
}
raii.addCleanup([target_ref] { git_reference_free(target_ref); });

// Checkout the local branch
ret = git_checkout_head(repo, &checkout_opts);
if (ret != 0) {
LOG(ERROR) << "Failed to checkout head: "
<< git_error_last_str();
return false;
}

LOG(INFO) << "Success on checking out remote branch";
} else {
raii.addCleanup([target_ref] { git_reference_free(target_ref); });

// Get the object of the target branch ref
ret = git_reference_peel(&treeish, target_ref, GIT_OBJECT_TREE);
if (ret != 0) {
LOG(ERROR) << "Failed to find the branch: "
<< git_error_last_str();
return false;
}
raii.addCleanup([treeish] { git_object_free(treeish); });

ret = git_checkout_tree(repo, treeish, nullptr);
if (ret != 0) {
LOG(ERROR) << "Failed to checkout tree: "
<< git_error_last_str();
return false;
}
}
ret = git_repository_set_head(
repo, ("refs/heads/" + std::string(branch_name)).c_str());
ret = git_repository_set_head(repo, target_ref_name.local.c_str());
if (ret != 0) {
LOG(ERROR) << "Failed to set HEAD";
LOG(ERROR) << "Failed to set HEAD: " << git_error_last_str();
return false;
}
} else {
Expand Down
5 changes: 5 additions & 0 deletions src/command_modules/runtime/cmd_RomBuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ void upload(PerBuildData data, const Bot& bot, const Message::Ptr& message) {
bot_editMessage(bot, uploadmsg, "Could'nt initialize upload");
} else {
bot_editMessage(bot, uploadmsg, uploadResult.getMessage());
if (uploadResult.value == PerBuildData::Result::ERROR_FATAL) {
bot.getApi().sendDocument(
message->chat->id,
TgBot::InputFile::fromFile("upload_err.txt", "text/plain"));
}
}
}
} // namespace
Expand Down
1 change: 0 additions & 1 deletion src/libos/libfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ std::filesystem::path FS::getPathForType(PathType type) {
}
if (ok) {
path.make_preferred();
if (type != PathType::HOME) makeRelativeToCWD(path);
} else {
LOG(ERROR) << "Could not find path for type " << static_cast<int>(type);
}
Expand Down

0 comments on commit 9148aa9

Please sign in to comment.