diff --git a/cmd/run.go b/cmd/run.go index 4f2999b3..a2fca760 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -33,10 +33,15 @@ func newRunCmd(opts *lefthook.Options) *cobra.Command { runCmd.Flags().BoolVar( &runArgs.AllFiles, "all-files", false, - "run hooks on all files", + "run hooks on all files in the Git index", ) - runCmd.Flags().StringSliceVar(&runArgs.Files, "files", nil, "run on specified files. takes precedence over --all-files") + runCmd.Flags().BoolVar( + &runArgs.AllFilesIncludingUntracked, "all-including-untracked-files", false, + "run hooks on all files, including untracked ones", + ) + + runCmd.Flags().StringSliceVar(&runArgs.Files, "files", nil, "run on specified files. takes precedence over --all-files and --all-including-untracked-filesß") runCmd.Flags().StringSliceVar(&runArgs.RunOnlyCommands, "commands", nil, "run only specified commands") diff --git a/docs/usage.md b/docs/usage.md index fcfae0e1..6ed0425c 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -130,7 +130,7 @@ You can also specify a flag to run only some commands: $ lefthook run pre-commit --commands lint ``` -and optionally run either on all files (any `{staged_files}` placeholder acts as `{all_files}`) or a list of files: +and optionally run either on all files in the Git index (any `{staged_files}` placeholder acts as `{all_files}`) or a list of files: ```bash $ lefthook run pre-commit --all-files @@ -139,6 +139,8 @@ $ lefthook run pre-commit --files file1.js,file2.js (if both are specified, `--all-files` is ignored) +In the same way, you can use `--all-including-untracked-files`. + ### `lefthook version` You can check version with `lefthook version` and you can also check the commit hash with `lefthook version --full` diff --git a/internal/config/files.go b/internal/config/files.go index ba9f1da5..3c9964de 100644 --- a/internal/config/files.go +++ b/internal/config/files.go @@ -3,10 +3,11 @@ package config import "strings" const ( - SubFiles string = "{files}" - SubAllFiles string = "{all_files}" - SubStagedFiles string = "{staged_files}" - PushFiles string = "{push_files}" + SubFiles string = "{files}" + SubAllFiles string = "{all_files}" + SubAllFilesIncludingUntracked string = "{all_including_untracked_files}" + SubStagedFiles string = "{staged_files}" + PushFiles string = "{push_files}" ) func isRunnerFilesCompatible(runner string) bool { diff --git a/internal/git/repository.go b/internal/git/repository.go index 693ab6e4..4955033f 100644 --- a/internal/git/repository.go +++ b/internal/git/repository.go @@ -11,17 +11,18 @@ import ( ) const ( - cmdRootPath = "git rev-parse --show-toplevel" - cmdHooksPath = "git rev-parse --git-path hooks" - cmdInfoPath = "git rev-parse --git-path info" - cmdGitPath = "git rev-parse --git-dir" - cmdStagedFiles = "git diff --name-only --cached --diff-filter=ACMR" - cmdAllFiles = "git ls-files --cached" - cmdPushFilesBase = "git diff --name-only HEAD @{push}" - cmdPushFilesHead = "git diff --name-only HEAD %s" - cmdStatusShort = "git status --short" - cmdCreateStash = "git stash create" - cmdListStash = "git stash list" + cmdRootPath = "git rev-parse --show-toplevel" + cmdHooksPath = "git rev-parse --git-path hooks" + cmdInfoPath = "git rev-parse --git-path info" + cmdGitPath = "git rev-parse --git-dir" + cmdStagedFiles = "git diff --name-only --cached --diff-filter=ACMR" + cmdAllFiles = "git ls-files --cached" + cmdAllFilesIncludingUntracked = "git ls-files --cached --others --exclude-standard" + cmdPushFilesBase = "git diff --name-only HEAD @{push}" + cmdPushFilesHead = "git diff --name-only HEAD %s" + cmdStatusShort = "git status --short" + cmdCreateStash = "git stash create" + cmdListStash = "git stash list" stashMessage = "lefthook auto backup" unstagedPatchName = "lefthook-unstaged.patch" @@ -103,6 +104,12 @@ func (r *Repository) AllFiles() ([]string, error) { return r.FilesByCommand(cmdAllFiles) } +// StagedFiles returns a list of all files in repository +// or an error if git command fails. +func (r *Repository) AllFilesIncludingUntracked() ([]string, error) { + return r.FilesByCommand(cmdAllFilesIncludingUntracked) +} + // 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) { diff --git a/internal/lefthook/run.go b/internal/lefthook/run.go index 0fec2287..b45c9b71 100644 --- a/internal/lefthook/run.go +++ b/internal/lefthook/run.go @@ -23,11 +23,12 @@ const ( ) type RunArgs struct { - NoTTY bool - AllFiles bool - Force bool - Files []string - RunOnlyCommands []string + NoTTY bool + AllFiles bool + AllFilesIncludingUntracked bool + Force bool + Files []string + RunOnlyCommands []string } func Run(opts *Options, args RunArgs, hookName string, gitArgs []string) error { @@ -116,17 +117,18 @@ Run 'lefthook install' manually.`, runner := run.NewRunner( run.Options{ - Repo: l.repo, - Hook: hook, - HookName: hookName, - GitArgs: gitArgs, - ResultChan: resultChan, - SkipSettings: logSettings, - DisableTTY: cfg.NoTTY || args.NoTTY, - AllFiles: args.AllFiles, - Files: args.Files, - Force: args.Force, - RunOnlyCommands: args.RunOnlyCommands, + Repo: l.repo, + Hook: hook, + HookName: hookName, + GitArgs: gitArgs, + ResultChan: resultChan, + SkipSettings: logSettings, + DisableTTY: cfg.NoTTY || args.NoTTY, + Files: args.Files, + AllFiles: args.AllFiles, + AllFilesIncludingUntracked: args.AllFilesIncludingUntracked, + Force: args.Force, + RunOnlyCommands: args.RunOnlyCommands, }, ) diff --git a/internal/lefthook/run/prepare_command.go b/internal/lefthook/run/prepare_command.go index 644b8bb9..8da48d3c 100644 --- a/internal/lefthook/run/prepare_command.go +++ b/internal/lefthook/run/prepare_command.go @@ -79,14 +79,17 @@ func (r *Runner) buildRun(command *config.Command) (*run, error, error) { stagedFiles = func() ([]string, error) { return r.Files, nil } case r.AllFiles: stagedFiles = r.Repo.AllFiles + case r.AllFilesIncludingUntracked: + stagedFiles = r.Repo.AllFilesIncludingUntracked default: stagedFiles = r.Repo.StagedFiles } filesFns := map[string]func() ([]string, error){ - config.SubStagedFiles: stagedFiles, - config.PushFiles: r.Repo.PushFiles, - config.SubAllFiles: r.Repo.AllFiles, + config.SubStagedFiles: stagedFiles, + config.PushFiles: r.Repo.PushFiles, + config.SubAllFiles: r.Repo.AllFiles, + config.SubAllFilesIncludingUntracked: r.Repo.AllFilesIncludingUntracked, config.SubFiles: func() ([]string, error) { return r.Repo.FilesByCommand(filesCmd) }, diff --git a/internal/lefthook/run/runner.go b/internal/lefthook/run/runner.go index 3ccd3c52..0b6bce1b 100644 --- a/internal/lefthook/run/runner.go +++ b/internal/lefthook/run/runner.go @@ -38,17 +38,18 @@ const ( var surroundingQuotesRegexp = regexp.MustCompile(`^'(.*)'$`) type Options struct { - Repo *git.Repository - Hook *config.Hook - HookName string - GitArgs []string - ResultChan chan Result - SkipSettings log.SkipSettings - DisableTTY bool - AllFiles bool - Force bool - Files []string - RunOnlyCommands []string + Repo *git.Repository + Hook *config.Hook + HookName string + GitArgs []string + ResultChan chan Result + SkipSettings log.SkipSettings + DisableTTY bool + AllFiles bool + AllFilesIncludingUntracked bool + Force bool + Files []string + RunOnlyCommands []string } // Runner responds for actual execution and handling the results.