Skip to content

Commit

Permalink
fix: calculate hashsum of the full config (evilmartians#854)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrexox authored Oct 22, 2024
1 parent f3b1a81 commit 5517878
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 60 deletions.
76 changes: 59 additions & 17 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
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"
)

type DumpFormat int

const (
YAMLFormat DumpFormat = iota
JSONFormat
TOMLFormat
JSONFormat
JSONCompactFormat

dumpIndent = 2
yamlIndent = 2
)

type Config struct {
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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
}
4 changes: 3 additions & 1 deletion internal/lefthook/dump.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package lefthook

import (
"os"

"github.com/evilmartians/lefthook/internal/config"
"github.com/evilmartians/lefthook/internal/log"
)
Expand Down Expand Up @@ -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
}
Expand Down
45 changes: 4 additions & 41 deletions internal/lefthook/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ package lefthook

import (
"bufio"
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"regexp"
Expand Down Expand Up @@ -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
}

Expand All @@ -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)
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -264,7 +261,7 @@ func (l *Lefthook) hooksSynchronized() bool {
return true
}

configChecksum, err := l.configChecksum()
configChecksum, err := cfg.Md5()
if err != nil {
return false
}
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion internal/lefthook/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ post-commit:
notify:
run: echo 'Done!'
`,
checksum: "8b2c9fc6b3391b3cf020b97ab7037c61 1555894310\n",
checksum: "939f59e3f706df65f379a9ff5ce0119b 1555894310\n",
wantExist: []string{
configPath,
infoPath(config.ChecksumFileName),
Expand Down

0 comments on commit 5517878

Please sign in to comment.