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 | ||||
|  | ||||
| // 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). | ||||
|   | ||||
		Reference in New Issue
	
	Block a user