I1: a merge writes each module its manifests name, at its directory. I2: a pull request's changed directory, a preview's touched module and a source revision's modules come from the modules bucket (a module a pull request adds is found in the preview by its manifest). I4: the value of today's form (fp, none) is no longer written, since it was computed from the build records; mesh-sdk keeps it readable until R4g. One commit: the three share applyMerged and its tests. Pins mesh-sdk feat/r4e-sdk 9cb4d59.
69 lines
2.7 KiB
Go
69 lines
2.7 KiB
Go
package index
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
)
|
|
|
|
// keepManifest writes manifests.<digest> for a manifest as the forge answered it, create-once (issue 1449): a key that
|
|
// exists with the same value is left and is no error; one that holds another value is an error (it cannot happen for
|
|
// one digest, ManifestDigest being a hash of the bytes, so it says the bucket was written by hand). It answers the
|
|
// digest. A manifest that cannot be a value (empty, not UTF-8, not JSON) is an error the caller says; it is never tried
|
|
// again. With no manifests store nothing is written and the digest is still answered.
|
|
func (ix *Indexer) keepManifest(ctx context.Context, module, raw string) (string, error) {
|
|
digest := delivery.ManifestDigest([]byte(raw))
|
|
if ix.Manifests == nil {
|
|
return digest, nil
|
|
}
|
|
key, err := delivery.ManifestsKey(digest)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
data, err := delivery.EncodeManifest(delivery.Manifest{Module: module, JSON: raw})
|
|
if err != nil {
|
|
return "", fmt.Errorf("%w: manifests.%s: %v", errCannotBeAValue, key, err)
|
|
}
|
|
err = ix.Manifests.Create(ctx, key, data)
|
|
if err == nil {
|
|
return digest, nil
|
|
}
|
|
if !errors.Is(err, ErrConflict) {
|
|
return "", fmt.Errorf("writing manifests.%s: %w", key, err)
|
|
}
|
|
held, _, found, err := ix.Manifests.Get(ctx, key)
|
|
if err != nil {
|
|
return "", fmt.Errorf("reading manifests.%s: %w", key, err)
|
|
}
|
|
if !found {
|
|
return "", fmt.Errorf("manifests.%s was there and is not: written again at the next delivery", key)
|
|
}
|
|
if cur, err := delivery.DecodeManifest(held); err == nil && delivery.SameManifest(cur, delivery.Manifest{V: delivery.Version, Module: module, JSON: raw}) {
|
|
return digest, nil
|
|
}
|
|
return "", fmt.Errorf("manifests.%s holds another value than the manifest of %s, which hashes to it", key, module)
|
|
}
|
|
|
|
// keepManifests writes the manifest of each directory a message carries, and answers the digest of each by directory.
|
|
// A manifest that cannot be kept is left out and said in the log, so the module reads as one with no manifest.
|
|
func (ix *Indexer) keepManifests(ctx context.Context, f delivery.Forge) (map[string]string, error) {
|
|
digests := make(map[string]string, len(f.Manifests))
|
|
for dir, raw := range f.Manifests {
|
|
module := manifestModule(raw) // the name the manifest gives itself: one digest always has one module
|
|
digest, err := ix.keepManifest(ctx, module, raw)
|
|
switch {
|
|
case err == nil:
|
|
digests[dir] = digest
|
|
case errors.Is(err, errCannotBeAValue):
|
|
ix.logf("%s#%d: the manifest of %q cannot be kept: %v", f.Repository, f.Number, dir, err)
|
|
default:
|
|
return nil, err
|
|
}
|
|
}
|
|
return digests, nil
|
|
}
|
|
|
|
var errCannotBeAValue = errors.New("not a manifest value")
|