diff options
Diffstat (limited to 'git')
| -rw-r--r-- | git/git.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/git/git.go b/git/git.go new file mode 100644 index 0000000..36b72b1 --- /dev/null +++ b/git/git.go @@ -0,0 +1,99 @@ +package git + +import ( + "errors" + "os" + "os/exec" + "path/filepath" + "pik/model" + "pik/spool" + "strconv" + "strings" +) + +type gitMod struct { + Git string + err error +} + +func (g *gitMod) Init() error { + p, err := exec.LookPath("git") + if err != nil { + g.err = err + return nil + } + g.Git = p + return nil +} + +var Git = &gitMod{} + +func (g *gitMod) Mod(source *model.Source, result *model.HydratedSource) error { + gitFolder := filepath.Join(source.Path, ".git") + if st, err := os.Stat(gitFolder); err == nil && st.IsDir() { + if g.Git == "" { + spool.Warn("source %v seems to be a git repository but git is not installed\n", source.Identity.Full) + return nil + } + branch, err := g.Branch(source) + if err != nil { + spool.Warn("%v", err) + return nil + } + ch, in, de, err := g.Diff(source) + if err != nil { + spool.Warn("%v", err) + return nil + } + result.Git = &model.GitInfo{ + Branch: branch, + Insertions: in, + Deletions: de, + Changes: ch, + } + } + + return nil +} + +func (g *gitMod) Branch(source *model.Source) (string, error) { + cmd := exec.Command(g.Git, "branch", "--show-current") + cmd.Dir = source.Path + b, err := cmd.CombinedOutput() + return strings.TrimSpace(string(b)), err +} + +var UnknownResponseError = errors.New("unknown response") + +func (g *gitMod) Diff(source *model.Source) (int, int, int, error) { + cmd := exec.Command(g.Git, "diff", "--shortstat") + cmd.Dir = source.Path + b, err := cmd.CombinedOutput() + if err != nil { + return 0, 0, 0, err + } + split := strings.Split(string(b), ",") + changes := 0 + insertions := 0 + deletions := 0 + for _, s := range split { + var e error + pt := strings.Split(strings.TrimSpace(s), " ") + num, e := strconv.Atoi(pt[0]) + switch { + case strings.Contains(s, "changed"): + changes = num + case strings.Contains(s, "insertions"): + insertions = num + case strings.Contains(s, "deletions"): + deletions = num + default: + return changes, insertions, deletions, UnknownResponseError + } + + if e != nil { + return changes, insertions, deletions, e + } + } + return changes, insertions, deletions, nil +} |
