From d999109c596d9fd89f14aa34af80a248789d6340 Mon Sep 17 00:00:00 2001 From: Valentin Kiselev Date: Wed, 17 May 2023 10:22:31 +0300 Subject: [PATCH] feat: add dump command (#481) --- cmd/dump.go | 20 ++++++++++++++++++++ cmd/root.go | 1 + internal/config/command.go | 24 ++++++++++++------------ internal/config/config.go | 35 +++++++++++++++++++++++++++-------- internal/config/hook.go | 20 ++++++++++---------- internal/config/script.go | 16 ++++++++-------- internal/lefthook/dump.go | 25 +++++++++++++++++++++++++ 7 files changed, 103 insertions(+), 38 deletions(-) create mode 100644 cmd/dump.go create mode 100644 internal/lefthook/dump.go diff --git a/cmd/dump.go b/cmd/dump.go new file mode 100644 index 00000000..2bf28af6 --- /dev/null +++ b/cmd/dump.go @@ -0,0 +1,20 @@ +package cmd + +import ( + "github.com/spf13/cobra" + + "github.com/evilmartians/lefthook/internal/lefthook" +) + +func newDumpCmd(opts *lefthook.Options) *cobra.Command { + dumpCmd := cobra.Command{ + Use: "dump", + Short: "Prints config merged from all extensions", + Example: "lefthook dump", + Run: func(cmd *cobra.Command, hooks []string) { + lefthook.Dump(opts) + }, + } + + return &dumpCmd +} diff --git a/cmd/root.go b/cmd/root.go index 8c52baa1..12949eb1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,6 +14,7 @@ var commands = [...]func(*lefthook.Options) *cobra.Command{ newInstallCmd, newUninstallCmd, newRunCmd, + newDumpCmd, } func newRootCmd() *cobra.Command { diff --git a/internal/config/command.go b/internal/config/command.go index 49d9c4b4..e578a81b 100644 --- a/internal/config/command.go +++ b/internal/config/command.go @@ -12,21 +12,21 @@ import ( var errFilesIncompatible = errors.New("One of your runners contains incompatible file types") type Command struct { - Run string `mapstructure:"run"` + Run string `mapstructure:"run" yaml:",omitempty"` - Skip interface{} `mapstructure:"skip"` - Only interface{} `mapstructure:"only"` - Tags []string `mapstructure:"tags"` - Glob string `mapstructure:"glob"` - Files string `mapstructure:"files"` - Env map[string]string `mapstructure:"env"` + Skip interface{} `mapstructure:"skip" yaml:",omitempty"` + Only interface{} `mapstructure:"only" yaml:",omitempty"` + Tags []string `mapstructure:"tags" yaml:",omitempty"` + Glob string `mapstructure:"glob" yaml:",omitempty"` + Files string `mapstructure:"files" yaml:",omitempty"` + Env map[string]string `mapstructure:"env" yaml:",omitempty"` - Root string `mapstructure:"root"` - Exclude string `mapstructure:"exclude"` + Root string `mapstructure:"root" yaml:",omitempty"` + Exclude string `mapstructure:"exclude" yaml:",omitempty"` - FailText string `mapstructure:"fail_text"` - Interactive bool `mapstructure:"interactive"` - StageFixed bool `mapstructure:"stage_fixed"` + FailText string `mapstructure:"fail_text" yaml:"fail_text,omitempty"` + Interactive bool `mapstructure:"interactive" yaml:",omitempty"` + StageFixed bool `mapstructure:"stage_fixed" yaml:"stage_fixed,omitempty"` } func (c Command) Validate() error { diff --git a/internal/config/config.go b/internal/config/config.go index 9839ffc3..88e3b4bd 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,19 +1,25 @@ package config import ( + "os" + + "gopkg.in/yaml.v3" + "github.com/evilmartians/lefthook/internal/version" ) +const dumpIndent = 2 + type Config struct { Colors bool `mapstructure:"colors"` - Extends []string `mapstructure:"extends"` - Remote Remote `mapstructure:"remote"` - MinVersion string `mapstructure:"min_version"` - SkipOutput []string `mapstructure:"skip_output"` - SourceDir string `mapstructure:"source_dir"` - SourceDirLocal string `mapstructure:"source_dir_local"` - Rc string `mapstructure:"rc"` - NoTTY bool `mapstructure:"no_tty"` + Extends []string `mapstructure:"extends" yaml:",omitempty"` + Remote Remote `mapstructure:"remote" yaml:",omitempty"` + MinVersion string `mapstructure:"min_version" yaml:"min_version,omitempty"` + SkipOutput []string `mapstructure:"skip_output" yaml:"skip_output,omitempty"` + SourceDir string `mapstructure:"source_dir" yaml:"source_dir,omitempty"` + SourceDirLocal string `mapstructure:"source_dir_local" yaml:"source_dir_local,omitempty"` + Rc string `mapstructure:"rc" yaml:",omitempty"` + NoTTY bool `mapstructure:"no_tty" yaml:"no_tty,omitempty"` Hooks map[string]*Hook } @@ -21,3 +27,16 @@ type Config struct { func (c *Config) Validate() error { return version.CheckCovered(c.MinVersion) } + +func (c *Config) Dump() error { + encoder := yaml.NewEncoder(os.Stdout) + encoder.SetIndent(dumpIndent) + defer encoder.Close() + + err := encoder.Encode(c) + if err != nil { + return err + } + + return nil +} diff --git a/internal/config/hook.go b/internal/config/hook.go index 2b538c14..4c1dd296 100644 --- a/internal/config/hook.go +++ b/internal/config/hook.go @@ -18,20 +18,20 @@ type Hook struct { // Should be unmarshalled with `mapstructure:"commands"` // But replacing '{cmd}' is still an issue // Unmarshaling it manually, so omit auto unmarshaling - Commands map[string]*Command `mapstructure:"?"` + Commands map[string]*Command `mapstructure:"?" yaml:",omitempty"` // Should be unmarshalled with `mapstructure:"scripts"` // But parsing keys with dots in it is still an issue: https://github.com/spf13/viper/issues/324 // Unmarshaling it manually, so omit auto unmarshaling - Scripts map[string]*Script `mapstructure:"?"` - - Files string `mapstructure:"files"` - Parallel bool `mapstructure:"parallel"` - Piped bool `mapstructure:"piped"` - ExcludeTags []string `mapstructure:"exclude_tags"` - Skip interface{} `mapstructure:"skip"` - Only interface{} `mapstructure:"only"` - Follow bool `mapstructure:"follow"` + Scripts map[string]*Script `mapstructure:"?" yaml:",omitempty"` + + Files string `mapstructure:"files" yaml:",omitempty"` + Parallel bool `mapstructure:"parallel" yaml:",omitempty"` + Piped bool `mapstructure:"piped" yaml:",omitempty"` + ExcludeTags []string `mapstructure:"exclude_tags" yaml:"exclude_tags,omitempty"` + Skip interface{} `mapstructure:"skip" yaml:",omitempty"` + Only interface{} `mapstructure:"only" yaml:",omitempty"` + Follow bool `mapstructure:"follow" yaml:",omitempty"` } func (h *Hook) Validate() error { diff --git a/internal/config/script.go b/internal/config/script.go index 41c0bc52..10a0218d 100644 --- a/internal/config/script.go +++ b/internal/config/script.go @@ -10,16 +10,16 @@ import ( ) type Script struct { - Runner string `mapstructure:"runner"` + Runner string `mapstructure:"runner" yaml:",omitempty"` - Skip interface{} `mapstructure:"skip"` - Only interface{} `mapstructure:"only"` - Tags []string `mapstructure:"tags"` - Env map[string]string `mapstructure:"env"` + Skip interface{} `mapstructure:"skip" yaml:",omitempty"` + Only interface{} `mapstructure:"only" yaml:",omitempty"` + Tags []string `mapstructure:"tags" yaml:",omitempty"` + Env map[string]string `mapstructure:"env" yaml:",omitempty"` - FailText string `mapstructure:"fail_text"` - Interactive bool `mapstructure:"interactive"` - StageFixed bool `mapstructure:"stage_fixed"` + FailText string `mapstructure:"fail_text" yaml:"fail_text,omitempty"` + Interactive bool `mapstructure:"interactive" yaml:",omitempty"` + StageFixed bool `mapstructure:"stage_fixed" yaml:"stage_fixed,omitempty"` } func (s Script) DoSkip(gitState git.State) bool { diff --git a/internal/lefthook/dump.go b/internal/lefthook/dump.go new file mode 100644 index 00000000..e6f4927c --- /dev/null +++ b/internal/lefthook/dump.go @@ -0,0 +1,25 @@ +package lefthook + +import ( + "github.com/evilmartians/lefthook/internal/config" + "github.com/evilmartians/lefthook/internal/log" +) + +func Dump(opts *Options) { + lefthook, err := initialize(opts) + if err != nil { + log.Errorf("couldn't initialize lefthook: %s\n", err) + return + } + + cfg, err := config.Load(lefthook.Fs, lefthook.repo) + if err != nil { + log.Errorf("couldn't load config: %s\n", err) + return + } + + if err := cfg.Dump(); err != nil { + log.Errorf("couldn't dump config: %s\n", err) + return + } +}