Knowledge base: progress counts an issue done only once its fix is delivered, and says every gap (issue 1947, review round 1)
mesh/delivery merged: source.main moved to novox/mesh-catalog@26908a89506f
mesh/delivery-group group feat/1947-progress merged: every member is merged
mesh/check pass 87fe2c45cfed on 26908a89506f | carried from 27a7757b970e, hq 3a5c4c7c4d9c | unit 2091 run, 2327 kept, 6 skipped | integration 2112 run…
mesh/delivery merged: source.main moved to novox/mesh-catalog@26908a89506f
mesh/delivery-group group feat/1947-progress merged: every member is merged
mesh/check pass 87fe2c45cfed on 26908a89506f | carried from 27a7757b970e, hq 3a5c4c7c4d9c | unit 2091 run, 2327 kept, 6 skipped | integration 2112 run…
A resolved issue whose delivery is held or failed is stuck, one merged and not delivered is moving; a row the tracker did not answer, an answer that does not read and linked issues cut by the list's limit are said as warnings instead of passing silently.
This commit is contained in:
@@ -208,9 +208,18 @@ func issueItem(r trackerRow) (Item, bool) {
|
||||
case r.Status == "wontfix":
|
||||
return it, false
|
||||
case r.Status == "resolved":
|
||||
it.State, it.Why = StateDone, "resolved"
|
||||
if r.Delivery != "" && !strings.HasPrefix(r.Delivery, "delivered") {
|
||||
it.Why = "resolved · " + r.Delivery
|
||||
// Done only when its fix is delivered, or it has nothing to deliver (ADR 0424 §2, §4; 1947/AC3).
|
||||
switch d := r.Delivery; {
|
||||
case d == "":
|
||||
it.State, it.Why = StateDone, "resolved, nothing to deliver"
|
||||
case strings.HasPrefix(d, "delivered"):
|
||||
it.State, it.Why = StateDone, "resolved, delivered"
|
||||
case held || strings.Contains(d, " stopped"):
|
||||
it.State, it.Why = StateStuck, "resolved · "+d
|
||||
case strings.HasPrefix(d, "fix merged, not delivered"):
|
||||
it.State, it.Why = StateMoving, "resolved · "+d
|
||||
default:
|
||||
it.State, it.Why = StateWaiting, "resolved · "+d
|
||||
}
|
||||
case r.Abandoned || r.Stale:
|
||||
it.State, it.Why = StateStuck, fmt.Sprintf("%s, worker %s stale since %s", r.Status, r.Worker, when(r.Since))
|
||||
@@ -259,6 +268,7 @@ func rollUp(parent *Item, children []Item) {
|
||||
func milestoneItems(d *Design, rows map[int]trackerRow, missing map[int]bool) ([]Item, []string) {
|
||||
var items []Item
|
||||
var warn []string
|
||||
var unanswered []string
|
||||
for _, m := range d.Milestones {
|
||||
mi := Item{ID: m.ID, Title: m.Outcome}
|
||||
var kids []Item
|
||||
@@ -269,6 +279,7 @@ func milestoneItems(d *Design, rows map[int]trackerRow, missing map[int]bool) ([
|
||||
}
|
||||
r, ok := rows[n]
|
||||
if !ok {
|
||||
unanswered = append(unanswered, strconv.Itoa(n))
|
||||
continue
|
||||
}
|
||||
if it, counts := issueItem(r); counts {
|
||||
@@ -279,6 +290,10 @@ func milestoneItems(d *Design, rows map[int]trackerRow, missing map[int]bool) ([
|
||||
mi.Children = kids
|
||||
items = append(items, mi)
|
||||
}
|
||||
if len(unanswered) > 0 {
|
||||
warn = append(warn, fmt.Sprintf("the tracker neither answered nor named missing %d issues the milestones name, left out of the counts: %s",
|
||||
len(unanswered), strings.Join(unanswered, ", ")))
|
||||
}
|
||||
return items, warn
|
||||
}
|
||||
|
||||
@@ -473,11 +488,15 @@ func (k *KB) progressRecord(p *Progress, kind string, n int) error {
|
||||
return fmt.Errorf("the issue tracker does not answer: %v", err)
|
||||
}
|
||||
var l struct {
|
||||
Rows []trackerRow `json:"rows"`
|
||||
Rows []trackerRow `json:"rows"`
|
||||
Matched int `json:"matched"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &l); err != nil {
|
||||
return fmt.Errorf("issue-tracker.list answered something else: %v", err)
|
||||
}
|
||||
if l.Matched > len(l.Rows) {
|
||||
p.Warnings = append(p.Warnings, fmt.Sprintf("%d issues are linked to %s; the first %d are counted", l.Matched, name, len(l.Rows)))
|
||||
}
|
||||
for _, r := range l.Rows {
|
||||
if it, counts := issueItem(r); counts {
|
||||
kids = append(kids, it)
|
||||
@@ -573,7 +592,9 @@ func (k *KB) readExtras(items []Item) (*extras, error) {
|
||||
Title string `json:"title"`
|
||||
} `json:"delivery"`
|
||||
}
|
||||
_ = json.Unmarshal(raw, &s)
|
||||
if err := json.Unmarshal(raw, &s); err != nil {
|
||||
x.warnings = append(x.warnings, fmt.Sprintf("mesh-delivery.show %s answered something else: %v", d.ID, err))
|
||||
}
|
||||
d.Issues, d.Title = s.Delivery.Issues, s.Delivery.Title
|
||||
x.deliveries = append(x.deliveries, d)
|
||||
}
|
||||
@@ -617,7 +638,10 @@ func (k *KB) readExtras(items []Item) (*extras, error) {
|
||||
Target string `json:"target"`
|
||||
} `json:"links"`
|
||||
}
|
||||
_ = json.Unmarshal(raw, &g)
|
||||
if err := json.Unmarshal(raw, &g); err != nil {
|
||||
x.warnings = append(x.warnings, fmt.Sprintf("issue-tracker.get %d answered something else: %v", n, err))
|
||||
continue
|
||||
}
|
||||
ig := &issueGot{notes: len(g.Notes) + g.Left, last: "none"}
|
||||
if len(g.Notes) > 0 {
|
||||
last := g.Notes[len(g.Notes)-1]
|
||||
@@ -804,12 +828,19 @@ func fitProgress(p *Progress, bound int) {
|
||||
return
|
||||
}
|
||||
const raise = ": raise bound (at most 65536) or ask a smaller of, such as one milestone"
|
||||
p.Cut = "the items, the tree's last lines and some warnings" + raise
|
||||
p.Cut = "the items, some warnings and the tree's last lines" + raise
|
||||
var cut []string
|
||||
if len(p.Items) > 0 {
|
||||
p.Items = nil
|
||||
cut = append(cut, "the items (the tree says the same)")
|
||||
}
|
||||
warned := len(p.Warnings)
|
||||
for size(p) > bound && len(p.Warnings) > 0 {
|
||||
p.Warnings = p.Warnings[:len(p.Warnings)-1]
|
||||
}
|
||||
if len(p.Warnings) < warned {
|
||||
cut = append(cut, fmt.Sprintf("the last %d of %d warnings", warned-len(p.Warnings), warned))
|
||||
}
|
||||
lines := strings.Split(p.Tree, "\n")
|
||||
dropped := 0
|
||||
for size(p) > bound && len(lines) > 1 {
|
||||
@@ -820,12 +851,6 @@ func fitProgress(p *Progress, bound int) {
|
||||
if dropped > 0 {
|
||||
cut = append(cut, fmt.Sprintf("the tree's last %d lines", dropped))
|
||||
}
|
||||
for size(p) > bound && len(p.Warnings) > 0 {
|
||||
p.Warnings = p.Warnings[:len(p.Warnings)-1]
|
||||
if !strings.Contains(strings.Join(cut, ""), "warnings") {
|
||||
cut = append(cut, "some warnings")
|
||||
}
|
||||
}
|
||||
if exact := strings.Join(cut, "; ") + raise; len(exact) <= len(p.Cut) {
|
||||
p.Cut = exact
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user