@plot-pm/board 0.6.0-rc.65 → 0.6.0-rc.67
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/package.json +1 -1
- package/plot-plan-meta.sh +76 -1
package/package.json
CHANGED
package/plot-plan-meta.sh
CHANGED
|
@@ -68,6 +68,21 @@
|
|
|
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
|
+
# changelog the plan's `## Changelog` entries, one string per bullet, in
|
|
72
|
+
# document order; [] when the plan has no changelog or an
|
|
73
|
+
# unfilled one. This is the one field that says WHAT A PLAN
|
|
74
|
+
# CHANGES, which title and story do not.
|
|
75
|
+
# ENTRIES, not lines: a bullet wrapped across several lines is
|
|
76
|
+
# one entry with the continuation lines joined by a single
|
|
77
|
+
# space (9 of the 34 changelogs in the origin repo wrap, so
|
|
78
|
+
# line-per-line would have shredded a quarter of them). An
|
|
79
|
+
# INDENTED bullet folds into the entry above it the same way:
|
|
80
|
+
# a sub-point is not a release note of its own.
|
|
81
|
+
# Non-bullet prose in the section is NOT an entry — 8 plans
|
|
82
|
+
# close their changelog with a "Board impact:" paragraph, which
|
|
83
|
+
# is a note to a reviewer rather than a release note. Comment
|
|
84
|
+
# interiors stay non-content, as everywhere else in this parser,
|
|
85
|
+
# so the template's guidance block contributes nothing.
|
|
71
86
|
# issues tracker issue numbers this plan answers, from the `## Status`
|
|
72
87
|
# `Issue:` line or front matter `issue:` (sorted, unique).
|
|
73
88
|
# A DEDICATED field, never a scan of the body for `#NNN`: a
|
|
@@ -138,7 +153,7 @@ if [ ${#files[@]} -eq 0 ] && [ ${#missing[@]} -eq 0 ]; then
|
|
|
138
153
|
fi
|
|
139
154
|
|
|
140
155
|
for f in ${missing[@]+"${missing[@]}"}; do
|
|
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' \
|
|
156
|
+
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":[],"changelog":[],"review_raw":"","review":"NONE","impl_raw":"","impl":"NONE","approved_raw":"","released_raw":"","delivered_raw":"","started_raw":[]}\n' \
|
|
142
157
|
"$(printf '%s' "$f" | sed 's/\\/\\\\/g; s/"/\\"/g')"
|
|
143
158
|
done
|
|
144
159
|
|
|
@@ -229,6 +244,8 @@ function reset_state() {
|
|
|
229
244
|
delete wave_names; delete wave_of; delete wave_seq; delete wave_count
|
|
230
245
|
delete deferred_of; delete claimed_of; delete ordered_b; n_waves = 0
|
|
231
246
|
delete started; n_started = 0
|
|
247
|
+
fm_changelog = ""
|
|
248
|
+
delete changelog; n_changelog = 0; changelog_seen = 0; cl_open = 0
|
|
232
249
|
}
|
|
233
250
|
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) {
|
|
234
251
|
if (fm_status != "" || fm_phase != "") {
|
|
@@ -302,6 +319,15 @@ function emit_record( fmt, praw, palt_raw, traw, title, sprint, story, assigne
|
|
|
302
319
|
out = out "],\"issues\":["
|
|
303
320
|
for (i = 1; i <= ni; i++) out = out (i > 1 ? "," : "") sorted_i[i]
|
|
304
321
|
out = out "]"
|
|
322
|
+
# Document order, never sorted: a changelog is a narrative sequence, and the
|
|
323
|
+
# first entry is the headline. Front matter wins, as it does for every other
|
|
324
|
+
# field, and contributes exactly one entry.
|
|
325
|
+
if (fm_changelog != "" && strip_placeholder(fm_changelog) != "") {
|
|
326
|
+
delete changelog; n_changelog = 1; changelog[1] = strip_placeholder(fm_changelog)
|
|
327
|
+
}
|
|
328
|
+
out = out ",\"changelog\":["
|
|
329
|
+
for (i = 1; i <= n_changelog; i++) out = out (i > 1 ? "," : "") "\"" jesc(changelog[i]) "\""
|
|
330
|
+
out = out "]"
|
|
305
331
|
# waves[]: branches grouped by `### ` subheading, in document order. A plan
|
|
306
332
|
# with no subheadings yields one wave with an empty name.
|
|
307
333
|
out = out ",\"waves\":["
|
|
@@ -354,6 +380,10 @@ in_fm {
|
|
|
354
380
|
else if (lower ~ /^released:/ && fm_released == "") fm_released = val_after_colon($0)
|
|
355
381
|
else if (lower ~ /^delivered:/ && fm_delivered == "") fm_delivered = val_after_colon($0)
|
|
356
382
|
else if (lower ~ /^started:/ && fm_started == "") fm_started = val_after_colon($0)
|
|
383
|
+
# A scalar `changelog:` in front matter is one entry. A YAML list is NOT read
|
|
384
|
+
# here: front matter in this repo is a flat key/value surface, and guessing a
|
|
385
|
+
# list grammar the format never promised would invent a contract.
|
|
386
|
+
else if (lower ~ /^changelog:/ && fm_changelog == "") fm_changelog = val_after_colon($0)
|
|
357
387
|
next
|
|
358
388
|
}
|
|
359
389
|
# Interior of multi-line HTML comments is non-content (template guidance
|
|
@@ -391,6 +421,10 @@ in_comment {
|
|
|
391
421
|
# section in prose, and those later headings are illustration, not contract.
|
|
392
422
|
else if ($0 ~ /^## Branches/) { section = branches_seen ? "" : "branches"; branches_seen = 1 }
|
|
393
423
|
else if ($0 ~ /^## Approval/) section = "approval"
|
|
424
|
+
# First `## Changelog` wins, for the same reason `## Branches` does: a plan
|
|
425
|
+
# about the plan format quotes the section in prose, and the later heading is
|
|
426
|
+
# illustration rather than contract.
|
|
427
|
+
else if ($0 ~ /^## Changelog/) { section = changelog_seen ? "" : "changelog"; changelog_seen = 1 }
|
|
394
428
|
else section = ""
|
|
395
429
|
next
|
|
396
430
|
}
|
|
@@ -417,6 +451,47 @@ section == "approval" {
|
|
|
417
451
|
if (lower ~ /^[ \t]*[-*]?[ \t]*\**assignee[:*]/ && canon_assignee == "") canon_assignee = val_after_colon($0)
|
|
418
452
|
next
|
|
419
453
|
}
|
|
454
|
+
# `## Changelog` — the release-note entries. One entry per bullet, wrapped
|
|
455
|
+
# continuation lines folded into the entry they belong to.
|
|
456
|
+
#
|
|
457
|
+
# A bullet opens an entry. An indented non-bullet line continues the open one.
|
|
458
|
+
# A blank line or a line at column zero closes it: the flush-left prose that 8
|
|
459
|
+
# plans use for a "Board impact:" note is a remark to a reviewer, not a release
|
|
460
|
+
# note, so it ends the entry rather than joining it.
|
|
461
|
+
section == "changelog" {
|
|
462
|
+
# A line that is nothing but an HTML comment is not content, at any
|
|
463
|
+
# indentation. Multi-line comments are already swallowed upstream; an INDENTED
|
|
464
|
+
# single-liner would otherwise land in the continuation branch below and paste
|
|
465
|
+
# its own markup into the entry above it.
|
|
466
|
+
if ($0 ~ /^[ \t]*<!--.*-->[ \t]*$/) next
|
|
467
|
+
# An INDENTED bullet is a sub-point of the entry above, not a release note of
|
|
468
|
+
# its own, so it continues rather than opens. No changelog in the repo nests
|
|
469
|
+
# today; the rule is here because the alternative silently promotes a
|
|
470
|
+
# sub-point to a headline the moment one does.
|
|
471
|
+
if (cl_open && $0 ~ /^[ \t]+[-*][ \t]/) {
|
|
472
|
+
_n = $0
|
|
473
|
+
sub(/^[ \t]*[-*][ \t]+/, "", _n)
|
|
474
|
+
changelog[n_changelog] = changelog[n_changelog] " " trim(_n)
|
|
475
|
+
next
|
|
476
|
+
}
|
|
477
|
+
if ($0 ~ /^[ \t]*[-*][ \t]/) {
|
|
478
|
+
_e = $0
|
|
479
|
+
sub(/^[ \t]*[-*][ \t]+/, "", _e)
|
|
480
|
+
_e = strip_placeholder(trim(_e))
|
|
481
|
+
if (_e != "") { changelog[++n_changelog] = _e; cl_open = 1 }
|
|
482
|
+
else cl_open = 0 # an unfilled bullet opens nothing to continue
|
|
483
|
+
next
|
|
484
|
+
}
|
|
485
|
+
if (cl_open && $0 ~ /^[ \t]+[^ \t]/) {
|
|
486
|
+
changelog[n_changelog] = changelog[n_changelog] " " trim($0)
|
|
487
|
+
next
|
|
488
|
+
}
|
|
489
|
+
# Blank line, or prose at column zero: whatever entry was open is finished.
|
|
490
|
+
# The flag matters — without it a continuation-shaped line after a break would
|
|
491
|
+
# glue itself onto an entry it never belonged to.
|
|
492
|
+
cl_open = 0
|
|
493
|
+
next
|
|
494
|
+
}
|
|
420
495
|
section == "branches" {
|
|
421
496
|
# `### <name>` opens a wave. Branches before any subheading belong to an
|
|
422
497
|
# unnamed wave, so a pre-wave plan parses as exactly one wave.
|