1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-04-17 12:06:50 +02:00
Carlos Alexandro Becker 3df29b67ab
feat: deprecate gofish (#2999)
* feat: deprecate gofish

gofish was deprecated by its authors, this deprecates it here too

refs https://github.com/goreleaser/goreleaser/discussions/2998

Signed-off-by: Carlos A Becker <caarlos0@gmail.com>

* fix: do not publish rig anymore

Signed-off-by: Carlos A Becker <caarlos0@gmail.com>

* docs: remove install

* chore: deprecate

* fix(gofish): fix broke logs

Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
2022-04-02 10:41:05 -03:00

316 lines
7.3 KiB
Go

package gofish
import (
"bufio"
"bytes"
"errors"
"fmt"
"os"
"path"
"path/filepath"
"strings"
"text/template"
"github.com/apex/log"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/client"
"github.com/goreleaser/goreleaser/internal/commitauthor"
"github.com/goreleaser/goreleaser/internal/deprecate"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
)
const (
goFishConfigExtra = "GoFishConfig"
foodFolder = "Food"
)
var ErrNoArchivesFound = errors.New("no linux/macos/windows archives found")
// Pipe for goFish deployment.
type Pipe struct{}
func (Pipe) String() string { return "gofish fish food cookbook" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.Rigs) == 0 }
func (Pipe) Default(ctx *context.Context) error {
if len(ctx.Config.Rigs) > 0 {
deprecate.Notice(ctx, "rigs")
}
for i := range ctx.Config.Rigs {
goFish := &ctx.Config.Rigs[i]
goFish.CommitAuthor = commitauthor.Default(goFish.CommitAuthor)
if goFish.CommitMessageTemplate == "" {
goFish.CommitMessageTemplate = "GoFish fish food update for {{ .ProjectName }} version {{ .Tag }}"
}
if goFish.Name == "" {
goFish.Name = ctx.Config.ProjectName
}
if goFish.Goarm == "" {
goFish.Goarm = "6"
}
}
return nil
}
func (Pipe) Run(ctx *context.Context) error {
cli, err := client.New(ctx)
if err != nil {
return err
}
return runAll(ctx, cli)
}
func runAll(ctx *context.Context, cli client.Client) error {
for _, goFish := range ctx.Config.Rigs {
err := doRun(ctx, goFish, cli)
if err != nil {
return err
}
}
return nil
}
func doRun(ctx *context.Context, goFish config.GoFish, cl client.Client) error {
if goFish.Rig.Name == "" {
return pipe.Skip("Rigs rig name is not set")
}
filters := []artifact.Filter{
artifact.Or(
artifact.ByGoos("darwin"),
artifact.ByGoos("linux"),
artifact.ByGoos("windows"),
),
artifact.Or(
artifact.ByGoarch("amd64"),
artifact.ByGoarch("arm64"),
artifact.ByGoarch("all"),
artifact.And(
artifact.ByGoarch("arm"),
artifact.ByGoarm(goFish.Goarm),
),
),
artifact.Or(
artifact.ByType(artifact.UploadableArchive),
artifact.ByType(artifact.UploadableBinary),
),
artifact.OnlyReplacingUnibins,
}
if len(goFish.IDs) > 0 {
filters = append(filters, artifact.ByIDs(goFish.IDs...))
}
archives := ctx.Artifacts.Filter(artifact.And(filters...)).List()
if len(archives) == 0 {
return ErrNoArchivesFound
}
name, err := tmpl.New(ctx).Apply(goFish.Name)
if err != nil {
return err
}
goFish.Name = name
content, err := buildFood(ctx, goFish, cl, archives)
if err != nil {
return err
}
filename := goFish.Name + ".lua"
luaPath := filepath.Join(ctx.Config.Dist, filename)
log.WithField("food", luaPath).Info("writing")
if err := os.WriteFile(luaPath, []byte(content), 0o644); err != nil { //nolint: gosec
return fmt.Errorf("failed to write gofish food: %w", err)
}
ctx.Artifacts.Add(&artifact.Artifact{
Name: filename,
Path: luaPath,
Type: artifact.GoFishRig,
Extra: map[string]interface{}{
goFishConfigExtra: goFish,
},
})
return nil
}
func buildFood(ctx *context.Context, goFish config.GoFish, client client.Client, artifacts []*artifact.Artifact) (string, error) {
data, err := dataFor(ctx, goFish, client, artifacts)
if err != nil {
return "", err
}
return doBuildFood(ctx, data)
}
func doBuildFood(ctx *context.Context, data templateData) (string, error) {
t, err := template.
New(data.Name).
Parse(foodTemplate)
if err != nil {
return "", err
}
var out bytes.Buffer
if err := t.Execute(&out, data); err != nil {
return "", err
}
content, err := tmpl.New(ctx).Apply(out.String())
if err != nil {
return "", err
}
out.Reset()
// Sanitize the template output and get rid of trailing whitespace.
var (
r = strings.NewReader(content)
s = bufio.NewScanner(r)
)
for s.Scan() {
l := strings.TrimRight(s.Text(), " ")
_, _ = out.WriteString(l)
_ = out.WriteByte('\n')
}
if err := s.Err(); err != nil {
return "", err
}
return out.String(), nil
}
func dataFor(ctx *context.Context, cfg config.GoFish, cl client.Client, artifacts []*artifact.Artifact) (templateData, error) {
result := templateData{
Name: cfg.Name,
Desc: cfg.Description,
Homepage: cfg.Homepage,
Version: ctx.Version,
License: cfg.License,
}
for _, art := range artifacts {
sum, err := art.Checksum("sha256")
if err != nil {
return result, err
}
if cfg.URLTemplate == "" {
url, err := cl.ReleaseURLTemplate(ctx)
if err != nil {
return result, err
}
cfg.URLTemplate = url
}
url, err := tmpl.New(ctx).WithArtifact(art, map[string]string{}).Apply(cfg.URLTemplate)
if err != nil {
return result, err
}
goarch := []string{art.Goarch}
if art.Goarch == "all" {
goarch = []string{"amd64", "arm64"}
}
for _, arch := range goarch {
releasePackage := releasePackage{
DownloadURL: url,
SHA256: sum,
OS: art.Goos,
Arch: arch,
Binaries: []binary{},
}
switch art.Type {
case artifact.UploadableArchive:
for _, bin := range art.ExtraOr(artifact.ExtraBinaries, []string{}).([]string) {
releasePackage.Binaries = append(releasePackage.Binaries, binary{
Name: bin,
Target: bin,
})
}
case artifact.UploadableBinary:
releasePackage.Binaries = append(releasePackage.Binaries, binary{
Name: art.Name,
Target: art.ExtraOr(artifact.ExtraBinary, art.Name).(string),
})
}
result.ReleasePackages = append(result.ReleasePackages, releasePackage)
}
}
return result, nil
}
// Publish gofish rig.
func (Pipe) Publish(ctx *context.Context) error {
cli, err := client.New(ctx)
if err != nil {
return err
}
return publishAll(ctx, cli)
}
func publishAll(ctx *context.Context, cli client.Client) error {
skips := pipe.SkipMemento{}
for _, rig := range ctx.Artifacts.Filter(artifact.ByType(artifact.GoFishRig)).List() {
err := doPublish(ctx, rig, cli)
if err != nil && pipe.IsSkip(err) {
skips.Remember(err)
continue
}
if err != nil {
return err
}
}
return skips.Evaluate()
}
func doPublish(ctx *context.Context, food *artifact.Artifact, cl client.Client) error {
rig := food.Extra[goFishConfigExtra].(config.GoFish)
var err error
cl, err = client.NewIfToken(ctx, cl, rig.Rig.Token)
if err != nil {
return err
}
if strings.TrimSpace(rig.SkipUpload) == "true" {
return pipe.Skip("rig.skip_upload is set")
}
if strings.TrimSpace(rig.SkipUpload) == "auto" && ctx.Semver.Prerelease != "" {
return pipe.Skip("prerelease detected with 'auto' upload, skipping gofish publish")
}
repo := client.RepoFromRef(rig.Rig)
gpath := buildFoodPath(foodFolder, food.Name)
log.WithField("food", gpath).
WithField("repo", repo.String()).
Info("pushing")
msg, err := tmpl.New(ctx).Apply(rig.CommitMessageTemplate)
if err != nil {
return err
}
author, err := commitauthor.Get(ctx, rig.CommitAuthor)
if err != nil {
return err
}
content, err := os.ReadFile(food.Path)
if err != nil {
return err
}
return cl.CreateFile(ctx, author, repo, content, gpath, msg)
}
func buildFoodPath(folder, filename string) string {
return path.Join(folder, filename)
}