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 "files.hpp"
#include "fs-compat.hpp"
#include "gitea.hpp"
#include "json.hpp"
#include <git2.h>
@ -76,43 +77,9 @@ void clone()
(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()
{
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 ref_name{"refs/heads/" + branch_name};
git_oid oid_parent;
@ -134,7 +101,7 @@ void create_branch()
void commit(const cgi::entry_type &entry)
{
// 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"
/ ("web-" + to_string(id))};
@ -197,7 +164,8 @@ void push()
{
git_push_options options;
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)};
char *refspec = &refspec_str[0];
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.
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.
void create_branch();

View File

@ -17,10 +17,12 @@
#include "gitea.hpp"
#include "cgi.hpp"
#include "curl/curl.h"
#include "files.hpp"
#include "json.hpp"
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <stdexcept>
#include <string>
#include <string_view>
@ -34,6 +36,8 @@ using std::string_view;
using std::to_string;
CURL *_connection;
string _curl_buffer_body;
uint64_t _last_pr_number{0};
void init()
{
@ -63,7 +67,7 @@ void init()
// Write the body into the void.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
curl_easy_setopt(_connection, CURLOPT_WRITEFUNCTION, noop_cb);
curl_easy_setopt(_connection, CURLOPT_WRITEFUNCTION, writer_body);
}
void cleanup()
@ -71,31 +75,55 @@ void cleanup()
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;
}
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;
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)
code = curl_easy_setopt(_connection, CURLOPT_URL, url.c_str());
if (code != CURLE_OK)
{
throw runtime_error{"Couldn't set URL"};
}
// 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"};
throw runtime_error{"Couldn't set URL: " + to_string(code)};
}
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)
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
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)};
}
return _curl_buffer_body;
}
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));
++_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

View File

@ -20,14 +20,21 @@
#include "cgi.hpp"
#include <cstdint>
#include <string>
#include <string_view>
namespace FediBlock::gitea
{
using std::string;
using std::string_view;
using std::uint64_t;
using std::string_view;
enum class http_method
{
GET,
POST
};
// Initialize the curl connection handle.
void init();
@ -35,16 +42,17 @@ void init();
// Clean up the curl connection handle.
void cleanup();
// No-op write function. Discards HTTP response bodies.
size_t noop_cb(void *ptr, size_t size, size_t nmemb, void *data);
// Write HTTP response to string.
size_t writer_body(char *data, size_t size, size_t nmemb);
// 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.
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

View File

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