(task, tasks, options = {})
| 189 | .filter((entry) => entry.blockers.length > 0); |
| 190 | } |
| 191 | |
| 192 | function validateMergeOrder(task, tasks, options = {}) { |
| 193 | const taskMap = buildTaskMap(tasks); |
| 194 | const candidate = typeof task === 'object' ? task : taskMap.get(String(task)); |
| 195 | if (!candidate) { |
| 196 | return { ok: false, blockers: [{ dep: String(task), status: 'missing', reason: 'candidate is not in the work queue' }] }; |
| 197 | } |
| 198 | |
| 199 | const blockers = []; |
| 200 | for (const dep of candidate.deps || []) { |
| 201 | const target = taskMap.get(String(dep)); |
| 202 | if (!target) { |
| 203 | blockers.push({ dep: String(dep), status: 'missing', reason: 'dependency is not in the work queue' }); |
| 204 | continue; |
| 205 | } |
| 206 | |
| 207 | const status = normalizeStatus(target.status); |
| 208 | const accepted = options.allowCompletedDependencies |
| 209 | ? SUCCESS_STATUSES.has(status) |
| 210 | : MERGED_STATUSES.has(status); |
| 211 | if (!accepted) { |
| 212 | blockers.push({ |
| 213 | dep: String(dep), |
| 214 | status, |
| 215 | reason: options.allowCompletedDependencies ? 'dependency is not complete' : 'dependency has not been merged', |
| 216 | }); |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | return { ok: blockers.length === 0, blockers }; |
| 221 | } |
| 222 | |
| 223 | function normalizeGovernanceId(value, fallback) { |
no test coverage detected