diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go index 19662258..c8eeb825 100644 --- a/cmd/cmd_test.go +++ b/cmd/cmd_test.go @@ -33,7 +33,7 @@ func TestInstallCmdExecutor(t *testing.T) { "prepare-commit-msg", } - files, err := afero.ReadDir(fs,getGitHooksDir()) + files, err := afero.ReadDir(fs, getGitHooksDir()) assert.NoError(t, err) actualFiles := []string{} diff --git a/cmd/install.go b/cmd/install.go index 65e5d944..7c5be190 100644 --- a/cmd/install.go +++ b/cmd/install.go @@ -89,15 +89,18 @@ func AddConfigYaml(fs afero.Fs) { # commands: # eslint: # glob: "*.{js,ts}" +# stage_fixed: true # run: yarn eslint {staged_files} # rubocop: # tags: backend style # glob: "*.rb" # exclude: "application.rb|routes.rb" +# stage_fixed: false # run: bundle exec rubocop --force-exclusion {all_files} # govet: # tags: backend style # files: git ls-files -m +# stage_fixed: true # glob: "*.go" # run: go vet {files} # scripts: diff --git a/cmd/root.go b/cmd/root.go index 9d76feca..348b43e8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -27,11 +27,11 @@ const ( ) var ( - Verbose bool - NoColors bool - rootPath string - cfgFile string - originConfig *viper.Viper + Verbose bool + NoColors bool + rootPath string + cfgFile string + originConfig *viper.Viper configFileExtensions = []string{".yml", ".yaml"} au aurora.Aurora diff --git a/cmd/run.go b/cmd/run.go index 0f902b2d..d57f3b58 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "io/ioutil" "log" "os" "os/exec" @@ -63,6 +64,7 @@ const ( pipedConfigKey string = "piped" excludeTagsConfigKey string = "exclude_tags" minVersionConfigKey string = "min_version" + stageFixedConfigKey string = "stage_fixed" execMode os.FileMode = 0751 ) @@ -247,9 +249,7 @@ func executeCommand(hooksGroup, commandName string, wg *sync.WaitGroup) { log.Println(au.Cyan("\n EXECUTE >"), au.Bold(commandName)) if err != nil { - failList = append(failList, commandName) - setPipeBroken() - log.Println(err) + processError(commandName, err) return } @@ -257,11 +257,29 @@ func executeCommand(hooksGroup, commandName string, wg *sync.WaitGroup) { defer func() { ptyOut.Close() }() // Make sure to close the pty at the end. // Copy stdin to the pty and the pty to stdout. go func() { io.Copy(ptyOut, os.Stdin) }() - io.Copy(os.Stdout, ptyOut) + rescueStdout := os.Stdout + r, w, _ := os.Pipe() + os.Stdout = w + + _, err = io.Copy(os.Stdout, ptyOut) + if err != nil { + processError(commandName, err) + return + } + + w.Close() + fileNames, _ := ioutil.ReadAll(r) + os.Stdout = rescueStdout + log.Println(string(fileNames)) // pty part end if command.Wait() == nil { okList = append(okList, commandName) + if isStageFixedFiles(hooksGroup, commandName) { + log.Println("\n", au.Bold(commandName), au.Brown("(STAGE FIXED FILES)")) + log.Println(fmt.Sprintf("%#v", string(fileNames))) + context.ExecGitCommand(fmt.Sprintf("git add %v", strings.Replace(string(fileNames), "\r\n", " ", -1))) + } } else { failList = append(failList, commandName) setPipeBroken() @@ -405,6 +423,11 @@ func isSkipCommmand(hooksGroup, executableName string) bool { return viper.GetBool(key) } +func isStageFixedFiles(hooksGroup, executableName string) bool { + key := strings.Join([]string{hooksGroup, commandsConfigKey, executableName, stageFixedConfigKey}, ".") + return viper.GetBool(key) +} + // NOTE: confusing option, suppose it unnesecary and should be deleted. func isSkipEmptyCommmand(hooksGroup, executableName string) bool { key := strings.Join([]string{hooksGroup, commandsConfigKey, executableName, skipEmptyConfigKey}, ".") @@ -613,3 +636,9 @@ func isVersionOk() bool { return true } + +func processError(commandName string, err error) { + failList = append(failList, commandName) + setPipeBroken() + log.Println(err) +} diff --git a/cmd/run_windows.go b/cmd/run_windows.go index 4e21e557..a07a4ac3 100644 --- a/cmd/run_windows.go +++ b/cmd/run_windows.go @@ -64,6 +64,7 @@ const ( pipedConfigKey string = "piped" excludeTagsConfigKey string = "exclude_tags" execMode os.FileMode = 0751 + stageFixedConfigKey string = "stage_fixed" ) // runCmd represents the run command @@ -245,18 +246,23 @@ func executeCommand(hooksGroup, commandName string, wg *sync.WaitGroup) { log.Println(au.Cyan("\n EXECUTE >"), au.Bold(commandName)) if err != nil { - failList = append(failList, commandName) - setPipeBroken() - log.Println(err) + processError(commandName, err) + return + } + fileNames, err := command.Output() + if err != nil { + processError(commandName, err) return } - // io.Copy(os.Stdout, ptyOut) // win specific if command.Wait() == nil { okList = append(okList, commandName) + context.ExecGitCommand(fmt.Sprintf("git add %v", strings.Replace(string(fileNames), "\r\n", " ", -1))) + } else { failList = append(failList, commandName) setPipeBroken() + } } @@ -384,6 +390,11 @@ func isScriptExist(hooksGroup, executableName string) bool { return viper.IsSet(key) } +func isStageFixedFiles(hooksGroup, executableName string) bool { + key := strings.Join([]string{hooksGroup, commandsConfigKey, executableName, stageFixedConfigKey}, ".") + return viper.GetBool(key) +} + func isSkipScript(hooksGroup, executableName string) bool { key := strings.Join([]string{hooksGroup, scriptsConfigKey, executableName, skipConfigKey}, ".") return viper.GetBool(key) @@ -576,3 +587,9 @@ func makeExecutable(path string) { log.Fatal(err) } } + +func processError(commandName string, err error) { + failList = append(failList, commandName) + setPipeBroken() + log.Println(err) +}