[agent/codex:gpt-5.4-mini] Read ~/spec/code/core/go/cli/RFC.md fully. Find features des... #83

Merged
Virgil merged 1 commit from agent/read---spec-code-core-go-cli-rfc-md-full into dev 2026-04-02 11:35:25 +00:00
2 changed files with 39 additions and 4 deletions

View file

@ -89,8 +89,11 @@ type TaskTracker struct {
func (tr *TaskTracker) Tasks() iter.Seq[*TrackedTask] {
return func(yield func(*TrackedTask) bool) {
tr.mu.Lock()
defer tr.mu.Unlock()
for _, t := range tr.tasks {
tasks := make([]*TrackedTask, len(tr.tasks))
copy(tasks, tr.tasks)
tr.mu.Unlock()
for _, t := range tasks {
if !yield(t) {
return
}
@ -102,8 +105,11 @@ func (tr *TaskTracker) Tasks() iter.Seq[*TrackedTask] {
func (tr *TaskTracker) Snapshots() iter.Seq2[string, string] {
return func(yield func(string, string) bool) {
tr.mu.Lock()
defer tr.mu.Unlock()
for _, t := range tr.tasks {
tasks := make([]*TrackedTask, len(tr.tasks))
copy(tasks, tr.tasks)
tr.mu.Unlock()
for _, t := range tasks {
name, status, _ := t.snapshot()
if !yield(name, status) {
return

View file

@ -189,6 +189,35 @@ func TestTaskTracker_Good(t *testing.T) {
assert.NotContains(t, out, "✓")
assert.NotContains(t, out, "✗")
})
t.Run("iterators tolerate mutation during iteration", func(t *testing.T) {
tr := NewTaskTracker()
tr.out = &bytes.Buffer{}
tr.Add("first")
tr.Add("second")
done := make(chan struct{})
go func() {
defer close(done)
for task := range tr.Tasks() {
task.Update("visited")
}
}()
require.Eventually(t, func() bool {
select {
case <-done:
return true
default:
return false
}
}, time.Second, 10*time.Millisecond)
for name, status := range tr.Snapshots() {
assert.Equal(t, "visited", status, name)
}
})
}
func TestTaskTracker_Bad(t *testing.T) {