diff --git a/config/config.go b/config/config.go index 1004a2ff9..85050f69b 100644 --- a/config/config.go +++ b/config/config.go @@ -34,6 +34,11 @@ type GitInfo struct { Diff string } +// ArchiveConfig +type ArchiveConfig struct { + Format string +} + // ProjectConfig includes all project configuration type ProjectConfig struct { Repo string @@ -43,6 +48,7 @@ type ProjectConfig struct { Token string `yaml:"-"` Build BuildConfig Git GitInfo `yaml:"-"` + Archive ArchiveConfig } // Load config file @@ -106,6 +112,9 @@ func (config *ProjectConfig) fillBasicData() { if len(config.Build.Arches) == 0 { config.Build.Arches = []string{"amd64", "386"} } + if config.Archive.Format == "" { + config.Archive.Format = "tar.gz" + } } func (config *ProjectConfig) fillGitData() (err error) { diff --git a/config/config_test.go b/config/config_test.go index 110f6178a..0cdad4a76 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -13,6 +13,7 @@ func TestFillBasicData(t *testing.T) { config.fillBasicData() assert.Equal("main.go", config.Build.Main) + assert.Equal("tar.gz", config.Archive.Format) assert.Contains(config.Build.Oses, "darwin") assert.Contains(config.Build.Oses, "linux") assert.Contains(config.Build.Arches, "386") diff --git a/pipeline/brew/brew.go b/pipeline/brew/brew.go index ff9b59483..07c7df8ee 100644 --- a/pipeline/brew/brew.go +++ b/pipeline/brew/brew.go @@ -18,7 +18,7 @@ import ( const formulae = `class {{ .Name }} < Formula desc "{{ .Desc }}" homepage "{{ .Homepage }}" - url "https://github.com/{{ .Repo }}/releases/download/{{ .Tag }}/{{ .BinaryName }}_#{%x(uname -s).gsub(/\n/, '')}_#{%x(uname -m).gsub(/\n/, '')}.tar.gz" + url "https://github.com/{{ .Repo }}/releases/download/{{ .Tag }}/{{ .BinaryName }}_#{%x(uname -s).gsub(/\n/, '')}_#{%x(uname -m).gsub(/\n/, '')}.{{ .Format }}" head "https://github.com/{{ .Repo }}.git" version "{{ .Tag }}" @@ -36,7 +36,7 @@ end ` type templateData struct { - Name, Desc, Homepage, Repo, Tag, BinaryName, Caveats string + Name, Desc, Homepage, Repo, Tag, BinaryName, Caveats, Format string } // Pipe for brew deployment @@ -138,6 +138,7 @@ func dataFor(config config.ProjectConfig, client *github.Client) (result templat Tag: config.Git.CurrentTag, BinaryName: config.BinaryName, Caveats: config.Brew.Caveats, + Format: config.Archive.Format, }, err } diff --git a/pipeline/brew/brew_test.go b/pipeline/brew/brew_test.go index 310cfa046..f188bd5c4 100644 --- a/pipeline/brew/brew_test.go +++ b/pipeline/brew/brew_test.go @@ -25,6 +25,7 @@ var defaultTemplateData = templateData{ Name: "Test", Repo: "caarlos0/test", Tag: "v0.1.3", + Format: "tar.gz", } func assertDefaultTemplateData(t *testing.T, formulae string) { diff --git a/pipeline/compress/compress.go b/pipeline/compress/compress.go index fd0a7efa6..861709e6b 100644 --- a/pipeline/compress/compress.go +++ b/pipeline/compress/compress.go @@ -1,13 +1,12 @@ package compress import ( - "archive/tar" - "compress/gzip" - "io" "log" "os" "github.com/goreleaser/releaser/config" + "github.com/goreleaser/releaser/pipeline/compress/tar" + "github.com/goreleaser/releaser/pipeline/compress/zip" "github.com/goreleaser/releaser/uname" "golang.org/x/sync/errgroup" ) @@ -35,51 +34,33 @@ func (Pipe) Run(config config.ProjectConfig) error { return g.Wait() } +type Archive interface { + Close() error + Add(name, path string) error +} + func create(system, arch string, config config.ProjectConfig) error { - file, err := os.Create("dist/" + nameFor(system, arch, config.BinaryName) + ".tar.gz") + file, err := os.Create("dist/" + nameFor(system, arch, config.BinaryName) + "." + config.Archive.Format) log.Println("Creating", file.Name(), "...") if err != nil { return err } - gw := gzip.NewWriter(file) - tw := tar.NewWriter(gw) - defer func() { - _ = tw.Close() - _ = gw.Close() - _ = file.Close() - }() + defer func() { _ = file.Close() }() + var archive = archiveFor(file, config.Archive.Format) + defer func() { _ = archive.Close() }() for _, f := range config.Files { - if err := addFile(tw, f, f); err != nil { + if err := archive.Add(f, f); err != nil { return err } } - return addFile(tw, config.BinaryName+ext(system), binaryPath(system, arch, config.BinaryName)) + return archive.Add(config.BinaryName+ext(system), binaryPath(system, arch, config.BinaryName)) } -func addFile(tw *tar.Writer, name, path string) (err error) { - file, err := os.Open(path) - if err != nil { - return +func archiveFor(file *os.File, format string) Archive { + if format == "zip" { + return zip.New(file) } - defer func() { - _ = file.Close() - }() - stat, err := file.Stat() - if err != nil { - return - } - header := new(tar.Header) - header.Name = name - header.Size = stat.Size() - header.Mode = int64(stat.Mode()) - header.ModTime = stat.ModTime() - if err := tw.WriteHeader(header); err != nil { - return err - } - if _, err := io.Copy(tw, file); err != nil { - return err - } - return + return tar.New(file) } func nameFor(system, arch, binary string) string { diff --git a/pipeline/compress/tar/tar.go b/pipeline/compress/tar/tar.go new file mode 100644 index 000000000..ee023325b --- /dev/null +++ b/pipeline/compress/tar/tar.go @@ -0,0 +1,58 @@ +package tar + +import ( + "archive/tar" + "compress/gzip" + "io" + "os" +) + +type Archive struct { + gw *gzip.Writer + tw *tar.Writer +} + +func (a Archive) Close() error { + if err := a.tw.Close(); err != nil { + return err + } + if err := a.gw.Close(); err != nil { + return err + } + return nil +} + +func New(target *os.File) Archive { + gw := gzip.NewWriter(target) + tw := tar.NewWriter(gw) + return Archive{ + gw: gw, + tw: tw, + } +} + +func (a Archive) Add(name, path string) (err error) { + file, err := os.Open(path) + if err != nil { + return + } + defer func() { + _ = file.Close() + }() + stat, err := file.Stat() + if err != nil { + return + } + header := new(tar.Header) + header.Name = name + header.Size = stat.Size() + header.Mode = int64(stat.Mode()) + header.ModTime = stat.ModTime() + if err := a.tw.WriteHeader(header); err != nil { + return err + } + if _, err := io.Copy(a.tw, file); err != nil { + return err + } + return +} diff --git a/pipeline/compress/zip/zip.go b/pipeline/compress/zip/zip.go new file mode 100644 index 000000000..b79bfd95d --- /dev/null +++ b/pipeline/compress/zip/zip.go @@ -0,0 +1,35 @@ +package zip + +import ( + "archive/zip" + "io" + "os" +) + +type Archive struct { + z *zip.Writer +} + +func (a Archive) Close() error { + return a.z.Close() +} + +func New(target *os.File) Archive { + return Archive{ + z: zip.NewWriter(target), + } +} + +func (a Archive) Add(name, path string) (err error) { + file, err := os.Open(path) + if err != nil { + return + } + defer func() { _ = file.Close() }() + f, err := a.z.Create(name) + if err != nil { + return err + } + _, err = io.Copy(f, file) + return err +} diff --git a/pipeline/release/release.go b/pipeline/release/release.go index 9f3c463e4..bf71d97b6 100644 --- a/pipeline/release/release.go +++ b/pipeline/release/release.go @@ -46,7 +46,7 @@ func (Pipe) Run(config config.ProjectConfig) error { system := system arch := arch g.Go(func() error { - return upload(client, *r.ID, owner, repo, system, arch, config.BinaryName) + return upload(client, *r.ID, system, arch, config) }) } } @@ -63,8 +63,9 @@ func description(diff string) string { return result + "\nBuilt with " + string(bts) } -func upload(client *github.Client, releaseID int, owner, repo, system, arch, binaryName string) error { - name := binaryName + "_" + uname.FromGo(system) + "_" + uname.FromGo(arch) + ".tar.gz" +func upload(client *github.Client, releaseID int, system, arch string, config config.ProjectConfig) error { + owner, repo := split.OnSlash(config.Repo) + name := config.BinaryName + "_" + uname.FromGo(system) + "_" + uname.FromGo(arch) + "." + config.Archive.Format file, err := os.Open("dist/" + name) if err != nil { return err