Warn when circumventing class spellbooks

This commit is contained in:
2026-05-26 18:37:59 +02:00
parent 16ed4fe47d
commit b7587cfd05
2 changed files with 113 additions and 0 deletions
+78
View File
@@ -47,6 +47,9 @@ func validateClassSpellbooks(dataDir string, report *ValidationReport) {
}
_, diagnostics := classSpellbookPlans(dataDir, collected)
report.Diagnostics = append(report.Diagnostics, diagnostics...)
if len(diagnostics) == 0 {
warnSpellModulesForManagedSpellbookColumns(dataDir, collected, report)
}
}
func collectSpellbookValidationDatasets(dataDir string) ([]nativeCollectedDataset, error) {
@@ -187,6 +190,81 @@ func classSpellbookPlans(dataDir string, collected []nativeCollectedDataset) ([]
return plans, diagnostics
}
func warnSpellModulesForManagedSpellbookColumns(dataDir string, collected []nativeCollectedDataset, report *ValidationReport) {
plans, diagnostics := classSpellbookPlans(dataDir, collected)
if len(diagnostics) > 0 || len(plans) == 0 {
return
}
managed := map[string]classSpellbookPlan{}
for _, plan := range plans {
managed[strings.ToLower(plan.Column)] = plan
}
paths, err := collectModulePaths(filepath.Join(dataDir, "spells", "modules"))
if err != nil {
report.Diagnostics = append(report.Diagnostics, Diagnostic{Severity: SeverityError, Path: dataDir, Message: fmt.Sprintf("collect spell modules for spellbook warnings: %v", err)})
return
}
for _, path := range paths {
obj, err := loadJSONObject(path)
if err != nil {
continue
}
warnSpellbookManagedColumnsInValue(dataDir, path, obj["entries"], managed, report)
warnSpellbookManagedColumnsInValue(dataDir, path, obj["overrides"], managed, report)
warnSpellbookManagedColumnsInValue(dataDir, path, obj["rows"], managed, report)
}
}
func warnSpellbookManagedColumnsInValue(dataDir, path string, value any, managed map[string]classSpellbookPlan, report *ValidationReport) {
switch typed := value.(type) {
case map[string]any:
for _, key := range sortedKeys(typed) {
row, ok := typed[key].(map[string]any)
if !ok {
continue
}
warnSpellbookManagedColumnsInRow(dataDir, path, row, managed, report)
}
case []any:
for _, raw := range typed {
row, ok := raw.(map[string]any)
if !ok {
continue
}
warnSpellbookManagedColumnsInRow(dataDir, path, row, managed, report)
}
}
}
func warnSpellbookManagedColumnsInRow(dataDir, path string, row map[string]any, managed map[string]classSpellbookPlan, report *ValidationReport) {
for field, value := range row {
plan, ok := managed[strings.ToLower(field)]
if !ok || isNullLikeValue(value) {
continue
}
spellbookPath := displayTopdataPath(dataDir, plan.Spec.Path)
report.Diagnostics = append(report.Diagnostics, Diagnostic{
Severity: SeverityWarning,
Path: path,
Message: fmt.Sprintf(
"spell module authors class spell column %q managed by class spellbook %s; use %s instead",
plan.Column,
spellbookPath,
spellbookPath,
),
})
}
}
func displayTopdataPath(dataDir, path string) string {
topdataDir := filepath.Dir(dataDir)
rel, err := filepath.Rel(filepath.Dir(topdataDir), path)
if err != nil {
return filepath.ToSlash(path)
}
return filepath.ToSlash(rel)
}
func loadClassSpellbookSpecs(dir string) ([]classSpellbookSpec, []Diagnostic) {
paths, err := collectModulePaths(dir)
if err != nil {