Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-add version code to cmd/builder #11208

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .chloggen/jackgopack4-re-add-ocb-version-number.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: bug_fix

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: cmd/builder

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: re-adds function to properly set and view version number of OpenTelemetry Collector Builder (ocb) binaries

# One or more tracking issues or pull requests related to the change
issues: [11208]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: []
2 changes: 1 addition & 1 deletion cmd/builder/internal/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ configuration is provided, ocb will generate a default Collector.
return nil, err
}
// version of this binary
cmd.AddCommand(versionCommand())
cmd.AddCommand(versionCommand(binVersion))

return cmd, nil
}
Expand Down
26 changes: 21 additions & 5 deletions cmd/builder/internal/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,34 @@ var (
version = ""
)

func init() {
// the second returned value is a boolean, which is true if the binaries are built with module support.
info, _ := debug.ReadBuildInfo()
version = info.Main.Version
type debugReadBuildInfoFunc func() (info *debug.BuildInfo, ok bool)
type binVersionFunc func(fn debugReadBuildInfoFunc) (string, error)

// binVersion returns the version of the binary.
// If the version is not set, it attempts to read the build information.
// Returns an error if the build information cannot be read.
func binVersion(fn debugReadBuildInfoFunc) (string, error) {
if version != "" {
return version, nil
}
info, ok := fn()
if !ok {
return "", fmt.Errorf("failed to read build info")
}
return info.Main.Version, nil
}

func versionCommand() *cobra.Command {
func versionCommand(fn binVersionFunc) *cobra.Command {
var err error
return &cobra.Command{
Use: "version",
Short: "Version of ocb",
Long: "Prints the version of the ocb binary",
RunE: func(cmd *cobra.Command, _ []string) error {
version, err = fn(debug.ReadBuildInfo)
if err != nil {
return err
}
cmd.Println(fmt.Sprintf("%s version %s", cmd.Parent().Name(), version))
return nil
},
Expand Down
123 changes: 123 additions & 0 deletions cmd/builder/internal/version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package internal

import (
"bytes"
"context"
"fmt"
"os"
"runtime/debug"
"testing"

"github.com/spf13/cobra"
)

// Mock debug.ReadBuildInfo function
var readBuildInfo = debug.ReadBuildInfo

func TestBinVersion(t *testing.T) {
// Test case: version is set
version = "v1.0.0"
v, err := binVersion(readBuildInfo)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if v != "v1.0.0" {
t.Fatalf("expected version 'v1.0.0', got %v", v)
}

// // Test case: version is not set, ReadBuildInfo returns valid info
version = ""
readBuildInfo = func() (*debug.BuildInfo, bool) {
return &debug.BuildInfo{
Main: debug.Module{
Version: "v2.0.0",
},
}, true
}
v, err = binVersion(readBuildInfo)
fmt.Printf("v: %v, err: %v", v, err)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if v != "v2.0.0" {
t.Fatalf("expected version 'v2.0.0', got %v", v)
}

// Test case: version is not set, ReadBuildInfo fails
readBuildInfo = func() (*debug.BuildInfo, bool) {
return nil, false
}
v, err = binVersion(readBuildInfo)
if err == nil {
t.Fatalf("expected error, got nil")
}
if v != "" {
t.Fatalf("expected empty version, got %v", v)
}
}

var validBinVersionFunc binVersionFunc = func(_ debugReadBuildInfoFunc) (string, error) {
return "v1.0.0", nil
}

var invalidBinVersionFunc binVersionFunc = func(_ debugReadBuildInfoFunc) (string, error) {
return "", fmt.Errorf("failed to read build info")
}

func TestVersionCommand(t *testing.T) {
tests := []struct {
name string
binVersion binVersionFunc
expectedOutput string
expectedError bool
}{
{
name: "valid version",
binVersion: validBinVersionFunc,
expectedOutput: "ocb version v1.0.0\n",
expectedError: false,
},
{
name: "error in binVersion",
binVersion: invalidBinVersionFunc,
expectedOutput: "",
expectedError: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Set a mock parent command name
parentCmd := &cobra.Command{
Use: "ocb <command>",
}
// Create the command
var cmd = versionCommand(tt.binVersion)
parentCmd.AddCommand(cmd)
// Capture the output
output := bytes.NewBufferString("")
errOutput := bytes.NewBufferString("")
cmd.SetOut(output)
cmd.SetErr(errOutput)
// Create a new context with a fake value
type contextKey string
ctx := context.WithValue(context.Background(), contextKey("key"), "value")
// Set fake CLI arguments
fakeArgs := []string{"cmd", "version"}
os.Args = fakeArgs
// Execute the command
err := cmd.ExecuteContext(ctx)
// Check for expected error
if (err != nil) != tt.expectedError {
t.Fatalf("expected error: %v, got: %v", tt.expectedError, err)
}
// Check for expected output
if output.String() != tt.expectedOutput {
t.Fatalf("expected output: %v, got: %v", tt.expectedOutput, output.String())
}
})
}
}
Loading