diff options
Diffstat (limited to 'pkg/git')
| -rw-r--r-- | pkg/git/git.go | 16 | ||||
| -rw-r--r-- | pkg/git/types.go | 24 | ||||
| -rw-r--r-- | pkg/git/utils.go | 15 | ||||
| -rw-r--r-- | pkg/git/utils_test.go | 24 |
4 files changed, 70 insertions, 9 deletions
diff --git a/pkg/git/git.go b/pkg/git/git.go index 9139261..7fc28fa 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -31,7 +31,7 @@ func Branches(repoDir string, filter *regexp.Regexp, defaultBranch string) ([]Re if filter != nil && !filter.MatchString(line) && line != defaultBranch { continue } - branches = append(branches, Ref(line)) + branches = append(branches, NewRef(line)) } return branches, nil } @@ -88,13 +88,13 @@ func Tags(repoDir string) ([]Tag, error) { } func Files(ref Ref, repoDir string) ([]Blob, error) { - if ref == "" { - ref = "HEAD" + if ref.IsEmpty() { + ref = NewRef("HEAD") } // -r: recurse into subtrees // -l: include blob size - cmd := exec.Command("git", "ls-tree", "--full-tree", "-r", "-l", string(ref)) + cmd := exec.Command("git", "ls-tree", "--full-tree", "-r", "-l", ref.Ref()) if repoDir != "" { cmd.Dir = repoDir } @@ -196,11 +196,11 @@ func Files(ref Ref, repoDir string) ([]Blob, error) { } func BlobContent(ref Ref, path string, repoDir string) ([]byte, bool, error) { - if ref == "" { - ref = "HEAD" + if ref.IsEmpty() { + ref = NewRef("HEAD") } // Use `git show ref:path` to get the blob content at that ref - cmd := exec.Command("git", "show", string(ref)+":"+path) + cmd := exec.Command("git", "show", ref.Ref()+":"+path) if repoDir != "" { cmd.Dir = repoDir } @@ -233,7 +233,7 @@ func Commits(ref Ref, repoDir string) ([]Commit, error) { "--date=unix", "--pretty=format:" + strings.Join(format, "\x1F"), "-z", // Separate the commits with NULs instead of newlines - string(ref), + ref.Ref(), } cmd := exec.Command("git", args...) diff --git a/pkg/git/types.go b/pkg/git/types.go index 3c12f14..121c7d8 100644 --- a/pkg/git/types.go +++ b/pkg/git/types.go @@ -4,7 +4,29 @@ import ( "time" ) -type Ref string +type Ref struct { + ref string + dirName string +} + +func NewRef(ref string) Ref { + return Ref{ + ref: ref, + dirName: RefToFileName(ref), + } +} + +func (r Ref) IsEmpty() bool { + return r.ref == "" +} + +func (r Ref) Ref() string { + return r.ref +} + +func (r Ref) DirName() string { + return r.dirName +} type Blob struct { Ref Ref diff --git a/pkg/git/utils.go b/pkg/git/utils.go index 24a2b75..68e4497 100644 --- a/pkg/git/utils.go +++ b/pkg/git/utils.go @@ -3,6 +3,7 @@ package git import ( "fmt" "strconv" + "strings" ) // ParseFileMode converts a git-style file mode (e.g. "100644") @@ -74,3 +75,17 @@ func IsBinary(b []byte) bool { // If more than 30% of sampled bytes are non-text, consider binary return bad*100 > n*30 } + +func RefToFileName(ref string) string { + var result strings.Builder + for _, c := range ref { + if (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '.' { + result.WriteByte(byte(c)) + } else if c >= 'A' && c <= 'Z' { + result.WriteByte(byte(c - 'A' + 'a')) + } else { + result.WriteByte('-') + } + } + return result.String() +} diff --git a/pkg/git/utils_test.go b/pkg/git/utils_test.go index ecbe952..4dcebe8 100644 --- a/pkg/git/utils_test.go +++ b/pkg/git/utils_test.go @@ -54,3 +54,27 @@ func TestParseFileModeInvalid(t *testing.T) { }) } } + +func TestRefToFileName(t *testing.T) { + tests := []struct { + in string + want string + }{ + {"main", "main"}, + {"master", "master"}, + {"release/v1.0", "release-v1.0"}, + {"feature/add-login", "feature-add-login"}, + {"bugfix\\windows\\path", "bugfix-windows-path"}, + {"1.0.0", "1.0.0"}, + {"1.x", "1.x"}, + } + + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + got := git.RefToFileName(tt.in) + if got != tt.want { + t.Fatalf("refToFileName(%q) = %q, want %q", tt.in, got, tt.want) + } + }) + } +} |
