Skip to content

Commit

Permalink
go: explicit library version
Browse files Browse the repository at this point in the history
  • Loading branch information
james-rms committed Oct 12, 2022
1 parent 14fa18a commit dc29fed
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 38 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,12 @@ jobs:
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.49.0
- run: make lint
- run: make test
- name: Check library version
if: |
!github.event.pull_request.head.repo.fork &&
startsWith(github.ref, 'refs/tags/go/mcap/v')
working-directory: go/cli/check-tag
run: make build && bin/check-tag

go-release-cli:
permissions:
Expand Down
4 changes: 4 additions & 0 deletions go/cli/check-tag/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.PHONY: build
build:
mkdir -p bin
go build -o bin/check-tag
14 changes: 14 additions & 0 deletions go/cli/check-tag/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module github.com/foxglove/mcap/go/cli/check-tag

go 1.18

require github.com/foxglove/mcap/go/mcap v0.0.0-20221010221948-8b72814b2c50

require (
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/klauspost/compress v1.14.1 // indirect
github.com/pierrec/lz4/v4 v4.1.12 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.7.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)
17 changes: 17 additions & 0 deletions go/cli/check-tag/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/foxglove/mcap/go/mcap v0.0.0-20221010221948-8b72814b2c50 h1:JnsYRxGWtsEJQGRfiTW+mstZA97FbKVc9h8PezcDMCo=
github.com/foxglove/mcap/go/mcap v0.0.0-20221010221948-8b72814b2c50/go.mod h1:LMCS7BVPyHRb7xRXqYuKfM7dUq+MSE7H0dvaYsAQXnc=
github.com/klauspost/compress v1.14.1 h1:hLQYb23E8/fO+1u53d02A97a8UnsddcvYzq4ERRU4ds=
github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/pierrec/lz4/v4 v4.1.12 h1:44l88ehTZAUGW4VlO1QC4zkilL99M6Y9MXNwEs0uzP8=
github.com/pierrec/lz4/v4 v4.1.12/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
38 changes: 38 additions & 0 deletions go/cli/check-tag/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/// Utility for checking that the current git tag matches the internal MCAP library version string.
package main

import (
"fmt"
"os"
"os/exec"
"strings"

"github.com/foxglove/mcap/go/mcap"
)

func getGitTags() ([]string, error) {
res, err := exec.Command("git", "tag", "--points-at", "HEAD").Output()
return strings.Split(string(res), "\n"), err
}

func main() {
tags, err := getGitTags()
if err != nil {
fmt.Printf("Error getting git tags: %e\n", err)
os.Exit(1)
}
expected := fmt.Sprintf("go/mcap/%s", mcap.Version)
found := false
for _, tag := range tags {
if expected == tag {
found = true
break
}
}
if !found {
fmt.Println("Did not find git tag for library version, expected", expected, "found", tags)
os.Exit(1)
} else {
fmt.Println("Success")
}
}
21 changes: 13 additions & 8 deletions go/cli/mcap/cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,27 @@ package cmd
import (
"fmt"

"github.com/foxglove/mcap/go/mcap"
"github.com/spf13/cobra"
)

var Version string
var printLibraryVersion bool

// versionCmd represents the version command
func versionCmd(version string) *cobra.Command {
return &cobra.Command{
Use: "version",
Short: "Output version information",
Run: func(cmd *cobra.Command, args []string) {
var versionCmd = &cobra.Command{
Use: "version",
Short: "Output version information",
Run: func(cmd *cobra.Command, args []string) {
if printLibraryVersion {
fmt.Println(mcap.Version)
} else {
fmt.Println(Version)
},
}
}
},
}

func init() {
rootCmd.AddCommand(versionCmd(Version))
versionCmd.PersistentFlags().BoolVarP(&printLibraryVersion, "library", "l", false, "print MCAP library version instead of CLI version")
rootCmd.AddCommand(versionCmd)
}
1 change: 1 addition & 0 deletions go/go.work
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ go 1.18

use (
./cli/mcap
./cli/check-tag
./conformance/test-streamed-read-conformance
./conformance/test-streamed-write-conformance
./mcap
Expand Down
9 changes: 0 additions & 9 deletions go/mcap/mcap.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"math"
"runtime/debug"
)

// Magic is the magic number for an MCAP file.
Expand All @@ -29,14 +28,6 @@ func (c CompressionFormat) String() string {
return string(c)
}

func Version() string {
info, ok := debug.ReadBuildInfo()
if !ok {
return "unknown"
}
return info.Main.Version
}

const (
OpReserved OpCode = 0x00
OpHeader OpCode = 0x01
Expand Down
4 changes: 4 additions & 0 deletions go/mcap/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package mcap

// Version of the MCAP library.
var Version = "v0.1.0"
4 changes: 2 additions & 2 deletions go/mcap/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ type Writer struct {
func (w *Writer) WriteHeader(header *Header) error {
var library string
if !w.opts.OverrideLibrary {
library = fmt.Sprintf("mcap go #%s", Version())
if header.Library != "" {
library = fmt.Sprintf("mcap go %s", Version)
if header.Library != "" && header.Library != library {
library += "; " + header.Library
}
} else {
Expand Down
90 changes: 71 additions & 19 deletions go/mcap/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import (
"github.com/stretchr/testify/assert"
)

const libraryString = "libfoo v0"

func TestMCAPReadWrite(t *testing.T) {
t.Run("test header", func(t *testing.T) {
buf := &bytes.Buffer{}
w, err := NewWriter(buf, &WriterOptions{Compression: CompressionZSTD})
w, err := NewWriter(buf, &WriterOptions{Compression: CompressionZSTD, OverrideLibrary: true})
assert.Nil(t, err)
err = w.WriteHeader(&Header{
Profile: "ros1",
Library: libraryString,
})
assert.Nil(t, err)
lexer, err := NewLexer(buf)
Expand All @@ -30,7 +33,7 @@ func TestMCAPReadWrite(t *testing.T) {
assert.Equal(t, "ros1", profile)
library, _, err := readPrefixedString(record, offset)
assert.Nil(t, err)
assert.Equal(t, "mcap go #", library)
assert.Equal(t, "libfoo v0", library)
assert.Equal(t, TokenHeader, tokenType)
})
t.Run("zero-valued schema IDs permitted", func(t *testing.T) {
Expand Down Expand Up @@ -70,14 +73,16 @@ func TestOutputDeterminism(t *testing.T) {
for i := 0; i < 10; i++ {
buf := &bytes.Buffer{}
w, err := NewWriter(buf, &WriterOptions{
Chunked: true,
Compression: CompressionZSTD,
IncludeCRC: true,
ChunkSize: 1024,
Chunked: true,
Compression: CompressionZSTD,
IncludeCRC: true,
ChunkSize: 1024,
OverrideLibrary: true,
})
assert.Nil(t, err)
assert.Nil(t, w.WriteHeader(&Header{
Profile: "ros1",
Library: libraryString,
}))
assert.Nil(t, w.WriteSchema(&Schema{
ID: 1,
Expand Down Expand Up @@ -141,13 +146,15 @@ func TestChunkedReadWrite(t *testing.T) {
t.Run(fmt.Sprintf("chunked file with %s", compression), func(t *testing.T) {
buf := &bytes.Buffer{}
w, err := NewWriter(buf, &WriterOptions{
Chunked: true,
Compression: compression,
IncludeCRC: true,
Chunked: true,
Compression: compression,
IncludeCRC: true,
OverrideLibrary: true,
})
assert.Nil(t, err)
assert.Nil(t, w.WriteHeader(&Header{
Profile: "ros1",
Library: libraryString,
}))
assert.Nil(t, w.WriteSchema(&Schema{
ID: 1,
Expand Down Expand Up @@ -218,13 +225,15 @@ func TestChunkBoundaryIndexing(t *testing.T) {
// Each chunk in the index should reflect the time of the corresponding
// message.
w, err := NewWriter(buf, &WriterOptions{
Chunked: true,
ChunkSize: 20,
Compression: CompressionZSTD,
Chunked: true,
ChunkSize: 20,
Compression: CompressionZSTD,
OverrideLibrary: true,
})
assert.Nil(t, err)
err = w.WriteHeader(&Header{
Profile: "ros1",
Library: libraryString,
})
assert.Nil(t, err)
assert.Nil(t, w.WriteSchema(&Schema{
Expand Down Expand Up @@ -266,13 +275,15 @@ func TestChunkBoundaryIndexing(t *testing.T) {
func TestIndexStructures(t *testing.T) {
buf := &bytes.Buffer{}
w, err := NewWriter(buf, &WriterOptions{
Chunked: true,
ChunkSize: 1024,
Compression: CompressionZSTD,
Chunked: true,
ChunkSize: 1024,
Compression: CompressionZSTD,
OverrideLibrary: true,
})
assert.Nil(t, err)
err = w.WriteHeader(&Header{
Profile: "ros1",
Library: libraryString,
})
assert.Nil(t, err)
assert.Nil(t, w.WriteSchema(&Schema{
Expand Down Expand Up @@ -339,13 +350,15 @@ func TestIndexStructures(t *testing.T) {
func TestStatistics(t *testing.T) {
buf := &bytes.Buffer{}
w, err := NewWriter(buf, &WriterOptions{
Chunked: true,
ChunkSize: 1024,
Compression: CompressionZSTD,
Chunked: true,
ChunkSize: 1024,
Compression: CompressionZSTD,
OverrideLibrary: true,
})
assert.Nil(t, err)
assert.Nil(t, w.WriteHeader(&Header{
Profile: "ros1",
Library: libraryString,
}))
assert.Nil(t, w.WriteSchema(&Schema{
ID: 1,
Expand Down Expand Up @@ -386,10 +399,11 @@ func TestStatistics(t *testing.T) {

func TestUnchunkedReadWrite(t *testing.T) {
buf := &bytes.Buffer{}
w, err := NewWriter(buf, &WriterOptions{})
w, err := NewWriter(buf, &WriterOptions{OverrideLibrary: true})
assert.Nil(t, err)
err = w.WriteHeader(&Header{
Profile: "ros1",
Library: libraryString,
})
assert.Nil(t, err)
err = w.WriteSchema(&Schema{
Expand Down Expand Up @@ -465,6 +479,44 @@ func TestUnchunkedReadWrite(t *testing.T) {
}
}

func TestLibraryString(t *testing.T) {
thisLibraryString := fmt.Sprintf("mcap go %s", Version)
cases := []struct {
input string
output string
}{
{"", thisLibraryString},
{thisLibraryString, thisLibraryString},
{"some-library", fmt.Sprintf("%s; some-library", thisLibraryString)},
}
for _, c := range cases {
t.Run("library string is automatically filled", func(t *testing.T) {
buf := &bytes.Buffer{}
w, err := NewWriter(buf, &WriterOptions{})
assert.Nil(t, err)
err = w.WriteHeader(&Header{
Profile: "ros1",
Library: c.input,
})
assert.Nil(t, err)
w.Close()
lexer, err := NewLexer(buf)
assert.Nil(t, err)
tokenType, record, err := lexer.Next(nil)
assert.Nil(t, err)
assert.Equal(t, tokenType, TokenHeader)
offset := 0
profile, offset, err := readPrefixedString(record, offset)
assert.Nil(t, err)
assert.Equal(t, "ros1", profile)
library, _, err := readPrefixedString(record, offset)
assert.Nil(t, err)
assert.Equal(t, library, c.output)
})

}
}

func TestMakePrefixedMap(t *testing.T) {
t.Run("output is deterministic", func(t *testing.T) {
bytes := makePrefixedMap(map[string]string{
Expand Down

0 comments on commit dc29fed

Please sign in to comment.