ci-platforms / windows amd64 smoke (push) Skipped
ci / release (push) Successful in 8m58s
ci-platforms / darwin amd64 smoke (push) Skipped
ci-platforms / darwin arm64 smoke (push) Skipped
ci / checks (push) Successful in 4m46s
ci / build (amd64, linux, ubuntu-24.04) (push) Successful in 13m28s
68 lines
2.0 KiB
Go
68 lines
2.0 KiB
Go
package pipeline
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
|
|
"aego/core/errs"
|
|
"aego/core/log"
|
|
"aego/project"
|
|
)
|
|
|
|
// resolveMetadata runs under the import lock; importers cannot write metadata or mutate the record.
|
|
// Stable references are persisted before publishing artifacts that use them.
|
|
func (p *Pipeline) resolveMetadata(r *record, ctx *ImportContext) error {
|
|
resolver, ok := r.importer.(MetadataResolver)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
copyMeta := *r.meta
|
|
copyMeta.Settings = r.meta.Settings.Clone()
|
|
copyMeta.Subs = append([]SubAsset(nil), r.meta.Subs...)
|
|
copyCtx := *ctx
|
|
copyCtx.Meta = ©Meta
|
|
settings, err := resolver.ResolveMetadata(©Ctx)
|
|
if err != nil || settings == nil {
|
|
return err
|
|
}
|
|
if bytes.Equal(canonicalSettings(settings), canonicalSettings(r.meta.Settings)) {
|
|
return nil
|
|
}
|
|
if p.shared || p.mode == MetaReadOnly {
|
|
return errs.New(errs.AssetBadMeta, "automatic asset references need a writable metadata owner", log.F("path", r.path))
|
|
}
|
|
path := p.abs(r.path) + MetaSuffix
|
|
before, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return errs.Wrap(err, errs.AssetBadMeta, "cannot read metadata before resolving references")
|
|
}
|
|
disk, err := ParseMeta(before, r.path+MetaSuffix)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if disk.Importer == "" {
|
|
disk.Importer = r.importer.ID()
|
|
}
|
|
for k, v := range r.importer.Defaults() {
|
|
if _, exists := disk.Settings[k]; !exists {
|
|
disk.Settings[k] = v
|
|
}
|
|
}
|
|
if !bytes.Equal(WriteMeta(disk), WriteMeta(r.meta)) {
|
|
return errs.New(errs.AssetSourceUnstable, "metadata changed during reference resolution; rescan before retrying", log.F("path", r.path))
|
|
}
|
|
copyMeta.Settings = settings.Clone()
|
|
after, err := os.ReadFile(path)
|
|
if err != nil || !bytes.Equal(before, after) {
|
|
return errs.New(errs.AssetSourceUnstable, "metadata is still being written", log.F("path", r.path))
|
|
}
|
|
if err := project.WriteAtomic(path, WriteMeta(©Meta)); err != nil {
|
|
return errs.Wrap(err, errs.VFSIO, "cannot persist resolved asset references")
|
|
}
|
|
r.meta = ©Meta
|
|
ctx.Meta = r.meta
|
|
p.metas[r.path+MetaSuffix] = true
|
|
p.rev++
|
|
return nil
|
|
}
|