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 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> string_to_vector(const string_view str)
{
vector<string> vec;
stringstream input(str.data());
stringstream input{str.data()};
string element;
while (getline(input, element, ','))

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -22,13 +22,15 @@
#include <git2.h>
#include <cstdint>
#include <string>
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

View File

@ -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;
}

View File

@ -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);

View File

@ -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 "
"<https://schlomp.space/FediBlock/backend/issues>.\r\n";
}
gitea::cleanup();