github.com/client9/goreleaser@v0.17.4-0.20170511023544-27e4b028926d/pipeline/fpm/fpm.go (about)

     1  // Package fpm implements the Pipe interface providing FPM bindings.
     2  package fpm
     3  
     4  import (
     5  	"errors"
     6  	"log"
     7  	"os/exec"
     8  	"path/filepath"
     9  
    10  	"github.com/goreleaser/goreleaser/context"
    11  	"golang.org/x/sync/errgroup"
    12  )
    13  
    14  var goarchToUnix = map[string]string{
    15  	"386":   "i386",
    16  	"amd64": "x86_64",
    17  }
    18  
    19  // ErrNoFPM is shown when fpm cannot be found in $PATH
    20  var ErrNoFPM = errors.New("fpm not present in $PATH")
    21  
    22  // Pipe for fpm packaging
    23  type Pipe struct{}
    24  
    25  // Description of the pipe
    26  func (Pipe) Description() string {
    27  	return "Creating Linux packages with fpm"
    28  }
    29  
    30  // Run the pipe
    31  func (Pipe) Run(ctx *context.Context) error {
    32  	if len(ctx.Config.FPM.Formats) == 0 {
    33  		log.Println("No output formats configured, skipping")
    34  		return nil
    35  	}
    36  	_, err := exec.LookPath("fpm")
    37  	if err != nil {
    38  		return ErrNoFPM
    39  	}
    40  
    41  	var g errgroup.Group
    42  	for _, format := range ctx.Config.FPM.Formats {
    43  		for _, goarch := range ctx.Config.Build.Goarch {
    44  			if ctx.Archives["linux"+goarch] == "" {
    45  				continue
    46  			}
    47  			archive := ctx.Archives["linux"+goarch]
    48  			arch := goarchToUnix[goarch]
    49  			g.Go(func() error {
    50  				return create(ctx, format, archive, arch)
    51  			})
    52  		}
    53  	}
    54  	return g.Wait()
    55  }
    56  
    57  func create(ctx *context.Context, format, archive, arch string) error {
    58  	var path = filepath.Join(ctx.Config.Dist, archive)
    59  	var file = path + "." + format
    60  	var name = ctx.Config.Build.Binary
    61  	log.Println("Creating", file)
    62  
    63  	var options = []string{
    64  		"--input-type", "dir",
    65  		"--output-type", format,
    66  		"--name", name,
    67  		"--version", ctx.Version,
    68  		"--architecture", arch,
    69  		"--chdir", path,
    70  		"--package", file,
    71  		"--force",
    72  	}
    73  
    74  	if ctx.Config.FPM.Vendor != "" {
    75  		options = append(options, "--vendor", ctx.Config.FPM.Vendor)
    76  	}
    77  	if ctx.Config.FPM.Homepage != "" {
    78  		options = append(options, "--url", ctx.Config.FPM.Homepage)
    79  	}
    80  	if ctx.Config.FPM.Maintainer != "" {
    81  		options = append(options, "--maintainer", ctx.Config.FPM.Maintainer)
    82  	}
    83  	if ctx.Config.FPM.Description != "" {
    84  		options = append(options, "--description", ctx.Config.FPM.Description)
    85  	}
    86  	if ctx.Config.FPM.License != "" {
    87  		options = append(options, "--license", ctx.Config.FPM.License)
    88  	}
    89  	for _, dep := range ctx.Config.FPM.Dependencies {
    90  		options = append(options, "--depends", dep)
    91  	}
    92  	for _, conflict := range ctx.Config.FPM.Conflicts {
    93  		options = append(options, "--conflicts", conflict)
    94  	}
    95  
    96  	// This basically tells fpm to put the binary in the /usr/local/bin
    97  	// binary=/usr/local/bin/binary
    98  	options = append(options, name+"="+filepath.Join("/usr/local/bin", name))
    99  
   100  	if out, err := exec.Command("fpm", options...).CombinedOutput(); err != nil {
   101  		return errors.New(string(out))
   102  	}
   103  	ctx.AddArtifact(file)
   104  	return nil
   105  }