github.com/szyn/goreleaser@v0.76.1-0.20180517112710-333da09a1297/pipeline/checksums/checksums.go (about) 1 // Package checksums provides a Pipe that creates .checksums files for 2 // each artifact. 3 package checksums 4 5 import ( 6 "bytes" 7 "fmt" 8 "os" 9 "path/filepath" 10 "text/template" 11 12 "github.com/apex/log" 13 "golang.org/x/sync/errgroup" 14 15 "github.com/goreleaser/goreleaser/checksum" 16 "github.com/goreleaser/goreleaser/context" 17 "github.com/goreleaser/goreleaser/internal/artifact" 18 ) 19 20 // Pipe for checksums 21 type Pipe struct{} 22 23 func (Pipe) String() string { 24 return "calculating checksums" 25 } 26 27 // Default sets the pipe defaults 28 func (Pipe) Default(ctx *context.Context) error { 29 if ctx.Config.Checksum.NameTemplate == "" { 30 ctx.Config.Checksum.NameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt" 31 } 32 return nil 33 } 34 35 // Run the pipe 36 func (Pipe) Run(ctx *context.Context) (err error) { 37 filename, err := filenameFor(ctx) 38 if err != nil { 39 return err 40 } 41 file, err := os.OpenFile( 42 filepath.Join(ctx.Config.Dist, filename), 43 os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 44 0444, 45 ) 46 if err != nil { 47 return err 48 } 49 defer file.Close() // nolint: errcheck 50 51 var g errgroup.Group 52 var semaphore = make(chan bool, ctx.Parallelism) 53 for _, artifact := range ctx.Artifacts.Filter( 54 artifact.Or( 55 artifact.ByType(artifact.UploadableArchive), 56 artifact.ByType(artifact.UploadableBinary), 57 artifact.ByType(artifact.LinuxPackage), 58 ), 59 ).List() { 60 semaphore <- true 61 artifact := artifact 62 g.Go(func() error { 63 defer func() { 64 <-semaphore 65 }() 66 return checksums(ctx, file, artifact) 67 }) 68 } 69 ctx.Artifacts.Add(artifact.Artifact{ 70 Type: artifact.Checksum, 71 Path: file.Name(), 72 Name: filename, 73 }) 74 return g.Wait() 75 } 76 77 func checksums(ctx *context.Context, file *os.File, artifact artifact.Artifact) error { 78 log.WithField("file", artifact.Name).Info("checksumming") 79 sha, err := checksum.SHA256(artifact.Path) 80 if err != nil { 81 return err 82 } 83 _, err = file.WriteString(fmt.Sprintf("%v %v\n", sha, artifact.Name)) 84 return err 85 } 86 87 func filenameFor(ctx *context.Context) (string, error) { 88 var out bytes.Buffer 89 t, err := template.New("checksums"). 90 Option("missingkey=error"). 91 Parse(ctx.Config.Checksum.NameTemplate) 92 if err != nil { 93 return "", err 94 } 95 err = t.Execute(&out, struct { 96 ProjectName string 97 Tag string 98 Version string 99 Env map[string]string 100 }{ 101 ProjectName: ctx.Config.ProjectName, 102 Tag: ctx.Git.CurrentTag, 103 Version: ctx.Version, 104 Env: ctx.Env, 105 }) 106 return out.String(), err 107 }