Load() reads .core/view.yml from any directory via io.Medium, LoadVerified() adds ed25519 signature check. Uses MockMedium for tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
43 lines
1 KiB
Go
43 lines
1 KiB
Go
package manifest
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"fmt"
|
|
"path/filepath"
|
|
|
|
"forge.lthn.ai/core/go/pkg/io"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
const manifestPath = ".core/view.yml"
|
|
|
|
// marshalYAML serializes a manifest to YAML bytes.
|
|
func marshalYAML(m *Manifest) ([]byte, error) {
|
|
return yaml.Marshal(m)
|
|
}
|
|
|
|
// Load reads and parses a .core/view.yml from the given root directory.
|
|
func Load(medium io.Medium, root string) (*Manifest, error) {
|
|
path := filepath.Join(root, manifestPath)
|
|
data, err := medium.Read(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("manifest.Load: %w", err)
|
|
}
|
|
return Parse([]byte(data))
|
|
}
|
|
|
|
// LoadVerified reads, parses, and verifies the ed25519 signature.
|
|
func LoadVerified(medium io.Medium, root string, pub ed25519.PublicKey) (*Manifest, error) {
|
|
m, err := Load(medium, root)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ok, err := Verify(m, pub)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("manifest.LoadVerified: %w", err)
|
|
}
|
|
if !ok {
|
|
return nil, fmt.Errorf("manifest.LoadVerified: signature verification failed for %q", m.Code)
|
|
}
|
|
return m, nil
|
|
}
|