Clean up everything.
continuous-integration/drone/push Build is passing Details

* More efficient.
* More readable.
* Errors are reported to the user.
This commit is contained in:
tastytea 2020-07-02 03:20:27 +02:00
parent a3fca80b29
commit f522c9ae45
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
8 changed files with 63 additions and 59 deletions

View File

@ -46,41 +46,30 @@ using std::vector;
entry_type parse_formdata() entry_type parse_formdata()
{ {
entry_type entry; 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"); cgicc::Cgicc cgi;
if (screenshot != cgi.getFiles().end()) 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. throw runtime_error{"Filesize too big"};
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};
}
} }
}
catch (const exception &e) const string filepath{files::get_tmpdir() / screenshot->getFilename()};
{ ofstream file{filepath, ios::binary};
cerr << e.what() << '\n'; if (!file.good())
// TODO: Make errors visible to the user in a helpful way. {
throw runtime_error{"Could not open temporary file: " + filepath};
}
screenshot->writeToStream(file);
entry.screenshot_filepath = filepath;
} }
return entry; return entry;
@ -90,7 +79,7 @@ vector<string> string_to_vector(const string_view str)
{ {
vector<string> vec; vector<string> vec;
stringstream input(str.data()); stringstream input{str.data()};
string element; string element;
while (getline(input, element, ',')) while (getline(input, element, ','))

View File

@ -76,7 +76,7 @@ fs::path get_datadir()
auto path{fs::path(env)}; auto path{fs::path(env)};
#if defined(__linux__) #if defined(__linux__)
path /= ".local/share/fediblock-backend"; path /= ".local/share/fediblock-backend";
#elif defined(__unix__) #else
path /= ".fediblock-backend"; path /= ".fediblock-backend";
#endif #endif
fs::create_directories(path); fs::create_directories(path);
@ -97,7 +97,7 @@ string get_access_token()
stringstream ss; stringstream ss;
ss << file.rdbuf(); 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 } // namespace FediBlock::files

View File

@ -26,13 +26,13 @@ namespace FediBlock::files
using std::string; using std::string;
// Creates and returns the temporary directory. // Create and return the temporary directory.
[[nodiscard]] fs::path get_tmpdir(); [[nodiscard]] fs::path get_tmpdir();
// Remove the temporary directory. Throws runtime_error on error. // Remove the temporary directory. Throws runtime_error on error.
void remove_tmpdir(); 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(); [[nodiscard]] fs::path get_datadir();
// Read and return access token. // Read and return access token.

View File

@ -43,13 +43,13 @@ namespace FediBlock::git
using std::ofstream; using std::ofstream;
using std::runtime_error; using std::runtime_error;
using std::stoull;
using std::string; using std::string;
using std::string_view; using std::string_view;
using std::to_string; using std::to_string;
using std::uint64_t; using std::uint64_t;
git_repository *_repo{nullptr}; git_repository *_repo{nullptr};
constexpr string_view _clone_url{"git@schlomp.space:FediBlock/data.git"};
void check(int error) 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*/, const char *username_from_url, unsigned int /*allowed_types*/,
void * /*payload*/) void * /*payload*/)
{ {
return git_credential_ssh_key_new( const auto datadir{files::get_datadir()};
cred, username_from_url, (files::get_datadir() / "ssh_id.pub").c_str(),
(files::get_datadir() / "ssh_id").c_str(), nullptr); return git_credential_ssh_key_new(cred, username_from_url,
(datadir / "ssh_id.pub").c_str(),
(datadir / "ssh_id").c_str(), nullptr);
} }
void clone() void clone()
{ {
git_clone_options options = GIT_CLONE_OPTIONS_INIT; git_clone_options options = GIT_CLONE_OPTIONS_INIT;
options.fetch_opts.callbacks.credentials = cred_acquire; 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)); (files::get_tmpdir() / "repo").c_str(), &options));
} }
void create_branch() void create_branch()
{ {
const auto id{gitea::get_last_pr_number() + 1}; const string branch_name{get_branch_name()};
const string branch_name = "web-" + std::to_string(id);
const string ref_name{"refs/heads/" + branch_name}; const string ref_name{"refs/heads/" + branch_name};
git_oid oid_parent; git_oid oid_parent;
git_commit *commit; git_commit *commit;
@ -101,14 +102,12 @@ void create_branch()
void commit(const cgi::entry_type &entry) void commit(const cgi::entry_type &entry)
{ {
// Write files. // Write files.
const auto id{gitea::get_last_pr_number() + 1}; const string basename{files::get_tmpdir() / "repo" / get_branch_name()};
const string basename{files::get_tmpdir() / "repo"
/ ("web-" + to_string(id))};
ofstream file(basename + ".json"); ofstream file(basename + ".json");
if (!file.good()) if (!file.good())
{ {
throw; // FIXME throw runtime_error{"Could not create file: " + basename + ".json"};
} }
file << json::to_json(entry); file << json::to_json(entry);
file.close(); file.close();
@ -158,15 +157,15 @@ void commit(const cgi::entry_type &entry)
git_index_free(index); git_index_free(index);
git_signature_free(sig); git_signature_free(sig);
git_tree_free(tree); git_tree_free(tree);
git_object_free(parent);
git_reference_free(ref);
} }
void push() void push()
{ {
git_push_options options; git_push_options options;
git_remote *remote{nullptr}; git_remote *remote{nullptr};
const string branch_name{"web-" string refspec_str{("refs/heads/" + get_branch_name())};
+ std::to_string(gitea::get_last_pr_number() + 1)};
string refspec_str{("refs/heads/" + branch_name)};
char *refspec = &refspec_str[0]; char *refspec = &refspec_str[0];
const git_strarray refspecs = {&refspec, 1}; const git_strarray refspecs = {&refspec, 1};
@ -175,6 +174,14 @@ void push()
options.callbacks.credentials = cred_acquire; options.callbacks.credentials = cred_acquire;
check(git_remote_push(remote, &refspecs, &options)); 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 } // namespace FediBlock::git

View File

@ -22,13 +22,15 @@
#include <git2.h> #include <git2.h>
#include <cstdint> #include <cstdint>
#include <string>
namespace FediBlock::git namespace FediBlock::git
{ {
using std::string;
using std::uint64_t; using std::uint64_t;
// Throws runtime_error on error. // Throw runtime_error on error.
void check(int error); void check(int error);
// Acquire credentials for SSH. // Acquire credentials for SSH.
@ -48,6 +50,9 @@ void commit(const cgi::entry_type &entry);
// Push the new commit. // Push the new commit.
void push(); void push();
// Get the name of the branch we use.
string get_branch_name();
} // namespace FediBlock::git } // namespace FediBlock::git
#endif // FEDIBLOCK_BACKEND_GIT_HPP #endif // FEDIBLOCK_BACKEND_GIT_HPP

View File

@ -38,6 +38,8 @@ using std::to_string;
CURL *_connection; CURL *_connection;
string _curl_buffer_body; string _curl_buffer_body;
uint64_t _last_pr_number{0}; uint64_t _last_pr_number{0};
constexpr string_view _forge_baseurl{"https://schlomp.space"};
constexpr string_view _repo_name{"FediBlock/data"};
void init() void init()
{ {
@ -65,7 +67,6 @@ void init()
throw runtime_error{"Could not add headers"}; throw runtime_error{"Could not add headers"};
} }
// Write the body into the void.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
curl_easy_setopt(_connection, CURLOPT_WRITEFUNCTION, writer_body); 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) const string_view body)
{ {
CURLcode code; CURLcode code;
string url{string("https://schlomp.space") += path}; string url{string(_forge_baseurl) += path};
_curl_buffer_body.clear(); _curl_buffer_body.clear();
switch (method) switch (method)
@ -106,7 +107,6 @@ string api_request(const http_method method, const string_view path,
} }
case http_method::POST: case http_method::POST:
{ {
// Prepare body to send.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
curl_easy_setopt(_connection, CURLOPT_POSTFIELDSIZE, body.size()); curl_easy_setopt(_connection, CURLOPT_POSTFIELDSIZE, body.size());
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) // 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) 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)); json::pull_request_body(branch, entry));
++_last_pr_number; ++_last_pr_number;
} }

View File

@ -31,6 +31,7 @@ using std::string_view;
// Convert an entry_type into a JSON string. // Convert an entry_type into a JSON string.
[[nodiscard]] string to_json(const cgi::entry_type &entry); [[nodiscard]] string to_json(const cgi::entry_type &entry);
// Return the body for a pull request.
[[nodiscard]] string pull_request_body(string_view branch, [[nodiscard]] string pull_request_body(string_view branch,
const cgi::entry_type &entry); const cgi::entry_type &entry);

View File

@ -50,12 +50,11 @@ int main()
git::commit(entry); git::commit(entry);
git::push(); git::push();
gitea::pull_request("web-" + to_string(gitea::get_last_pr_number() + 1), gitea::pull_request(git::get_branch_name(), entry);
entry);
cout << "Created pull request: <" cout << "Created pull request: <"
<< "https://schlomp.space/FediBlock/data/pulls/" << "https://schlomp.space/FediBlock/data/pulls/"
<< gitea::get_last_pr_number() << ">\r\n"; << gitea::get_last_pr_number() << ">.\r\n";
files::remove_tmpdir(); files::remove_tmpdir();
} }
@ -63,6 +62,8 @@ int main()
{ {
cerr << e.what() << '\n'; cerr << e.what() << '\n';
cout << "An error happened: " << e.what() << "\r\n"; cout << "An error happened: " << e.what() << "\r\n";
cout << "Please report it at "
"<https://schlomp.space/FediBlock/backend/issues>.\r\n";
} }
gitea::cleanup(); gitea::cleanup();