Skip to content

Commit

Permalink
Merge pull request #9 from opentofu/test_git_tag_parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
Yantrio authored Nov 17, 2023
2 parents 8603ca6 + 4100281 commit fe9b7fb
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 21 deletions.
49 changes: 31 additions & 18 deletions src/internal/github/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,54 @@ import (
"strings"
)

func GetTags(repositoryUrl string) ([]string, error) {
log.Printf("Getting tags for repository %s", repositoryUrl)

var buf bytes.Buffer
var bufErr bytes.Buffer
cmd := exec.Command("git", "ls-remote", "--tags", "--refs", repositoryUrl)
cmd.Stdout = &buf
cmd.Stderr = &bufErr
func parseTagsFromStdout(lines []string) ([]string, error) {
tags := make([]string, 0, len(lines))

if err := cmd.Run(); err != nil {
log.Printf("Could not get tags for repository %s: %s", repositoryUrl, bufErr.String())
return nil, err
}

tags := make([]string, 0)
for _, line := range strings.Split(buf.String(), "\n") {
for _, line := range lines {
if !strings.Contains(line, "refs/tags/") {
continue
}

fields := strings.Fields(line)
if len(fields) != 2 {
return nil, fmt.Errorf("could not parse tags for %s: tags are in wrong format", repositoryUrl)
return nil, fmt.Errorf("invalid format for tag '%s', expected two fields", line)
}

ref := fields[1]
if !strings.HasPrefix(ref, "refs/tags/") {
return nil, fmt.Errorf("could not parse tags for %s: tags are in wrong format", repositoryUrl)
return nil, fmt.Errorf("invalid format for tag '%s', expected 'refs/tags/' prefix", line)
}

tag := strings.TrimPrefix(ref, "refs/tags/")
if tag == "" {
return nil, fmt.Errorf("invalid format for tag '%s', no version provided", line)
}

tags = append(tags, tag)
}

log.Printf("Found %d tags for repository %s", len(tags), repositoryUrl)
return tags, nil
}

// GetTags lists the tags of the remote repository and returns the refs/tags/ found
func GetTags(repositoryUrl string) ([]string, error) {
log.Printf("Getting tags for repository %s", repositoryUrl)

var buf bytes.Buffer
var bufErr bytes.Buffer
cmd := exec.Command("git", "ls-remote", "--tags", "--refs", repositoryUrl)
cmd.Stdout = &buf
cmd.Stderr = &bufErr

if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("could not get tags for %s, %w: %s", repositoryUrl, err, bufErr.String())
}

tags, err := parseTagsFromStdout(strings.Split(buf.String(), "\n"))
if err != nil {
return nil, fmt.Errorf("could not parse tags for %s: %w", repositoryUrl, err)
}

log.Printf("Found %d tags for repository %s", len(tags), repositoryUrl)
return tags, nil
}
70 changes: 70 additions & 0 deletions src/internal/github/git_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package github

import (
"errors"
"testing"

"github.com/stretchr/testify/assert"
)

func Test_parseTagsFromStdout(t *testing.T) {
cases := map[string]struct {
input []string
expected []string
expectedErr error
}{
"Empty input": {
input: []string{""},
expected: []string{},
},
// Successful
"Simple Tag": {
input: []string{"314159265358979 refs/tags/v0.0.1"},
expected: []string{"v0.0.1"},
},
"Multiple Tags": {
input: []string{"314159265358979 refs/tags/v0.0.1", "314159265358979 refs/tags/v0.1.1", "314159265358979 refs/tags/v1.0.1"},
expected: []string{"v0.0.1", "v0.1.1", "v1.0.1"},
},
// Invalid entries (ignored)
"No Tags": {
input: []string{},
expected: []string{},
},
"Empty Tags": {
input: []string{""},
expected: []string{},
},
"Multiple Tags w/ Invalid": {
input: []string{"314159265358979 HEAD", "314159265358979 refs/tags/v0.1.1", "314159265358979 refs/tags/v1.0.1"},
expected: []string{"v0.1.1", "v1.0.1"},
},
// Error cases
"Missing Field": {
input: []string{"borkborkborkrefs/tags/"},
expectedErr: errors.New("invalid format for tag 'borkborkborkrefs/tags/', expected two fields"),
},
"Extra Field": {
input: []string{"bork bork refs/tags/"},
expectedErr: errors.New("invalid format for tag 'bork bork refs/tags/', expected two fields"),
},
"Missing tags/refs": {
input: []string{"314159265358979refs/tags/ v0.0.1"},
expectedErr: errors.New("invalid format for tag '314159265358979refs/tags/ v0.0.1', expected 'refs/tags/' prefix"),
},
"Missing version": {
input: []string{"314159265358979 refs/tags/"},
expectedErr: errors.New("invalid format for tag '314159265358979 refs/tags/', no version provided"),
},
}

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
out, err := parseTagsFromStdout(tc.input)

assert.Equal(t, tc.expectedErr, err)
assert.Equal(t, tc.expected, out)

})
}
}
3 changes: 2 additions & 1 deletion src/internal/repository-metadata-files/module/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package module

import (
"fmt"
"golang.org/x/mod/semver"
"registry-stable/internal"
"registry-stable/internal/github"
"registry-stable/internal/module"

"golang.org/x/mod/semver"
)

func BuildMetadataFile(m module.Module) (*module.MetadataFile, error) {
Expand Down
5 changes: 3 additions & 2 deletions src/internal/repository-metadata-files/provider/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import (
"context"
"errors"
"fmt"
"golang.org/x/mod/semver"
"log"
"os"
"slices"

"golang.org/x/mod/semver"
"registry-stable/internal"
"registry-stable/internal/github"
"registry-stable/internal/provider"
"slices"
)

func filterNewReleases(releases []github.GHRelease, existingMetadata provider.MetadataFile) ([]github.GHRelease, error) {
Expand Down

0 comments on commit fe9b7fb

Please sign in to comment.