| 
									
										
										
										
											2017-04-14 15:39:32 -03:00
										 |  |  | // Package archive implements the pipe interface with the intent of | 
					
						
							|  |  |  | // archiving and compressing the binaries, readme, and other artifacts. It | 
					
						
							|  |  |  | // also provides an Archive interface which represents an archiving format. | 
					
						
							| 
									
										
										
										
											2017-01-14 19:47:15 -02:00
										 |  |  | package archive | 
					
						
							| 
									
										
										
										
											2016-12-28 22:23:39 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 22:53:56 -02:00
										 |  |  | import ( | 
					
						
							| 
									
										
										
										
											2017-09-09 11:10:08 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2016-12-29 18:10:11 -02:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2017-07-13 20:22:10 -03:00
										 |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2017-12-17 18:01:58 -02:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2016-12-29 18:10:11 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-22 00:09:14 -03:00
										 |  |  | 	"github.com/apex/log" | 
					
						
							| 
									
										
										
										
											2018-01-21 12:59:15 -02:00
										 |  |  | 	"github.com/campoy/unique" | 
					
						
							| 
									
										
										
										
											2018-08-05 10:23:39 -03:00
										 |  |  | 	zglob "github.com/mattn/go-zglob" | 
					
						
							| 
									
										
										
										
											2017-12-17 15:50:09 -02:00
										 |  |  | 	"golang.org/x/sync/errgroup" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/goreleaser/goreleaser/internal/artifact" | 
					
						
							| 
									
										
										
										
											2018-07-08 20:47:30 -07:00
										 |  |  | 	"github.com/goreleaser/goreleaser/internal/tmpl" | 
					
						
							| 
									
										
										
										
											2018-08-05 10:23:39 -03:00
										 |  |  | 	"github.com/goreleaser/goreleaser/pkg/archive" | 
					
						
							| 
									
										
										
										
											2018-08-14 23:50:20 -03:00
										 |  |  | 	"github.com/goreleaser/goreleaser/pkg/context" | 
					
						
							| 
									
										
										
										
											2016-12-28 22:53:56 -02:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2016-12-28 22:23:39 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-26 21:19:58 -02:00
										 |  |  | const ( | 
					
						
							|  |  |  | 	defaultNameTemplate       = "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" | 
					
						
							|  |  |  | 	defaultBinaryNameTemplate = "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2017-12-18 21:32:31 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-14 19:47:15 -02:00
										 |  |  | // Pipe for archive | 
					
						
							| 
									
										
										
										
											2016-12-30 09:27:35 -02:00
										 |  |  | type Pipe struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-02 19:53:19 -02:00
										 |  |  | func (Pipe) String() string { | 
					
						
							|  |  |  | 	return "creating archives" | 
					
						
							| 
									
										
										
										
											2016-12-30 09:27:35 -02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-02 19:53:19 -02:00
										 |  |  | // Default sets the pipe defaults | 
					
						
							|  |  |  | func (Pipe) Default(ctx *context.Context) error { | 
					
						
							| 
									
										
										
										
											2017-12-26 21:19:58 -02:00
										 |  |  | 	var archive = &ctx.Config.Archive | 
					
						
							|  |  |  | 	if archive.Format == "" { | 
					
						
							|  |  |  | 		archive.Format = "tar.gz" | 
					
						
							| 
									
										
										
										
											2017-12-02 19:53:19 -02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-26 21:19:58 -02:00
										 |  |  | 	if len(archive.Files) == 0 { | 
					
						
							|  |  |  | 		archive.Files = []string{ | 
					
						
							| 
									
										
										
										
											2017-12-02 19:53:19 -02:00
										 |  |  | 			"licence*", | 
					
						
							|  |  |  | 			"LICENCE*", | 
					
						
							|  |  |  | 			"license*", | 
					
						
							|  |  |  | 			"LICENSE*", | 
					
						
							|  |  |  | 			"readme*", | 
					
						
							|  |  |  | 			"README*", | 
					
						
							|  |  |  | 			"changelog*", | 
					
						
							|  |  |  | 			"CHANGELOG*", | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-26 21:19:58 -02:00
										 |  |  | 	if archive.NameTemplate == "" { | 
					
						
							| 
									
										
										
										
											2018-02-16 10:35:44 -02:00
										 |  |  | 		archive.NameTemplate = defaultNameTemplate | 
					
						
							| 
									
										
										
										
											2017-12-26 21:19:58 -02:00
										 |  |  | 		if archive.Format == "binary" { | 
					
						
							|  |  |  | 			archive.NameTemplate = defaultBinaryNameTemplate | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-02 19:53:19 -02:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-26 21:19:58 -02:00
										 |  |  | // Run the pipe | 
					
						
							|  |  |  | func (Pipe) Run(ctx *context.Context) error { | 
					
						
							|  |  |  | 	var g errgroup.Group | 
					
						
							|  |  |  | 	var filtered = ctx.Artifacts.Filter(artifact.ByType(artifact.Binary)) | 
					
						
							| 
									
										
										
										
											2018-10-10 13:14:12 -03:00
										 |  |  | 	for group, artifacts := range filtered.GroupByPlatform() { | 
					
						
							|  |  |  | 		log.Debugf("group %s has %d binaries", group, len(artifacts)) | 
					
						
							| 
									
										
										
										
											2017-12-26 21:19:58 -02:00
										 |  |  | 		artifacts := artifacts | 
					
						
							|  |  |  | 		g.Go(func() error { | 
					
						
							| 
									
										
										
										
											2018-03-17 02:52:04 +01:00
										 |  |  | 			if packageFormat(ctx, artifacts[0].Goos) == "binary" { | 
					
						
							| 
									
										
										
										
											2017-12-26 21:19:58 -02:00
										 |  |  | 				return skip(ctx, artifacts) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return create(ctx, artifacts) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return g.Wait() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-29 11:47:13 -02:00
										 |  |  | func create(ctx *context.Context, binaries []artifact.Artifact) error { | 
					
						
							|  |  |  | 	var format = packageFormat(ctx, binaries[0].Goos) | 
					
						
							| 
									
										
										
										
											2018-07-08 20:47:30 -07:00
										 |  |  | 	folder, err := tmpl.New(ctx). | 
					
						
							|  |  |  | 		WithArtifact(binaries[0], ctx.Config.Archive.Replacements). | 
					
						
							|  |  |  | 		Apply(ctx.Config.Archive.NameTemplate) | 
					
						
							| 
									
										
										
										
											2017-12-17 15:50:09 -02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	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", archivePath, err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-17 23:04:29 -02:00
										 |  |  | 	defer archiveFile.Close() // nolint: errcheck | 
					
						
							| 
									
										
										
										
											2018-10-10 12:49:50 -03:00
										 |  |  | 	var log = log.WithField("archive", archivePath) | 
					
						
							|  |  |  | 	log.Info("creating") | 
					
						
							| 
									
										
										
										
											2017-12-17 15:50:09 -02:00
										 |  |  | 	var a = archive.New(archiveFile) | 
					
						
							| 
									
										
										
										
											2017-12-17 23:04:29 -02:00
										 |  |  | 	defer a.Close() // nolint: errcheck | 
					
						
							| 
									
										
										
										
											2017-12-17 15:50:09 -02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	files, err := findFiles(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("failed to find files to archive: %s", err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, f := range files { | 
					
						
							| 
									
										
										
										
											2018-01-21 12:59:15 -02:00
										 |  |  | 		log.Debugf("adding %s", f) | 
					
						
							| 
									
										
										
										
											2017-12-17 15:50:09 -02:00
										 |  |  | 		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()) | 
					
						
							| 
									
										
										
										
											2017-07-13 19:46:48 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-12-17 15:50:09 -02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-29 11:47:13 -02:00
										 |  |  | 	for _, binary := range binaries { | 
					
						
							| 
									
										
										
										
											2018-01-21 12:59:15 -02:00
										 |  |  | 		var bin = wrap(ctx, binary.Name, folder) | 
					
						
							|  |  |  | 		log.Debugf("adding %s", bin) | 
					
						
							|  |  |  | 		if err := a.Add(bin, binary.Path); err != nil { | 
					
						
							| 
									
										
										
										
											2017-12-17 15:50:09 -02:00
										 |  |  | 			return fmt.Errorf("failed to add %s -> %s to the archive: %s", binary.Path, binary.Name, err.Error()) | 
					
						
							| 
									
										
										
										
											2017-07-13 19:46:48 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-05-11 00:05:51 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-17 15:50:09 -02:00
										 |  |  | 	ctx.Artifacts.Add(artifact.Artifact{ | 
					
						
							| 
									
										
										
										
											2017-12-17 16:46:45 -02:00
										 |  |  | 		Type:   artifact.UploadableArchive, | 
					
						
							| 
									
										
										
										
											2017-12-17 15:50:09 -02:00
										 |  |  | 		Name:   folder + "." + format, | 
					
						
							|  |  |  | 		Path:   archivePath, | 
					
						
							| 
									
										
										
										
											2017-12-29 11:47:13 -02:00
										 |  |  | 		Goos:   binaries[0].Goos, | 
					
						
							|  |  |  | 		Goarch: binaries[0].Goarch, | 
					
						
							|  |  |  | 		Goarm:  binaries[0].Goarm, | 
					
						
							| 
									
										
										
										
											2017-12-17 15:50:09 -02:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2017-01-14 12:51:09 -02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2016-12-28 22:53:56 -02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-29 11:47:13 -02:00
										 |  |  | func skip(ctx *context.Context, binaries []artifact.Artifact) error { | 
					
						
							|  |  |  | 	for _, binary := range binaries { | 
					
						
							|  |  |  | 		log.WithField("binary", binary.Name).Info("skip archiving") | 
					
						
							| 
									
										
										
										
											2018-07-08 20:47:30 -07:00
										 |  |  | 		name, err := tmpl.New(ctx). | 
					
						
							|  |  |  | 			WithArtifact(binary, ctx.Config.Archive.Replacements). | 
					
						
							|  |  |  | 			Apply(ctx.Config.Archive.NameTemplate) | 
					
						
							| 
									
										
										
										
											2017-12-17 18:01:58 -02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-12-29 11:47:13 -02:00
										 |  |  | 		binary.Type = artifact.UploadableBinary | 
					
						
							|  |  |  | 		binary.Name = name + binary.Extra["Ext"] | 
					
						
							|  |  |  | 		ctx.Artifacts.Add(binary) | 
					
						
							| 
									
										
										
										
											2017-07-03 00:57:39 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-05 16:38:59 +02:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-11 00:05:51 -03:00
										 |  |  | func findFiles(ctx *context.Context) (result []string, err error) { | 
					
						
							|  |  |  | 	for _, glob := range ctx.Config.Archive.Files { | 
					
						
							| 
									
										
										
										
											2017-05-11 12:43:04 -03:00
										 |  |  | 		files, err := zglob.Glob(glob) | 
					
						
							| 
									
										
										
										
											2017-05-11 00:05:51 -03:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2017-09-09 11:10:08 +02:00
										 |  |  | 			return result, fmt.Errorf("globbing failed for pattern %s: %s", glob, err.Error()) | 
					
						
							| 
									
										
										
										
											2017-05-11 00:05:51 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		result = append(result, files...) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-21 12:59:15 -02:00
										 |  |  | 	// remove duplicates | 
					
						
							|  |  |  | 	unique.Slice(&result, func(i, j int) bool { | 
					
						
							|  |  |  | 		return strings.Compare(result[i], result[j]) < 0 | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2017-05-11 00:05:51 -03:00
										 |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-10-02 18:43:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // 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 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-18 21:15:32 -02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func packageFormat(ctx *context.Context, platform string) string { | 
					
						
							|  |  |  | 	for _, override := range ctx.Config.Archive.FormatOverrides { | 
					
						
							|  |  |  | 		if strings.HasPrefix(platform, override.Goos) { | 
					
						
							|  |  |  | 			return override.Format | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return ctx.Config.Archive.Format | 
					
						
							|  |  |  | } |