Execute hooks after bootstrap and checkout commands

Closes #15
This commit is contained in:
Bernd Ahlers
2019-04-06 17:05:07 +02:00
parent 42ba2223fc
commit fe433c2e59
4 changed files with 121 additions and 0 deletions

View File

@@ -2,6 +2,7 @@ package cmd
import (
"github.com/Graylog2/graylog-project-cli/git"
"github.com/Graylog2/graylog-project-cli/hooks"
"github.com/Graylog2/graylog-project-cli/logger"
"github.com/Graylog2/graylog-project-cli/utils"
"github.com/spf13/cobra"
@@ -15,6 +16,7 @@ var bootstrapShallowClone bool
var bootstrapCheckoutPath string
var bootstrapManifest string
var bootstrapProjectBranch string
var bootstrapSkipHooks bool
// bootstrapCmd represents the bootstrap command
var bootstrapCmd = &cobra.Command{
@@ -40,6 +42,7 @@ func init() {
bootstrapCmd.Flags().StringVarP(&bootstrapManifest, "manifest", "m", DefaultProjectManifest, "Manifest to checkout")
bootstrapCmd.Flags().StringVarP(&bootstrapProjectBranch, "project-branch", "B", "master", "graylog-project branch to check out")
bootstrapCmd.Flags().StringP("auth-token", "T", "", "Auth token to access protected URLs")
bootstrapCmd.Flags().BoolVarP(&bootstrapSkipHooks, "skip-hooks", "", false, "Do not execute hooks")
viper.BindPFlag("checkout.auth-token", bootstrapCmd.Flags().Lookup("auth-token"))
viper.BindEnv("checkout.auth-token", "GPC_AUTH_TOKEN")
@@ -83,5 +86,12 @@ func bootstrapCommand(cmd *cobra.Command, args []string) {
utils.InDirectory(bootstrapCheckoutPath, func() {
git.Git("checkout", bootstrapProjectBranch)
checkoutCommand(cmd, []string{bootstrapManifest})
if !bootstrapSkipHooks {
if hooks.Run(cmd.Name(), false) != nil {
logger.Error("Couldn't run hooks for %s: %s", cmd.Name(), err)
}
}
})
}

View File

@@ -2,6 +2,7 @@ package cmd
import (
c "github.com/Graylog2/graylog-project-cli/config"
"github.com/Graylog2/graylog-project-cli/hooks"
"github.com/Graylog2/graylog-project-cli/logger"
"github.com/Graylog2/graylog-project-cli/manifest"
"github.com/Graylog2/graylog-project-cli/pom"
@@ -46,12 +47,14 @@ func init() {
checkoutCmd.Flags().BoolP("force", "f", false, "Force checkout event though repository is unexpected")
checkoutCmd.Flags().StringP("auth-token", "T", "", "Auth token to access protected URLs")
checkoutCmd.Flags().StringSliceP("module-override", "O", []string{}, "Override manifest modules, see help for details")
checkoutCmd.Flags().BoolP("skip-hooks", "", false, "Do not execute hooks")
viper.BindPFlag("checkout.update-repos", checkoutCmd.Flags().Lookup("update-repos"))
viper.BindPFlag("checkout.shallow-clone", checkoutCmd.Flags().Lookup("shallow-clone"))
viper.BindPFlag("checkout.force", checkoutCmd.Flags().Lookup("force"))
viper.BindPFlag("checkout.auth-token", checkoutCmd.Flags().Lookup("auth-token"))
viper.BindPFlag("checkout.module-override", checkoutCmd.Flags().Lookup("module-override"))
viper.BindPFlag("checkout.skip-hooks", checkoutCmd.Flags().Lookup("skip-hooks"))
viper.BindEnv("checkout.auth-token", "GPC_AUTH_TOKEN")
}
@@ -170,5 +173,12 @@ func checkoutCommand(cmd *cobra.Command, args []string) {
manifest.WriteState(cleanupManifestFiles(config.Checkout.ManifestFiles))
if !viper.GetBool("checkout.skip-hooks") {
if err := hooks.Run(cmd.Name(), false); err != nil {
logger.Error("Couldn't run hooks for %s: %s", cmd.Name(), err)
return
}
}
CheckForUpdate()
}

44
cmd/hooks.go Normal file
View File

@@ -0,0 +1,44 @@
package cmd
import (
"github.com/Graylog2/graylog-project-cli/hooks"
"github.com/Graylog2/graylog-project-cli/logger"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"os"
)
var hooksCmd = &cobra.Command{
Use: "hooks",
Short: "Manage hooks",
}
var hooksRunCmd = &cobra.Command{
Use: "run",
Short: "Execute hooks",
Long: "Executes hooks for the given name if any exist.",
Run: hooksRunCommand,
}
func init() {
hooksCmd.AddCommand(hooksRunCmd)
RootCmd.AddCommand(hooksCmd)
hooksRunCmd.Flags().BoolP("noop", "n", false, "Don't execute hooks, only show which ones would be executed.")
viper.BindPFlag("hooks.noop", hooksRunCmd.Flags().Lookup("noop"))
}
func hooksRunCommand(cmd *cobra.Command, args []string) {
if len(args) < 1 {
logger.Info("Missing hook name")
cmd.UsageFunc()(cmd)
os.Exit(1)
}
noop := viper.GetBool("hooks.noop")
if err := hooks.Run(args[0], noop); err != nil {
logger.Error("Running hooks failed: %s", err)
}
}

57
hooks/hooks.go Normal file
View File

@@ -0,0 +1,57 @@
package hooks
import (
"fmt"
"github.com/Graylog2/graylog-project-cli/logger"
"github.com/pkg/errors"
"os"
"os/exec"
"path/filepath"
)
const path = "hooks"
func Run(name string, noop bool) error {
if _, err := os.Stat(path); os.IsNotExist(err) {
return errors.Wrap(err, "scripts directory doesn't exist")
}
// Supported scripts are named after the command that is executed. (e.g. bootstrap.sh)
// To support custom scripts, we also look for "<name>-custom.sh".
scripts := []string{
filepath.Join(path, fmt.Sprintf("%s.sh", name)),
filepath.Join(path, fmt.Sprintf("%s-custom.sh", name)),
}
for _, script := range scripts {
if _, err := os.Stat(script); os.IsNotExist(err) {
logger.Debug("script %s doesn't exist, skipping", script)
continue
}
if noop {
logger.Info("Would execute script %s", script)
continue
}
customEnv := []string{"GPC_COMMAND=" + name, "GPC_HOOK_SCRIPT=" + script, "GPC_BIN=" + os.Args[0]}
cmd := exec.Command(script)
cmd.Env = append(os.Environ(), customEnv...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
logger.Debug("Running script %s for hook %s with environment: %v", script, name, customEnv)
if err := cmd.Run(); err != nil {
return errors.Wrapf(err, "couldn't run hook script %s", script)
}
}
return nil
}
func Simulate(name string) error {
return nil
}