85 lines
1.7 KiB
Go
85 lines
1.7 KiB
Go
package vcs
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/go-git/go-git/v5"
|
|
|
|
"code.icb4dc0.de/buildr/buildr/internal/maps"
|
|
)
|
|
|
|
func ParseGitInfo(root string) (*Git, error) {
|
|
repo, err := git.PlainOpen(root)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
g := &Git{
|
|
StagedFiles: make([]string, 0),
|
|
UnstagedFiles: make([]string, 0),
|
|
ModifiedFiles: make([]string, 0),
|
|
UntrackedFiles: make([]string, 0),
|
|
}
|
|
|
|
workTree, err := repo.Worktree()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
stat, err := workTree.Status()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
g.Dirty = !stat.IsClean()
|
|
|
|
uniqueModifiedFiles := make(map[string]bool)
|
|
|
|
//nolint:exhaustive // on purpose
|
|
for p, s := range stat {
|
|
switch s.Staging {
|
|
case git.Added, git.Modified, git.Copied, git.Renamed:
|
|
g.StagedFiles = append(g.StagedFiles, p)
|
|
uniqueModifiedFiles[p] = true
|
|
}
|
|
|
|
switch s.Worktree {
|
|
case git.Added, git.Modified, git.Copied, git.Renamed:
|
|
g.UnstagedFiles = append(g.UnstagedFiles, p)
|
|
uniqueModifiedFiles[p] = true
|
|
case git.Untracked:
|
|
g.UntrackedFiles = append(g.UntrackedFiles, p)
|
|
}
|
|
}
|
|
|
|
g.ModifiedFiles = maps.Keys(uniqueModifiedFiles)
|
|
|
|
if head, err := repo.Head(); err != nil {
|
|
return nil, fmt.Errorf("failed to read HEAD information: %w", err)
|
|
} else {
|
|
g.Commit.Hash = head.Hash().String()
|
|
name := head.Name()
|
|
|
|
g.Reference = name.String()
|
|
|
|
switch {
|
|
case name.IsTag():
|
|
g.Tag = name.Short()
|
|
case name.IsBranch():
|
|
g.Branch = name.Short()
|
|
}
|
|
|
|
commit, err := repo.CommitObject(head.Hash())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
g.Commit.Author.Name = commit.Author.Name
|
|
g.Commit.Author.Email = commit.Author.Email
|
|
|
|
g.Commit.Message = commit.Message
|
|
}
|
|
|
|
return g, nil
|
|
}
|