Skip to content

Commit

Permalink
Merge pull request #11 from uw-labs/go-dev-version
Browse files Browse the repository at this point in the history
buildinfo parser: handle version strings from Go dev builds
  • Loading branch information
Nicholas Jones authored Aug 26, 2021
2 parents 12863f4 + 0688ce1 commit fa9ebb1
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 29 deletions.
23 changes: 6 additions & 17 deletions internal/buildinfo/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package buildinfo

import (
"fmt"
"regexp"
"strings"

"github.com/uw-labs/lichen/internal/model"
)

var goVersionRgx = regexp.MustCompile(`^(.*?): (?:(?:devel )?go[0-9]+|devel \+[0-9a-f]+)`)

// Parse parses build info details as returned by `go version -m [bin ...]`
func Parse(info string) ([]model.BuildInfo, error) {
var (
Expand All @@ -23,28 +26,14 @@ func Parse(info string) ([]model.BuildInfo, error) {

// start of new build info output
if !strings.HasPrefix(l, "\t") {
parts := strings.Split(l, ":")
if len(parts) < 2 {
return nil, fmt.Errorf("invalid version line: %s", l)
}
version := strings.TrimSpace(parts[len(parts)-1])
path := strings.Join(parts[:len(parts)-1], ":")
switch {
case version == "not executable file":
return nil, fmt.Errorf("%s is not an executable", parts[0])
case version == "unrecognized executable format":
return nil, fmt.Errorf("%s has an unrecognized executable format", parts[0])
case version == "go version not found":
return nil, fmt.Errorf("%s does not appear to be a Go compiled binary", parts[0])
case strings.HasPrefix(version, "go"):
// sensible looking
default:
matches := goVersionRgx.FindStringSubmatch(l)
if len(matches) != 2 {
return nil, fmt.Errorf("unrecognised version line: %s", l)
}
if current.Path != "" {
results = append(results, current)
}
current = model.BuildInfo{Path: path}
current = model.BuildInfo{Path: matches[1]}
continue
}

Expand Down
41 changes: 31 additions & 10 deletions internal/buildinfo/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,22 +117,43 @@ func TestParse(t *testing.T) {
},
},
{
name: "not executable file",
input: `/tmp/lichen: not executable file`,
expectedErr: "/tmp/lichen is not an executable",
name: "development version (pre-go1.17)",
input: `/tmp/lichen: devel +01821137c2 Sat Apr 3 01:45:17 2021 +0000`,
expected: []model.BuildInfo{
{
Path: "/tmp/lichen",
},
},
},
{
name: "development version (current)",
input: `/tmp/lichen: devel go1.18-0c83e01e0c Wed Aug 18 15:11:52 2021 +0000`,
expected: []model.BuildInfo{
{
Path: "/tmp/lichen",
},
},
},
{
name: "unrecognised exe file",
input: `/tmp/lichen: unrecognized executable format`,
expectedErr: "/tmp/lichen has an unrecognized executable format",
name: "development version (old)",
input: `/tmp/lichen: devel +b7a85e0003 linux/amd64`,
expected: []model.BuildInfo{
{
Path: "/tmp/lichen",
},
},
},
{
name: "go version not found",
input: `/tmp/lichen: go version not found`,
expectedErr: "/tmp/lichen does not appear to be a Go compiled binary",
name: "windows development version",
input: `C:\lichen.exe: devel go1.18-0c83e01e0c Wed Aug 18 15:11:52 2021 +0000`,
expected: []model.BuildInfo{
{
Path: `C:\lichen.exe`,
},
},
},
{
name: "invalid",
name: "unrecognised line",
input: `/tmp/lichen: invalid`,
expectedErr: "unrecognised version line: /tmp/lichen: invalid",
},
Expand Down
4 changes: 2 additions & 2 deletions internal/module/extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func Extract(ctx context.Context, paths ...string) ([]model.BuildInfo, error) {
return nil, err
}
if err := verifyExtracted(parsed, paths); err != nil {
return nil, fmt.Errorf("could not extract module information from binaries: %v", paths)
return nil, fmt.Errorf("could not extract module information: %w", err)
}
return parsed, nil
}
Expand All @@ -37,7 +37,7 @@ func verifyExtracted(extracted []model.BuildInfo, requested []string) (err error
}
for _, path := range requested {
if _, found := buildInfos[path]; !found {
err = multierror.Append(err, fmt.Errorf("modules could not be obtained from %s", path))
err = multierror.Append(err, fmt.Errorf("modules could not be obtained from %[1]s (hint: run `go version -m %[1]q`)", path))
}
}
return
Expand Down

0 comments on commit fa9ebb1

Please sign in to comment.