Class: Agentilda::PullRequests
- Inherits:
-
Object
- Object
- Agentilda::PullRequests
- Defined in:
- lib/agentilda/pull_request.rb
Overview
Extracts the pull request roll-up from a plan folder.
Constant Summary collapse
- LINK =
A markdown link whose text may contain escaped brackets, because every title this tool writes now opens with
\[NNN.MM\]. Matching[^\]]+stops at the escaped]and loses the URL with it. /\[((?:\\.|[^\]\\])+)\]\((https?:[^)\s]+)\)/- STATES =
Canonical wording for the states we recognise, most specific first.
[ [/\bclosed\b|\bunmerged\b|\babandoned\b/i, "Closed 🔴"], [/\bmerged\b/i, "Merged 🟣"], [/\bdraft\b|\bwip\b/i, "WIP 🟡"], [/\bopen\b/i, "Open 🟡"] ].freeze
- CANDIDATES =
Filenames that may hold the table.
%w[pull-requests.md pull_requests.md prs.md].freeze
- FILENAME =
The file this class writes, and the first one it looks for.
CANDIDATES.first
Class Method Summary collapse
- .describe(pr) ⇒ String
-
.escape(text) ⇒ String
Three characters have to survive a round trip through a table cell.
-
.render(prs) ⇒ String
Render
pull-requests.mdfor a set of pull requests fetched from GitHub.
Instance Method Summary collapse
-
#all ⇒ Array<Agentilda::PullRequest>
Possibly empty.
-
#initialize(dir:) ⇒ PullRequests
constructor
A new instance of PullRequests.
Constructor Details
#initialize(dir:) ⇒ PullRequests
Returns a new instance of PullRequests.
114 115 116 |
# File 'lib/agentilda/pull_request.rb', line 114 def initialize(dir:) @dir = dir end |
Class Method Details
.describe(pr) ⇒ String
82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/agentilda/pull_request.rb', line 82 def self.describe(pr) body = pr[:body].to_s.strip body = "_No description was written on the pull request._" if body.empty? <<~MARKDOWN ### ##{pr[:number]} — #{pr[:title]} #{pr[:url]} #{body} MARKDOWN end |
.escape(text) ⇒ String
Three characters have to survive a round trip through a table cell.
A | ends the cell, and a title containing one is not unusual —
"fix: guard against a || b".
[ and ] are newer and cost more. Every title this tool writes now
opens with a plan number, so the row reads [[013.00] Ship it](url) —
and a markdown link whose text starts with [ does not parse. The
title came back with the URL glued to it and url came back nil, which
is not a cosmetic loss: it is every pull request link on the page, and
the attachment on every Linear issue.
109 110 111 |
# File 'lib/agentilda/pull_request.rb', line 109 def self.escape(text) text.to_s.gsub(/([\[\]|])/) { "\\#{$1}" }.gsub(/\s+/, " ").strip end |
.render(prs) ⇒ String
Render pull-requests.md for a set of pull requests fetched from GitHub.
The table is what #parse reads back and what the state machine judges
a folder by. The descriptions below it are for a reader — human or
agent — synthesizing a specification from work that already shipped:
the table says which pull requests, the bodies say what they did,
and a retroactive spec.md cannot be written from numbers alone.
Prose after the table is ignored by the parser, so the two can coexist in one file rather than needing a scratch file the folder rules forbid.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/agentilda/pull_request.rb', line 62 def self.render(prs) rows = prs.map { |pr| "| #{pr[:number]} | [#{escape(pr[:title])}](#{pr[:url]}) | #{pr[:state]} |" } <<~MARKDOWN # Pull Requests | Pull Request Number | Pull Request Name | Status | | ------------------: | :---------------- | -----: | #{rows.join("\n")} ## What these pull requests did #{prs.map { |pr| describe(pr) }.join("\n")} MARKDOWN end |
Instance Method Details
#all ⇒ Array<Agentilda::PullRequest>
Returns possibly empty.
119 |
# File 'lib/agentilda/pull_request.rb', line 119 def all = @all ||= parse |