From aea5cc69c39eaa4460fd9d8cf0571d6c76c547ad Mon Sep 17 00:00:00 2001 From: decentral1se Date: Mon, 22 Nov 2021 21:11:16 +0100 Subject: [PATCH] fix: include ignored files Part of https://git.coopcloud.tech/coop-cloud/organising/issues/226. --- pkg/git/read.go | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/pkg/git/read.go b/pkg/git/read.go index 038ea6f4..69081322 100644 --- a/pkg/git/read.go +++ b/pkg/git/read.go @@ -1,11 +1,17 @@ package git import ( + "io/ioutil" + "os/user" "path" + "path/filepath" + "strings" "coopcloud.tech/abra/pkg/config" "github.com/go-git/go-git/v5" + gitConfigPkg "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/format/gitignore" "github.com/sirupsen/logrus" ) @@ -40,6 +46,12 @@ func IsClean(recipeName string) (bool, error) { return false, err } + patterns, err := GetExcludesFiles() + if err != nil { + return false, err + } + worktree.Excludes = append(patterns, worktree.Excludes...) + status, err := worktree.Status() if err != nil { return false, err @@ -53,3 +65,95 @@ func IsClean(recipeName string) (bool, error) { return status.IsClean(), nil } + +// GetExcludesFiles reads the exlude files from a global git ignore +func GetExcludesFiles() ([]gitignore.Pattern, error) { + var err error + var patterns []gitignore.Pattern + + cfg, err := parseGitConfig() + if err != nil { + return patterns, err + } + + excludesfile := getExcludesFile(cfg) + patterns, err = parseExcludesFile(excludesfile) + if err != nil { + return patterns, err + } + + return patterns, nil +} + +func parseGitConfig() (*gitConfigPkg.Config, error) { + cfg := gitConfigPkg.NewConfig() + + usr, err := user.Current() + if err != nil { + return nil, err + } + + b, err := ioutil.ReadFile(usr.HomeDir + "/.gitconfig") + if err != nil { + return nil, err + } + + if err := cfg.Unmarshal(b); err != nil { + return nil, err + } + + return cfg, err +} + +func getExcludesFile(cfg *gitConfigPkg.Config) string { + for _, sec := range cfg.Raw.Sections { + if sec.Name == "core" { + for _, opt := range sec.Options { + if opt.Key == "excludesfile" { + return opt.Value + } + } + } + } + return "" +} + +func parseExcludesFile(excludesfile string) ([]gitignore.Pattern, error) { + excludesfile, err := expandTilde(excludesfile) + if err != nil { + return nil, err + } + + data, err := ioutil.ReadFile(excludesfile) + if err != nil { + return nil, err + } + + var ps []gitignore.Pattern + for _, s := range strings.Split(string(data), "\n") { + if !strings.HasPrefix(s, "#") && len(strings.TrimSpace(s)) > 0 { + ps = append(ps, gitignore.ParsePattern(s, nil)) + } + } + + return ps, nil +} + +func expandTilde(path string) (string, error) { + if !strings.HasPrefix(path, "~") { + return path, nil + } + var paths []string + u, err := user.Current() + if err != nil { + return "", err + } + for _, p := range strings.Split(path, string(filepath.Separator)) { + if p == "~" { + paths = append(paths, u.HomeDir) + } else { + paths = append(paths, p) + } + } + return "/" + filepath.Join(paths...), nil +}