package pipeline import ( "encoding/json" "fmt" "os" "path/filepath" "strings" "git.westgate.pw/ShadowsOverWestgate/sow-tools/internal/gff" "git.westgate.pw/ShadowsOverWestgate/sow-tools/internal/project" ) type ApplyManifestResult struct { ManifestPath string ModuleSource string HAKCount int } func ApplyHAKManifest(p *project.Project, manifestPath string) (ApplyManifestResult, error) { if manifestPath == "" { manifestPath = p.HAKManifestPath() } if strings.TrimSpace(p.EffectiveConfig().Paths.Source) == "" { return ApplyManifestResult{}, fmt.Errorf("cannot apply hak manifest: paths.source is not configured") } sourceRoot := filepath.Clean(p.SourceDir()) if sourceRoot == "." || sourceRoot == string(filepath.Separator) || sourceRoot == filepath.Clean(p.Root) { return ApplyManifestResult{}, fmt.Errorf("cannot apply hak manifest: paths.source resolves to unsafe source root %s", sourceRoot) } raw, err := os.ReadFile(manifestPath) if err != nil { return ApplyManifestResult{}, fmt.Errorf("read hak manifest: %w", err) } var manifest BuildManifest if err := json.Unmarshal(raw, &manifest); err != nil { return ApplyManifestResult{}, fmt.Errorf("parse hak manifest: %w", err) } moduleSource := filepath.Join(sourceRoot, "module", "module.ifo.json") sourceRaw, err := os.ReadFile(moduleSource) if err != nil { return ApplyManifestResult{}, fmt.Errorf("read module ifo source: %w", err) } var document gff.Document if err := json.Unmarshal(sourceRaw, &document); err != nil { return ApplyManifestResult{}, fmt.Errorf("parse module ifo source: %w", err) } setModuleHAKList(&document, manifest.ModuleHAKs) formatted, err := json.MarshalIndent(document, "", " ") if err != nil { return ApplyManifestResult{}, fmt.Errorf("marshal updated module ifo: %w", err) } formatted = append(formatted, '\n') if err := os.WriteFile(moduleSource, formatted, 0o644); err != nil { return ApplyManifestResult{}, fmt.Errorf("write module ifo source: %w", err) } return ApplyManifestResult{ ManifestPath: manifestPath, ModuleSource: moduleSource, HAKCount: len(manifest.ModuleHAKs), }, nil }