Use PR numbers instead of branch names to determine IDs.
This commit is contained in:
parent
24d9e419fa
commit
b1224b82b5
42
src/git.cpp
42
src/git.cpp
|
@ -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};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
15
src/main.cpp
15
src/main.cpp
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue