github.com/triarius/goreleaser@v1.12.5/internal/pipe/sourcearchive/source.go (about)

     1  // Package sourcearchive archives the source of the project using git-archive.
     2  package sourcearchive
     3  
     4  import (
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/caarlos0/log"
    11  	"github.com/triarius/goreleaser/internal/archivefiles"
    12  	"github.com/triarius/goreleaser/internal/artifact"
    13  	"github.com/triarius/goreleaser/internal/git"
    14  	"github.com/triarius/goreleaser/internal/tmpl"
    15  	"github.com/triarius/goreleaser/pkg/archive"
    16  	"github.com/triarius/goreleaser/pkg/config"
    17  	"github.com/triarius/goreleaser/pkg/context"
    18  )
    19  
    20  // Pipe for source archive.
    21  type Pipe struct{}
    22  
    23  func (Pipe) String() string {
    24  	return "creating source archive"
    25  }
    26  
    27  func (Pipe) Skip(ctx *context.Context) bool {
    28  	return !ctx.Config.Source.Enabled
    29  }
    30  
    31  // Run the pipe.
    32  func (Pipe) Run(ctx *context.Context) (err error) {
    33  	name, err := tmpl.New(ctx).Apply(ctx.Config.Source.NameTemplate)
    34  	if err != nil {
    35  		return err
    36  	}
    37  	filename := name + "." + ctx.Config.Source.Format
    38  	path := filepath.Join(ctx.Config.Dist, filename)
    39  	log.WithField("file", filename).Info("creating source archive")
    40  
    41  	out, err := git.Run(ctx, "ls-files")
    42  	if err != nil {
    43  		return fmt.Errorf("could not list source files: %w", err)
    44  	}
    45  
    46  	prefix, err := tmpl.New(ctx).Apply(ctx.Config.Source.PrefixTemplate)
    47  	if err != nil {
    48  		return err
    49  	}
    50  
    51  	af, err := os.Create(path)
    52  	if err != nil {
    53  		return fmt.Errorf("could not create archive: %w", err)
    54  	}
    55  	defer af.Close() //nolint:errcheck
    56  
    57  	arch, err := archive.New(af, ctx.Config.Source.Format)
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	var ff []config.File
    63  	for _, f := range strings.Split(out, "\n") {
    64  		if strings.TrimSpace(f) == "" {
    65  			continue
    66  		}
    67  		ff = append(ff, config.File{
    68  			Source: f,
    69  		})
    70  	}
    71  	files, err := archivefiles.Eval(tmpl.New(ctx), append(ff, ctx.Config.Source.Files...))
    72  	if err != nil {
    73  		return err
    74  	}
    75  	for _, f := range files {
    76  		f.Destination = filepath.Join(prefix, f.Destination)
    77  		if err := arch.Add(f); err != nil {
    78  			return fmt.Errorf("could not add %q to archive: %w", f.Source, err)
    79  		}
    80  	}
    81  
    82  	if err := arch.Close(); err != nil {
    83  		return fmt.Errorf("could not close archive file: %w", err)
    84  	}
    85  	if err := af.Close(); err != nil {
    86  		return fmt.Errorf("could not close archive file: %w", err)
    87  	}
    88  
    89  	ctx.Artifacts.Add(&artifact.Artifact{
    90  		Type: artifact.UploadableSourceArchive,
    91  		Name: filename,
    92  		Path: path,
    93  		Extra: map[string]interface{}{
    94  			artifact.ExtraFormat: ctx.Config.Source.Format,
    95  		},
    96  	})
    97  	return err
    98  }
    99  
   100  // Default sets the pipe defaults.
   101  func (Pipe) Default(ctx *context.Context) error {
   102  	archive := &ctx.Config.Source
   103  	if archive.Format == "" {
   104  		archive.Format = "tar.gz"
   105  	}
   106  
   107  	if archive.NameTemplate == "" {
   108  		archive.NameTemplate = "{{ .ProjectName }}-{{ .Version }}"
   109  	}
   110  	return nil
   111  }