@plot-pm/board 0.6.0-rc.2 → 0.6.0-rc.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/board-server.mjs +104 -98
- package/package.json +1 -1
- package/plot-config.sh +7 -0
- package/plot-plan-meta.sh +35 -2
package/package.json
CHANGED
package/plot-config.sh
CHANGED
|
@@ -47,6 +47,13 @@
|
|
|
47
47
|
# Tracker plot | jira | github-issues | linear (+ URL)
|
|
48
48
|
# (plot = plans in this repo ARE the tracker; absent = same)
|
|
49
49
|
# Git host github | bitbucket (resolves gh vs bb)
|
|
50
|
+
# CI jenkins | github-actions | none — which CI system this
|
|
51
|
+
# project uses. Recorded by /plot-board-setup; not yet
|
|
52
|
+
# read by the board.
|
|
53
|
+
# Jenkins instance the slug or URL passed to a Jenkins CLI's -I flag.
|
|
54
|
+
# Read back by /plot-board-setup to verify auth against
|
|
55
|
+
# the right instance — without it the only runnable
|
|
56
|
+
# check verifies nothing.
|
|
50
57
|
#
|
|
51
58
|
# `Plan template` is a repo-root-relative path to the plan template /plot-idea
|
|
52
59
|
# instantiates; when absent, /plot-idea falls back to the shipped template.
|
package/plot-plan-meta.sh
CHANGED
|
@@ -68,6 +68,12 @@
|
|
|
68
68
|
# continuation line is not seen — keep it on the branch line.
|
|
69
69
|
# prs PR numbers from `→ #NNN` links in the `## Branches`
|
|
70
70
|
# section (sorted, unique)
|
|
71
|
+
# issues tracker issue numbers this plan answers, from the `## Status`
|
|
72
|
+
# `Issue:` line or front matter `issue:` (sorted, unique).
|
|
73
|
+
# A DEDICATED field, never a scan of the body for `#NNN`: a
|
|
74
|
+
# body scan cannot tell a signal from a citation, which is the
|
|
75
|
+
# same reason `prs` reads only `→ #NNN`. Accepts a list
|
|
76
|
+
# (`Issue: #226, #228`) because one plan can answer several.
|
|
71
77
|
# review_raw the plan's review-channel answer as written (`## Status`
|
|
72
78
|
# `Review:` or front matter `review:`); "" if absent
|
|
73
79
|
# review normalized: pr|in-session|ballot|UNKNOWN|NONE
|
|
@@ -132,7 +138,7 @@ if [ ${#files[@]} -eq 0 ] && [ ${#missing[@]} -eq 0 ]; then
|
|
|
132
138
|
fi
|
|
133
139
|
|
|
134
140
|
for f in ${missing[@]+"${missing[@]}"}; do
|
|
135
|
-
printf '{"file":"%s","format":"none","error":"file not found","phase_raw":"","phase":"NONE","phase_alt_raw":"","phase_alt":"NONE","type":"","title":"","sprint":"","story":"","assignee":"","branches":[],"prs":[],"review_raw":"","review":"NONE","impl_raw":"","impl":"NONE","approved_raw":"","released_raw":"","delivered_raw":"","started_raw":[]}\n' \
|
|
141
|
+
printf '{"file":"%s","format":"none","error":"file not found","phase_raw":"","phase":"NONE","phase_alt_raw":"","phase_alt":"NONE","type":"","title":"","sprint":"","story":"","assignee":"","branches":[],"prs":[],"issues":[],"review_raw":"","review":"NONE","impl_raw":"","impl":"NONE","approved_raw":"","released_raw":"","delivered_raw":"","started_raw":[]}\n' \
|
|
136
142
|
"$(printf '%s' "$f" | sed 's/\\/\\\\/g; s/"/\\"/g')"
|
|
137
143
|
done
|
|
138
144
|
|
|
@@ -218,11 +224,13 @@ function reset_state() {
|
|
|
218
224
|
in_fm = 0; section = ""; in_comment = 0; in_challenge = 0; branches_seen = 0
|
|
219
225
|
delete branches; n_branches = 0
|
|
220
226
|
delete prs; n_prs = 0
|
|
227
|
+
fm_issue = ""; canon_issue = ""
|
|
228
|
+
delete issues; n_issues = 0
|
|
221
229
|
delete wave_names; delete wave_of; delete wave_seq; delete wave_count
|
|
222
230
|
delete deferred_of; delete claimed_of; delete ordered_b; n_waves = 0
|
|
223
231
|
delete started; n_started = 0
|
|
224
232
|
}
|
|
225
|
-
function emit_record( fmt, praw, palt_raw, traw, title, sprint, story, assignee, review, impl, approved, delivered, i, j, out, sorted_b, sorted_p, nb, np) {
|
|
233
|
+
function emit_record( fmt, praw, palt_raw, traw, title, sprint, story, assignee, review, impl, approved, delivered, issue, i, j, out, sorted_b, sorted_p, sorted_i, nb, np, ni) {
|
|
226
234
|
if (fm_status != "" || fm_phase != "") {
|
|
227
235
|
fmt = "frontmatter"
|
|
228
236
|
praw = (fm_status != "") ? fm_status : fm_phase
|
|
@@ -245,6 +253,20 @@ function emit_record( fmt, praw, palt_raw, traw, title, sprint, story, assigne
|
|
|
245
253
|
released = strip_placeholder((fm_released != "") ? fm_released : canon_released)
|
|
246
254
|
delivered = strip_placeholder((fm_delivered != "") ? fm_delivered : canon_delivered)
|
|
247
255
|
if (fm_started != "" && strip_placeholder(fm_started) != "") started[++n_started] = fm_started
|
|
256
|
+
# `Issue:` names the tracker signals this plan answers, and it is a DEDICATED
|
|
257
|
+
# field rather than a scan of the body for `#NNN`. A body scan cannot tell a
|
|
258
|
+
# signal from a citation: plans in this repo mention PR numbers constantly,
|
|
259
|
+
# and one of them cites `#226`, `#227`, `#228` as history in its Motivation
|
|
260
|
+
# while naming `PR #232` two sections later. That is the same ambiguity `prs`
|
|
261
|
+
# already answered by reading only `-> #NNN` — one field, one meaning.
|
|
262
|
+
#
|
|
263
|
+
# A LIST, because one plan can answer several signals; the plan that
|
|
264
|
+
# introduced this field subsumes three.
|
|
265
|
+
issue = strip_placeholder((fm_issue != "") ? fm_issue : canon_issue)
|
|
266
|
+
while (match(issue, /#[0-9]+/)) {
|
|
267
|
+
issues[++n_issues] = substr(issue, RSTART + 1, RLENGTH - 1)
|
|
268
|
+
issue = substr(issue, RSTART + RLENGTH)
|
|
269
|
+
}
|
|
248
270
|
# Insertion sort + dedupe (portable: no gawk asort).
|
|
249
271
|
nb = 0
|
|
250
272
|
for (i = 1; i <= n_branches; i++) {
|
|
@@ -260,6 +282,13 @@ function emit_record( fmt, praw, palt_raw, traw, title, sprint, story, assigne
|
|
|
260
282
|
for (j = np; j >= 1 && sorted_p[j] > prs[i]+0; j--) sorted_p[j+1] = sorted_p[j]
|
|
261
283
|
sorted_p[j+1] = prs[i]+0; np++
|
|
262
284
|
}
|
|
285
|
+
ni = 0
|
|
286
|
+
for (i = 1; i <= n_issues; i++) {
|
|
287
|
+
for (j = 1; j <= ni && sorted_i[j] != issues[i]+0; j++) ;
|
|
288
|
+
if (j <= ni) continue
|
|
289
|
+
for (j = ni; j >= 1 && sorted_i[j] > issues[i]+0; j--) sorted_i[j+1] = sorted_i[j]
|
|
290
|
+
sorted_i[j+1] = issues[i]+0; ni++
|
|
291
|
+
}
|
|
263
292
|
out = "{\"file\":\"" jesc(cur_file) "\",\"format\":\"" fmt "\""
|
|
264
293
|
out = out ",\"phase_raw\":\"" jesc(praw) "\",\"phase\":\"" norm_phase(praw) "\""
|
|
265
294
|
out = out ",\"phase_alt_raw\":\"" jesc(palt_raw) "\",\"phase_alt\":\"" norm_phase(palt_raw) "\""
|
|
@@ -270,6 +299,8 @@ function emit_record( fmt, praw, palt_raw, traw, title, sprint, story, assigne
|
|
|
270
299
|
for (i = 1; i <= nb; i++) out = out (i > 1 ? "," : "") "\"" jesc(sorted_b[i]) "\""
|
|
271
300
|
out = out "],\"prs\":["
|
|
272
301
|
for (i = 1; i <= np; i++) out = out (i > 1 ? "," : "") sorted_p[i]
|
|
302
|
+
out = out "],\"issues\":["
|
|
303
|
+
for (i = 1; i <= ni; i++) out = out (i > 1 ? "," : "") sorted_i[i]
|
|
273
304
|
out = out "]"
|
|
274
305
|
# waves[]: branches grouped by `### ` subheading, in document order. A plan
|
|
275
306
|
# with no subheadings yields one wave with an empty name.
|
|
@@ -315,6 +346,7 @@ in_fm {
|
|
|
315
346
|
else if (lower ~ /^title:/ && fm_title == "") fm_title = val_after_colon($0)
|
|
316
347
|
else if (lower ~ /^sprint:/ && fm_sprint == "") fm_sprint = val_after_colon($0)
|
|
317
348
|
else if (lower ~ /^story:/ && fm_story == "") fm_story = val_after_colon($0)
|
|
349
|
+
else if (lower ~ /^issue:/ && fm_issue == "") fm_issue = val_after_colon($0)
|
|
318
350
|
else if (lower ~ /^assignee:/ && fm_assignee == "") fm_assignee = val_after_colon($0)
|
|
319
351
|
else if (lower ~ /^review:/ && fm_review == "") fm_review = val_after_colon($0)
|
|
320
352
|
else if (lower ~ /^impl:/ && fm_impl == "") fm_impl = val_after_colon($0)
|
|
@@ -368,6 +400,7 @@ section == "status" {
|
|
|
368
400
|
else if (lower ~ /^[ \t]*[-*]?[ \t]*\**type[:*]/ && canon_type == "") canon_type = val_after_colon($0)
|
|
369
401
|
else if (lower ~ /^[ \t]*[-*]?[ \t]*\**sprint[:*]/ && canon_sprint == "") canon_sprint = val_after_colon($0)
|
|
370
402
|
else if (lower ~ /^[ \t]*[-*]?[ \t]*\**story[:*]/ && canon_story == "") canon_story = val_after_colon($0)
|
|
403
|
+
else if (lower ~ /^[ \t]*[-*]?[ \t]*\**issue[:*]/ && canon_issue == "") canon_issue = val_after_colon($0)
|
|
371
404
|
else if (lower ~ /^[ \t]*[-*]?[ \t]*\**review[:*]/ && canon_review == "") canon_review = val_after_colon($0)
|
|
372
405
|
else if (lower ~ /^[ \t]*[-*]?[ \t]*\**impl[:*]/ && canon_impl == "") canon_impl = val_after_colon($0)
|
|
373
406
|
else if (lower ~ /^[ \t]*[-*]?[ \t]*\**approved[:*]/ && canon_approved == "") canon_approved = val_after_colon($0)
|