diff --git a/internal/git/exec.go b/internal/git/exec.go index 91ae864e..19012958 100644 --- a/internal/git/exec.go +++ b/internal/git/exec.go @@ -3,6 +3,7 @@ package git import ( "os" "os/exec" + "path/filepath" "strings" "github.com/evilmartians/lefthook/internal/log" @@ -12,6 +13,7 @@ type Exec interface { SetRootPath(root string) Cmd(cmd []string) (string, error) CmdLines(cmd []string) ([]string, error) + CmdLinesWithinFolder(cmd []string, folder string) ([]string, error) } type OsExec struct { @@ -30,7 +32,7 @@ func (o *OsExec) SetRootPath(root string) { // Cmd runs plain string command. Trims spaces around output. func (o *OsExec) Cmd(cmd []string) (string, error) { - out, err := o.rawExecArgs(cmd) + out, err := o.rawExecArgs(cmd, "") if err != nil { return "", err } @@ -40,7 +42,17 @@ func (o *OsExec) Cmd(cmd []string) (string, error) { // CmdLines runs plain string command, returns its output split by newline. func (o *OsExec) CmdLines(cmd []string) ([]string, error) { - out, err := o.rawExecArgs(cmd) + out, err := o.rawExecArgs(cmd, "") + if err != nil { + return nil, err + } + + return strings.Split(strings.TrimSpace(out), "\n"), nil +} + +// CmdLines runs plain string command, returns its output split by newline. +func (o *OsExec) CmdLinesWithinFolder(cmd []string, folder string) ([]string, error) { + out, err := o.rawExecArgs(cmd, folder) if err != nil { return nil, err } @@ -50,15 +62,16 @@ func (o *OsExec) CmdLines(cmd []string) ([]string, error) { // rawExecArgs executes git command with LEFTHOOK=0 in order // to prevent calling subsequent lefthook hooks. -func (o *OsExec) rawExecArgs(args []string) (string, error) { +func (o *OsExec) rawExecArgs(args []string, folder string) (string, error) { log.Debug("[lefthook] cmd: ", args) + root := filepath.Join(o.root, folder) cmd := exec.Command(args[0], args[1:]...) - cmd.Dir = o.root + cmd.Dir = root cmd.Env = append(os.Environ(), "LEFTHOOK=0") out, err := cmd.CombinedOutput() - log.Debug("[lefthook] dir: ", o.root) + log.Debug("[lefthook] dir: ", root) log.Debug("[lefthook] err: ", err) log.Debug("[lefthook] out: ", string(out)) if err != nil { diff --git a/internal/git/repository.go b/internal/git/repository.go index aa92adac..01901d2b 100644 --- a/internal/git/repository.go +++ b/internal/git/repository.go @@ -108,19 +108,19 @@ func NewRepository(fs afero.Fs, git Exec) (*Repository, error) { // StagedFiles returns a list of staged files // or an error if git command fails. func (r *Repository) StagedFiles() ([]string, error) { - return r.FilesByCommand(cmdStagedFiles) + return r.FilesByCommand(cmdStagedFiles, "") } // StagedFiles returns a list of all files in repository // or an error if git command fails. func (r *Repository) AllFiles() ([]string, error) { - return r.FilesByCommand(cmdAllFiles) + return r.FilesByCommand(cmdAllFiles, "") } // PushFiles returns a list of files that are ready to be pushed // or an error if git command fails. func (r *Repository) PushFiles() ([]string, error) { - res, err := r.FilesByCommand(cmdPushFilesBase) + res, err := r.FilesByCommand(cmdPushFilesBase, "") if err == nil { return res, nil } @@ -147,7 +147,7 @@ func (r *Repository) PushFiles() ([]string, error) { r.headBranch = r.emptyTreeSHA } - return r.FilesByCommand(append(cmdPushFilesHead, r.headBranch)) + return r.FilesByCommand(append(cmdPushFilesHead, r.headBranch), "") } // PartiallyStagedFiles returns the list of files that have both staged and @@ -319,8 +319,8 @@ func (r *Repository) AddFiles(files []string) error { } // FilesByCommand accepts git command and returns its result as a list of filepaths. -func (r *Repository) FilesByCommand(command []string) ([]string, error) { - lines, err := r.Git.CmdLines(command) +func (r *Repository) FilesByCommand(command []string, folder string) ([]string, error) { + lines, err := r.Git.CmdLinesWithinFolder(command, folder) if err != nil { return nil, err } diff --git a/internal/git/repository_test.go b/internal/git/repository_test.go index ea2be416..68f77369 100644 --- a/internal/git/repository_test.go +++ b/internal/git/repository_test.go @@ -31,6 +31,10 @@ func (g GitMock) CmdLines(cmd []string) ([]string, error) { return strings.Split(res, "\n"), nil } +func (g GitMock) CmdLinesWithinFolder(cmd []string, _folder string) ([]string, error) { + return g.CmdLines(cmd) +} + func TestPartiallyStagedFiles(t *testing.T) { for i, tt := range [...]struct { name, gitOut string diff --git a/internal/lefthook/run_test.go b/internal/lefthook/run_test.go index ac6b7f1b..fd8b2da5 100644 --- a/internal/lefthook/run_test.go +++ b/internal/lefthook/run_test.go @@ -23,6 +23,10 @@ func (g GitMock) CmdLines(_cmd []string) ([]string, error) { return nil, nil } +func (g GitMock) CmdLinesWithinFolder(_cmd []string, _folder string) ([]string, error) { + return nil, nil +} + func TestRun(t *testing.T) { root, err := filepath.Abs("src") if err != nil { diff --git a/internal/lefthook/runner/prepare_command.go b/internal/lefthook/runner/prepare_command.go index f021a37a..09b6a36b 100644 --- a/internal/lefthook/runner/prepare_command.go +++ b/internal/lefthook/runner/prepare_command.go @@ -88,7 +88,7 @@ func (r *Runner) buildRun(command *config.Command) (*run, error) { } else { cmd = []string{"sh", "-c", filesCmd} } - return r.Repo.FilesByCommand(cmd) + return r.Repo.FilesByCommand(cmd, command.Root) } } diff --git a/internal/lefthook/runner/runner_test.go b/internal/lefthook/runner/runner_test.go index 0c427754..41e8ee0c 100644 --- a/internal/lefthook/runner/runner_test.go +++ b/internal/lefthook/runner/runner_test.go @@ -68,6 +68,10 @@ func (g *GitMock) CmdLines(args []string) ([]string, error) { return nil, nil } +func (g *GitMock) CmdLinesWithinFolder(args []string, _folder string) ([]string, error) { + return g.CmdLines(args) +} + func (g *GitMock) reset() { g.mux.Lock() g.commands = []string{}