Skip to content

Commit

Permalink
fix: consider annotated tags and use official pseudo version generator (
Browse files Browse the repository at this point in the history
#57)

* build(deps): bump golang.org/x/mod from 0.4.2 to 0.5.0

Signed-off-by: nscuro <[email protected]>

* consider annotated tags and use official pseudo version generator

Signed-off-by: nscuro <[email protected]>

* fix broken test due to limited cloning depth

Signed-off-by: nscuro <[email protected]>

Closes #53
Closes #55 
Fixes #56
  • Loading branch information
nscuro authored Aug 23, 2021
1 parent 0cbc174 commit 9616ceb
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 61 deletions.
8 changes: 4 additions & 4 deletions e2e/testdata/snapshots/TestModCmdLocal
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:00000000-0000-0000-0000-000000000000" version="1">
<metadata>
<component bom-ref="pkg:golang/[email protected]20210716205356-32d6b8adc872" type="library">
<component bom-ref="pkg:golang/[email protected]20210716185356-32d6b8adc872" type="library">
<name>testmod-local</name>
<version>v0.0.0-20210716205356-32d6b8adc872</version>
<purl>pkg:golang/[email protected]20210716205356-32d6b8adc872</purl>
<version>v0.0.0-20210716185356-32d6b8adc872</version>
<purl>pkg:golang/[email protected]20210716185356-32d6b8adc872</purl>
</component>
</metadata>
<components>
Expand All @@ -19,7 +19,7 @@
</component>
</components>
<dependencies>
<dependency ref="pkg:golang/[email protected]20210716205356-32d6b8adc872">
<dependency ref="pkg:golang/[email protected]20210716185356-32d6b8adc872">
<dependency ref="pkg:golang/testmod-local-dependency"></dependency>
</dependency>
<dependency ref="pkg:golang/testmod-local-dependency"></dependency>
Expand Down
8 changes: 4 additions & 4 deletions e2e/testdata/snapshots/TestModCmdNested
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:00000000-0000-0000-0000-000000000000" version="1">
<metadata>
<component bom-ref="pkg:golang/[email protected]20210716210707-a62fcff56e7e" type="library">
<component bom-ref="pkg:golang/[email protected]20210716190707-a62fcff56e7e" type="library">
<name>testmod-simple</name>
<version>v0.0.0-20210716210707-a62fcff56e7e</version>
<purl>pkg:golang/[email protected]20210716210707-a62fcff56e7e</purl>
<version>v0.0.0-20210716190707-a62fcff56e7e</version>
<purl>pkg:golang/[email protected]20210716190707-a62fcff56e7e</purl>
</component>
</metadata>
<components>
Expand All @@ -31,7 +31,7 @@
</component>
</components>
<dependencies>
<dependency ref="pkg:golang/[email protected]20210716210707-a62fcff56e7e">
<dependency ref="pkg:golang/[email protected]20210716190707-a62fcff56e7e">
<dependency ref="pkg:golang/github.com/google/[email protected]"></dependency>
</dependency>
<dependency ref="pkg:golang/github.com/google/[email protected]"></dependency>
Expand Down
8 changes: 4 additions & 4 deletions e2e/testdata/snapshots/TestModCmdNoDependencies
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:00000000-0000-0000-0000-000000000000" version="1">
<metadata>
<component bom-ref="pkg:golang/[email protected]20210716210350-6880323ad03d" type="library">
<component bom-ref="pkg:golang/[email protected]20210716190350-6880323ad03d" type="library">
<name>testmod-nodeps</name>
<version>v0.0.0-20210716210350-6880323ad03d</version>
<purl>pkg:golang/[email protected]20210716210350-6880323ad03d</purl>
<version>v0.0.0-20210716190350-6880323ad03d</version>
<purl>pkg:golang/[email protected]20210716190350-6880323ad03d</purl>
</component>
</metadata>
<components></components>
<dependencies>
<dependency ref="pkg:golang/[email protected]20210716210350-6880323ad03d"></dependency>
<dependency ref="pkg:golang/[email protected]20210716190350-6880323ad03d"></dependency>
</dependencies>
</bom>
8 changes: 4 additions & 4 deletions e2e/testdata/snapshots/TestModCmdSimple
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:00000000-0000-0000-0000-000000000000" version="1">
<metadata>
<component bom-ref="pkg:golang/[email protected]20210716203230-c7ea7c975ab8" type="library">
<component bom-ref="pkg:golang/[email protected]20210716183230-c7ea7c975ab8" type="library">
<name>testmod-simple</name>
<version>v0.0.0-20210716203230-c7ea7c975ab8</version>
<purl>pkg:golang/[email protected]20210716203230-c7ea7c975ab8</purl>
<version>v0.0.0-20210716183230-c7ea7c975ab8</version>
<purl>pkg:golang/[email protected]20210716183230-c7ea7c975ab8</purl>
</component>
</metadata>
<components>
Expand All @@ -31,7 +31,7 @@
</component>
</components>
<dependencies>
<dependency ref="pkg:golang/[email protected]20210716203230-c7ea7c975ab8">
<dependency ref="pkg:golang/[email protected]20210716183230-c7ea7c975ab8">
<dependency ref="pkg:golang/github.com/google/[email protected]"></dependency>
</dependency>
<dependency ref="pkg:golang/github.com/google/[email protected]"></dependency>
Expand Down
8 changes: 4 additions & 4 deletions e2e/testdata/snapshots/TestModCmdVendored
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:00000000-0000-0000-0000-000000000000" version="1">
<metadata>
<component bom-ref="pkg:golang/[email protected]20210716205931-5c9f3d791930" type="library">
<component bom-ref="pkg:golang/[email protected]20210716185931-5c9f3d791930" type="library">
<name>testmod-vendored</name>
<version>v0.0.0-20210716205931-5c9f3d791930</version>
<purl>pkg:golang/[email protected]20210716205931-5c9f3d791930</purl>
<version>v0.0.0-20210716185931-5c9f3d791930</version>
<purl>pkg:golang/[email protected]20210716185931-5c9f3d791930</purl>
</component>
</metadata>
<components>
Expand All @@ -28,7 +28,7 @@
</component>
</components>
<dependencies>
<dependency ref="pkg:golang/[email protected]20210716205931-5c9f3d791930">
<dependency ref="pkg:golang/[email protected]20210716185931-5c9f3d791930">
<dependency ref="pkg:golang/github.com/google/[email protected]"></dependency>
</dependency>
<dependency ref="pkg:golang/github.com/google/[email protected]"></dependency>
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ require (
github.com/rs/zerolog v1.23.0
github.com/stretchr/testify v1.7.0
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
golang.org/x/mod v0.4.2
golang.org/x/mod v0.5.0
)
5 changes: 3 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2 h1:y102fOLFqhV41b+4GPiJoa0k/
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand Down Expand Up @@ -176,6 +176,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.7.0 h1:Hdks0L0hgznZLG9nzXb8vZ0rRvqNvAcgAp84y7Mwkgw=
Expand Down
100 changes: 65 additions & 35 deletions internal/gomod/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ import (

"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/storer"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/rs/zerolog/log"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
)

// GetModuleVersion attempts to detect a given module's version by first
Expand Down Expand Up @@ -53,23 +56,15 @@ func GetModuleVersion(moduleDir string) (string, error) {
}
repoDir = filepath.Dir(repoDir) // Move to the parent dir
continue
} else if errors.Is(err, plumbing.ErrObjectNotFound) {
// It's a Git repo, but there's no tag pointing at HEAD.
// Construct a pseudo version instead.
pseudoVersion, err := GetPseudoVersion(repoDir)
if err != nil {
return "", fmt.Errorf("constructing pseudo version failed: %w", err)
}
return pseudoVersion, nil
}

return "", err
}
}
}

// GetPseudoVersion constructs a pseudo version for a Go module at a given path.
// See https://golang.org/ref/mod#pseudo-versions
func GetPseudoVersion(moduleDir string) (string, error) {
// GetVersionFromTag checks if the current commit is annotated with a tag and if it is, returns that tag's name.
func GetVersionFromTag(moduleDir string) (string, error) {
repo, err := git.PlainOpen(moduleDir)
if err != nil {
return "", err
Expand All @@ -85,44 +80,79 @@ func GetPseudoVersion(moduleDir string) (string, error) {
return "", err
}

commitHash := headCommit.Hash.String()[:12]
commitDate := headCommit.Author.When.Format("20060102150405")

return fmt.Sprintf("v0.0.0-%s-%s", commitDate, commitHash), nil
}

// GetVersionFromTag checks if the current commit is annotated with a tag and if it is, returns that tag's name.
func GetVersionFromTag(moduleDir string) (string, error) {
repo, err := git.PlainOpen(moduleDir)
latestTag, err := GetLatestTag(repo, headCommit)
if err != nil {
if errors.Is(err, plumbing.ErrObjectNotFound) {
return module.PseudoVersion("v0", "", headCommit.Author.When, headCommit.Hash.String()[:12]), nil
}

return "", err
}

headRef, err := repo.Head()
if err != nil {
return "", err
if latestTag.commit.Hash.String() == headCommit.Hash.String() {
return latestTag.name, nil
}

tags, err := repo.Tags()
return module.PseudoVersion(
semver.Major(latestTag.name),
latestTag.name,
latestTag.commit.Author.When,
latestTag.commit.Hash.String()[:12],
), nil
}

type tag struct {
name string
commit *object.Commit
}

// GetLatestTag determines the latest tag relative to HEAD.
// Only tags with valid semver are considered.
func GetLatestTag(repo *git.Repository, headCommit *object.Commit) (*tag, error) {
tagRefs, err := repo.Tags()
if err != nil {
return "", err
return nil, err
}

var tagName string
err = tags.ForEach(func(reference *plumbing.Reference) error {
if reference.Hash() == headRef.Hash() && strings.HasPrefix(reference.Name().String(), "refs/tags/v") {
tagName = strings.TrimPrefix(reference.Name().String(), "refs/tags/")
return storer.ErrStop // break
var latestTag tag

err = tagRefs.ForEach(func(ref *plumbing.Reference) error {
if semver.IsValid(ref.Name().Short()) {
rev := plumbing.Revision(ref.Name().String())

commitHash, err := repo.ResolveRevision(rev)
if err != nil {
return err
}

commit, err := repo.CommitObject(*commitHash)
if err != nil {
return err
}

isBeforeOrAtHead := commit.Committer.When.Before(headCommit.Author.When) ||
commit.Committer.When.Equal(headCommit.Committer.When)

if isBeforeOrAtHead && (latestTag.commit == nil || commit.Committer.When.After(latestTag.commit.Committer.When)) {
latestTag.name = ref.Name().Short()
latestTag.commit = commit
}
} else {
log.Debug().
Str("tag", ref.Name().Short()).
Str("hash", ref.Hash().String()).
Msg("tag is not a valid semver")
}

return nil
})
if err != nil {
return "", err
return nil, err
}

if tagName == "" {
return "", plumbing.ErrObjectNotFound
if latestTag.commit == nil {
return nil, plumbing.ErrObjectNotFound
}

return tagName, nil
return &latestTag, nil
}
19 changes: 16 additions & 3 deletions internal/gomod/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,24 @@ package gomod
import (
"testing"

"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/stretchr/testify/require"
)

func TestGetPseudoVersion(t *testing.T) {
version, err := GetPseudoVersion("../../")
func TestGetLatestTag(t *testing.T) {
repo, err := git.PlainClone(t.TempDir(), false, &git.CloneOptions{
URL: "https:/CycloneDX/cyclonedx-go.git",
})
require.NoError(t, err)
require.Regexp(t, "^v0\\.0\\.0-[\\d]{14}-[\\da-z]{12}$", version)

headCommit, err := repo.CommitObject(plumbing.NewHash("a20be9f00d406e7b792973ee1826e637e58a23d7"))
require.NoError(t, err)

tag, err := GetLatestTag(repo, headCommit)
require.NoError(t, err)
require.NotNil(t, tag)

require.Equal(t, "v0.3.0", tag.name)
require.Equal(t, "a20be9f00d406e7b792973ee1826e637e58a23d7", tag.commit.Hash.String())
}

0 comments on commit 9616ceb

Please sign in to comment.