From f522c9ae45df06a105288a2fdc66cbb7cff188e1 Mon Sep 17 00:00:00 2001 From: tastytea Date: Thu, 2 Jul 2020 03:20:27 +0200 Subject: [PATCH] Clean up everything. * More efficient. * More readable. * Errors are reported to the user. --- src/cgi.cpp | 55 +++++++++++++++++++++------------------------------ src/files.cpp | 4 ++-- src/files.hpp | 4 ++-- src/git.cpp | 35 +++++++++++++++++++------------- src/git.hpp | 7 ++++++- src/gitea.cpp | 9 +++++---- src/json.hpp | 1 + src/main.cpp | 7 ++++--- 8 files changed, 63 insertions(+), 59 deletions(-) diff --git a/src/cgi.cpp b/src/cgi.cpp index 66f39f5..5928dcc 100644 --- a/src/cgi.cpp +++ b/src/cgi.cpp @@ -46,41 +46,30 @@ using std::vector; entry_type parse_formdata() { entry_type entry; - try - { - cgicc::Cgicc cgi; - entry.instance = cgi("instance"); - entry.tags = string_to_vector(cgi("tags")); - entry.receipts = string_to_vector(cgi("receipts")); - entry.description = cgi("description"); - const auto screenshot = cgi.getFile("screenshot"); - if (screenshot != cgi.getFiles().end()) + cgicc::Cgicc cgi; + entry.instance = cgi("instance"); + entry.tags = string_to_vector(cgi("tags")); + entry.receipts = string_to_vector(cgi("receipts")); + entry.description = cgi("description"); + + const auto screenshot = cgi.getFile("screenshot"); + if (screenshot != cgi.getFiles().end()) + { + constexpr size_t size_limit{1024 * 1024 * 2}; // 2 MiB. + if (screenshot->getDataLength() > size_limit) { - constexpr size_t size_limit{1024 * 1024 * 2}; // 2 MiB. - if (screenshot->getDataLength() > size_limit) - { - throw runtime_error{"Filesize too big"}; - } - - string filepath{files::get_tmpdir() / screenshot->getFilename()}; - ofstream file{filepath, ios::binary}; - if (file.good()) - { - screenshot->writeToStream(file); - entry.screenshot_filepath = filepath; - } - else - { - throw runtime_error{"Could not open temporary file: " - + filepath}; - } + throw runtime_error{"Filesize too big"}; } - } - catch (const exception &e) - { - cerr << e.what() << '\n'; - // TODO: Make errors visible to the user in a helpful way. + + const string filepath{files::get_tmpdir() / screenshot->getFilename()}; + ofstream file{filepath, ios::binary}; + if (!file.good()) + { + throw runtime_error{"Could not open temporary file: " + filepath}; + } + screenshot->writeToStream(file); + entry.screenshot_filepath = filepath; } return entry; @@ -90,7 +79,7 @@ vector string_to_vector(const string_view str) { vector vec; - stringstream input(str.data()); + stringstream input{str.data()}; string element; while (getline(input, element, ',')) diff --git a/src/files.cpp b/src/files.cpp index e539a76..2b9aa9f 100644 --- a/src/files.cpp +++ b/src/files.cpp @@ -76,7 +76,7 @@ fs::path get_datadir() auto path{fs::path(env)}; #if defined(__linux__) path /= ".local/share/fediblock-backend"; -#elif defined(__unix__) +#else path /= ".fediblock-backend"; #endif fs::create_directories(path); @@ -97,7 +97,7 @@ string get_access_token() stringstream ss; ss << file.rdbuf(); - return ss.str().substr(0, ss.str().find('\n')); + return ss.str().substr(0, ss.str().find('\n')); // Remove trailing newline. } } // namespace FediBlock::files diff --git a/src/files.hpp b/src/files.hpp index d78136a..2dde43c 100644 --- a/src/files.hpp +++ b/src/files.hpp @@ -26,13 +26,13 @@ namespace FediBlock::files using std::string; -// Creates and returns the temporary directory. +// Create and return the temporary directory. [[nodiscard]] fs::path get_tmpdir(); // Remove the temporary directory. Throws runtime_error on error. void remove_tmpdir(); -// Returns the data directory and creates it if necessary. +// Return the data directory and create it if necessary. [[nodiscard]] fs::path get_datadir(); // Read and return access token. diff --git a/src/git.cpp b/src/git.cpp index d0bd9eb..9cfefa6 100644 --- a/src/git.cpp +++ b/src/git.cpp @@ -43,13 +43,13 @@ namespace FediBlock::git using std::ofstream; using std::runtime_error; -using std::stoull; using std::string; using std::string_view; using std::to_string; using std::uint64_t; git_repository *_repo{nullptr}; +constexpr string_view _clone_url{"git@schlomp.space:FediBlock/data.git"}; void check(int error) { @@ -64,23 +64,24 @@ int cred_acquire(git_cred **cred, const char * /*url*/, const char *username_from_url, unsigned int /*allowed_types*/, void * /*payload*/) { - return git_credential_ssh_key_new( - cred, username_from_url, (files::get_datadir() / "ssh_id.pub").c_str(), - (files::get_datadir() / "ssh_id").c_str(), nullptr); + const auto datadir{files::get_datadir()}; + + return git_credential_ssh_key_new(cred, username_from_url, + (datadir / "ssh_id.pub").c_str(), + (datadir / "ssh_id").c_str(), nullptr); } void clone() { git_clone_options options = GIT_CLONE_OPTIONS_INIT; options.fetch_opts.callbacks.credentials = cred_acquire; - check(git_clone(&_repo, "git@schlomp.space:FediBlock/data.git", + check(git_clone(&_repo, _clone_url.data(), (files::get_tmpdir() / "repo").c_str(), &options)); } void create_branch() { - const auto id{gitea::get_last_pr_number() + 1}; - const string branch_name = "web-" + std::to_string(id); + const string branch_name{get_branch_name()}; const string ref_name{"refs/heads/" + branch_name}; git_oid oid_parent; git_commit *commit; @@ -101,14 +102,12 @@ void create_branch() void commit(const cgi::entry_type &entry) { // Write files. - const auto id{gitea::get_last_pr_number() + 1}; - const string basename{files::get_tmpdir() / "repo" - / ("web-" + to_string(id))}; + const string basename{files::get_tmpdir() / "repo" / get_branch_name()}; ofstream file(basename + ".json"); if (!file.good()) { - throw; // FIXME + throw runtime_error{"Could not create file: " + basename + ".json"}; } file << json::to_json(entry); file.close(); @@ -158,15 +157,15 @@ void commit(const cgi::entry_type &entry) git_index_free(index); git_signature_free(sig); git_tree_free(tree); + git_object_free(parent); + git_reference_free(ref); } void push() { git_push_options options; git_remote *remote{nullptr}; - const string branch_name{"web-" - + std::to_string(gitea::get_last_pr_number() + 1)}; - string refspec_str{("refs/heads/" + branch_name)}; + string refspec_str{("refs/heads/" + get_branch_name())}; char *refspec = &refspec_str[0]; const git_strarray refspecs = {&refspec, 1}; @@ -175,6 +174,14 @@ void push() options.callbacks.credentials = cred_acquire; check(git_remote_push(remote, &refspecs, &options)); + + git_remote_free(remote); +} + +string get_branch_name() +{ + const auto id{gitea::get_last_pr_number() + 1}; + return "web-" + to_string(id); } } // namespace FediBlock::git diff --git a/src/git.hpp b/src/git.hpp index 4afa25c..7cf86bb 100644 --- a/src/git.hpp +++ b/src/git.hpp @@ -22,13 +22,15 @@ #include #include +#include namespace FediBlock::git { +using std::string; using std::uint64_t; -// Throws runtime_error on error. +// Throw runtime_error on error. void check(int error); // Acquire credentials for SSH. @@ -48,6 +50,9 @@ void commit(const cgi::entry_type &entry); // Push the new commit. void push(); +// Get the name of the branch we use. +string get_branch_name(); + } // namespace FediBlock::git #endif // FEDIBLOCK_BACKEND_GIT_HPP diff --git a/src/gitea.cpp b/src/gitea.cpp index d750d2e..f8a1dcf 100644 --- a/src/gitea.cpp +++ b/src/gitea.cpp @@ -38,6 +38,8 @@ using std::to_string; CURL *_connection; string _curl_buffer_body; uint64_t _last_pr_number{0}; +constexpr string_view _forge_baseurl{"https://schlomp.space"}; +constexpr string_view _repo_name{"FediBlock/data"}; void init() { @@ -65,7 +67,6 @@ void init() throw runtime_error{"Could not add headers"}; } - // Write the body into the void. // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) curl_easy_setopt(_connection, CURLOPT_WRITEFUNCTION, writer_body); } @@ -91,7 +92,7 @@ string api_request(const http_method method, const string_view path, const string_view body) { CURLcode code; - string url{string("https://schlomp.space") += path}; + string url{string(_forge_baseurl) += path}; _curl_buffer_body.clear(); switch (method) @@ -106,7 +107,6 @@ string api_request(const http_method method, const string_view path, } case http_method::POST: { - // Prepare body to send. // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) curl_easy_setopt(_connection, CURLOPT_POSTFIELDSIZE, body.size()); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) @@ -145,7 +145,8 @@ string api_request(const http_method method, const string_view path, void pull_request(const string_view branch, const cgi::entry_type &entry) { - api_request(http_method::POST, "/api/v1/repos/FediBlock/data/pulls", + api_request(http_method::POST, + (string("/api/v1/repos/") += _repo_name) += "/pulls", json::pull_request_body(branch, entry)); ++_last_pr_number; } diff --git a/src/json.hpp b/src/json.hpp index e0501ea..69858d1 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -31,6 +31,7 @@ using std::string_view; // Convert an entry_type into a JSON string. [[nodiscard]] string to_json(const cgi::entry_type &entry); +// Return the body for a pull request. [[nodiscard]] string pull_request_body(string_view branch, const cgi::entry_type &entry); diff --git a/src/main.cpp b/src/main.cpp index e7db5b9..7e6e09e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -50,12 +50,11 @@ int main() git::commit(entry); git::push(); - gitea::pull_request("web-" + to_string(gitea::get_last_pr_number() + 1), - entry); + gitea::pull_request(git::get_branch_name(), entry); cout << "Created pull request: <" << "https://schlomp.space/FediBlock/data/pulls/" - << gitea::get_last_pr_number() << ">\r\n"; + << gitea::get_last_pr_number() << ">.\r\n"; files::remove_tmpdir(); } @@ -63,6 +62,8 @@ int main() { cerr << e.what() << '\n'; cout << "An error happened: " << e.what() << "\r\n"; + cout << "Please report it at " + ".\r\n"; } gitea::cleanup();