github.com/jdhenke/godel@v0.0.0-20161213181855-abeb3861bf0d/apps/distgo/cmd/dist/rpmdist.go (about)

     1  // Copyright 2016 Palantir Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package dist
    16  
    17  import (
    18  	"fmt"
    19  	"io"
    20  	"os"
    21  	"os/exec"
    22  	"strings"
    23  
    24  	"github.com/pkg/errors"
    25  
    26  	"github.com/palantir/godel/apps/distgo/params"
    27  	"github.com/palantir/godel/apps/distgo/pkg/script"
    28  )
    29  
    30  const defaultRPMRelease = "1"
    31  
    32  func checkRPMDependencies() error {
    33  	var missing []string
    34  	if _, err := exec.LookPath("fpm"); err != nil {
    35  		missing = append(missing, "Missing `fpm` command required to build RPMs. Install with `gem install fpm`.")
    36  	}
    37  	if _, err := exec.LookPath("rpmbuild"); err != nil {
    38  		missing = append(missing, "Missing `rpmbuild` command required to build RPMs. Install with `yum install rpm-build` or `apt-get install rpm` or `brew install rpm`.")
    39  	}
    40  	if len(missing) > 0 {
    41  		return errors.New(strings.Join(missing, "\n"))
    42  	}
    43  	return nil
    44  }
    45  
    46  func rpmDist(buildSpecWithDeps params.ProductBuildSpecWithDeps, distCfg params.Dist, outputProductDir string, stdout io.Writer) (p Packager, rErr error) {
    47  	buildSpec := buildSpecWithDeps.Spec
    48  	rpmDistInfo, ok := distCfg.Info.(*params.RPMDistInfo)
    49  	if !ok {
    50  		rpmDistInfo = &params.RPMDistInfo{}
    51  		distCfg.Info = rpmDistInfo
    52  	}
    53  
    54  	release := defaultRPMRelease
    55  	if rpmDistInfo.Release != "" {
    56  		release = rpmDistInfo.Release
    57  	}
    58  
    59  	// These are run after the cmd is executed.
    60  	var cleanups []func() error
    61  	// clean up unless everything below succeeds
    62  	runCleanups := true
    63  	defer func() {
    64  		if runCleanups {
    65  			var errs []string
    66  			for _, cleanup := range cleanups {
    67  				if err := cleanup(); err != nil {
    68  					errs = append(errs, err.Error())
    69  				}
    70  			}
    71  			if len(errs) > 0 {
    72  				rErr = errors.Errorf(strings.Join(append([]string{"encountered errors during cleanup:"}, errs...), "\n"))
    73  			}
    74  		}
    75  	}()
    76  
    77  	cmd := exec.Command("fpm")
    78  	cmd.Dir = buildSpec.ProjectDir
    79  	cmd.Stdout = stdout
    80  	cmd.Stderr = os.Stderr
    81  
    82  	cmd.Args = []string{
    83  		"fpm",
    84  		"-t", "rpm",
    85  		"-n", buildSpec.ProductName,
    86  		"-v", buildSpec.ProductVersion,
    87  		"--iteration", release,
    88  		"-p", ArtifactPath(buildSpec, distCfg),
    89  		"-s", "dir",
    90  		"-C", outputProductDir,
    91  	}
    92  
    93  	for _, configFile := range rpmDistInfo.ConfigFiles {
    94  		cmd.Args = append(cmd.Args, "--config-files", configFile)
    95  	}
    96  
    97  	scriptArg := func(name string, content string) error {
    98  		if content == "" {
    99  			return nil
   100  		}
   101  		f, cleanup, err := script.Write(buildSpec, rpmDistInfo.BeforeInstallScript)
   102  		if err != nil {
   103  			return errors.Wrapf(err, "failed to write %v script for %v", name, buildSpec.ProductName)
   104  		}
   105  		cleanups = append(cleanups, cleanup)
   106  		cmd.Args = append(cmd.Args, "--"+name, f)
   107  		return nil
   108  	}
   109  	if err := scriptArg("before-install", rpmDistInfo.BeforeInstallScript); err != nil {
   110  		return nil, err
   111  	}
   112  	if err := scriptArg("after-install", rpmDistInfo.AfterInstallScript); err != nil {
   113  		return nil, err
   114  	}
   115  	if err := scriptArg("after-remove", rpmDistInfo.AfterRemoveScript); err != nil {
   116  		return nil, err
   117  	}
   118  
   119  	runCleanups = false
   120  	return packager(func() error {
   121  		err := cmd.Run()
   122  		for _, cleanup := range cleanups {
   123  			if err := cleanup(); err != nil {
   124  				fmt.Fprintln(os.Stderr, err)
   125  			}
   126  		}
   127  		return err
   128  	}), nil
   129  }