Module: GT::GitHub
- Defined in:
- lib/gt/github.rb
Constant Summary collapse
- STACK_MARKER =
"<!-- gt-stack -->"
Class Method Summary collapse
- .find_stack_comment_id(pr_number) ⇒ Object
- .merged_into(branch) ⇒ Object
- .pr_merged?(branch) ⇒ Boolean
-
.pr_numbers(branches) ⇒ Object
Returns { “branch-name” => pr_number } for all open PRs whose branch is in
branches. - .pr_retarget(branch, base) ⇒ Object
- .repo_url ⇒ Object
- .stack_comment_body(branches, current_branch, pr_nums, base_url = nil) ⇒ Object
- .update_stack_comments(branches) ⇒ Object
- .upsert_stack_comment(pr_number, body) ⇒ Object
Class Method Details
.find_stack_comment_id(pr_number) ⇒ Object
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/gt/github.rb', line 82 def find_stack_comment_id(pr_number) out, _, status = Open3.capture3( "gh api repos/{owner}/{repo}/issues/#{pr_number}/comments " \ "--jq '[.[] | select(.body | contains(\"#{STACK_MARKER}\")) | .id] | first'" ) return nil unless status.success? id = out.strip (id.empty? || id == "null") ? nil : id.to_i end |
.merged_into(branch) ⇒ Object
28 29 30 31 32 33 34 |
# File 'lib/gt/github.rb', line 28 def merged_into(branch) out, _, status = Open3.capture3("gh pr view #{branch} --json mergeCommit --jq .mergeCommit.oid") return nil unless status.success? sha = out.strip sha.empty? ? nil : sha end |
.pr_merged?(branch) ⇒ Boolean
9 10 11 12 13 14 15 16 |
# File 'lib/gt/github.rb', line 9 def pr_merged?(branch) out, _, status = Open3.capture3("gh pr view #{branch} --json state --jq .state") return false unless status.success? out.strip == "MERGED" rescue Errno::ENOENT false end |
.pr_numbers(branches) ⇒ Object
Returns { “branch-name” => pr_number } for all open PRs whose branch is in branches. Uses a single gh pr list call. Returns {} on any failure.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/gt/github.rb', line 50 def pr_numbers(branches) out, _, status = Open3.capture3( "gh pr list --json number,headRefName " \ "--jq 'map({(.headRefName): .number}) | add'" ) return {} unless status.success? data = JSON.parse(out.strip) return {} unless data.is_a?(Hash) data.select { |branch, _| branches.include?(branch) } rescue JSON::ParserError, Errno::ENOENT {} end |
.pr_retarget(branch, base) ⇒ Object
18 19 20 21 22 23 24 25 26 |
# File 'lib/gt/github.rb', line 18 def pr_retarget(branch, base) out, err, status = Open3.capture3("gh pr edit #{branch} --base #{base}") unless status.success? GT::UI.warn("Failed to retarget PR '#{branch}' to '#{base}': #{(err.strip.empty? ? out : err).strip}") end status.success? rescue Errno::ENOENT false end |
.repo_url ⇒ Object
38 39 40 41 42 43 44 45 46 |
# File 'lib/gt/github.rb', line 38 def repo_url out, _, status = Open3.capture3("gh repo view --json url --jq .url") return nil unless status.success? url = out.strip url.empty? ? nil : url rescue Errno::ENOENT nil end |
.stack_comment_body(branches, current_branch, pr_nums, base_url = nil) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/gt/github.rb', line 65 def stack_comment_body(branches, current_branch, pr_nums, base_url = nil) lines = ["[gt](https://github.com/grodowski/gt) stack", ""] branches.each do |branch| num = pr_nums[branch] if branch == current_branch pr_url = base_url && num ? "#{base_url}/pull/#{num}" : (num ? "##{num}" : nil) lines << (pr_url ? "- 👉 #{pr_url}" : "- 👉 **#{branch}**") else pr_url = base_url && num ? "#{base_url}/pull/#{num}" : (num ? "##{num}" : nil) lines << (pr_url ? "- #{pr_url}" : "- #{branch}") end end lines << "" lines << STACK_MARKER lines.join("\n") end |
.update_stack_comments(branches) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/gt/github.rb', line 109 def update_stack_comments(branches) nums = pr_numbers(branches) url = repo_url branches[1..].each do |branch| next unless nums[branch] body = stack_comment_body(branches, branch, nums, url) upsert_stack_comment(nums[branch], body) end rescue StandardError # Best-effort — silently skip if GitHub API is unavailable end |
.upsert_stack_comment(pr_number, body) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/gt/github.rb', line 93 def upsert_stack_comment(pr_number, body) json = JSON.generate({ body: body }) existing_id = find_stack_comment_id(pr_number) if existing_id Open3.capture3( "gh api repos/{owner}/{repo}/issues/comments/#{existing_id} -X PATCH --input -", stdin_data: json ) else Open3.capture3( "gh api repos/{owner}/{repo}/issues/#{pr_number}/comments --input -", stdin_data: json ) end end |