diff --git a/internal/config/config.go b/internal/config/config.go index 9f8fbab2..23f11549 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,14 +1,17 @@ package config import ( + "bytes" + "crypto/md5" + "encoding/hex" "encoding/json" - "os" + "fmt" + "io" "github.com/mitchellh/mapstructure" toml "github.com/pelletier/go-toml/v2" "gopkg.in/yaml.v3" - "github.com/evilmartians/lefthook/internal/log" "github.com/evilmartians/lefthook/internal/version" ) @@ -16,10 +19,11 @@ type DumpFormat int const ( YAMLFormat DumpFormat = iota - JSONFormat TOMLFormat + JSONFormat + JSONCompactFormat - dumpIndent = 2 + yamlIndent = 2 ) type Config struct { @@ -45,7 +49,25 @@ func (c *Config) Validate() error { return version.CheckCovered(c.MinVersion) } -func (c *Config) Dump(format DumpFormat) error { +func (c *Config) Md5() (checksum string, err error) { + configBytes := new(bytes.Buffer) + + err = c.Dump(JSONCompactFormat, configBytes) + if err != nil { + return + } + + hash := md5.New() + _, err = io.Copy(hash, configBytes) + if err != nil { + return + } + + checksum = hex.EncodeToString(hash.Sum(nil)[:16]) + return +} + +func (c *Config) Dump(format DumpFormat, out io.Writer) error { res := make(map[string]interface{}) if err := mapstructure.Decode(c, &res); err != nil { return err @@ -69,23 +91,25 @@ func (c *Config) Dump(format DumpFormat) error { case TOMLFormat: dumper = tomlDumper{} case JSONFormat: - dumper = jsonDumper{} + dumper = jsonDumper{pretty: true} + case JSONCompactFormat: + dumper = jsonDumper{pretty: false} default: dumper = yamlDumper{} } - return dumper.Dump(res) + return dumper.Dump(res, out) } type dumper interface { - Dump(map[string]interface{}) error + Dump(map[string]interface{}, io.Writer) error } type yamlDumper struct{} -func (yamlDumper) Dump(input map[string]interface{}) error { - encoder := yaml.NewEncoder(os.Stdout) - encoder.SetIndent(dumpIndent) +func (yamlDumper) Dump(input map[string]interface{}, out io.Writer) error { + encoder := yaml.NewEncoder(out) + encoder.SetIndent(yamlIndent) defer encoder.Close() err := encoder.Encode(input) @@ -98,8 +122,8 @@ func (yamlDumper) Dump(input map[string]interface{}) error { type tomlDumper struct{} -func (tomlDumper) Dump(input map[string]interface{}) error { - encoder := toml.NewEncoder(os.Stdout) +func (tomlDumper) Dump(input map[string]interface{}, out io.Writer) error { + encoder := toml.NewEncoder(out) err := encoder.Encode(input) if err != nil { return err @@ -108,15 +132,33 @@ func (tomlDumper) Dump(input map[string]interface{}) error { return nil } -type jsonDumper struct{} +type jsonDumper struct { + pretty bool +} -func (jsonDumper) Dump(input map[string]interface{}) error { - res, err := json.MarshalIndent(input, "", " ") +func (j jsonDumper) Dump(input map[string]interface{}, out io.Writer) error { + var res []byte + var err error + if j.pretty { + res, err = json.MarshalIndent(input, "", " ") + } else { + res, err = json.Marshal(input) + } if err != nil { return err } - log.Info(string(res)) + n, err := out.Write(res) + if n != len(res) { + return fmt.Errorf("file not written fully: %d/%d", n, len(res)) + } + if err != nil { + return err + } + + if j.pretty { + _, _ = out.Write([]byte("\n")) + } return nil } diff --git a/internal/lefthook/dump.go b/internal/lefthook/dump.go index 54372091..f973951c 100644 --- a/internal/lefthook/dump.go +++ b/internal/lefthook/dump.go @@ -1,6 +1,8 @@ package lefthook import ( + "os" + "github.com/evilmartians/lefthook/internal/config" "github.com/evilmartians/lefthook/internal/log" ) @@ -45,7 +47,7 @@ func Dump(opts *Options, args DumpArgs) { format = config.TOMLFormat } - if err := cfg.Dump(format); err != nil { + if err := cfg.Dump(format, os.Stdout); err != nil { log.Errorf("couldn't dump config: %s\n", err) return } diff --git a/internal/lefthook/install.go b/internal/lefthook/install.go index a082545a..6a2c202d 100644 --- a/internal/lefthook/install.go +++ b/internal/lefthook/install.go @@ -2,11 +2,8 @@ package lefthook import ( "bufio" - "crypto/md5" - "encoding/hex" "errors" "fmt" - "io" "os" "path/filepath" "regexp" @@ -145,7 +142,7 @@ func (l *Lefthook) syncHooks(cfg *config.Config, fetchRemotes bool) (*config.Con } func (l *Lefthook) createHooksIfNeeded(cfg *config.Config, checkHashSum, force bool) error { - if checkHashSum && l.hooksSynchronized() { + if checkHashSum && l.hooksSynchronized(cfg) { return nil } @@ -158,7 +155,7 @@ func (l *Lefthook) createHooksIfNeeded(cfg *config.Config, checkHashSum, force b } }() - checksum, err := l.configChecksum() + checksum, err := cfg.Md5() if err != nil { return fmt.Errorf("could not calculate checksum: %w", err) } @@ -224,7 +221,7 @@ func (l *Lefthook) createHooksIfNeeded(cfg *config.Config, checkHashSum, force b return nil } -func (l *Lefthook) hooksSynchronized() bool { +func (l *Lefthook) hooksSynchronized(cfg *config.Config) bool { // Check checksum in a checksum file file, err := l.Fs.Open(l.checksumFilePath()) if err != nil { @@ -264,7 +261,7 @@ func (l *Lefthook) hooksSynchronized() bool { return true } - configChecksum, err := l.configChecksum() + configChecksum, err := cfg.Md5() if err != nil { return false } @@ -294,40 +291,6 @@ func (l *Lefthook) configLastUpdateTimestamp() (timestamp int64, err error) { return } -func (l *Lefthook) configChecksum() (checksum string, err error) { - paths, err := afero.ReadDir(l.Fs, l.repo.RootPath) - if err != nil { - return - } - - var config string - for _, file := range paths { - if ok := configGlob.Match(file.Name()); ok { - config = file.Name() - break - } - } - if len(config) == 0 { - err = errNoConfig - return - } - - file, err := l.Fs.Open(filepath.Join(l.repo.RootPath, config)) - if err != nil { - return - } - defer file.Close() - - hash := md5.New() - _, err = io.Copy(hash, file) - if err != nil { - return - } - - checksum = hex.EncodeToString(hash.Sum(nil)[:16]) - return -} - func (l *Lefthook) addChecksumFile(checksum string) error { timestamp, err := l.configLastUpdateTimestamp() if err != nil { diff --git a/internal/lefthook/install_test.go b/internal/lefthook/install_test.go index 6772f8b3..10d79985 100644 --- a/internal/lefthook/install_test.go +++ b/internal/lefthook/install_test.go @@ -326,7 +326,7 @@ post-commit: notify: run: echo 'Done!' `, - checksum: "8b2c9fc6b3391b3cf020b97ab7037c61 1555894310\n", + checksum: "939f59e3f706df65f379a9ff5ce0119b 1555894310\n", wantExist: []string{ configPath, infoPath(config.ChecksumFileName),