Add reconciliation state foundation
This commit is contained in:
82
internal/state/outputs.go
Normal file
82
internal/state/outputs.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OutputProjection struct {
|
||||
Path string
|
||||
Kind string
|
||||
SourcePath string
|
||||
Transform string
|
||||
URL string
|
||||
SHA256 string
|
||||
Size int64
|
||||
}
|
||||
|
||||
func FindOutputByPath(outputs []OutputFile, path string) (OutputFile, bool) {
|
||||
for _, output := range outputs {
|
||||
if output.Path == path {
|
||||
return output, true
|
||||
}
|
||||
}
|
||||
return OutputFile{}, false
|
||||
}
|
||||
|
||||
func MergeOutputFiles(retained, planned []OutputFile) ([]OutputFile, error) {
|
||||
outputs := make([]OutputFile, 0, len(retained)+len(planned))
|
||||
indexByPath := make(map[string]int, len(retained)+len(planned))
|
||||
for _, output := range retained {
|
||||
if _, exists := indexByPath[output.Path]; exists {
|
||||
return nil, fmt.Errorf("state output path %q is duplicated", output.Path)
|
||||
}
|
||||
indexByPath[output.Path] = len(outputs)
|
||||
outputs = append(outputs, output)
|
||||
}
|
||||
seenPlanned := make(map[string]struct{}, len(planned))
|
||||
for _, output := range planned {
|
||||
if _, exists := seenPlanned[output.Path]; exists {
|
||||
return nil, fmt.Errorf("state output path %q is duplicated", output.Path)
|
||||
}
|
||||
seenPlanned[output.Path] = struct{}{}
|
||||
if index, exists := indexByPath[output.Path]; exists {
|
||||
outputs[index] = output
|
||||
continue
|
||||
}
|
||||
indexByPath[output.Path] = len(outputs)
|
||||
outputs = append(outputs, output)
|
||||
}
|
||||
return outputs, nil
|
||||
}
|
||||
|
||||
func ManagedOutputPaths(s DistributorState) []string {
|
||||
paths := make([]string, 0, len(s.Outputs))
|
||||
for _, output := range s.Outputs {
|
||||
paths = append(paths, output.Path)
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
func ProjectOutputs(outputs []OutputProjection, existing []OutputFile, now time.Time) []OutputFile {
|
||||
now = now.UTC()
|
||||
files := make([]OutputFile, 0, len(outputs))
|
||||
for _, output := range outputs {
|
||||
createdAt := now
|
||||
if existingOutput, ok := FindOutputByPath(existing, output.Path); ok {
|
||||
createdAt = existingOutput.CreatedAt
|
||||
}
|
||||
files = append(files, OutputFile{
|
||||
Path: output.Path,
|
||||
Kind: output.Kind,
|
||||
SourcePath: output.SourcePath,
|
||||
Transform: output.Transform,
|
||||
URL: output.URL,
|
||||
SHA256: output.SHA256,
|
||||
Size: output.Size,
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: now,
|
||||
})
|
||||
}
|
||||
return files
|
||||
}
|
||||
Reference in New Issue
Block a user