Simplify node lock and various small changes

Co-authored-by: Fabian Kammel <fabian@kammel.dev>
Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com>
This commit is contained in:
Malte Poll 2022-07-14 15:45:04 +02:00 committed by Paul Meyer
parent 2bcf001d52
commit cce2611e2a
31 changed files with 530 additions and 229 deletions

View file

@ -0,0 +1,119 @@
package git
import (
"errors"
"regexp"
"time"
git "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/storer"
)
var versionRegex = regexp.MustCompile(`^v\d+\.\d+\.\d+$`)
type Git struct {
repo *git.Repository
}
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()[:8], commit.Author.When, nil
}
// FirstParentWithVersionTag returns the first parent of the HEAD commit (or HEAD itself) that has a version tag.
func (g *Git) FirstParentWithVersionTag() (revision string, versionTag string, err error) {
commitRef, err := g.repo.Head()
if err != nil {
return "", "", err
}
commit, err := g.repo.CommitObject(commitRef.Hash())
if err != nil {
return "", "", err
}
commitToHash, err := g.tagsByRevisionHash()
if err != nil {
return "", "", err
}
iter := object.NewCommitIterCTime(commit, nil, nil)
if err := iter.ForEach(
func(c *object.Commit) error {
tags, ok := commitToHash[c.Hash.String()]
if !ok {
return nil
}
version := g.findVersionTag(tags)
if version == nil {
return nil
}
versionTag = *version
revision = c.Hash.String()
return storer.ErrStop
},
); err != nil {
return "", "", err
}
if revision == "" || versionTag == "" {
return "", "", errors.New("no version tag found")
}
return revision, versionTag, nil
}
// tagsByRevisionHash returns a map from revision hash to a list of associated tags.
func (g *Git) tagsByRevisionHash() (map[string][]string, error) {
tags := make(map[string][]string)
refs, err := g.repo.Tags()
if err != nil {
return nil, err
}
if err := refs.ForEach(
func(ref *plumbing.Reference) error {
tag, err := g.repo.TagObject(ref.Hash())
switch err {
case nil:
// Tag object present
case plumbing.ErrObjectNotFound:
// Not a tag object
return nil
default:
// Some other error
return err
}
commit, err := tag.Commit()
if err != nil {
return err
}
commitHash := commit.Hash.String()
tags[commitHash] = append(tags[commitHash], tag.Name)
return nil
},
); err != nil {
return nil, err
}
return tags, nil
}
// findVersionTag tries to find a tag for a semantic version (e.g.: v1.0.0).
func (g *Git) findVersionTag(tags []string) *string {
for _, tag := range tags {
if versionRegex.MatchString(tag) {
return &tag
}
}
return nil
}

View file

@ -0,0 +1,60 @@
package main
import (
"flag"
"fmt"
"time"
"github.com/edgelesssys/constellation/hack/pseudo-version/internal/git"
"github.com/edgelesssys/constellation/internal/logger"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/mod/module"
)
func main() {
major := flag.String("major", "v1", "Optional major version")
base := flag.String("base", "", "Optional base version")
revisionTimestamp := flag.String("time", "", "Optional revision time")
revision := flag.String("revision", "", "Optional revision (git commit hash)")
flag.Parse()
log := logger.New(logger.JSONLog, zapcore.InfoLevel)
gitc, err := git.New()
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to initialize git client")
}
if *base == "" {
_, versionTag, err := gitc.FirstParentWithVersionTag()
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to find base version")
}
*base = versionTag
}
var headRevision string
var headTime time.Time
if *revisionTimestamp == "" || *revision == "" {
var err error
headRevision, headTime, err = gitc.Revision()
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to retrieve HEAD")
}
}
if *revisionTimestamp != "" {
headTime, err := time.Parse("20060102150405", *revisionTimestamp)
if err != nil {
log.With(zap.Error(err)).With("time", headTime).Fatalf("Failed to parse revision timestamp")
}
}
if *revision == "" {
*revision = headRevision
}
version := module.PseudoVersion(*major, *base, headTime, *revision)
fmt.Println(version)
}