You've already forked goreleaser
							
							
				mirror of
				https://github.com/goreleaser/goreleaser.git
				synced 2025-10-30 23:58:09 +02:00 
			
		
		
		
	feat: Add archive config 'wrap_in_directory'
The field is optional. When set to true, files in archive are wrapped in a directory, which has the same name as the archive itself. Tests have also been extended to cover this. Closes #251
This commit is contained in:
		| @@ -106,6 +106,7 @@ type Archive struct { | ||||
| 	Format          string            `yaml:",omitempty"` | ||||
| 	FormatOverrides []FormatOverride  `yaml:"format_overrides,omitempty"` | ||||
| 	NameTemplate    string            `yaml:"name_template,omitempty"` | ||||
| 	WrapInDirectory bool              `yaml:"wrap_in_directory,omitempty"` | ||||
| 	Replacements    map[string]string `yaml:",omitempty"` | ||||
| 	Files           []string          `yaml:",omitempty"` | ||||
|  | ||||
|   | ||||
| @@ -23,6 +23,13 @@ archive: | ||||
|   # Default is `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`. | ||||
|   name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" | ||||
|  | ||||
|   # Set to true, if you want all files in the archive to be in a single directory. | ||||
|   # If set to true and you extract the archive 'goreleaser_Linux_arm64.tar.gz', | ||||
|   # you get a folder 'goreleaser_Linux_arm64'. | ||||
|   # If set to false, all files are extracted separately. | ||||
|   # Default is false. | ||||
|   wrap_in_directory: true | ||||
|  | ||||
|   # Archive format. Valid options are `tar.gz`, `zip` and `binary`. | ||||
|   # If format is `binary`, no archives are created and the binaries are instead uploaded directly. | ||||
|   # In that case name_template and the below specified files are ignored. | ||||
|   | ||||
| @@ -43,31 +43,39 @@ func (Pipe) Run(ctx *context.Context) error { | ||||
| func create(ctx *context.Context, platform string, groups map[string][]context.Binary) error { | ||||
| 	for folder, binaries := range groups { | ||||
| 		var format = archiveformat.For(ctx, platform) | ||||
| 		targetFolder := filepath.Join(ctx.Config.Dist, folder+"."+format) | ||||
| 		file, err := os.Create(targetFolder) | ||||
| 		archivePath := filepath.Join(ctx.Config.Dist, folder+"."+format) | ||||
| 		archiveFile, err := os.Create(archivePath) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("failed to create directory %s: %s", targetFolder, err.Error()) | ||||
| 			return fmt.Errorf("failed to create directory %s: %s", archivePath, err.Error()) | ||||
| 		} | ||||
| 		defer func() { _ = file.Close() }() | ||||
| 		log.WithField("archive", file.Name()).Info("creating") | ||||
| 		var archive = archive.New(file) | ||||
| 		defer func() { _ = archive.Close() }() | ||||
| 		defer func() { | ||||
| 			if e := archiveFile.Close(); e != nil { | ||||
| 				log.WithField("archive", archivePath).Errorf("failed to close file: %v", e) | ||||
| 			} | ||||
| 		}() | ||||
| 		log.WithField("archive", archivePath).Info("creating") | ||||
| 		var a = archive.New(archiveFile) | ||||
| 		defer func() { | ||||
| 			if e := a.Close(); e != nil { | ||||
| 				log.WithField("archive", archivePath).Errorf("failed to close archive: %v", e) | ||||
| 			} | ||||
| 		}() | ||||
|  | ||||
| 		files, err := findFiles(ctx) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("failed to find files to archive: %s", err.Error()) | ||||
| 		} | ||||
| 		for _, f := range files { | ||||
| 			if err = archive.Add(f, f); err != nil { | ||||
| 			if err = a.Add(wrap(ctx, f, folder), f); err != nil { | ||||
| 				return fmt.Errorf("failed to add %s to the archive: %s", f, err.Error()) | ||||
| 			} | ||||
| 		} | ||||
| 		for _, binary := range binaries { | ||||
| 			if err := archive.Add(binary.Name, binary.Path); err != nil { | ||||
| 			if err := a.Add(wrap(ctx, binary.Name, folder), binary.Path); err != nil { | ||||
| 				return fmt.Errorf("failed to add %s -> %s to the archive: %s", binary.Path, binary.Name, err.Error()) | ||||
| 			} | ||||
| 		} | ||||
| 		ctx.AddArtifact(file.Name()) | ||||
| 		ctx.AddArtifact(archivePath) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @@ -92,3 +100,11 @@ func findFiles(ctx *context.Context) (result []string, err error) { | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // Wrap archive files with folder if set in config. | ||||
| func wrap(ctx *context.Context, name, folder string) string { | ||||
| 	if ctx.Config.Archive.WrapInDirectory { | ||||
| 		return filepath.Join(folder, name) | ||||
| 	} | ||||
| 	return name | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,9 @@ | ||||
| package archive | ||||
|  | ||||
| import ( | ||||
| 	"archive/tar" | ||||
| 	"compress/gzip" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
| @@ -52,6 +55,23 @@ func TestRunPipe(t *testing.T) { | ||||
| 			assert.NoError(t, Pipe{}.Run(ctx)) | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	// Check archive contents | ||||
| 	f, err := os.Open(filepath.Join(dist, "mybin_darwin_amd64.tar.gz")) | ||||
| 	assert.NoError(t, err) | ||||
| 	defer func() { assert.NoError(t, f.Close()) }() | ||||
| 	gr, err := gzip.NewReader(f) | ||||
| 	assert.NoError(t, err) | ||||
| 	defer func() { assert.NoError(t, gr.Close()) }() | ||||
| 	r := tar.NewReader(gr) | ||||
| 	for _, n := range []string{"README.md", "mybin"} { | ||||
| 		h, err := r.Next() | ||||
| 		if err == io.EOF { | ||||
| 			break | ||||
| 		} | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, n, h.Name) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestRunPipeBinary(t *testing.T) { | ||||
| @@ -132,3 +152,46 @@ func TestRunPipeGlobFailsToAdd(t *testing.T) { | ||||
| 	ctx.AddBinary("windows386", "mybin", "mybin", "dist/mybin") | ||||
| 	assert.Error(t, Pipe{}.Run(ctx)) | ||||
| } | ||||
|  | ||||
| func TestRunPipeWrap(t *testing.T) { | ||||
| 	folder, back := testlib.Mktmp(t) | ||||
| 	defer back() | ||||
| 	var dist = filepath.Join(folder, "dist") | ||||
| 	assert.NoError(t, os.Mkdir(dist, 0755)) | ||||
| 	assert.NoError(t, os.Mkdir(filepath.Join(dist, "mybin_darwin_amd64"), 0755)) | ||||
| 	_, err := os.Create(filepath.Join(dist, "mybin_darwin_amd64", "mybin")) | ||||
| 	assert.NoError(t, err) | ||||
| 	_, err = os.Create(filepath.Join(folder, "README.md")) | ||||
| 	assert.NoError(t, err) | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config: config.Project{ | ||||
| 			Dist: dist, | ||||
| 			Archive: config.Archive{ | ||||
| 				WrapInDirectory: true, | ||||
| 				Format:          "tar.gz", | ||||
| 				Files: []string{ | ||||
| 					"README.*", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	ctx.AddBinary("darwinamd64", "mybin_darwin_amd64", "mybin", filepath.Join(dist, "mybin_darwin_amd64", "mybin")) | ||||
| 	assert.NoError(t, Pipe{}.Run(ctx)) | ||||
|  | ||||
| 	// Check archive contents | ||||
| 	f, err := os.Open(filepath.Join(dist, "mybin_darwin_amd64.tar.gz")) | ||||
| 	assert.NoError(t, err) | ||||
| 	defer func() { assert.NoError(t, f.Close()) }() | ||||
| 	gr, err := gzip.NewReader(f) | ||||
| 	assert.NoError(t, err) | ||||
| 	defer func() { assert.NoError(t, gr.Close()) }() | ||||
| 	r := tar.NewReader(gr) | ||||
| 	for _, n := range []string{"README.md", "mybin"} { | ||||
| 		h, err := r.Next() | ||||
| 		if err == io.EOF { | ||||
| 			break | ||||
| 		} | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, filepath.Join("mybin_darwin_amd64", n), h.Name) | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user