github.com/joselitofilho/goreleaser@v0.155.1-0.20210123221854-e4891856c593/internal/pipe/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 "fmt" 7 "os" 8 "path/filepath" 9 "sort" 10 "strings" 11 12 "github.com/apex/log" 13 "github.com/goreleaser/goreleaser/internal/artifact" 14 "github.com/goreleaser/goreleaser/internal/pipe" 15 "github.com/goreleaser/goreleaser/internal/semerrgroup" 16 "github.com/goreleaser/goreleaser/internal/tmpl" 17 "github.com/goreleaser/goreleaser/pkg/context" 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 if ctx.Config.Checksum.Algorithm == "" { 33 ctx.Config.Checksum.Algorithm = "sha256" 34 } 35 return nil 36 } 37 38 // Run the pipe. 39 func (Pipe) Run(ctx *context.Context) (err error) { 40 if ctx.Config.Checksum.Disable { 41 return pipe.Skip("checksum.disable is set") 42 } 43 filter := artifact.Or( 44 artifact.ByType(artifact.UploadableArchive), 45 artifact.ByType(artifact.UploadableBinary), 46 artifact.ByType(artifact.UploadableSourceArchive), 47 artifact.ByType(artifact.LinuxPackage), 48 ) 49 if len(ctx.Config.Checksum.IDs) > 0 { 50 filter = artifact.And(filter, artifact.ByIDs(ctx.Config.Checksum.IDs...)) 51 } 52 53 artifactList := ctx.Artifacts.Filter(filter).List() 54 if len(artifactList) == 0 { 55 return nil 56 } 57 58 var g = semerrgroup.New(ctx.Parallelism) 59 sumLines := make([]string, len(artifactList)) 60 for i, artifact := range artifactList { 61 i := i 62 artifact := artifact 63 g.Go(func() error { 64 sumLine, err := checksums(ctx.Config.Checksum.Algorithm, artifact) 65 if err != nil { 66 return err 67 } 68 sumLines[i] = sumLine 69 return nil 70 }) 71 } 72 73 err = g.Wait() 74 if err != nil { 75 return err 76 } 77 78 filename, err := tmpl.New(ctx).Apply(ctx.Config.Checksum.NameTemplate) 79 if err != nil { 80 return err 81 } 82 file, err := os.OpenFile( 83 filepath.Join(ctx.Config.Dist, filename), 84 os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 85 0644, 86 ) 87 if err != nil { 88 return err 89 } 90 defer file.Close() 91 92 ctx.Artifacts.Add(&artifact.Artifact{ 93 Type: artifact.Checksum, 94 Path: file.Name(), 95 Name: filename, 96 }) 97 98 // sort to ensure the signature is deterministic downstream 99 sort.Strings(sumLines) 100 _, err = file.WriteString(strings.Join(sumLines, "")) 101 return err 102 } 103 104 func checksums(algorithm string, artifact *artifact.Artifact) (string, error) { 105 log.WithField("file", artifact.Name).Info("checksumming") 106 sha, err := artifact.Checksum(algorithm) 107 if err != nil { 108 return "", err 109 } 110 return fmt.Sprintf("%v %v\n", sha, artifact.Name), nil 111 }