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 "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};
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
15
src/main.cpp
15
src/main.cpp
|
@ -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;
|
||||
}
|
||||
|
|
Reference in New Issue