Skip to content
Permalink
Browse files

feat: support different checksum algorithms (#951)

* feat: support different checksum algorithms

* feat: added more algorithms

Co-Authored-By: caarlos0 <caarlos0@users.noreply.github.com>

* fix: build
  • Loading branch information...
caarlos0 committed Feb 4, 2019
1 parent 457041f commit 7e79db1cc290eb184b0d6ffa6073be6611a8234c
@@ -1,9 +1,16 @@
// Package artifact provides the core artifact storage for goreleaser
package artifact

// nolint: gosec
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"fmt"
"hash"
"hash/crc32"
"io"
"os"
"sync"
@@ -78,20 +85,39 @@ func (a Artifact) ExtraOr(key string, or interface{}) interface{} {
return a.Extra[key]
}

// Checksum calculates the SHA256 checksum of the artifact.
func (a Artifact) Checksum() (string, error) {
log.Debugf("calculating sha256sum for %s", a.Path)
// Checksum calculates the checksum of the artifact.
// nolint: gosec
func (a Artifact) Checksum(algorithm string) (string, error) {
log.Debugf("calculating checksum for %s", a.Path)
file, err := os.Open(a.Path)
if err != nil {
return "", errors.Wrap(err, "failed to checksum")
}
defer file.Close() // nolint: errcheck
var hash = sha256.New()
_, err = io.Copy(hash, file)
var h hash.Hash
switch algorithm {
case "crc32":
h = crc32.NewIEEE()
case "md5":
h = md5.New()
case "sha224":
h = sha256.New224()
case "sha384":
h = sha512.New384()
case "sha256":
h = sha256.New()
case "sha1":
h = sha1.New()
case "sha512":
h = sha512.New()
default:
return "", fmt.Errorf("invalid algorith: %s", algorithm)
}
_, err = io.Copy(h, file)
if err != nil {
return "", errors.Wrap(err, "failed to checksum")
}
return hex.EncodeToString(hash.Sum(nil)), nil
return hex.EncodeToString(h.Sum(nil)), nil
}

// Artifacts is a list of artifacts
@@ -149,20 +149,43 @@ func TestChecksum(t *testing.T) {
Path: file,
}

sum, err := artifact.Checksum()
require.NoError(t, err)
require.Equal(t, "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269", sum)
for algo, result := range map[string]string{
"sha256": "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269",
"sha512": "f80eebd9aabb1a15fb869ed568d858a5c0dca3d5da07a410e1bd988763918d973e344814625f7c844695b2de36ffd27af290d0e34362c51dee5947d58d40527a",
"sha1": "bfb7759a67daeb65410490b4d98bb9da7d1ea2ce",
"crc32": "72d7748e",
"md5": "80a751fde577028640c419000e33eba6",
"sha224": "e191edf06005712583518ced92cc2ac2fac8d6e4623b021a50736a91",
"sha384": "597493a6cf1289757524e54dfd6f68b332c7214a716a3358911ef5c09907adc8a654a18c1d721e183b0025f996f6e246",
} {
t.Run(algo, func(t *testing.T) {
sum, err := artifact.Checksum(algo)
require.NoError(t, err)
require.Equal(t, result, sum)
})
}
}

func TestChecksumFileDoesntExist(t *testing.T) {
var artifact = Artifact{
Path: "/tmp/adasdasdas/asdasd/asdas",
}
sum, err := artifact.Checksum()
sum, err := artifact.Checksum("sha1")
require.EqualError(t, err, `failed to checksum: open /tmp/adasdasdas/asdasd/asdas: no such file or directory`)
require.Empty(t, sum)
}

func TestInvalidAlgorithm(t *testing.T) {
f, err := ioutil.TempFile("", "")
require.NoError(t, err)
var artifact = Artifact{
Path: f.Name(),
}
sum, err := artifact.Checksum("sha1ssss")
require.EqualError(t, err, `invalid algorith: sha1ssss`)
require.Empty(t, sum)
}

func TestExtraOr(t *testing.T) {
var a = Artifact{
Extra: map[string]interface{}{
@@ -207,7 +207,7 @@ func uploadAsset(ctx *context.Context, put *config.Put, artifact artifact.Artifa

var headers = map[string]string{}
if put.ChecksumHeader != "" {
sum, err := artifact.Checksum()
sum, err := artifact.Checksum("sha256")
if err != nil {
return err
}
@@ -175,7 +175,7 @@ func doBuildFormula(data templateData) (out bytes.Buffer, err error) {
}

func dataFor(ctx *context.Context, artifact artifact.Artifact) (result templateData, err error) {
sum, err := artifact.Checksum()
sum, err := artifact.Checksum("sha256")
if err != nil {
return
}
@@ -27,6 +27,9 @@ func (Pipe) Default(ctx *context.Context) error {
if ctx.Config.Checksum.NameTemplate == "" {
ctx.Config.Checksum.NameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
}
if ctx.Config.Checksum.Algorithm == "" {
ctx.Config.Checksum.Algorithm = "sha256"
}
return nil
}

@@ -56,7 +59,7 @@ func (Pipe) Run(ctx *context.Context) (err error) {
).List() {
artifact := artifact
g.Go(func() error {
return checksums(file, artifact)
return checksums(ctx.Config.Checksum.Algorithm, file, artifact)
})
}
ctx.Artifacts.Add(artifact.Artifact{
@@ -67,9 +70,9 @@ func (Pipe) Run(ctx *context.Context) (err error) {
return g.Wait()
}

func checksums(file *os.File, artifact artifact.Artifact) error {
func checksums(algorithm string, file *os.File, artifact artifact.Artifact) error {
log.WithField("file", artifact.Name).Info("checksumming")
sha, err := artifact.Checksum()
sha, err := artifact.Checksum(algorithm)
if err != nil {
return err
}
@@ -29,6 +29,7 @@ func TestPipe(t *testing.T) {
ProjectName: binary,
Checksum: config.Checksum{
NameTemplate: "{{ .ProjectName }}_{{ .Env.FOO }}_checksums.txt",
Algorithm: "sha256",
},
},
)
@@ -142,6 +143,7 @@ func TestDefault(t *testing.T) {
"{{ .ProjectName }}_{{ .Version }}_checksums.txt",
ctx.Config.Checksum.NameTemplate,
)
assert.Equal(t, "sha256", ctx.Config.Checksum.Algorithm)
}

func TestDefaultSet(t *testing.T) {
@@ -138,7 +138,7 @@ func buildManifest(ctx *context.Context, artifacts []artifact.Artifact) (bytes.B
return result, err
}

sum, err := artifact.Checksum()
sum, err := artifact.Checksum("sha256")
if err != nil {
return result, err
}
@@ -238,6 +238,7 @@ type Snapshot struct {
// Checksum config
type Checksum struct {
NameTemplate string `yaml:"name_template,omitempty"`
Algorithm string `yaml:"algorithm,omitempty"`
}

// Docker image config
@@ -16,6 +16,11 @@ checksum:
# You can change the name of the checksums file.
# Default is `{{ .ProjectName }}_{{ .Version }}_checksums.txt`.
name_template: "{{ .ProjectName }}_checksums.txt"
# Algorithm to be used.
# Accepted options are sha256, sha512, sha1, crc32, md5, sha224 and sha384.
# Default is sha256.
algorithm: sha256
```

> Learn more about the [name template engine](/templates).

0 comments on commit 7e79db1

Please sign in to comment.
You can’t perform that action at this time.