From b8d841bd5f9ece0f74f15c07f16fc4d460451266 Mon Sep 17 00:00:00 2001 From: Singee Date: Fri, 13 Oct 2023 16:29:51 +0800 Subject: [PATCH] lint-staged: optimize for ignore files loading --- internal/ext/lint-staged/config.go | 4 ++-- internal/ext/lint-staged/git.go | 8 ++++++++ internal/ext/lint-staged/ignore.go | 28 +++++++++++++++++++++++++++- internal/lib/ignore/ignore.go | 19 +++++++++++++++++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/internal/ext/lint-staged/config.go b/internal/ext/lint-staged/config.go index ac6ab61..db652fc 100644 --- a/internal/ext/lint-staged/config.go +++ b/internal/ext/lint-staged/config.go @@ -61,12 +61,12 @@ func searchConfigs(cwd, gitDir, configPath string) ([]*Config, error) { return []*Config{config}, nil } - cachedFiles, err := execGitZ([]string{"ls-files", "-z", "--full-name"}, gitDir) + cachedFiles, err := getCachedFiles(gitDir) if err != nil { return nil, ee.Wrap(err, "cannot get list of known files") } - //otherFiles, err := execGitZ([]string{"ls-files", "-z", "--full-name", "--others", "--exclude-standard"}, gitDir) + //otherFiles, err := getUncommittedFiles(gitDir) //if err != nil { // return nil, ee.Wrap(err, "cannot get list of uncommitted files") //} diff --git a/internal/ext/lint-staged/git.go b/internal/ext/lint-staged/git.go index 331c9cf..8b382ef 100644 --- a/internal/ext/lint-staged/git.go +++ b/internal/ext/lint-staged/git.go @@ -125,3 +125,11 @@ func execGitZ(args []string, dir string) ([]string, error) { return parseGitZOutput(lines), nil } + +func getCachedFiles(gitDir string) ([]string, error) { + return execGitZ([]string{"ls-files", "-z", "--full-name"}, gitDir) +} + +func getUncommittedFiles(gitDir string) ([]string, error) { + return execGitZ([]string{"ls-files", "-z", "--full-name", "--others", "--exclude-standard"}, gitDir) +} diff --git a/internal/ext/lint-staged/ignore.go b/internal/ext/lint-staged/ignore.go index 91273a8..f6c2ba3 100644 --- a/internal/ext/lint-staged/ignore.go +++ b/internal/ext/lint-staged/ignore.go @@ -1,9 +1,13 @@ package lintstaged import ( + "log/slog" + "path/filepath" "strings" "github.com/ImSingee/go-ex/ee" + "github.com/ImSingee/go-ex/exstrings" + "github.com/ImSingee/go-ex/mr" "github.com/ImSingee/kitty/internal/lib/ignore" ) @@ -18,10 +22,11 @@ var ignoreFilenames = []string{ } func NewIgnoreChecker(repoRoot string) (*IgnoreChecker, error) { - ps, err := ignore.ReadPatterns(repoRoot, nil, ignoreFilenames...) + ps, err := parseIgnoreRules(repoRoot) if err != nil { return nil, ee.Wrap(err, "cannot read ignore patterns") } + return &IgnoreChecker{ignore.NewMatcher(ps)}, nil } @@ -30,3 +35,24 @@ func (c *IgnoreChecker) ShouldIgnore(gitRelativePath string) bool { return c.matcher.Match(parts, false) } + +func parseIgnoreRules(gitDir string) ([]ignore.Pattern, error) { + cachedFiles, err := getCachedFiles(gitDir) + if err != nil { + return nil, ee.Wrap(err, "cannot get list of known files") + } + + possibleIgnoreRuleFiles := cachedFiles + + possibleIgnoreRuleFiles = mr.Filter(possibleIgnoreRuleFiles, func(file string, _index int) bool { + return exstrings.InStringList(ignoreFilenames, filepath.Base(file)) + }) + + slog.Debug("Found possible ignore rule files", "possibleIgnoreRuleFiles", possibleIgnoreRuleFiles, "possibleIgnoreRuleFilesCount", len(possibleIgnoreRuleFiles)) + + ps, err := ignore.ParsePatternFiles(gitDir, possibleIgnoreRuleFiles...) + + slog.Debug("Load ignore patterns", "count", len(ps)) + + return ps, err +} diff --git a/internal/lib/ignore/ignore.go b/internal/lib/ignore/ignore.go index dba599a..05abd9d 100644 --- a/internal/lib/ignore/ignore.go +++ b/internal/lib/ignore/ignore.go @@ -24,6 +24,9 @@ func NewMatcher(ps []Pattern) Matcher { // ReadPatterns read and parse ignoreFileNames recursively // // The result is in the ascending order of priority (last higher). +// +// WARNING: This is too slow in most casts. +// You can use git to find the ignore files and use ParseIgnoreFiles to parse them. func ReadPatterns(root string, dirs []string, ignoreFileNames ...string) ([]Pattern, error) { ps, err := readIgnoreFiles(root, dirs, ignoreFileNames...) if err != nil { @@ -91,3 +94,19 @@ func readIgnoreFile(root string, dirs []string, ignoreFile string) (ps []Pattern return } + +func ParsePatternFiles(root string, gitRelativePaths ...string) (ps []Pattern, err error) { + for _, filename := range gitRelativePaths { + parts := strings.Split(filename, "/") + dirs := parts[:len(parts)-1] + ignoreFile := parts[len(parts)-1] + + subps, err := readIgnoreFile(root, dirs, ignoreFile) + if err != nil { + return nil, err + } + + ps = append(ps, subps...) + } + return +}