2017-04-14 20:39:32 +02:00
|
|
|
// Package fpm implements the Pipe interface providing FPM bindings.
|
2017-01-30 01:55:32 +02:00
|
|
|
package fpm
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
2017-06-28 00:36:36 +02:00
|
|
|
"fmt"
|
2017-07-01 17:58:48 +02:00
|
|
|
"io/ioutil"
|
2017-01-30 01:55:32 +02:00
|
|
|
"os/exec"
|
|
|
|
"path/filepath"
|
2017-07-01 17:58:48 +02:00
|
|
|
"strings"
|
2017-01-30 01:55:32 +02:00
|
|
|
|
2017-06-22 05:09:14 +02:00
|
|
|
"github.com/apex/log"
|
2017-01-30 01:55:32 +02:00
|
|
|
"github.com/goreleaser/goreleaser/context"
|
2017-01-30 02:01:26 +02:00
|
|
|
"golang.org/x/sync/errgroup"
|
2017-01-30 01:55:32 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
// ErrNoFPM is shown when fpm cannot be found in $PATH
|
|
|
|
var ErrNoFPM = errors.New("fpm not present in $PATH")
|
|
|
|
|
|
|
|
// Pipe for fpm packaging
|
|
|
|
type Pipe struct{}
|
|
|
|
|
|
|
|
// Description of the pipe
|
|
|
|
func (Pipe) Description() string {
|
|
|
|
return "Creating Linux packages with fpm"
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run the pipe
|
|
|
|
func (Pipe) Run(ctx *context.Context) error {
|
2017-01-30 02:01:26 +02:00
|
|
|
if len(ctx.Config.FPM.Formats) == 0 {
|
2017-06-22 15:47:34 +02:00
|
|
|
log.Info("no output formats configured, skipping")
|
2017-01-30 02:01:26 +02:00
|
|
|
return nil
|
|
|
|
}
|
2017-01-30 11:53:05 +02:00
|
|
|
_, err := exec.LookPath("fpm")
|
|
|
|
if err != nil {
|
2017-01-30 01:55:32 +02:00
|
|
|
return ErrNoFPM
|
|
|
|
}
|
2017-01-30 02:33:08 +02:00
|
|
|
|
2017-01-30 01:55:32 +02:00
|
|
|
var g errgroup.Group
|
|
|
|
for _, format := range ctx.Config.FPM.Formats {
|
2017-07-01 17:58:48 +02:00
|
|
|
for key, folder := range ctx.Folders {
|
2017-07-01 18:02:41 +02:00
|
|
|
if !strings.Contains(key, "linux") {
|
|
|
|
log.WithField("key", key).Debug("skipped non-linux builds for fpm")
|
|
|
|
continue
|
|
|
|
}
|
2017-07-01 17:58:48 +02:00
|
|
|
folder := folder
|
|
|
|
format := format
|
|
|
|
arch := archFor(key)
|
|
|
|
g.Go(func() error {
|
|
|
|
return create(ctx, format, folder, arch)
|
|
|
|
})
|
2017-01-30 01:55:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return g.Wait()
|
|
|
|
}
|
|
|
|
|
2017-07-01 17:58:48 +02:00
|
|
|
func archFor(key string) string {
|
|
|
|
if strings.Contains(key, "386") {
|
|
|
|
return "i386"
|
|
|
|
}
|
|
|
|
return "x86_64"
|
|
|
|
}
|
|
|
|
|
|
|
|
func create(ctx *context.Context, format, folder, arch string) error {
|
|
|
|
var path = filepath.Join(ctx.Config.Dist, folder)
|
2017-04-22 15:41:58 +02:00
|
|
|
var file = path + "." + format
|
2017-07-01 17:58:48 +02:00
|
|
|
log.WithField("file", file).Info("creating fpm archive")
|
2017-01-30 01:55:32 +02:00
|
|
|
|
|
|
|
var options = []string{
|
2017-02-01 19:40:27 +02:00
|
|
|
"--input-type", "dir",
|
|
|
|
"--output-type", format,
|
2017-06-28 00:36:36 +02:00
|
|
|
"--name", ctx.Config.Name,
|
2017-02-01 19:40:27 +02:00
|
|
|
"--version", ctx.Version,
|
|
|
|
"--architecture", arch,
|
|
|
|
"--chdir", path,
|
|
|
|
"--package", file,
|
2017-01-30 01:55:32 +02:00
|
|
|
"--force",
|
|
|
|
}
|
2017-04-21 11:28:19 +02:00
|
|
|
|
2017-04-21 22:02:28 +02:00
|
|
|
if ctx.Config.FPM.Vendor != "" {
|
|
|
|
options = append(options, "--vendor", ctx.Config.FPM.Vendor)
|
2017-04-21 11:28:19 +02:00
|
|
|
}
|
2017-04-21 22:02:28 +02:00
|
|
|
if ctx.Config.FPM.Homepage != "" {
|
|
|
|
options = append(options, "--url", ctx.Config.FPM.Homepage)
|
2017-04-21 11:28:19 +02:00
|
|
|
}
|
2017-04-21 22:02:28 +02:00
|
|
|
if ctx.Config.FPM.Maintainer != "" {
|
|
|
|
options = append(options, "--maintainer", ctx.Config.FPM.Maintainer)
|
2017-04-21 11:28:19 +02:00
|
|
|
}
|
2017-04-21 22:02:28 +02:00
|
|
|
if ctx.Config.FPM.Description != "" {
|
|
|
|
options = append(options, "--description", ctx.Config.FPM.Description)
|
2017-04-21 11:28:19 +02:00
|
|
|
}
|
2017-04-21 22:02:28 +02:00
|
|
|
if ctx.Config.FPM.License != "" {
|
|
|
|
options = append(options, "--license", ctx.Config.FPM.License)
|
2017-04-21 11:28:19 +02:00
|
|
|
}
|
2017-01-30 02:33:08 +02:00
|
|
|
for _, dep := range ctx.Config.FPM.Dependencies {
|
2017-02-01 19:40:27 +02:00
|
|
|
options = append(options, "--depends", dep)
|
2017-01-30 01:55:32 +02:00
|
|
|
}
|
2017-02-01 19:40:27 +02:00
|
|
|
for _, conflict := range ctx.Config.FPM.Conflicts {
|
|
|
|
options = append(options, "--conflicts", conflict)
|
|
|
|
}
|
|
|
|
|
2017-07-01 17:58:48 +02:00
|
|
|
files, err := ioutil.ReadDir(path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, file := range files {
|
|
|
|
// XXX: skip non executable files here?
|
2017-06-28 00:36:36 +02:00
|
|
|
// This basically tells fpm to put the binary in the /usr/local/bin
|
|
|
|
// binary=/usr/local/bin/binary
|
2017-07-01 17:58:48 +02:00
|
|
|
log.WithField("file", file.Name()).Debug("passed binary to fpm")
|
2017-06-28 00:36:36 +02:00
|
|
|
options = append(options, fmt.Sprintf(
|
|
|
|
"%s=%s",
|
2017-07-01 17:58:48 +02:00
|
|
|
file.Name(),
|
|
|
|
filepath.Join("/usr/local/bin", file.Name()),
|
2017-06-28 00:36:36 +02:00
|
|
|
))
|
|
|
|
}
|
2017-01-30 02:33:08 +02:00
|
|
|
|
2017-02-01 19:40:27 +02:00
|
|
|
if out, err := exec.Command("fpm", options...).CombinedOutput(); err != nil {
|
2017-01-30 12:17:15 +02:00
|
|
|
return errors.New(string(out))
|
2017-01-30 01:55:32 +02:00
|
|
|
}
|
2017-04-14 17:07:40 +02:00
|
|
|
ctx.AddArtifact(file)
|
2017-01-30 01:55:32 +02:00
|
|
|
return nil
|
|
|
|
}
|