gitlab.com/pidrakin/dotfiles-cli@v1.7.5/cmd/link/hooks.go (about)

     1  package link
     2  
     3  import (
     4  	log "github.com/sirupsen/logrus"
     5  	"gitlab.com/pidrakin/dotfiles-cli/exec"
     6  	"gitlab.com/pidrakin/dotfiles-cli/text"
     7  	"gitlab.com/pidrakin/go/sysfs"
     8  	"os"
     9  	exec2 "os/exec"
    10  	"path"
    11  )
    12  
    13  type HookType int
    14  
    15  func (h HookType) String() string {
    16  	return [...]string{"pre-link", "post-link"}[h-1]
    17  }
    18  
    19  type HookEnum struct {
    20  	PRE  HookType
    21  	POST HookType
    22  }
    23  
    24  var hook = HookEnum{
    25  	PRE:  1,
    26  	POST: 2,
    27  }
    28  
    29  func runHook(basepath string, hooktype HookType, collection string) (found bool, succeeded bool, err error) {
    30  	var hookpath string
    31  	found, hookpath = findHook(basepath, hooktype, collection)
    32  	if err != nil {
    33  		return
    34  	}
    35  	if found {
    36  		succeeded = true
    37  		if err = executeHook(hookpath); err != nil {
    38  			if _, ok := err.(*exec2.ExitError); ok {
    39  				succeeded = false
    40  				err = nil
    41  			}
    42  		}
    43  	}
    44  	return
    45  }
    46  
    47  func isExecutable(mode os.FileMode) bool {
    48  	return mode&0111 != 0
    49  }
    50  
    51  func findHook(basepath string, hooktype HookType, collection string) (found bool, hookpath string) {
    52  	dir := path.Join(basepath, ".dotfiles/hooks")
    53  	if collection != "" {
    54  		dir = path.Join(dir, collection)
    55  	}
    56  	hookpath = path.Join(dir, hooktype.String())
    57  
    58  	if info, osErr := os.Stat(hookpath); !os.IsNotExist(osErr) {
    59  		found = true
    60  		if !isExecutable(info.Mode()) {
    61  			log.WithField("hook", hookpath).Debug(text.HookNotExecutable)
    62  		}
    63  		return
    64  	}
    65  	return
    66  }
    67  
    68  func executeHook(hook string) error {
    69  	log.WithField("hook", hook).Info(text.ExecuteHook)
    70  	if !sysfs.DryRun {
    71  		out, err := exec.Command(hook)
    72  		if err != nil {
    73  			log.WithField("hook", hook).Errorf("hook failed\n%s", out)
    74  			if _, ok := err.(*exec2.ExitError); ok {
    75  				return err
    76  			}
    77  		} else {
    78  			log.WithField("hook", hook).Debugf("hook succeeded\n%s", out)
    79  		}
    80  	}
    81  	return nil
    82  }