mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
added git fetch and checkout
fixed has_remote trying to fetch stuff pr: implemented remote method
This commit is contained in:
@@ -40,7 +40,7 @@ void help(const clipp::group& g, const std::string& more)
|
||||
<< "Options:\n"
|
||||
<< clipp::documentation(g, options_df)
|
||||
<< "\n\n"
|
||||
<< "To use global options with command options, make sure command "
|
||||
<< "To use global options with command options, make sure command \n"
|
||||
<< "options are together, with no global options in the middle.\n";
|
||||
|
||||
if (!more.empty())
|
||||
|
||||
+3
-3
@@ -244,6 +244,7 @@ public:
|
||||
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
std::string do_doc() override;
|
||||
int do_run() override;
|
||||
|
||||
private:
|
||||
@@ -254,13 +255,12 @@ private:
|
||||
std::pair<const modorganizer*, std::string> parse_pr(
|
||||
const std::string& pr) const;
|
||||
|
||||
int get_pr_branch();
|
||||
|
||||
int do_apply();
|
||||
int do_remote();
|
||||
int do_fetch();
|
||||
|
||||
url get_diff_url(const modorganizer* task, std::string pr);
|
||||
nlohmann::json get_pr_info(const modorganizer* task, const std::string& pr);
|
||||
url get_diff_url(const modorganizer* task, const std::string& pr);
|
||||
};
|
||||
|
||||
|
||||
|
||||
+112
-56
@@ -5,6 +5,13 @@
|
||||
namespace mob
|
||||
{
|
||||
|
||||
std::string read_file(const fs::path& p)
|
||||
{
|
||||
std::ifstream t(p);
|
||||
return {std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>()};
|
||||
}
|
||||
|
||||
|
||||
pr_command::pr_command()
|
||||
: command(requires_options | handle_sigint), method_("apply")
|
||||
{
|
||||
@@ -40,6 +47,20 @@ clipp::group pr_command::do_group()
|
||||
% "PR to apply, must be `task/pr`, such as `modorganizer/123`";
|
||||
}
|
||||
|
||||
std::string pr_command::do_doc()
|
||||
{
|
||||
return
|
||||
"Methods:\n"
|
||||
" - apply: retrieves the .diff file for this PR and runs\n"
|
||||
" `git apply` with it, which patches the local repo and\n"
|
||||
" leaves the changes uncommitted\n"
|
||||
"\n"
|
||||
" - remote: adds a new remote to the local repo that matches the \n"
|
||||
" PR's origin and checks out the PR's branch from it\n"
|
||||
"\n"
|
||||
" - fetch: ??";
|
||||
}
|
||||
|
||||
int pr_command::do_run()
|
||||
{
|
||||
if (method_ == "apply")
|
||||
@@ -96,63 +117,8 @@ std::pair<const modorganizer*, std::string> pr_command::parse_pr(
|
||||
return {task, pr_number};
|
||||
}
|
||||
|
||||
int pr_command::get_pr_branch()
|
||||
{
|
||||
if (pr_.empty())
|
||||
return 0;
|
||||
|
||||
if (github_token_.empty())
|
||||
{
|
||||
u8cerr << "missing --github-token\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto&& [task, pr] = parse_pr(pr_);
|
||||
|
||||
if (!task)
|
||||
return 1;
|
||||
|
||||
const url u(::fmt::format(
|
||||
"https://api.github.com/repos/{}/{}/pulls/{}",
|
||||
task->org(), task->repo(), pr));
|
||||
|
||||
curl_downloader dl;
|
||||
|
||||
dl
|
||||
.url(u)
|
||||
.header("Authorization", "token " + github_token_)
|
||||
.start()
|
||||
.join();
|
||||
|
||||
if (!dl.ok())
|
||||
{
|
||||
u8cerr << "getting pr failed\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
const auto output = dl.steal_output();
|
||||
u8cout << output << "\n";
|
||||
|
||||
|
||||
nlohmann::json j(output);
|
||||
|
||||
const std::string diff_url = j["diff_url"];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
url pr_command::get_diff_url(const modorganizer* task, std::string pr)
|
||||
{
|
||||
return ::fmt::format(
|
||||
"https://github.com/{}/{}/pull/{}.diff",
|
||||
task->org(), task->repo(), pr);
|
||||
}
|
||||
|
||||
int pr_command::do_apply()
|
||||
{
|
||||
if (pr_.empty())
|
||||
return 0;
|
||||
|
||||
auto&& [task, pr] = parse_pr(pr_);
|
||||
if (!task)
|
||||
return 1;
|
||||
@@ -180,7 +146,59 @@ int pr_command::do_apply()
|
||||
|
||||
int pr_command::do_remote()
|
||||
{
|
||||
return 0;
|
||||
auto&& [task, pr] = parse_pr(pr_);
|
||||
if (!task)
|
||||
return 1;
|
||||
|
||||
try
|
||||
{
|
||||
u8cout << "looking for pr " << pr << " in " << task->name() << "\n";
|
||||
|
||||
//const auto json = get_pr_info(task, pr);
|
||||
auto json = nlohmann::json::parse(read_file("c:\\tmp\\" + pr + ".json"));
|
||||
if (json.empty())
|
||||
return 1;
|
||||
|
||||
const std::string repo = json["head"]["repo"]["name"];
|
||||
const std::string org = json["head"]["repo"]["owner"]["login"];
|
||||
const std::string remote_name = org;
|
||||
const std::string branch = json["head"]["ref"];
|
||||
|
||||
u8cout
|
||||
<< "found pr: "
|
||||
<< "repo=" << repo << " "
|
||||
<< "org=" << org << " "
|
||||
<< "branch=" << branch << "\n";
|
||||
|
||||
if (git::has_remote(task->this_source_path(), remote_name))
|
||||
{
|
||||
u8cout << "remote already exists\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
u8cout << "adding remote " << remote_name << "\n";
|
||||
|
||||
git::add_remote(
|
||||
task->this_source_path(),
|
||||
remote_name, org, {}, false,
|
||||
"https://github.com/{}/{}");
|
||||
}
|
||||
|
||||
u8cout << "fetching from " << remote_name << "\n";
|
||||
git::fetch(task->this_source_path(), remote_name, branch);
|
||||
|
||||
u8cout << "checking out " << remote_name << "/" << branch << "\n";
|
||||
git::checkout(
|
||||
task->this_source_path(),
|
||||
::fmt::format("{}/{}", remote_name, branch));
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
u8cerr << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int pr_command::do_fetch()
|
||||
@@ -188,4 +206,42 @@ int pr_command::do_fetch()
|
||||
return 0;
|
||||
}
|
||||
|
||||
url pr_command::get_diff_url(const modorganizer* task, const std::string& pr)
|
||||
{
|
||||
return ::fmt::format(
|
||||
"https://github.com/{}/{}/pull/{}.diff",
|
||||
task->org(), task->repo(), pr);
|
||||
}
|
||||
|
||||
nlohmann::json pr_command::get_pr_info(
|
||||
const modorganizer* task, const std::string& pr)
|
||||
{
|
||||
if (github_token_.empty())
|
||||
{
|
||||
u8cerr << "missing --github-token\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
const url u(::fmt::format(
|
||||
"https://api.github.com/repos/{}/{}/pulls/{}",
|
||||
task->org(), task->repo(), pr));
|
||||
|
||||
curl_downloader dl;
|
||||
|
||||
dl
|
||||
.url(u)
|
||||
.header("Authorization", "token " + github_token_)
|
||||
.start()
|
||||
.join();
|
||||
|
||||
if (!dl.ok())
|
||||
{
|
||||
u8cerr << "failed to get pr info from github\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto output = dl.steal_output();
|
||||
return nlohmann::json::parse(output);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
+60
-8
@@ -7,6 +7,8 @@ namespace mob
|
||||
{
|
||||
|
||||
constexpr git::ops no_op(git::ops(0));
|
||||
const std::string default_github_url_pattern = "git@github.com:{}/{}";
|
||||
|
||||
|
||||
git::git(ops o)
|
||||
: basic_process_runner("git"), op_(o)
|
||||
@@ -68,9 +70,17 @@ void git::ignore_ts(const fs::path& repo, bool b)
|
||||
.do_ignore_ts();
|
||||
}
|
||||
|
||||
bool git::has_remote(const fs::path& repo, const std::string& name)
|
||||
{
|
||||
git g(no_op);
|
||||
g.root(repo);
|
||||
return g.has_remote(name);
|
||||
}
|
||||
|
||||
void git::add_remote(
|
||||
const fs::path& repo, const std::string& remote_name,
|
||||
const std::string& username, const std::string& key, bool push_default)
|
||||
const std::string& username, const std::string& key, bool push_default,
|
||||
const std::string& url_pattern)
|
||||
{
|
||||
git g(no_op);
|
||||
g.root(repo);
|
||||
@@ -79,7 +89,7 @@ void git::add_remote(
|
||||
|
||||
if (!g.has_remote(remote_name))
|
||||
{
|
||||
g.add_remote(remote_name, make_url(username, gf));
|
||||
g.add_remote(remote_name, make_url(username, gf, url_pattern));
|
||||
|
||||
if (push_default)
|
||||
g.set_config("remote.pushdefault", remote_name);
|
||||
@@ -130,6 +140,45 @@ void git::apply(const std::string& diff)
|
||||
execute_and_join();
|
||||
}
|
||||
|
||||
void git::fetch(
|
||||
const fs::path& p, const std::string& remote, const std::string& branch)
|
||||
{
|
||||
git g(no_op);
|
||||
g.root(p);
|
||||
g.fetch(remote, branch);
|
||||
}
|
||||
|
||||
void git::fetch(const std::string& remote, const std::string& branch)
|
||||
{
|
||||
process_ = make_process()
|
||||
.arg("fetch")
|
||||
.arg("-q")
|
||||
.arg(remote)
|
||||
.arg(branch)
|
||||
.cwd(root_);
|
||||
|
||||
execute_and_join();
|
||||
}
|
||||
|
||||
void git::checkout(const fs::path& p, const std::string& what)
|
||||
{
|
||||
git g(no_op);
|
||||
g.root(p);
|
||||
g.checkout(what);
|
||||
}
|
||||
|
||||
void git::checkout(const std::string& what)
|
||||
{
|
||||
process_ = make_process()
|
||||
.arg("-c", "advice.detachedHead=false")
|
||||
.arg("checkout")
|
||||
.arg("-q")
|
||||
.arg(what)
|
||||
.cwd(root_);
|
||||
|
||||
execute_and_join();
|
||||
}
|
||||
|
||||
fs::path git::binary()
|
||||
{
|
||||
return conf::tool_by_name("git");
|
||||
@@ -447,9 +496,8 @@ bool git::has_remote(const std::string& name)
|
||||
process_ = make_process()
|
||||
.flags(process::allow_failure)
|
||||
.stderr_level(context::level::debug)
|
||||
.arg("remote")
|
||||
.arg("show")
|
||||
.arg(name)
|
||||
.arg("config")
|
||||
.arg("remote." + name + ".url")
|
||||
.cwd(root_);
|
||||
|
||||
return (execute_and_join() == 0);
|
||||
@@ -613,9 +661,13 @@ std::string git::git_file()
|
||||
}
|
||||
|
||||
std::string git::make_url(
|
||||
const std::string& org, const std::string& git_file)
|
||||
{
|
||||
return "git@github.com:" + org + "/" + git_file;
|
||||
const std::string& org, const std::string& git_file,
|
||||
const std::string& url_pattern)
|
||||
{
|
||||
const std::string pattern =
|
||||
url_pattern.empty() ? default_github_url_pattern : url_pattern;
|
||||
|
||||
return fmt::format(pattern, org, git_file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+11
-2
@@ -174,16 +174,22 @@ public:
|
||||
|
||||
static void ignore_ts(const fs::path& repo, bool b);
|
||||
|
||||
static bool has_remote(const fs::path& repo, const std::string& name);
|
||||
|
||||
static void add_remote(
|
||||
const fs::path& repo, const std::string& remote_name,
|
||||
const std::string& org, const std::string& key,
|
||||
bool push_default);
|
||||
bool push_default, const std::string& url_pattern={});
|
||||
|
||||
static bool is_git_repo(const fs::path& p);
|
||||
static bool branch_exists(const mob::url& u, const std::string& name);
|
||||
static void init_repo(const fs::path& p);
|
||||
|
||||
static void apply(const fs::path& p, const std::string& diff);
|
||||
static void fetch(
|
||||
const fs::path& p,
|
||||
const std::string& remote, const std::string& branch);
|
||||
static void checkout(const fs::path& p, const std::string& what);
|
||||
|
||||
|
||||
git& url(const mob::url& u);
|
||||
@@ -240,6 +246,8 @@ private:
|
||||
void set_remote_push(const std::string& remote, const std::string& url);
|
||||
void set_assume_unchanged(const fs::path& relative_file, bool on);
|
||||
void apply(const std::string& diff);
|
||||
void fetch(const std::string& remote, const std::string& branch);
|
||||
void checkout(const std::string& what);
|
||||
bool is_repo();
|
||||
bool branch_exists();
|
||||
bool has_uncommitted_changes();
|
||||
@@ -249,7 +257,8 @@ private:
|
||||
std::string git_file();
|
||||
|
||||
static std::string make_url(
|
||||
const std::string& org, const std::string& git_file);
|
||||
const std::string& org, const std::string& git_file,
|
||||
const std::string& url_pattern={});
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user