63 lines
1.6 KiB
Go
63 lines
1.6 KiB
Go
// Package artifact owns shared build artifact identity rules.
|
|
package artifact
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
const ManifestFilename = "SHA256SUMS"
|
|
|
|
type Target struct {
|
|
OS string
|
|
Arch string
|
|
}
|
|
|
|
type Declaration struct {
|
|
Target Target
|
|
Filename string
|
|
}
|
|
|
|
// NormalizeTargets removes duplicate targets while preserving their first
|
|
// occurrence.
|
|
func NormalizeTargets(targets []Target) []Target {
|
|
seen := make(map[Target]struct{}, len(targets))
|
|
result := make([]Target, 0, len(targets))
|
|
for _, target := range targets {
|
|
if _, ok := seen[target]; ok {
|
|
continue
|
|
}
|
|
seen[target] = struct{}{}
|
|
result = append(result, target)
|
|
}
|
|
return result
|
|
}
|
|
|
|
// ValidComponent reports whether value is a nonempty filename component under
|
|
// the build and receipt contracts.
|
|
func ValidComponent(value string) bool {
|
|
return value != "" && !strings.ContainsAny(value, "/\\\r\n")
|
|
}
|
|
|
|
// Filename returns the declared binary filename for one target.
|
|
func Filename(binaryName, version string, target Target) string {
|
|
filename := fmt.Sprintf("%s-%s-%s-%s", binaryName, version, target.OS, target.Arch)
|
|
if target.OS == "windows" {
|
|
filename += ".exe"
|
|
}
|
|
return filename
|
|
}
|
|
|
|
// ExpectedBuild returns artifact declarations in target order. Callers retain
|
|
// responsibility for validating their boundary-specific build identity.
|
|
func ExpectedBuild(binaryName, version string, targets []Target) []Declaration {
|
|
declarations := make([]Declaration, 0, len(targets))
|
|
for _, target := range targets {
|
|
declarations = append(declarations, Declaration{
|
|
Target: target,
|
|
Filename: Filename(binaryName, version, target),
|
|
})
|
|
}
|
|
return declarations
|
|
}
|