Fix lockfile generation, Key authoring hardening, and generic table injection

This commit is contained in:
2026-04-17 20:43:07 +02:00
parent 376de5d67a
commit d77b44c210
5 changed files with 1025 additions and 87 deletions
+23 -40
View File
@@ -40,12 +40,6 @@ func parseRowMetadata(raw any) (map[string]any, error) {
if len(wiki) > 0 {
meta["wiki"] = wiki
}
case "portrait":
portrait, err := parsePortraitMetadata(value)
if err != nil {
return nil, fmt.Errorf("meta.portrait: %w", err)
}
meta["portrait"] = portrait
default:
return nil, fmt.Errorf("unknown metadata key %q", key)
}
@@ -53,32 +47,6 @@ func parseRowMetadata(raw any) (map[string]any, error) {
return meta, nil
}
func parsePortraitMetadata(raw any) (map[string]any, error) {
obj, ok := raw.(map[string]any)
if !ok {
return nil, fmt.Errorf("must be an object")
}
portrait := map[string]any{}
for key, value := range obj {
switch normalizeMetadataKey(key) {
case "resref":
text, ok := value.(string)
if !ok || strings.TrimSpace(text) == "" {
return nil, fmt.Errorf("resref must be a non-empty string")
}
portrait["resref"] = text
case "sex", "race", "inanimate_type", "plot", "low_gore":
portrait[normalizeMetadataKey(key)] = value
default:
return nil, fmt.Errorf("unknown field %q", key)
}
}
if _, ok := portrait["resref"]; !ok {
return nil, fmt.Errorf("resref is required")
}
return portrait, nil
}
func mergeExpansionData(collected []nativeCollectedDataset) ([]nativeCollectedDataset, error) {
datasetIndexMap := make(map[string]int)
for i, ds := range collected {
@@ -106,6 +74,7 @@ func mergeExpansionData(collected []nativeCollectedDataset) ([]nativeCollectedDa
return collected, nil
}
modifiedTargets := map[int]struct{}{}
for _, src := range rowsWithExpansion {
expansion, _ := extractExpansionData(src.row)
for targetDatasetName, targetRows := range expansion.Data {
@@ -158,10 +127,8 @@ func mergeExpansionData(collected []nativeCollectedDataset) ([]nativeCollectedDa
}
key, _ := targetRow["key"].(string)
if key == "" && targetDatasetName == "portraits" {
if baseResRef, ok := targetRow["BaseResRef"].(string); ok {
key = "portraits:" + baseResRef
}
if strings.TrimSpace(key) == "" {
return nil, fmt.Errorf("expansion into %s: injected rows must specify key", targetDatasetName)
}
if key != "" {
@@ -190,6 +157,7 @@ func mergeExpansionData(collected []nativeCollectedDataset) ([]nativeCollectedDa
if _, exists := targetDS.LockData[key]; !exists {
targetDS.LockData[key] = rowID
lockModified = true
targetDS.LockAdded++
}
}
@@ -207,10 +175,8 @@ func mergeExpansionData(collected []nativeCollectedDataset) ([]nativeCollectedDa
targetDS.Rows = append(targetDS.Rows, newRow)
}
if lockModified && targetDS.Dataset.LockPath != "" {
if err := saveLockfile(targetDS.Dataset.LockPath, targetDS.LockData); err != nil {
return nil, fmt.Errorf("dataset %s: %w", targetDS.Dataset.Name, err)
}
if lockModified {
modifiedTargets[targetIndex] = struct{}{}
}
slices.SortFunc(targetDS.Rows, func(a, b map[string]any) int {
@@ -224,6 +190,23 @@ func mergeExpansionData(collected []nativeCollectedDataset) ([]nativeCollectedDa
}
}
for targetIndex := range modifiedTargets {
targetDS := collected[targetIndex]
referencedKeys, err := collectReferencedLockKeys(nativeDatasetSourceDir(targetDS.Dataset))
if err != nil {
return nil, fmt.Errorf("dataset %s: collect referenced keys: %w", targetDS.Dataset.Name, err)
}
if pruned, updated := pruneLockDataToActiveRows(targetDS.LockData, targetDS.Rows, referencedKeys); pruned > 0 || updated > 0 {
targetDS.LockPruned += pruned
collected[targetIndex] = targetDS
}
if targetDS.Dataset.LockPath != "" {
if err := saveLockfile(targetDS.Dataset.LockPath, targetDS.LockData); err != nil {
return nil, fmt.Errorf("dataset %s: %w", targetDS.Dataset.Name, err)
}
}
}
return collected, nil
}