Native Workflow Support
This commit is contained in:
+111
-4
@@ -12,6 +12,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gitea.westgate.pw/ShadowsOverWestgate/sow-tools/internal/erf"
|
||||
"gitea.westgate.pw/ShadowsOverWestgate/sow-tools/internal/project"
|
||||
)
|
||||
|
||||
@@ -72,6 +73,18 @@ type BuildResult struct {
|
||||
FilesTLK int
|
||||
}
|
||||
|
||||
type PackageResult struct {
|
||||
Mode string
|
||||
Output2DADir string
|
||||
OutputTLKDir string
|
||||
OutputHAKPath string
|
||||
OutputTLKPath string
|
||||
Files2DA int
|
||||
FilesTLK int
|
||||
HAKResources int
|
||||
AssetFiles int
|
||||
}
|
||||
|
||||
type CompareResult struct {
|
||||
Mode string
|
||||
Compared2DA int
|
||||
@@ -192,6 +205,7 @@ func ValidateProject(p *project.Project) ValidationReport {
|
||||
report.DataFiles++
|
||||
_ = validateJSONFile(path, "data", &report)
|
||||
})
|
||||
validateTopPackageAssets(sourceDir, dataDir, &report)
|
||||
validateNativeOutputCatalog(dataDir, &report)
|
||||
validateItempropsRegistryGraph(dataDir, &report)
|
||||
if _, err := os.Stat(statePath); err == nil {
|
||||
@@ -635,20 +649,26 @@ func validateBaseDialogObject(path string, obj map[string]any, report *Validatio
|
||||
func validateLegacyDialogEntries(path string, obj map[string]any, report *ValidationReport, label string) {
|
||||
entries, ok := obj["entries"]
|
||||
if ok {
|
||||
if _, ok := entries.(map[string]any); !ok {
|
||||
switch entries.(type) {
|
||||
case map[string]any, []any:
|
||||
// accepted compatibility shapes
|
||||
default:
|
||||
report.Diagnostics = append(report.Diagnostics, Diagnostic{
|
||||
Severity: SeverityError,
|
||||
Path: path,
|
||||
Message: fmt.Sprintf("%s entries must be a JSON object", label),
|
||||
Message: fmt.Sprintf("%s entries must be a JSON object or array", label),
|
||||
})
|
||||
}
|
||||
}
|
||||
if language, ok := obj["language"]; ok {
|
||||
if _, ok := language.(string); !ok {
|
||||
switch language.(type) {
|
||||
case string, float64:
|
||||
// accepted compatibility shapes
|
||||
default:
|
||||
report.Diagnostics = append(report.Diagnostics, Diagnostic{
|
||||
Severity: SeverityError,
|
||||
Path: path,
|
||||
Message: fmt.Sprintf("%s language must be a string when present", label),
|
||||
Message: fmt.Sprintf("%s language must be a string or numeric language id when present", label),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -866,6 +886,93 @@ func validateNativeOutputCatalog(dataDir string, report *ValidationReport) {
|
||||
}
|
||||
}
|
||||
|
||||
func validateTopPackageAssets(sourceDir, dataDir string, report *ValidationReport) {
|
||||
assetsDir := filepath.Join(sourceDir, "assets")
|
||||
info, err := os.Stat(assetsDir)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return
|
||||
}
|
||||
report.Diagnostics = append(report.Diagnostics, Diagnostic{
|
||||
Severity: SeverityError,
|
||||
Path: assetsDir,
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !info.IsDir() {
|
||||
report.Diagnostics = append(report.Diagnostics, Diagnostic{
|
||||
Severity: SeverityError,
|
||||
Path: assetsDir,
|
||||
Message: "must be a directory",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
projectOutputs, err := discoverNativeOutputCatalog(dataDir)
|
||||
if err != nil {
|
||||
report.Diagnostics = append(report.Diagnostics, Diagnostic{
|
||||
Severity: SeverityError,
|
||||
Path: assetsDir,
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
seen := map[string]string{}
|
||||
err = filepath.WalkDir(assetsDir, func(path string, d fs.DirEntry, walkErr error) error {
|
||||
if walkErr != nil {
|
||||
return walkErr
|
||||
}
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
report.Files++
|
||||
rel, err := filepath.Rel(assetsDir, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.HasPrefix(filepath.Base(path), ".") {
|
||||
return nil
|
||||
}
|
||||
base := strings.ToLower(strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)))
|
||||
ext := strings.TrimPrefix(strings.ToLower(filepath.Ext(path)), ".")
|
||||
if _, ok := erf.ResourceTypeForExtension(ext); !ok {
|
||||
report.Diagnostics = append(report.Diagnostics, Diagnostic{
|
||||
Severity: SeverityError,
|
||||
Path: path,
|
||||
Message: fmt.Sprintf("unsupported topdata asset resource extension %q", filepath.Ext(path)),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
key := base + "." + ext
|
||||
if previous, ok := seen[key]; ok {
|
||||
report.Diagnostics = append(report.Diagnostics, Diagnostic{
|
||||
Severity: SeverityError,
|
||||
Path: path,
|
||||
Message: fmt.Sprintf("duplicate topdata asset resource %q also defined by %s", key, previous),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
seen[key] = rel
|
||||
if owner, ok := projectOutputs[key]; ok {
|
||||
report.Diagnostics = append(report.Diagnostics, Diagnostic{
|
||||
Severity: SeverityError,
|
||||
Path: path,
|
||||
Message: fmt.Sprintf("topdata asset resource %q collides with compiled topdata output from %s", key, owner),
|
||||
})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
report.Diagnostics = append(report.Diagnostics, Diagnostic{
|
||||
Severity: SeverityError,
|
||||
Path: assetsDir,
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func recordNativeOutputOwner(outputName, owner string, outputOwners map[string]string, report *ValidationReport) {
|
||||
if existing, ok := outputOwners[outputName]; ok {
|
||||
report.Diagnostics = append(report.Diagnostics, Diagnostic{
|
||||
|
||||
Reference in New Issue
Block a user