fix: union repeated Blocked by declarations #185
3 changed files with 28 additions and 17 deletions
|
|
@ -178,26 +178,26 @@ issue_references() { # text on stdin -> LOCAL/CROSS<TAB>reference
|
||||||
|
|
||||||
blocked_reference_records() { # body on stdin -> classified reference records
|
blocked_reference_records() { # body on stdin -> classified reference records
|
||||||
# Dependency declarations sometimes soft-wrap after a comma. Continue
|
# Dependency declarations sometimes soft-wrap after a comma. Continue
|
||||||
# through the first sentence terminator; if prose omits one, conservatively
|
# each occurrence through its sentence terminator. Unioning every occurrence
|
||||||
# retain later references so ambiguity can keep an issue blocked, never
|
# can over-retain historical prose, but a stale block is safer than falsely
|
||||||
# promote it prematurely.
|
# promoting work whose live dependency was dropped (#184).
|
||||||
awk '
|
awk '
|
||||||
{
|
{
|
||||||
line = $0
|
body = body (NR == 1 ? "" : "\n") $0
|
||||||
lower = tolower(line)
|
}
|
||||||
if (!active) {
|
END {
|
||||||
marker = "blocked by"
|
marker = "blocked by"
|
||||||
start = index(lower, marker)
|
rest = body
|
||||||
if (!start) next
|
while ((start = index(tolower(rest), marker))) {
|
||||||
line = substr(line, start + length(marker))
|
clause = substr(rest, start + length(marker))
|
||||||
active = 1
|
if (match(clause, /[.;]/)) {
|
||||||
|
print substr(clause, 1, RSTART - 1)
|
||||||
|
rest = substr(clause, RSTART + 1)
|
||||||
|
} else {
|
||||||
|
print clause
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (line ~ /[.;]/) {
|
|
||||||
sub(/[.;].*/, "", line)
|
|
||||||
print line
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
print line
|
|
||||||
}
|
}
|
||||||
' | issue_references
|
' | issue_references
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
changelog.d/184.md
Normal file
3
changelog.d/184.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Issue-flow reconciliation unions every `Blocked by` clause, preventing a closed first dependency from hiding later open blockers (#184).
|
||||||
|
|
@ -115,6 +115,12 @@ check "empty offsite timeline extracts nothing" 0 "" offsite_cross_referenced_pr
|
||||||
# Invariant 3: blocked declarations parse and release only when all close.
|
# Invariant 3: blocked declarations parse and release only when all close.
|
||||||
refs="$(blocked_references <<< $'Context #99. Blocked by #12 (first), #7 (second). Blocks #44.')"
|
refs="$(blocked_references <<< $'Context #99. Blocked by #12 (first), #7 (second). Blocks #44.')"
|
||||||
check "blocked declaration extracts only declared refs" 0 $'7\n12' printf '%s\n' "$refs"
|
check "blocked declaration extracts only declared refs" 0 $'7\n12' printf '%s\n' "$refs"
|
||||||
|
body='Part of #151. Blocked by #152. Blocked by #153. Blocked by #148 — prose. Blocks #155.'
|
||||||
|
check "repeated blocker declarations retain every clause" 0 "" test \
|
||||||
|
"$(blocked_references <<<"$body")" = $'148\n152\n153'
|
||||||
|
body=$'Note: restored because it is blocked by an operator act. See below.\nBlocked by #152, #153, #148.'
|
||||||
|
check "earlier blocker prose does not hide a later declaration" 0 "" test \
|
||||||
|
"$(blocked_references <<<"$body")" = $'148\n152\n153'
|
||||||
body=$'Blocked by #12 (first),\n#7 (soft-wrapped second). Blocks #44.'
|
body=$'Blocked by #12 (first),\n#7 (soft-wrapped second). Blocks #44.'
|
||||||
check "soft-wrapped blocker declaration retains continuation refs" 0 "" test \
|
check "soft-wrapped blocker declaration retains continuation refs" 0 "" test \
|
||||||
"$(blocked_references <<<"$body")" = $'7\n12'
|
"$(blocked_references <<<"$body")" = $'7\n12'
|
||||||
|
|
@ -143,6 +149,8 @@ check "slash-adjacent local references survive" 0 $'14\n15' \
|
||||||
check "comma-adjacent local references survive" 0 $'11\n12' \
|
check "comma-adjacent local references survive" 0 $'11\n12' \
|
||||||
blocked_references <<<"Blocked by #11, #12."
|
blocked_references <<<"Blocked by #11, #12."
|
||||||
check "open blocker keeps issue blocked" 0 "KEEP" blocked_decision "$refs" $'CLOSED\nOPEN'
|
check "open blocker keeps issue blocked" 0 "KEEP" blocked_decision "$refs" $'CLOSED\nOPEN'
|
||||||
|
check "an open blocker in a repeated declaration prevents promotion" 0 "KEEP" \
|
||||||
|
blocked_decision $'12\n13' $'CLOSED\nOPEN'
|
||||||
check "all closed blockers release issue" 0 "READY" blocked_decision "$refs" $'CLOSED\nCLOSED'
|
check "all closed blockers release issue" 0 "READY" blocked_decision "$refs" $'CLOSED\nCLOSED'
|
||||||
check "missing blocked declaration is flagged" 0 "FLAG_UNPARSEABLE" blocked_decision "" ""
|
check "missing blocked declaration is flagged" 0 "FLAG_UNPARSEABLE" blocked_decision "" ""
|
||||||
check "unreadable blocker is flagged" 0 "FLAG_UNPARSEABLE" blocked_decision "12" "UNKNOWN"
|
check "unreadable blocker is flagged" 0 "FLAG_UNPARSEABLE" blocked_decision "12" "UNKNOWN"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue