Execute incremental analysis artifact plans
This commit is contained in:
@@ -291,6 +291,41 @@ func (c *ArtifactCatalog) MarkAvailableGenerated(sourceID, path string) error {
|
||||
return c.markAvailable(sourceID, path, ArtifactProvenanceGeneratedCurrentAnalyzeRun)
|
||||
}
|
||||
|
||||
// MarkAvailableGeneratedEvidence marks one source as available from the
|
||||
// current analyze invocation and retains the semantic output identity needed
|
||||
// by later scheduled dependents.
|
||||
func (c *ArtifactCatalog) MarkAvailableGeneratedEvidence(
|
||||
sourceID, path, producerRunID, checksum string,
|
||||
size int64,
|
||||
contract *artifactmodel.ContractMetadata,
|
||||
) error {
|
||||
producerRunID = strings.TrimSpace(producerRunID)
|
||||
checksum = strings.TrimSpace(checksum)
|
||||
if err := ValidateRunIdentity(producerRunID); err != nil {
|
||||
return fmt.Errorf("generated artifact producer run id: %w", err)
|
||||
}
|
||||
if err := validateSHA256(checksum); err != nil {
|
||||
return fmt.Errorf("generated artifact checksum: %w", err)
|
||||
}
|
||||
if size <= 0 {
|
||||
return fmt.Errorf("generated artifact size must be positive")
|
||||
}
|
||||
if contract == nil || strings.TrimSpace(contract.MediaType) == "" ||
|
||||
strings.TrimSpace(contract.SchemaID) == "" || strings.TrimSpace(contract.SchemaVersion) == "" {
|
||||
return fmt.Errorf("generated artifact contract is incomplete")
|
||||
}
|
||||
if err := c.markAvailable(sourceID, path, ArtifactProvenanceGeneratedCurrentAnalyzeRun); err != nil {
|
||||
return err
|
||||
}
|
||||
entry := c.entries[strings.TrimSpace(sourceID)]
|
||||
entry.ProducerRunID = producerRunID
|
||||
entry.Checksum = checksum
|
||||
entry.Size = size
|
||||
entry.Contract = cloneArtifactContract(contract)
|
||||
c.entries[entry.SourceID] = entry
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ArtifactCatalog) markAvailableFromExtractManifest(
|
||||
sourceID, path, producerRunID, checksum string,
|
||||
size int64,
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package artifacts
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifactmodel"
|
||||
)
|
||||
|
||||
func TestArtifactCatalogRegisterBuiltInsAndLookup(t *testing.T) {
|
||||
catalog := NewArtifactCatalog()
|
||||
@@ -179,6 +184,30 @@ func TestArtifactCatalogMarkAvailableGenerated(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestArtifactCatalogMarkAvailableGeneratedEvidence(t *testing.T) {
|
||||
catalog := NewArtifactCatalog()
|
||||
if err := catalog.RegisterConfiguredArtifacts(map[string]ConfiguredArtifactDefinition{
|
||||
"session_recap": {Enabled: true, OutputPath: "artifacts/session_recap.md"},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sourceID, _ := catalog.SourceIDForConfiguredKey("session_recap")
|
||||
contract := &artifactmodel.ContractMetadata{
|
||||
MediaType: "text/markdown", SchemaID: "narratio.session_recap", SchemaVersion: "1",
|
||||
}
|
||||
checksum := strings.Repeat("a", 64)
|
||||
if err := catalog.MarkAvailableGeneratedEvidence(
|
||||
sourceID, "/tmp/session_recap.md", "run-1", checksum, 42, contract,
|
||||
); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
entry, _ := catalog.Lookup(sourceID)
|
||||
if !entry.Available || entry.ProducerRunID != "run-1" || entry.Checksum != checksum || entry.Size != 42 ||
|
||||
entry.Contract == nil || *entry.Contract != *contract {
|
||||
t.Fatalf("generated evidence entry = %#v", entry)
|
||||
}
|
||||
}
|
||||
|
||||
func TestArtifactCatalogLookupPlannedButUnavailable(t *testing.T) {
|
||||
catalog := NewArtifactCatalog()
|
||||
if err := catalog.RegisterConfiguredArtifacts(
|
||||
|
||||
Reference in New Issue
Block a user