Skip to content

Commit

Permalink
Implement git status parsing
Browse files Browse the repository at this point in the history
- Tests aren't 100% complete
- Implementation probably doesn't need to use scanner
  • Loading branch information
carhartl committed Nov 25, 2024
1 parent 41ae9d6 commit 917a483
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 0 deletions.
77 changes: 77 additions & 0 deletions git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package main

import (
"bufio"
"io"
"strconv"
"strings"
)

type Dir = string

type GitInfo struct {
modified int
added int
deleted int
renamed int
copied int
unmerged int
untracked int
stashed int
}

func (gi *GitInfo) Parse(r io.Reader) {
var s = bufio.NewScanner(r)
for s.Scan() {
gi.parseLine(s.Text())
}
}

func (gi GitInfo) Summary() string {
// TODO: produces human readable output
return ""
}

func (gi *GitInfo) parseLine(l string) {
s := bufio.NewScanner(strings.NewReader(l))
s.Split(bufio.ScanWords)
s.Scan()
switch s.Text() {
case "#":
gi.parseStashes(l)
case "1", "2":
s.Scan()
gi.parseXY(s.Text())
case "u":
gi.unmerged++
case "?":
gi.untracked++
}
}

func (gi *GitInfo) parseXY(xy string) {
// x: staged, y: unstaged
for _, c := range xy {
switch c { // staged
case 'M':
gi.modified++
case 'A':
gi.added++
case 'D':
gi.deleted++
case 'R':
gi.renamed++
case 'C':
gi.copied++
}
}
}

func (gi *GitInfo) parseStashes(s string) {
// line: # stash <N>
stashed := strings.Split(s, " ")
if stashed[1] == "stash" {
n, _ := strconv.Atoi(stashed[2])
gi.stashed = n
}
}
96 changes: 96 additions & 0 deletions git_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package main

import (
"strings"
"testing"
)

func TestParseWithModified(t *testing.T) {
// TODO: also test staged area, M.
s := strings.NewReader("1 .M N... 100644 100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 test.txt\n")

gi := GitInfo{}
gi.Parse(s)

if gi.modified != 1 {
t.Errorf("Expected modified == 1, got: %v", gi.modified)
}
}

func TestParseWithAdded(t *testing.T) {
s := strings.NewReader("1 A. N... 000000 100644 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 test.txt\n")

gi := GitInfo{}
gi.Parse(s)

if gi.added != 1 {
t.Errorf("Expected added == 1, got: %v", gi.added)
}
}

func TestParseWithDeleted(t *testing.T) {
// TODO: can also be "1 .D N... 100644 100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 test.txt\n"
s := strings.NewReader("1 D. N... 100644 000000 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 test.txt\n")

gi := GitInfo{}
gi.Parse(s)

if gi.deleted != 1 {
t.Errorf("Expected deleted == 1, got: %v", gi.deleted)
}
}

func TestParseWithRenamed(t *testing.T) {
s := strings.NewReader("2 R. N... 100644 100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 R100 renamed.txt test.txt\n")

gi := GitInfo{}
gi.Parse(s)

if gi.renamed != 1 {
t.Errorf("Expected renamed == 1, got: %v", gi.renamed)
}
}

func TestParseWithCopied(t *testing.T) {
s := strings.NewReader("2 CD N... 100644 100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 C100 copied.txt test.txt")

gi := GitInfo{}
gi.Parse(s)

if gi.copied != 1 {
t.Errorf("Expected copied == 1, got: %v", gi.copied)
}
}

func TestParseWithUnmerged(t *testing.T) {
s := strings.NewReader("u UU N... 100644 100644 100644 100644 323fae03f4606ea9991df8befbb2fca795e648fa 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 27f5cb292011032e79279cbd0fac3b1ecff8ce9a test.txt\n")

gi := GitInfo{}
gi.Parse(s)

if gi.unmerged != 1 {
t.Errorf("Expected unmerged == 1, got: %v", gi.unmerged)
}
}

func TestParseWithUntracked(t *testing.T) {
s := strings.NewReader("? test.txt\n")

gi := GitInfo{}
gi.Parse(s)

if gi.untracked != 1 {
t.Errorf("Expected untracked == 1, got: %v", gi.untracked)
}
}

func TestParseWithStashed(t *testing.T) {
s := strings.NewReader("# stash 1\n")

gi := GitInfo{}
gi.Parse(s)

if gi.stashed != 1 {
t.Errorf("Expected stashed == 1, got: %v", gi.stashed)
}
}

0 comments on commit 917a483

Please sign in to comment.