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

未关闭 适合新手
#610 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
82/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
go
领域
cli

调研方向

该缺陷位于 pkg/config/localconfig.go 中的 UpsertEntry,现有的 context 切片被单个 context 的条目覆盖。请先阅读该函数和 issue 中的复现步骤,然后在 pkg/config 中添加一个测试:在已存在 context 的情况下对条目执行 upsert,并检查之前的所有 context 都被保留。当合并后的 context 列表保留所有 context 且没有重复,并且空的 entry.Context 不再导致 panic 时,即为完成。

由索引模型根据 Issue 内容生成。

描述

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!

主要语言
Go
星标
59
派生
74
平均合并
4 天 5 小时
30 天内合并 PR
15

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

microcks/microcks-cli 的其他 Issue

查看 microcks/microcks-cli 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。