WatchConfig.UpsertEntry silently deletes existing contexts when re-upserting a watched file

Aperta Adatta ai principianti
#610 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
82/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
go
Ambito
cli

Direzione di ricerca

Il bug è in UpsertEntry in pkg/config/localconfig.go, dove la slice di context esistente viene sovrascritta dalla voce con un singolo context. Inizia leggendo quella funzione e il reproducer nella issue, poi aggiungi in pkg/config un test che esegue l'upsert di una voce quando un context è già presente e verifica che tutti i context precedenti sopravvivano. Il lavoro è completato quando la lista di context unita conserva ogni context senza duplicati e un entry.Context vuoto non causa più un panic.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Describe the bug

When a file is being watched across multiple contexts (e.g. ["dev", "staging"]), re-running microcks import --watch <file> on an existing context—or calling WatchConfig.UpsertEntry with a context already present—silently deletes all other contexts associated with that file from .config/microcks/watch.

In pkg/config/localconfig.go:

func (w *WatchConfig) UpsertEntry(entry WatchEntry) {
    for i, e := range w.Entries {
        if e.FilePath == entry.FilePath {
            contexts := w.Entries[i].Context
            if !slices.Contains(contexts, entry.Context[0]) {
                entry.Context = append(entry.Context, contexts...)
            }
            w.Entries[i] = entry
            return
        }
    }
    w.Entries = append(w.Entries, entry)
}

If entry.Context[0] is already in contexts, the if !slices.Contains(...) check evaluates to false and does nothing. Because entry.Context only contains the single context from the current invocation, w.Entries[i] = entry replaces the existing context slice with only entry.Context, wiping out all other contexts.

Additionally:

  • If entry.Context is empty, accessing entry.Context[0] unconditionally panics with runtime error: index out of range [0] with length 0.
  • If entry.Context contains multiple items, only index 0 is ever evaluated.
Expected behavior

WatchConfig.UpsertEntry should preserve all existing contexts for a file while adding any new context without duplicates. Re-importing or updating a watched file from one context must not delete other contexts that are monitoring the same file.

Actual behavior

When re-upserting a file with an already existing context, all other contexts previously attached to the entry are discarded, leaving only the single re-upserted context in the watch configuration.

How to Reproduce?
Reproducer
package main

import (
    "fmt"
    "github.com/microcks/microcks-cli/pkg/config"
)

func main() {
    cfg := config.WatchConfig{
        Entries: []config.WatchEntry{
            {FilePath: "api.yaml", Context: []string{"dev"}},
        },
    }

    // 1. Add "staging" -> Entry has ["staging", "dev"]
    cfg.UpsertEntry(config.WatchEntry{FilePath: "api.yaml", Context: []string{"staging"}})
    fmt.Printf("After adding staging: %v\n", cfg.Entries[0].Context)

    // 2. Re-import / re-upsert from "staging"
    cfg.UpsertEntry(config.WatchEntry{FilePath: "api.yaml", Context: []string{"staging"}, MainArtifact: true})
    fmt.Printf("After re-upserting staging: %v\n", cfg.Entries[0].Context)

    // Output: [staging] --> "dev" context was deleted!
}
Steps to Reproduce via CLI
  1. Register a file in watch mode across two contexts (dev and staging).
  2. Run microcks import --watch <file> again while on the staging context.
  3. Check the watch configuration file: <file> now only lists staging, and dev has been deleted.
Microcks version or git rev

master

Install method (docker-compose, helm chart, operator, docker-desktop extension,...)

No response

Additional information

I would be happy to submit a PR with unit test coverage if the team agrees!

Lingua principale
Go
Stelle
59
Fork
74
Merge medio
4g 5h
PR unite (30g)
15

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di microcks/microcks-cli

Tutte le issue di microcks/microcks-cli

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.