(md, headingRe)
| 208 | // gates to an explicit "Validation gates" section so unrelated checklist items |
| 209 | // that merely mention "build"/"vulnerable"/etc. don't hijack a gate's status. |
| 210 | function sectionSteps(md, headingRe) { |
| 211 | if (!md) return null; |
| 212 | let inSection = false; |
| 213 | const buf = []; |
| 214 | for (const line of md.split(/\r?\n/)) { |
| 215 | const h = line.match(/^\s*#{1,6}\s+(.*\S)\s*$/); |
| 216 | if (h) { |
| 217 | if (inSection) break; // next heading closes the section |
| 218 | if (headingRe.test(h[1])) inSection = true; |
| 219 | continue; |
| 220 | } |
| 221 | if (inSection) buf.push(line); |
| 222 | } |
| 223 | if (!inSection) return null; |
| 224 | const steps = parseSteps(buf.join("\n")); |
| 225 | return steps.length ? steps : null; |
| 226 | } |
| 227 | |
| 228 | function percentDone(steps) { |
| 229 | if (!steps.length) return 0; |
no test coverage detected