You've already forked goreleaser
							
							
				mirror of
				https://github.com/goreleaser/goreleaser.git
				synced 2025-10-30 23:58:09 +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:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						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{ | ||||||
| 	require.NoError(t, err) | 		"sha256": "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269", | ||||||
| 	require.Equal(t, "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269", sum) | 		"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) { | 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). | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user