1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-26 04:22:05 +02:00
Carlos Alexandro Becker a209757ad2
feat: better archives relative paths (#3656)
with this patch, a config like:

```yaml
archives:
  - format: tar.gz
    # this name template makes the OS and Arch compatible with the results of uname.
    name_template: >-
      {{ .ProjectName }}_
      {{- title .Os }}_
      {{- if eq .Arch "amd64" }}x86_64
      {{- else if eq .Arch "386" }}i386
      {{- else }}{{ .Arch }}{{ end }}
      {{- if .Arm }}v{{ .Arm }}{{ end }}
    rlcp: true
    files:
      - src: "build/**/*"
        dst: .

nfpms:
  - package_name: foo
    contents:
      - src: "build/**/*"
        dst: usr/share/foo
    formats:
      - apk

```

will eval this:

<img width="1384" alt="CleanShot 2022-12-21 at 22 21 00@2x"
src="https://user-images.githubusercontent.com/245435/209034244-7c31b5f7-cfcd-4825-bb2f-7dd463c5286a.png">

as much as I would like to make this the default, it would be a breaking
change, so we really can't do it.

If `dst` is empty, it'll have the same behavior as before (no rlcp), and
if `strip_parent` is set, it will also still have the same behavior.
Finally, if the format is binary, `rlcp` is ignored too (as it doesn't
make sense).

So, this only changes if:
- your format is not binary; and
- you have files with `src` and `dst` set

Then, goreleaser will warn you to set `rlcp: true`.

## todo

- [x] docs
- [x] more tests probably
- [x] any ideas for a better name for the new config option?

fixes #3655

Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>
2022-12-27 17:42:55 -03:00

121 lines
2.9 KiB
Go

// Package sourcearchive archives the source of the project using git-archive.
package sourcearchive
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/caarlos0/log"
"github.com/goreleaser/goreleaser/internal/archivefiles"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/deprecate"
"github.com/goreleaser/goreleaser/internal/git"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/archive"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
)
// Pipe for source archive.
type Pipe struct{}
func (Pipe) String() string {
return "creating source archive"
}
func (Pipe) Skip(ctx *context.Context) bool {
return !ctx.Config.Source.Enabled
}
// Run the pipe.
func (Pipe) Run(ctx *context.Context) (err error) {
name, err := tmpl.New(ctx).Apply(ctx.Config.Source.NameTemplate)
if err != nil {
return err
}
filename := name + "." + ctx.Config.Source.Format
path := filepath.Join(ctx.Config.Dist, filename)
log.WithField("file", filename).Info("creating source archive")
out, err := git.Run(ctx, "ls-files")
if err != nil {
return fmt.Errorf("could not list source files: %w", err)
}
prefix, err := tmpl.New(ctx).Apply(ctx.Config.Source.PrefixTemplate)
if err != nil {
return err
}
af, err := os.Create(path)
if err != nil {
return fmt.Errorf("could not create archive: %w", err)
}
defer af.Close() //nolint:errcheck
arch, err := archive.New(af, ctx.Config.Source.Format)
if err != nil {
return err
}
var ff []config.File
for _, f := range strings.Split(out, "\n") {
if strings.TrimSpace(f) == "" {
continue
}
ff = append(ff, config.File{
Source: f,
})
}
files, err := archivefiles.Eval(
tmpl.New(ctx),
ctx.Config.Source.RLCP,
append(ff, ctx.Config.Source.Files...),
)
if err != nil {
return err
}
for _, f := range files {
f.Destination = filepath.Join(prefix, f.Destination)
if err := arch.Add(f); err != nil {
return fmt.Errorf("could not add %q to archive: %w", f.Source, err)
}
}
if err := arch.Close(); err != nil {
return fmt.Errorf("could not close archive file: %w", err)
}
if err := af.Close(); err != nil {
return fmt.Errorf("could not close archive file: %w", err)
}
ctx.Artifacts.Add(&artifact.Artifact{
Type: artifact.UploadableSourceArchive,
Name: filename,
Path: path,
Extra: map[string]interface{}{
artifact.ExtraFormat: ctx.Config.Source.Format,
},
})
return err
}
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
archive := &ctx.Config.Source
if archive.Format == "" {
archive.Format = "tar.gz"
}
if archive.NameTemplate == "" {
archive.NameTemplate = "{{ .ProjectName }}-{{ .Version }}"
}
if archive.Enabled && !archive.RLCP {
deprecate.NoticeCustom(ctx, "source.rlcp", "`{{ .Property }}` will be the default soon, check {{ .URL }} for more info")
}
return nil
}