Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow skipping hooks in certain git states: merge and/or rebase #173

Merged
merged 4 commits into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,32 @@ func getRootPath() string {
return rootPath
}

// Get absolute path to repository or worktree root
func setRootPath() {
// get absolute path to .git dir (project root)
cmd := exec.Command("git", "rev-parse", "--show-toplevel")

outputBytes, _ := cmd.CombinedOutput()
rootPath = strings.TrimSpace(string(outputBytes))
}

// Get absolute path to .git directory (or current worktree subdirectory in it)
func getGitDir() string {
cmd := exec.Command("git", "rev-parse", "--git-dir") // that may be relative

outputBytes, err := cmd.CombinedOutput()
if err != nil {
panic(err)
}

path := strings.TrimSpace(string(outputBytes))

if filepath.IsAbs(path) {
return path
}

return filepath.Join(getRootPath(), path)
}

func getGitHooksPath() string {
return gitHooksPath
}
Expand Down
65 changes: 63 additions & 2 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,12 +409,73 @@ func isScriptExist(hooksGroup, executableName string) bool {

func isSkipScript(hooksGroup, executableName string) bool {
key := strings.Join([]string{hooksGroup, scriptsConfigKey, executableName, skipConfigKey}, ".")
return viper.GetBool(key)
return isSkip(key)
}

func isSkipCommand(hooksGroup, executableName string) bool {
key := strings.Join([]string{hooksGroup, commandsConfigKey, executableName, skipConfigKey}, ".")
return viper.GetBool(key)
return isSkip(key)
}

func isSkip(key string) bool {
value := viper.Get(key)

switch typedValue := value.(type) {
case bool:
/*
pre-push:
commands:
packages-audit:
skip: true
*/
return typedValue
case string:
/*
pre-push:
commands:
packages-audit:
skip: merge
*/
return isSkippedGitState(typedValue)
case []interface{}:
/*
pre-push:
commands:
packages-audit:
skip:
- merge
- rebase
*/
for _, gitState := range typedValue {
if isSkippedGitState(gitState.(string)) {
return true
}
}
}

return false
}

func isSkippedGitState(state string) bool {
return state == "merge" && isMergeInProgress() || state == "rebase" && isRebaseInProgress()
}

func isMergeInProgress() bool {
if _, err := os.Stat(filepath.Join(getGitDir(), "MERGE_HEAD")); os.IsNotExist(err) {
return false
}

return true
}

func isRebaseInProgress() bool {
if _, mergeErr := os.Stat(filepath.Join(getGitDir(), "rebase-merge")); os.IsNotExist(mergeErr) {
if _, applyErr := os.Stat(filepath.Join(getGitDir(), "rebase-apply")); os.IsNotExist(applyErr) {
return false
}
}

return true
}

// NOTE: confusing option, suppose it unnesecary and should be deleted.
Expand Down
20 changes: 20 additions & 0 deletions docs/full_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,26 @@ pre-push:
skip: true
```

## Skipping commands during rebase or merge

You can skip commands during rebase and/or merge by the same `skip` option:

```yml
pre-push:
commands:
packages-audit:
skip: merge
# or
pre-push:
commands:
packages-audit:
skip:
- merge
- rebase
```

## Skipping commands by tags

If we have a lot of commands and scripts we can tag them and run skip commands with a specific tag.
Expand Down