use crate::context::CommandContext;
use crate::display::short_id;
use crate::models::{Problem, Solution};
use crate::storage::MetadataStore;
use crate::sync::github::GitHubProvider;
use crate::sync::SyncProvider;
pub fn do_create_issue(store: &MetadataStore, problem: &mut Problem) -> crate::error::Result<()> {
let config = store.load_config()?;
let repo_root = store.jj_client.repo_root();
let provider = GitHubProvider::from_config(repo_root, &config.github)?;
let number = provider.create_issue(problem)?;
problem.github_issue = Some(number);
store.save_problem(problem)?;
println!(" (auto-created GitHub issue #{})", number);
Ok(())
}
pub fn do_close_issue(store: &MetadataStore, problem: &Problem) -> crate::error::Result<()> {
let issue_number = match problem.github_issue {
Some(n) => n,
None => return Ok(()),
};
let config = store.load_config()?;
let repo_root = store.jj_client.repo_root();
let provider = GitHubProvider::from_config(repo_root, &config.github)?;
provider.close_issue(issue_number)?;
println!(" (auto-closed GitHub issue #{})", issue_number);
Ok(())
}
pub fn do_create_or_update_pr(
store: &MetadataStore,
solution: &mut Solution,
) -> crate::error::Result<()> {
let config = store.load_config()?;
let repo_root = store.jj_client.repo_root();
let provider = GitHubProvider::from_config(repo_root, &config.github)?;
let problem = store.load_problem(&solution.problem_id)?;
if let Some(pr_number) = solution.github_pr {
println!(" (GitHub PR #{} will be updated on push)", pr_number);
return Ok(());
}
if solution.change_ids.is_empty() {
return Ok(());
}
let sid = short_id(&solution.id);
let branch = format!("jjj/s-{}", sid);
let pr_number = provider.create_pr(solution, &problem, &branch)?;
solution.github_pr = Some(pr_number);
solution.github_branch = Some(branch);
store.with_metadata("Link GitHub PR to solution", || {
store.save_solution(solution)
})?;
println!(" (auto-created GitHub PR #{})", pr_number);
Ok(())
}
pub fn do_merge_pr(store: &MetadataStore, solution: &Solution) -> crate::error::Result<()> {
let pr_number = match solution.github_pr {
Some(n) => n,
None => return Ok(()),
};
let config = store.load_config()?;
let repo_root = store.jj_client.repo_root();
let provider = GitHubProvider::from_config(repo_root, &config.github)?;
provider.merge_pr(pr_number)?;
println!(" (auto-merged GitHub PR #{})", pr_number);
Ok(())
}
pub fn auto_create_issue(ctx: &CommandContext, problem: &mut Problem) {
let config = match ctx.store.load_config() {
Ok(c) => c,
Err(_) => return,
};
if !config.github.auto_push {
return;
}
if let Err(e) = do_create_issue(&ctx.store, problem) {
eprintln!("Warning: auto-push to GitHub failed: {}", e);
}
}
pub fn auto_close_issue(ctx: &CommandContext, problem: &Problem, force: bool) {
let config = match ctx.store.load_config() {
Ok(c) => c,
Err(_) => return,
};
if !force && !config.github.auto_push && !config.github.auto_close_on_solve {
return;
}
if let Err(e) = do_close_issue(&ctx.store, problem) {
eprintln!("Warning: auto-close GitHub issue failed: {}", e);
}
}