github.com/ahmet2mir/goreleaser@v0.180.3-0.20210927151101-8e5ee5a9b8c5/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/extrafiles" 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 { return "calculating checksums" } 24 func (Pipe) Skip(ctx *context.Context) bool { return ctx.Config.Checksum.Disable } 25 26 // Default sets the pipe defaults. 27 func (Pipe) Default(ctx *context.Context) error { 28 if ctx.Config.Checksum.NameTemplate == "" { 29 ctx.Config.Checksum.NameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt" 30 } 31 if ctx.Config.Checksum.Algorithm == "" { 32 ctx.Config.Checksum.Algorithm = "sha256" 33 } 34 return nil 35 } 36 37 // Run the pipe. 38 func (Pipe) Run(ctx *context.Context) (err error) { 39 filter := artifact.Or( 40 artifact.ByType(artifact.UploadableArchive), 41 artifact.ByType(artifact.UploadableBinary), 42 artifact.ByType(artifact.UploadableSourceArchive), 43 artifact.ByType(artifact.LinuxPackage), 44 ) 45 if len(ctx.Config.Checksum.IDs) > 0 { 46 filter = artifact.And(filter, artifact.ByIDs(ctx.Config.Checksum.IDs...)) 47 } 48 49 artifactList := ctx.Artifacts.Filter(filter).List() 50 if len(artifactList) == 0 { 51 return nil 52 } 53 54 extraFiles, err := extrafiles.Find(ctx.Config.Checksum.ExtraFiles) 55 if err != nil { 56 return err 57 } 58 59 for name, path := range extraFiles { 60 artifactList = append(artifactList, &artifact.Artifact{ 61 Name: name, 62 Path: path, 63 Type: artifact.UploadableFile, 64 }) 65 } 66 67 g := semerrgroup.New(ctx.Parallelism) 68 sumLines := make([]string, len(artifactList)) 69 for i, artifact := range artifactList { 70 i := i 71 artifact := artifact 72 g.Go(func() error { 73 sumLine, err := checksums(ctx.Config.Checksum.Algorithm, artifact) 74 if err != nil { 75 return err 76 } 77 sumLines[i] = sumLine 78 return nil 79 }) 80 } 81 82 err = g.Wait() 83 if err != nil { 84 return err 85 } 86 87 filename, err := tmpl.New(ctx).Apply(ctx.Config.Checksum.NameTemplate) 88 if err != nil { 89 return err 90 } 91 file, err := os.OpenFile( 92 filepath.Join(ctx.Config.Dist, filename), 93 os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 94 0o644, 95 ) 96 if err != nil { 97 return err 98 } 99 defer file.Close() 100 101 ctx.Artifacts.Add(&artifact.Artifact{ 102 Type: artifact.Checksum, 103 Path: file.Name(), 104 Name: filename, 105 }) 106 107 // sort to ensure the signature is deterministic downstream 108 sort.Strings(sumLines) 109 _, err = file.WriteString(strings.Join(sumLines, "")) 110 return err 111 } 112 113 func checksums(algorithm string, artifact *artifact.Artifact) (string, error) { 114 log.WithField("file", artifact.Name).Info("checksumming") 115 sha, err := artifact.Checksum(algorithm) 116 if err != nil { 117 return "", err 118 } 119 return fmt.Sprintf("%v %v\n", sha, artifact.Name), nil 120 }