Details (original message): Implement the intent core, conformance suite, catalog alignment, examples, and the intentctl diagnostics CLI.
81 lines
2.3 KiB
Go
81 lines
2.3 KiB
Go
package intent
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/fs"
|
|
"path"
|
|
"sort"
|
|
)
|
|
|
|
// overlayDoc 是 JSON 配置文件的顶层结构。
|
|
//
|
|
// {
|
|
// "intents": [ { ...IntentSpec... } ],
|
|
// "disable": [ "demo.run.status_query" ]
|
|
// }
|
|
//
|
|
// intents 内同 id 条目覆盖内置或先前定义(version 必须递增);disable 按id禁用
|
|
// (保护域内的 id 会整批失败)。目录 root 内按文件名字典序加载,roots 按给定顺序应用。
|
|
type overlayDoc struct {
|
|
Intents []IntentSpec `json:"intents"`
|
|
Disable []string `json:"disable"`
|
|
}
|
|
|
|
// overlayEntry 单条 overlay 指令,source 定位到文件与下标,供错误与诊断使用。
|
|
type overlayEntry struct {
|
|
disable bool
|
|
id string
|
|
spec IntentSpec
|
|
source string
|
|
}
|
|
|
|
// loadOverlays 从 fsys 读取全部 roots。root 可以是目录(加载其中 *.json,字典序)
|
|
// 或单个文件路径。任何读取、解析或未知字段错误都会带来源返回。
|
|
func loadOverlays(fsys fs.FS, roots []string) ([]overlayEntry, error) {
|
|
var entries []overlayEntry
|
|
for _, root := range roots {
|
|
root = path.Clean(root)
|
|
files, err := overlayFiles(fsys, root)
|
|
if err != nil {
|
|
return nil, newError(LoadFailed, "读取配置 root 失败", "root", root, "error", err.Error())
|
|
}
|
|
for _, f := range files {
|
|
data, err := fs.ReadFile(fsys, f)
|
|
if err != nil {
|
|
return nil, newError(LoadFailed, "读取配置文件失败", "file", f, "error", err.Error())
|
|
}
|
|
var doc overlayDoc
|
|
dec := json.NewDecoder(bytes.NewReader(data))
|
|
dec.DisallowUnknownFields()
|
|
if err := dec.Decode(&doc); err != nil {
|
|
return nil, newError(InvalidSpec, "配置解析失败(含未知字段)", "file", f, "error", err.Error())
|
|
}
|
|
for i := range doc.Intents {
|
|
entries = append(entries, overlayEntry{spec: doc.Intents[i], source: fmt.Sprintf("%s#intents[%d]", f, i)})
|
|
}
|
|
for i, id := range doc.Disable {
|
|
entries = append(entries, overlayEntry{disable: true, id: id, source: fmt.Sprintf("%s#disable[%d]", f, i)})
|
|
}
|
|
}
|
|
}
|
|
return entries, nil
|
|
}
|
|
|
|
func overlayFiles(fsys fs.FS, root string) ([]string, error) {
|
|
st, err := fs.Stat(fsys, root)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !st.IsDir() {
|
|
return []string{root}, nil
|
|
}
|
|
matches, err := fs.Glob(fsys, path.Join(root, "*.json"))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
sort.Strings(matches)
|
|
return matches, nil
|
|
}
|