Use PR numbers instead of branch names to determine IDs.

This commit is contained in:
tastytea 2020-07-02 01:17:08 +02:00
parent 24d9e419fa
commit b1224b82b5
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
5 changed files with 93 additions and 71 deletions

View File

@ -17,6 +17,7 @@
#include "git.hpp" #include "git.hpp"
#include "files.hpp" #include "files.hpp"
#include "fs-compat.hpp" #include "fs-compat.hpp"
#include "gitea.hpp"
#include "json.hpp" #include "json.hpp"
#include <git2.h> #include <git2.h>
@ -76,43 +77,9 @@ void clone()
(files::get_tmpdir() / "repo").c_str(), &options)); (files::get_tmpdir() / "repo").c_str(), &options));
} }
uint64_t get_last_id()
{
constexpr string_view branch_prefix{"web-"};
uint64_t id{0};
git_branch_iterator *it;
if (git_branch_iterator_new(&it, _repo, GIT_BRANCH_REMOTE) == 0)
{
git_reference *ref;
git_branch_t type;
while (git_branch_next(&ref, &type, it) == 0)
{
const char *out{nullptr};
git_branch_name(&out, ref);
const string branch_name{out};
size_t pos{branch_name.find(branch_prefix)};
if (pos != string::npos)
{
pos += branch_prefix.size();
uint64_t newid{stoull(branch_name.substr(pos))};
if (newid > id)
{
id = newid;
}
}
git_reference_free(ref);
}
git_branch_iterator_free(it);
}
return id;
}
void create_branch() void create_branch()
{ {
const auto id{get_last_id() + 1}; const auto id{gitea::get_last_pr_number() + 1};
const string branch_name = "web-" + std::to_string(id); 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;
@ -134,7 +101,7 @@ void create_branch()
void commit(const cgi::entry_type &entry) void commit(const cgi::entry_type &entry)
{ {
// Write files. // Write files.
const auto id{get_last_id() + 1}; const auto id{gitea::get_last_pr_number() + 1};
const string basename{files::get_tmpdir() / "repo" const string basename{files::get_tmpdir() / "repo"
/ ("web-" + to_string(id))}; / ("web-" + to_string(id))};
@ -197,7 +164,8 @@ void push()
{ {
git_push_options options; git_push_options options;
git_remote *remote{nullptr}; git_remote *remote{nullptr};
const string branch_name{"web-" + std::to_string(get_last_id() + 1)}; 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/" + branch_name)};
char *refspec = &refspec_str[0]; char *refspec = &refspec_str[0];
const git_strarray refspecs = {&refspec, 1}; const git_strarray refspecs = {&refspec, 1};

View File

@ -39,10 +39,6 @@ int cred_acquire(git_cred **cred, const char *url,
// Clone the git repo. // Clone the git repo.
void clone(); void clone();
// FIXME: This will collapse when branches are deleted, use pull request IDs?
// Get highest branch-ID in use.
[[nodiscard]] uint64_t get_last_id();
// Make a new branch for preparing the pull request. // Make a new branch for preparing the pull request.
void create_branch(); void create_branch();

View File

@ -17,10 +17,12 @@
#include "gitea.hpp" #include "gitea.hpp"
#include "cgi.hpp" #include "cgi.hpp"
#include "curl/curl.h"
#include "files.hpp" #include "files.hpp"
#include "json.hpp" #include "json.hpp"
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <string_view> #include <string_view>
@ -34,6 +36,8 @@ using std::string_view;
using std::to_string; using std::to_string;
CURL *_connection; CURL *_connection;
string _curl_buffer_body;
uint64_t _last_pr_number{0};
void init() void init()
{ {
@ -63,7 +67,7 @@ void init()
// Write the body into the void. // Write the body into the void.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
curl_easy_setopt(_connection, CURLOPT_WRITEFUNCTION, noop_cb); curl_easy_setopt(_connection, CURLOPT_WRITEFUNCTION, writer_body);
} }
void cleanup() void cleanup()
@ -71,31 +75,55 @@ void cleanup()
curl_easy_cleanup(gitea::_connection); curl_easy_cleanup(gitea::_connection);
} }
size_t noop_cb(void * /*ptr*/, size_t size, size_t nmemb, void * /*data*/) size_t writer_body(char *data, size_t size, size_t nmemb)
{ {
if (data == nullptr)
{
return 0;
}
_curl_buffer_body.append(data, size * nmemb);
return size * nmemb; return size * nmemb;
} }
void api_request(const string_view path, const string_view body) string api_request(const http_method method, const string_view path,
const string_view body)
{ {
CURLcode code; CURLcode code;
const string url{string("https://schlomp.space") += path}; string url{string("https://schlomp.space") += path};
_curl_buffer_body.clear();
switch (method)
{
case http_method::GET:
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
curl_easy_setopt(_connection, CURLOPT_HTTPGET, 1L);
url += body;
break;
}
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)
code = curl_easy_setopt(_connection, CURLOPT_POSTFIELDS, body.data());
if (code != CURLE_OK)
{
throw runtime_error{"Couldn't set up data to send"};
}
break;
}
}
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
code = curl_easy_setopt(_connection, CURLOPT_URL, url.c_str()); code = curl_easy_setopt(_connection, CURLOPT_URL, url.c_str());
if (code != CURLE_OK) if (code != CURLE_OK)
{ {
throw runtime_error{"Couldn't set URL"}; throw runtime_error{"Couldn't set URL: " + to_string(code)};
}
// Prepare body to send.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
curl_easy_setopt(_connection, CURLOPT_POSTFIELDSIZE, body.size());
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
curl_easy_setopt(_connection, CURLOPT_POSTFIELDS, body.data());
if (code != CURLE_OK)
{
throw runtime_error{"Couldn't set up data to send"};
} }
code = curl_easy_perform(_connection); code = curl_easy_perform(_connection);
@ -107,16 +135,37 @@ void api_request(const string_view path, const string_view body)
long http_status; // NOLINT(google-runtime-int) long http_status; // NOLINT(google-runtime-int)
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
curl_easy_getinfo(_connection, CURLINFO_RESPONSE_CODE, &http_status); curl_easy_getinfo(_connection, CURLINFO_RESPONSE_CODE, &http_status);
if (http_status != 201) // 201 == Created. if (http_status < 200 || http_status >= 300)
{ {
throw runtime_error{"HTTP error: " + to_string(http_status)}; throw runtime_error{"HTTP error: " + to_string(http_status)};
} }
return _curl_buffer_body;
} }
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("/api/v1/repos/FediBlock/data/pulls", api_request(http_method::POST, "/api/v1/repos/FediBlock/data/pulls",
json::pull_request_body(branch, entry)); json::pull_request_body(branch, entry));
++_last_pr_number;
}
uint64_t get_last_pr_number()
{
if (_last_pr_number == 0)
{
const auto answer{api_request(http_method::GET,
"/api/v1/repos/FediBlock/data/pulls",
"?sort=recentupdate")};
if (answer == "[]")
{
return 0;
}
const auto json{nlohmann::json::parse(answer)};
_last_pr_number = json.front().front()["number"].get<uint64_t>();
}
return _last_pr_number;
} }
} // namespace FediBlock::gitea } // namespace FediBlock::gitea

View File

@ -20,14 +20,21 @@
#include "cgi.hpp" #include "cgi.hpp"
#include <cstdint> #include <cstdint>
#include <string>
#include <string_view> #include <string_view>
namespace FediBlock::gitea namespace FediBlock::gitea
{ {
using std::string;
using std::string_view;
using std::uint64_t; using std::uint64_t;
using std::string_view; enum class http_method
{
GET,
POST
};
// Initialize the curl connection handle. // Initialize the curl connection handle.
void init(); void init();
@ -35,16 +42,17 @@ void init();
// Clean up the curl connection handle. // Clean up the curl connection handle.
void cleanup(); void cleanup();
// No-op write function. Discards HTTP response bodies. // Write HTTP response to string.
size_t noop_cb(void *ptr, size_t size, size_t nmemb, void *data); size_t writer_body(char *data, size_t size, size_t nmemb);
// Make a HTTP POST request to the Gitea API. // Make a HTTP POST request to the Gitea API.
void api_request(string_view path, string_view body); string api_request(http_method method, string_view path, string_view body);
// Make a pull request. // Make a pull request.
void pull_request(string_view branch, const cgi::entry_type &entry); void pull_request(string_view branch, const cgi::entry_type &entry);
[[nodiscard]] uint64_t get_last_pr_id(); // Get number of last pull request.
[[nodiscard]] uint64_t get_last_pr_number();
} // namespace FediBlock::gitea } // namespace FediBlock::gitea

View File

@ -67,21 +67,22 @@ int main()
const cgi::entry_type entry{cgi::parse_formdata()}; const cgi::entry_type entry{cgi::parse_formdata()};
print_debug(entry); // print_debug(entry);
git_libgit2_init(); git_libgit2_init();
gitea::init();
git::clone(); git::clone();
git::create_branch(); git::create_branch();
git::commit(entry); git::commit(entry);
git::push(); git::push();
cout << "Created branch: " gitea::pull_request("web-" + to_string(gitea::get_last_pr_number() + 1),
<< "<https://schlomp.space/FediBlock/data/src/branch/web-" entry);
<< git::get_last_id() << ">\r\n";
gitea::init(); cout << "Created pull request: <"
gitea::pull_request("web-" + to_string(git::get_last_id()), entry); << "https://schlomp.space/FediBlock/data/pulls/"
<< gitea::get_last_pr_number() << ">\r\n";
try try
{ {
@ -92,8 +93,8 @@ int main()
cerr << e.what() << '\n'; cerr << e.what() << '\n';
} }
git_libgit2_shutdown();
gitea::cleanup(); gitea::cleanup();
git_libgit2_shutdown();
return 0; return 0;
} }