mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-06-06 23:46:42 +02:00
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
This commit is contained in:
parent
457041ff3d
commit
7e79db1cc2
@ -1,9 +1,16 @@
|
|||||||
// Package artifact provides the core artifact storage for goreleaser
|
// Package artifact provides the core artifact storage for goreleaser
|
||||||
package artifact
|
package artifact
|
||||||
|
|
||||||
|
// nolint: gosec
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/sha1"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"crypto/sha512"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"hash/crc32"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
@ -78,20 +85,39 @@ func (a Artifact) ExtraOr(key string, or interface{}) interface{} {
|
|||||||
return a.Extra[key]
|
return a.Extra[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checksum calculates the SHA256 checksum of the artifact.
|
// Checksum calculates the checksum of the artifact.
|
||||||
func (a Artifact) Checksum() (string, error) {
|
// nolint: gosec
|
||||||
log.Debugf("calculating sha256sum for %s", a.Path)
|
func (a Artifact) Checksum(algorithm string) (string, error) {
|
||||||
|
log.Debugf("calculating checksum for %s", a.Path)
|
||||||
file, err := os.Open(a.Path)
|
file, err := os.Open(a.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "failed to checksum")
|
return "", errors.Wrap(err, "failed to checksum")
|
||||||
}
|
}
|
||||||
defer file.Close() // nolint: errcheck
|
defer file.Close() // nolint: errcheck
|
||||||
var hash = sha256.New()
|
var h hash.Hash
|
||||||
_, err = io.Copy(hash, file)
|
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 {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "failed to checksum")
|
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
|
// Artifacts is a list of artifacts
|
||||||
|
@ -149,20 +149,43 @@ func TestChecksum(t *testing.T) {
|
|||||||
Path: file,
|
Path: file,
|
||||||
}
|
}
|
||||||
|
|
||||||
sum, err := artifact.Checksum()
|
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.NoError(t, err)
|
||||||
require.Equal(t, "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269", sum)
|
require.Equal(t, result, sum)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChecksumFileDoesntExist(t *testing.T) {
|
func TestChecksumFileDoesntExist(t *testing.T) {
|
||||||
var artifact = Artifact{
|
var artifact = Artifact{
|
||||||
Path: "/tmp/adasdasdas/asdasd/asdas",
|
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.EqualError(t, err, `failed to checksum: open /tmp/adasdasdas/asdasd/asdas: no such file or directory`)
|
||||||
require.Empty(t, sum)
|
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) {
|
func TestExtraOr(t *testing.T) {
|
||||||
var a = Artifact{
|
var a = Artifact{
|
||||||
Extra: map[string]interface{}{
|
Extra: map[string]interface{}{
|
||||||
|
@ -207,7 +207,7 @@ func uploadAsset(ctx *context.Context, put *config.Put, artifact artifact.Artifa
|
|||||||
|
|
||||||
var headers = map[string]string{}
|
var headers = map[string]string{}
|
||||||
if put.ChecksumHeader != "" {
|
if put.ChecksumHeader != "" {
|
||||||
sum, err := artifact.Checksum()
|
sum, err := artifact.Checksum("sha256")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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) {
|
func dataFor(ctx *context.Context, artifact artifact.Artifact) (result templateData, err error) {
|
||||||
sum, err := artifact.Checksum()
|
sum, err := artifact.Checksum("sha256")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,9 @@ func (Pipe) Default(ctx *context.Context) error {
|
|||||||
if ctx.Config.Checksum.NameTemplate == "" {
|
if ctx.Config.Checksum.NameTemplate == "" {
|
||||||
ctx.Config.Checksum.NameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
|
ctx.Config.Checksum.NameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
|
||||||
}
|
}
|
||||||
|
if ctx.Config.Checksum.Algorithm == "" {
|
||||||
|
ctx.Config.Checksum.Algorithm = "sha256"
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +59,7 @@ func (Pipe) Run(ctx *context.Context) (err error) {
|
|||||||
).List() {
|
).List() {
|
||||||
artifact := artifact
|
artifact := artifact
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
return checksums(file, artifact)
|
return checksums(ctx.Config.Checksum.Algorithm, file, artifact)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ctx.Artifacts.Add(artifact.Artifact{
|
ctx.Artifacts.Add(artifact.Artifact{
|
||||||
@ -67,9 +70,9 @@ func (Pipe) Run(ctx *context.Context) (err error) {
|
|||||||
return g.Wait()
|
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")
|
log.WithField("file", artifact.Name).Info("checksumming")
|
||||||
sha, err := artifact.Checksum()
|
sha, err := artifact.Checksum(algorithm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ func TestPipe(t *testing.T) {
|
|||||||
ProjectName: binary,
|
ProjectName: binary,
|
||||||
Checksum: config.Checksum{
|
Checksum: config.Checksum{
|
||||||
NameTemplate: "{{ .ProjectName }}_{{ .Env.FOO }}_checksums.txt",
|
NameTemplate: "{{ .ProjectName }}_{{ .Env.FOO }}_checksums.txt",
|
||||||
|
Algorithm: "sha256",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -142,6 +143,7 @@ func TestDefault(t *testing.T) {
|
|||||||
"{{ .ProjectName }}_{{ .Version }}_checksums.txt",
|
"{{ .ProjectName }}_{{ .Version }}_checksums.txt",
|
||||||
ctx.Config.Checksum.NameTemplate,
|
ctx.Config.Checksum.NameTemplate,
|
||||||
)
|
)
|
||||||
|
assert.Equal(t, "sha256", ctx.Config.Checksum.Algorithm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaultSet(t *testing.T) {
|
func TestDefaultSet(t *testing.T) {
|
||||||
|
@ -138,7 +138,7 @@ func buildManifest(ctx *context.Context, artifacts []artifact.Artifact) (bytes.B
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sum, err := artifact.Checksum()
|
sum, err := artifact.Checksum("sha256")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
@ -238,6 +238,7 @@ type Snapshot struct {
|
|||||||
// Checksum config
|
// Checksum config
|
||||||
type Checksum struct {
|
type Checksum struct {
|
||||||
NameTemplate string `yaml:"name_template,omitempty"`
|
NameTemplate string `yaml:"name_template,omitempty"`
|
||||||
|
Algorithm string `yaml:"algorithm,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Docker image config
|
// Docker image config
|
||||||
|
@ -16,6 +16,11 @@ checksum:
|
|||||||
# You can change the name of the checksums file.
|
# You can change the name of the checksums file.
|
||||||
# Default is `{{ .ProjectName }}_{{ .Version }}_checksums.txt`.
|
# Default is `{{ .ProjectName }}_{{ .Version }}_checksums.txt`.
|
||||||
name_template: "{{ .ProjectName }}_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).
|
> Learn more about the [name template engine](/templates).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user