constellation/hack/pseudo-version/internal/git/git.go
2023-03-14 14:53:33 +01:00

81 lines
1.9 KiB
Go

/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package git
import (
"fmt"
"regexp"
"strings"
"time"
git "github.com/go-git/go-git/v5"
)
// Git represents a git repository.
type Git struct {
repo *git.Repository
}
// New opens the git repository in current directory.
func New() (*Git, error) {
repo, err := git.PlainOpenWithOptions("", &git.PlainOpenOptions{DetectDotGit: true})
return &Git{repo: repo}, err
}
// Revision returns the current revision (HEAD) of the repository in the format used by go pseudo versions.
func (g *Git) Revision() (string, time.Time, error) {
commitRef, err := g.repo.Head()
if err != nil {
return "", time.Time{}, err
}
commit, err := g.repo.CommitObject(commitRef.Hash())
if err != nil {
return "", time.Time{}, err
}
return commitRef.Hash().String()[:12], commit.Committer.When, nil
}
// ParsedBranchName returns the name of the current branch.
// Special characters are replaced with "-", and the name is lowercased and trimmed to 49 characters.
// This makes sure that the branch name is usable as a GCP image name.
func (g *Git) ParsedBranchName() (string, error) {
commitRef, err := g.repo.Head()
if err != nil {
return "", err
}
rxp, err := regexp.Compile("[^a-zA-Z0-9-]+")
if err != nil {
return "", err
}
branch := strings.ToLower(rxp.ReplaceAllString(commitRef.Name().Short(), "-"))
if len(branch) > 49 {
branch = branch[:49]
}
return strings.TrimSuffix(branch, "-"), nil
}
// BranchName of current HEAD.
func (g *Git) BranchName() (string, error) {
commitRef, err := g.repo.Head()
if err != nil {
return "", err
}
return commitRef.Name().Short(), nil
}
// Path returns the path of the git repository.
func (g *Git) Path() (string, error) {
worktree, err := g.repo.Worktree()
if err != nil {
return "", fmt.Errorf("failed to get worktree: %w", err)
}
return worktree.Filesystem.Root(), nil
}