• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

evilmartians / lefthook / 8373477831

21 Mar 2024 10:31AM UTC coverage: 77.882% (-0.08%) from 77.962%
8373477831

Pull #684

github

web-flow
Merge 44eb0e36f into 599459eb8
Pull Request #684: feat: add priorities to scripts

25 of 32 new or added lines in 3 files covered. (78.13%)

4 existing lines in 2 files now uncovered.

2405 of 3088 relevant lines covered (77.88%)

3.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.31
/internal/config/script.go
1
package config
2

3
import (
4
        "strings"
5

6
        "github.com/mitchellh/mapstructure"
7
        "github.com/spf13/viper"
8

9
        "github.com/evilmartians/lefthook/internal/git"
10
)
11

12
type Script struct {
13
        Runner string `json:"runner" mapstructure:"runner" toml:"runner" yaml:"runner"`
14

15
        Skip     interface{}       `json:"skip,omitempty"     mapstructure:"skip"     toml:"skip,omitempty,inline" yaml:",omitempty"`
16
        Only     interface{}       `json:"only,omitempty"     mapstructure:"only"     toml:"only,omitempty,inline" yaml:",omitempty"`
17
        Tags     []string          `json:"tags,omitempty"     mapstructure:"tags"     toml:"tags,omitempty"        yaml:",omitempty"`
18
        Env      map[string]string `json:"env,omitempty"      mapstructure:"env"      toml:"env,omitempty"         yaml:",omitempty"`
19
        Priority int               `json:"priority,omitempty" mapstructure:"priority" toml:"priority,omitempty"    yaml:",omitempty"`
20

21
        FailText    string `json:"fail_text,omitempty"   mapstructure:"fail_text"   toml:"fail_text,omitempty"   yaml:"fail_text,omitempty"`
22
        Interactive bool   `json:"interactive,omitempty" mapstructure:"interactive" toml:"interactive,omitempty" yaml:",omitempty"`
23
        UseStdin    bool   `json:"use_stdin,omitempty"   mapstructure:"use_stdin"   toml:"use_stdin,omitempty"   yaml:",omitempty"`
24
        StageFixed  bool   `json:"stage_fixed,omitempty" mapstructure:"stage_fixed" toml:"stage_fixed,omitempty" yaml:"stage_fixed,omitempty"`
25
}
26

27
func (s Script) DoSkip(gitState git.State) bool {
3✔
28
        skipChecker := NewSkipChecker(NewOsExec())
3✔
29
        return skipChecker.Check(gitState, s.Skip, s.Only)
3✔
30
}
3✔
31

32
type scriptRunnerReplace struct {
33
        Runner string `mapstructure:"runner"`
34
}
35

NEW
36
func (s Script) GetPriority() int {
×
NEW
37
        return s.Priority
×
NEW
UNCOV
38
}
×
39

40
func mergeScripts(base, extra *viper.Viper) (map[string]*Script, error) {
6✔
41
        if base == nil && extra == nil {
6✔
42
                return nil, nil
×
43
        }
×
44

45
        if base == nil {
12✔
46
                return unmarshalScripts(extra.GetStringMap("scripts"))
6✔
47
        }
6✔
48

49
        if extra == nil {
6✔
50
                return unmarshalScripts(base.GetStringMap("scripts"))
×
51
        }
×
52

53
        scriptsOrigin := base.GetStringMap("scripts")
6✔
54
        scriptsOverride := extra.GetStringMap("scripts")
6✔
55
        if scriptsOrigin == nil {
6✔
56
                return unmarshalScripts(scriptsOverride)
×
57
        }
×
58
        if scriptsOverride == nil {
6✔
59
                return unmarshalScripts(scriptsOrigin)
×
60
        }
×
61

62
        runReplaces := make(map[string]*scriptRunnerReplace)
6✔
63
        for key, originConfig := range scriptsOrigin {
12✔
64
                var runReplace scriptRunnerReplace
6✔
65

6✔
66
                if err := unmarshal(originConfig, &runReplace); err != nil {
6✔
67
                        return nil, err
×
68
                }
×
69

70
                runReplaces[key] = &runReplace
6✔
71
        }
72

73
        err := base.MergeConfigMap(map[string]interface{}{
6✔
74
                "scripts": scriptsOverride,
6✔
75
        })
6✔
76
        if err != nil {
6✔
77
                return nil, err
×
78
        }
×
79

80
        scripts, err := unmarshalScripts(base.GetStringMap("scripts"))
6✔
81
        if err != nil {
6✔
82
                return nil, err
×
83
        }
×
84

85
        for key, replace := range runReplaces {
12✔
86
                if replace.Runner != "" {
12✔
87
                        scripts[key].Runner = strings.ReplaceAll(scripts[key].Runner, CMD, replace.Runner)
6✔
88
                }
6✔
89
        }
90

91
        return scripts, nil
6✔
92
}
93

94
func unmarshalScripts(s map[string]interface{}) (map[string]*Script, error) {
6✔
95
        if len(s) == 0 {
12✔
96
                return nil, nil
6✔
97
        }
6✔
98

99
        scripts := make(map[string]*Script)
6✔
100
        for name, scriptConfig := range s {
12✔
101
                var script Script
6✔
102

6✔
103
                if err := unmarshal(scriptConfig, &script); err != nil {
6✔
104
                        return nil, err
×
105
                }
×
106

107
                scripts[name] = &script
6✔
108
        }
109

110
        return scripts, nil
6✔
111
}
112

113
// `scripts` are unmarshalled manually because viper
114
// uses "." as a key delimiter. So, this definition:
115
//
116
// ```yaml
117
// scripts:
118
//
119
//        "example.sh":
120
//            runner: bash
121
//
122
// ```
123
//
124
// Unmarshals into this:
125
//
126
// ```yaml
127
// scripts:
128
//
129
//        example:
130
//          sh:
131
//            runner: bash
132
//
133
// ```
134
//
135
// This is not an expected behavior and cannot be controlled yet
136
// Working with GetStringMap is the only way to get the structure "as is".
137
func unmarshal(input, output interface{}) error {
6✔
138
        return mapstructure.WeakDecode(input, &output)
6✔
139
}
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc