diff --git a/.chloggen/builder-skip-go-mod.yaml b/.chloggen/builder-skip-go-mod.yaml deleted file mode 100644 index 619e29e3489..00000000000 --- a/.chloggen/builder-skip-go-mod.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Use this changelog template to create an entry for release notes. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) -component: builder - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add a --skip-new-go-module flag to skip creating a module in the output directory. - -# One or more tracking issues or pull requests related to the change -issues: [9252] - -# (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: [] diff --git a/cmd/builder/Makefile b/cmd/builder/Makefile index 4c4549c747a..988ed9e64a5 100644 --- a/cmd/builder/Makefile +++ b/cmd/builder/Makefile @@ -1,7 +1,5 @@ include ../../Makefile.Common -GOTEST_TIMEOUT=360s - .PHONY: ocb ocb: CGO_ENABLED=0 $(GOCMD) build -trimpath -o ../../bin/ocb_$(GOOS)_$(GOARCH) . diff --git a/cmd/builder/README.md b/cmd/builder/README.md index a0226b5ed2e..b64a4d4cdc0 100644 --- a/cmd/builder/README.md +++ b/cmd/builder/README.md @@ -157,24 +157,6 @@ ocb --skip-generate --skip-get-modules --config=config.yaml ``` to only execute the compilation step. -### Avoiding the use of a new go.mod file - -You can optionally skip creating a new `go.mod` file. This is helpful when -using a monorepo setup with a shared go.mod file. When the `--skip-new-go-module` -command-line flag is supplied, the build process issues a `go get` command for -each component, relying on the Go toolchain to update the enclosing Go module -appropriately. - -This command will avoid downgrading a dependency in the enclosing -module, according to -[`semver.Compare()`](https://pkg.go.dev/golang.org/x/mod/semver#Compare), -and will instead issue a log indicating that the component was not -upgraded. - -`--skip-new-go-module` is incompatible with `replaces`, `excludes`, -and the component `path` override. For each of these features, users -are expected to modify the enclosing `go.mod` directly. - ### Strict versioning checks The builder checks the relevant `go.mod` diff --git a/cmd/builder/go.mod b/cmd/builder/go.mod index 9f27326220d..e724b8c175d 100644 --- a/cmd/builder/go.mod +++ b/cmd/builder/go.mod @@ -31,7 +31,7 @@ require ( github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect golang.org/x/sys v0.21.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/cmd/builder/go.sum b/cmd/builder/go.sum index 4dd87472a19..dfdbd91a46b 100644 --- a/cmd/builder/go.sum +++ b/cmd/builder/go.sum @@ -37,8 +37,8 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK 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/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= diff --git a/cmd/builder/internal/builder/config.go b/cmd/builder/internal/builder/config.go index 7f8fe523cd6..b1103fe70ba 100644 --- a/cmd/builder/internal/builder/config.go +++ b/cmd/builder/internal/builder/config.go @@ -19,12 +19,8 @@ import ( const defaultOtelColVersion = "0.107.0" -var ( - // ErrMissingGoMod indicates an empty gomod field - ErrMissingGoMod = errors.New("missing gomod specification for module") - // ErrIncompatibleConfigurationValues indicates that there is configuration that cannot be combined - ErrIncompatibleConfigurationValues = errors.New("cannot combine configuration values") -) +// ErrMissingGoMod indicates an empty gomod field +var ErrMissingGoMod = errors.New("missing gomod specification for module") // Config holds the builder's configuration type Config struct { @@ -33,7 +29,6 @@ type Config struct { SkipGenerate bool `mapstructure:"-"` SkipCompilation bool `mapstructure:"-"` SkipGetModules bool `mapstructure:"-"` - SkipNewGoModule bool `mapstructure:"-"` SkipStrictVersioning bool `mapstructure:"-"` LDFlags string `mapstructure:"-"` Verbose bool `mapstructure:"-"` @@ -121,15 +116,14 @@ func NewDefaultConfig() Config { func (c *Config) Validate() error { var providersError error if c.Providers != nil { - providersError = c.validateModules("provider", *c.Providers) + providersError = validateModules("provider", *c.Providers) } return multierr.Combine( - c.validateModules("extension", c.Extensions), - c.validateModules("receiver", c.Receivers), - c.validateModules("exporter", c.Exporters), - c.validateModules("processor", c.Processors), - c.validateModules("connector", c.Connectors), - c.validateFlags(), + validateModules("extension", c.Extensions), + validateModules("receiver", c.Receivers), + validateModules("exporter", c.Exporters), + validateModules("processor", c.Processors), + validateModules("connector", c.Connectors), providersError, ) } @@ -246,21 +240,11 @@ func (c *Config) ParseModules() error { return nil } -func (c *Config) validateFlags() error { - if c.SkipNewGoModule && (len(c.Replaces) != 0 || len(c.Excludes) != 0) { - return fmt.Errorf("%w excludes or replaces with --skip-new-go-module; please modify the enclosing go.mod file directly", ErrIncompatibleConfigurationValues) - } - return nil -} - -func (c *Config) validateModules(name string, mods []Module) error { +func validateModules(name string, mods []Module) error { for i, mod := range mods { if mod.GoMod == "" { return fmt.Errorf("%s module at index %v: %w", name, i, ErrMissingGoMod) } - if mod.Path != "" && c.SkipNewGoModule { - return fmt.Errorf("%w cannot modify mod.path %q combined with --skip-new-go-module; please modify the enclosing go.mod file directly", ErrIncompatibleConfigurationValues, mod.Path) - } } return nil } diff --git a/cmd/builder/internal/builder/config_test.go b/cmd/builder/internal/builder/config_test.go index bb99cf849a4..9daf158cb8e 100644 --- a/cmd/builder/internal/builder/config_test.go +++ b/cmd/builder/internal/builder/config_test.go @@ -4,6 +4,7 @@ package builder import ( + "errors" "os" "strings" "testing" @@ -139,37 +140,10 @@ func TestMissingModule(t *testing.T) { }, err: ErrMissingGoMod, }, - { - cfg: Config{ - Logger: zap.NewNop(), - SkipNewGoModule: true, - Extensions: []Module{{ - GoMod: "some-module", - Path: "invalid", - }}, - }, - err: ErrIncompatibleConfigurationValues, - }, - { - cfg: Config{ - Logger: zap.NewNop(), - SkipNewGoModule: true, - Replaces: []string{"", ""}, - }, - err: ErrIncompatibleConfigurationValues, - }, - { - cfg: Config{ - Logger: zap.NewNop(), - SkipNewGoModule: true, - Excludes: []string{"", ""}, - }, - err: ErrIncompatibleConfigurationValues, - }, } for _, test := range configurations { - assert.ErrorIs(t, test.cfg.Validate(), test.err) + assert.True(t, errors.Is(test.cfg.Validate(), test.err)) } } diff --git a/cmd/builder/internal/builder/main.go b/cmd/builder/internal/builder/main.go index e13dcec53a7..ba54c40e591 100644 --- a/cmd/builder/internal/builder/main.go +++ b/cmd/builder/internal/builder/main.go @@ -13,6 +13,7 @@ import ( "slices" "strings" "text/template" + "time" "go.uber.org/zap" "golang.org/x/mod/modfile" @@ -24,6 +25,7 @@ var ( ErrGoNotFound = errors.New("go binary not found") ErrDepNotFound = errors.New("dependency not found in go mod file") ErrVersionMismatch = errors.New("mismatch in go.mod and builder configuration versions") + errDownloadFailed = errors.New("failed to download go modules") errCompileFailed = errors.New("failed to compile the OpenTelemetry Collector distribution") skipStrictMsg = "Use --skip-strict-versioning to temporarily disable this check. This flag will be removed in a future minor version" ) @@ -84,30 +86,18 @@ func Generate(cfg Config) error { return fmt.Errorf("failed to create output path: %w", err) } - allTemplates := []*template.Template{ + for _, tmpl := range []*template.Template{ mainTemplate, mainOthersTemplate, mainWindowsTemplate, componentsTemplate, - } - - // Add the go.mod template unless that file is skipped. - if !cfg.SkipNewGoModule { - allTemplates = append(allTemplates, goModTemplate) - } - - for _, tmpl := range allTemplates { + goModTemplate, + } { if err := processAndWrite(cfg, tmpl, tmpl.Name(), cfg); err != nil { return fmt.Errorf("failed to generate source file %q: %w", tmpl.Name(), err) } } - // when not creating a new go.mod file, update modules one-by-one in the - // enclosing go module. - if err := cfg.updateModules(); err != nil { - return err - } - cfg.Logger.Info("Sources created", zap.String("path", cfg.Distribution.OutputPath)) return nil } @@ -155,7 +145,7 @@ func GetModules(cfg Config) error { } if cfg.SkipStrictVersioning { - return nil + return downloadModules(cfg) } // Perform strict version checking. For each component listed and the @@ -195,7 +185,22 @@ func GetModules(cfg Config) error { } } - return nil + return downloadModules(cfg) +} + +func downloadModules(cfg Config) error { + cfg.Logger.Info("Getting go modules") + failReason := "unknown" + for i := 1; i <= cfg.downloadModules.numRetries; i++ { + if _, err := runGoCommand(cfg, "mod", "download"); err != nil { + failReason = err.Error() + cfg.Logger.Info("Failed modules download", zap.String("retry", fmt.Sprintf("%d/%d", i, cfg.downloadModules.numRetries))) + time.Sleep(cfg.downloadModules.wait) + continue + } + return nil + } + return fmt.Errorf("%w: %s", errDownloadFailed, failReason) } func processAndWrite(cfg Config, tmpl *template.Template, outFile string, tmplParams any) error { @@ -221,68 +226,6 @@ func (c *Config) allComponents() []Module { c.Extensions, c.Connectors, *c.Providers) } -func (c *Config) updateModules() error { - if !c.SkipNewGoModule { - return nil - } - - // Build the main service dependency - coremod, corever := c.coreModuleAndVersion() - corespec := coremod + " " + corever - - if err := c.updateGoModule(corespec); err != nil { - return err - } - - for _, comp := range c.allComponents() { - if err := c.updateGoModule(comp.GoMod); err != nil { - return err - } - } - return nil -} - -func (c *Config) updateGoModule(modspec string) error { - mod, ver, found := strings.Cut(modspec, " ") - if !found { - return fmt.Errorf("ill-formatted modspec %q: missing space separator", modspec) - } - - // Re-parse the go.mod file on each iteration, since it can - // change each time. - modulePath, dependencyVersions, err := c.readGoModFile() - if err != nil { - return err - } - - if mod == modulePath { - // this component is part of the same module, nothing to update. - return nil - } - - // check for exact match - hasVer, ok := dependencyVersions[mod] - if ok && hasVer == ver { - c.Logger.Info("Component version match", zap.String("module", mod), zap.String("version", ver)) - return nil - } - - scomp := semver.Compare(hasVer, ver) - if scomp > 0 { - // version in enclosing module is newer, do not change - c.Logger.Info("Not upgrading component, enclosing module is newer.", zap.String("module", mod), zap.String("existing", hasVer), zap.String("config_version", ver)) - return nil - } - - // upgrading or changing version - updatespec := "-require=" + mod + "@" + ver - - if _, err := runGoCommand(*c, "mod", "edit", updatespec); err != nil { - return err - } - return nil -} - func (c *Config) readGoModFile() (string, map[string]string, error) { var modPath string stdout, err := runGoCommand(*c, "mod", "edit", "-print") diff --git a/cmd/builder/internal/builder/main_test.go b/cmd/builder/internal/builder/main_test.go index 93151739252..146c58b1d17 100644 --- a/cmd/builder/internal/builder/main_test.go +++ b/cmd/builder/internal/builder/main_test.go @@ -19,7 +19,23 @@ import ( "golang.org/x/mod/modfile" ) -const modulePrefix = "go.opentelemetry.io/collector" +const ( + goModTestFile = `// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 +module go.opentelemetry.io/collector/cmd/builder/internal/tester +go 1.20 +require ( + go.opentelemetry.io/collector/component v0.96.0 + go.opentelemetry.io/collector/connector v0.94.1 + go.opentelemetry.io/collector/exporter v0.94.1 + go.opentelemetry.io/collector/extension v0.94.1 + go.opentelemetry.io/collector/otelcol v0.94.1 + go.opentelemetry.io/collector/processor v0.94.1 + go.opentelemetry.io/collector/receiver v0.94.1 + go.opentelemetry.io/collector v0.96.0 +)` + modulePrefix = "go.opentelemetry.io/collector" +) var ( replaceModules = []string{ @@ -91,6 +107,18 @@ func newInitializedConfig(t *testing.T) Config { return cfg } +func TestGenerateDefault(t *testing.T) { + require.NoError(t, Generate(newInitializedConfig(t))) +} + +func TestGenerateInvalidOutputPath(t *testing.T) { + cfg := newInitializedConfig(t) + cfg.Distribution.OutputPath = ":/invalid" + err := Generate(cfg) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to create output path") +} + func TestVersioning(t *testing.T) { replaces := generateReplaces() tests := []struct { @@ -217,7 +245,7 @@ func TestSkipGenerate(t *testing.T) { cfg.SkipGenerate = true err := Generate(cfg) require.NoError(t, err) - outputFile, err := os.Open(filepath.Clean(cfg.Distribution.OutputPath)) + outputFile, err := os.Open(cfg.Distribution.OutputPath) defer func() { require.NoError(t, outputFile.Close()) }() @@ -228,13 +256,10 @@ func TestSkipGenerate(t *testing.T) { func TestGenerateAndCompile(t *testing.T) { replaces := generateReplaces() - type testDesc struct { - testCase string - cfgBuilder func(t *testing.T) Config - verifyFiles func(t *testing.T, dir string) - expectedErr string - } - testCases := []testDesc{ + testCases := []struct { + testCase string + cfgBuilder func(t *testing.T) Config + }{ { testCase: "Default Configuration Compilation", cfgBuilder: func(t *testing.T) Config { @@ -245,68 +270,6 @@ func TestGenerateAndCompile(t *testing.T) { cfg.Replaces = append(cfg.Replaces, replaces...) return cfg }, - }, { - testCase: "Skip New Gomod Configuration Compilation", - cfgBuilder: func(t *testing.T) Config { - cfg := newTestConfig() - err := cfg.SetBackwardsCompatibility() - require.NoError(t, err) - cfg.Receivers = append(cfg.Receivers, - Module{ - GoMod: "go.opentelemetry.io/collector/receiver/otlpreceiver v0.106.0", - }, - ) - cfg.Exporters = append(cfg.Exporters, - Module{ - GoMod: "go.opentelemetry.io/collector/exporter/otlpexporter v0.106.0", - }, - ) - tempDir := t.TempDir() - err = makeModule(tempDir, []byte(goModTestFile)) - require.NoError(t, err) - cfg.Distribution.OutputPath = filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - verifyFiles: func(t *testing.T, dir string) { - assert.FileExists(t, filepath.Clean(filepath.Join(dir, mainTemplate.Name()))) - assert.NoFileExists(t, filepath.Clean(filepath.Join(dir, "go.mod"))) - }, - }, - { - testCase: "Generate Only", - cfgBuilder: func(t *testing.T) Config { - cfg := newInitializedConfig(t) - cfg.SkipCompilation = true - cfg.SkipGetModules = true - return cfg - }, - }, - { - testCase: "Skip Everything", - cfgBuilder: func(_ *testing.T) Config { - cfg := NewDefaultConfig() - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipCompilation = true - cfg.SkipGenerate = true - cfg.SkipGetModules = true - cfg.SkipNewGoModule = true - return cfg - }, - verifyFiles: func(t *testing.T, dir string) { - // gosec linting error: G304 Potential file inclusion via variable - // we are setting the dir - outputFile, err := os.Open(dir) //nolint:gosec - defer func() { - require.NoError(t, outputFile.Close()) - }() - require.NoError(t, err) - _, err = outputFile.Readdirnames(1) - require.ErrorIs(t, err, io.EOF, "skip generate should leave output directory empty") - }, }, { testCase: "LDFlags Compilation", @@ -385,53 +348,6 @@ func TestGenerateAndCompile(t *testing.T) { return cfg }, }, - { - testCase: "Invalid Output Path", - cfgBuilder: func(t *testing.T) Config { - cfg := newInitializedConfig(t) - cfg.Distribution.OutputPath = ":/invalid" - return cfg - }, - expectedErr: "failed to create output path", - }, - { - testCase: "Malformed Receiver", - cfgBuilder: func(t *testing.T) Config { - cfg := NewDefaultConfig() - cfg.Receivers = append(cfg.Receivers, - Module{ - Name: "missing version", - GoMod: "go.opentelemetry.io/collector/cmd/builder/unittests", - }, - ) - tempDir := t.TempDir() - err := makeModule(tempDir, []byte(goModTestFile)) - require.NoError(t, err) - cfg.Distribution.OutputPath = filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - expectedErr: "ill-formatted modspec", - }, - } - - // file permissions don't work the same on windows systems, so this test always passes. - if runtime.GOOS != "windows" { - testCases = append(testCases, testDesc{ - testCase: "No Dir Permissions", - cfgBuilder: func(t *testing.T) Config { - cfg := newTestConfig() - err := cfg.SetBackwardsCompatibility() - require.NoError(t, err) - cfg.Distribution.OutputPath = t.TempDir() - assert.NoError(t, os.Chmod(cfg.Distribution.OutputPath, 0400)) - cfg.Replaces = append(cfg.Replaces, replaces...) - return cfg - }, - expectedErr: "failed to generate source file", - }) } for _, tt := range testCases { @@ -440,221 +356,7 @@ func TestGenerateAndCompile(t *testing.T) { assert.NoError(t, cfg.Validate()) assert.NoError(t, cfg.SetGoPath()) assert.NoError(t, cfg.ParseModules()) - err := GenerateAndCompile(cfg) - if len(tt.expectedErr) == 0 { - assert.NoError(t, err) - } else { - assert.ErrorContains(t, err, tt.expectedErr) - } - if tt.verifyFiles != nil { - tt.verifyFiles(t, cfg.Distribution.OutputPath) - } - }) - } -} - -func TestGetModules(t *testing.T) { - testCases := []struct { - description string - cfgBuilder func(t *testing.T) Config - expectedErr string - }{ - { - description: "Skip New Gomod Success", - cfgBuilder: func(t *testing.T) Config { - cfg := newTestConfig() - cfg.Distribution.Go = "go" - tempDir := t.TempDir() - require.NoError(t, makeModule(tempDir, []byte(goModTestFile))) - outputDir := filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Distribution.OutputPath = outputDir - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - }, - { - description: "Core Version Mismatch", - cfgBuilder: func(t *testing.T) Config { - cfg := newTestConfig() - cfg.Distribution.Go = "go" - cfg.Distribution.OtelColVersion = "0.100.0" - tempDir := t.TempDir() - require.NoError(t, makeModule(tempDir, []byte(goModTestFile))) - outputDir := filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Distribution.OutputPath = outputDir - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - expectedErr: ErrVersionMismatch.Error(), - }, - { - description: "No Go Distribution", - cfgBuilder: func(_ *testing.T) Config { - cfg := NewDefaultConfig() - cfg.downloadModules.wait = 0 - return cfg - }, - expectedErr: "failed to update go.mod", - }, - { - description: "Invalid Dependency", - cfgBuilder: func(t *testing.T) Config { - cfg := NewDefaultConfig() - cfg.downloadModules.wait = 0 - cfg.Distribution.Go = "go" - tempDir := t.TempDir() - require.NoError(t, makeModule(tempDir, []byte(invalidDependencyGoMod))) - outputDir := filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Distribution.OutputPath = outputDir - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - expectedErr: "failed to update go.mod", - }, - { - description: "Malformed Go Mod", - cfgBuilder: func(t *testing.T) Config { - cfg := NewDefaultConfig() - cfg.downloadModules.wait = 0 - cfg.Distribution.Go = "go" - tempDir := t.TempDir() - require.NoError(t, makeModule(tempDir, []byte(malformedGoMod))) - outputDir := filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Distribution.OutputPath = outputDir - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - expectedErr: "go subcommand failed with args '[mod edit -print]'", - }, - { - description: "Receiver Version Mismatch - Configured Lower", - cfgBuilder: func(t *testing.T) Config { - cfg := NewDefaultConfig() - cfg.Distribution.Go = "go" - cfg.Receivers = append(cfg.Receivers, - Module{ - GoMod: "go.opentelemetry.io/collector/receiver/otlpreceiver v0.105.0", - }, - ) - tempDir := t.TempDir() - err := makeModule(tempDir, []byte(goModTestFile)) - require.NoError(t, err) - cfg.Distribution.OutputPath = filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - expectedErr: ErrVersionMismatch.Error(), - }, - { - description: "Receiver Version Mismatch - Configured Higher", - cfgBuilder: func(t *testing.T) Config { - cfg := NewDefaultConfig() - cfg.Distribution.Go = "go" - cfg.Receivers = append(cfg.Receivers, - Module{ - GoMod: "go.opentelemetry.io/collector/receiver/otlpreceiver v0.106.1", - }, - ) - tempDir := t.TempDir() - err := makeModule(tempDir, []byte(goModTestFile)) - require.NoError(t, err) - cfg.Distribution.OutputPath = filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - }, - { - description: "Exporter Not in Gomod", - cfgBuilder: func(t *testing.T) Config { - cfg := NewDefaultConfig() - cfg.Distribution.Go = "go" - cfg.Exporters = append(cfg.Exporters, - Module{ - GoMod: "go.opentelemetry.io/collector/exporter/otlpexporter v0.106.0", - }, - ) - tempDir := t.TempDir() - err := makeModule(tempDir, []byte(goModTestFile)) - require.NoError(t, err) - cfg.Distribution.OutputPath = filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - }, - { - description: "Receiver Nonexistent Version", - cfgBuilder: func(t *testing.T) Config { - cfg := NewDefaultConfig() - cfg.Distribution.Go = "go" - cfg.Receivers = append(cfg.Receivers, - Module{ - GoMod: "go.opentelemetry.io/collector/receiver/otlpreceiver v0.106.2", - }, - ) - tempDir := t.TempDir() - err := makeModule(tempDir, []byte(goModTestFile)) - require.NoError(t, err) - cfg.Distribution.OutputPath = filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - expectedErr: "failed to update go.mod", - }, - { - description: "Receiver In Current Module", - cfgBuilder: func(t *testing.T) Config { - cfg := NewDefaultConfig() - cfg.Distribution.Go = "go" - cfg.Receivers = append(cfg.Receivers, - Module{ - GoMod: "go.opentelemetry.io/collector/cmd/builder/unittests v0.0.0", - }, - ) - tempDir := t.TempDir() - err := makeModule(tempDir, []byte(goModTestFile)) - require.NoError(t, err) - cfg.Distribution.OutputPath = filepath.Clean(filepath.Join(tempDir, "output")) - cfg.Replaces = nil - cfg.Excludes = nil - cfg.SkipNewGoModule = true - return cfg - }, - expectedErr: "failed to update go.mod", - }, - } - for _, tc := range testCases { - t.Run(tc.description, func(t *testing.T) { - cfg := tc.cfgBuilder(t) - require.NoError(t, cfg.SetBackwardsCompatibility()) - require.NoError(t, cfg.Validate()) - require.NoError(t, cfg.ParseModules()) - // GenerateAndCompile calls GetModules(). We want to call Generate() - // first so our dependencies stay in the gomod after go mod tidy. - err := GenerateAndCompile(cfg) - if len(tc.expectedErr) == 0 { - if !assert.NoError(t, err) { - mf, mvm, readErr := cfg.readGoModFile() - t.Log("go mod file", mf, mvm, readErr) - } - return - } - assert.ErrorContains(t, err, tc.expectedErr) + require.NoError(t, GenerateAndCompile(cfg)) }) } } diff --git a/cmd/builder/internal/builder/modfiles_test.go b/cmd/builder/internal/builder/modfiles_test.go deleted file mode 100644 index 45d478975ba..00000000000 --- a/cmd/builder/internal/builder/modfiles_test.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package builder - -const ( - goModTestFile = `// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -module go.opentelemetry.io/collector/cmd/builder/unittests - -go 1.21.0 - -require ( - go.opentelemetry.io/collector/component v0.106.0 - go.opentelemetry.io/collector/confmap v0.106.0 - go.opentelemetry.io/collector/confmap/converter/expandconverter v0.106.0 - go.opentelemetry.io/collector/confmap/provider/envprovider v0.106.0 - go.opentelemetry.io/collector/confmap/provider/fileprovider v0.106.0 - go.opentelemetry.io/collector/confmap/provider/httpprovider v0.106.0 - go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.106.0 - go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.106.0 - go.opentelemetry.io/collector/connector v0.106.0 - go.opentelemetry.io/collector/exporter v0.106.0 - go.opentelemetry.io/collector/exporter/otlpexporter v0.106.0 - go.opentelemetry.io/collector/extension v0.106.0 - go.opentelemetry.io/collector/otelcol v0.106.0 - go.opentelemetry.io/collector/processor v0.106.0 - go.opentelemetry.io/collector/receiver v0.106.0 - go.opentelemetry.io/collector/receiver/otlpreceiver v0.106.0 - golang.org/x/sys v0.20.0 -)` - - invalidDependencyGoMod = `// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -module go.opentelemetry.io/collector/cmd/builder/unittests - -go 1.21.0 - -require ( - go.opentelemetry.io/collector/bad/otelcol v0.94.1 - go.opentelemetry.io/collector/component v0.102.1 - go.opentelemetry.io/collector/confmap v0.102.1 - go.opentelemetry.io/collector/confmap/converter/expandconverter v0.102.1 - go.opentelemetry.io/collector/confmap/provider/envprovider v0.102.1 - go.opentelemetry.io/collector/confmap/provider/fileprovider v0.102.1 - go.opentelemetry.io/collector/confmap/provider/httpprovider v0.102.1 - go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.102.1 - go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.102.1 - go.opentelemetry.io/collector/connector v0.102.1 - go.opentelemetry.io/collector/exporter v0.102.1 - go.opentelemetry.io/collector/exporter/otlpexporter v0.102.1 - go.opentelemetry.io/collector/extension v0.102.1 - go.opentelemetry.io/collector/otelcol v0.102.1 - go.opentelemetry.io/collector/processor v0.102.1 - go.opentelemetry.io/collector/receiver v0.102.1 - go.opentelemetry.io/collector/receiver/otlpreceiver v0.102.1 - golang.org/x/sys v0.20.0 -)` - - malformedGoMod = `// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 -module go.opentelemetry.io/collector/cmd/builder/unittests - -go 1.21.0 - -require ( - go.opentelemetry.io/collector/componentv0.102.1 - go.opentelemetry.io/collector/confmap v0.102.1 - go.opentelemetry.io/collector/confmap/converter/expandconverter v0.102.1 - go.opentelemetry.io/collector/confmap/provider/envprovider v0.102.1 - go.opentelemetry.io/collector/confmap/provider/fileprovider v0.102.1 - go.opentelemetry.io/collector/confmap/provider/httpprovider v0.102.1 - go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.102.1 - go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.102.1 - go.opentelemetry.io/collector/connector v0.102.1 - go.opentelemetry.io/collector/exporter v0.102.1 - go.opentelemetry.io/collector/exporter/otlpexporter v0.102.1 - go.opentelemetry.io/collector/extension v0.102.1 - go.opentelemetry.io/collector/otelcol v0.102.1 - go.opentelemetry.io/collector/processor v0.102.1 - go.opentelemetry.io/collector/receiver v0.102.1 - go.opentelemetry.io/collector/receiver/otlpreceiver v0.102.1 - golang.org/x/sys v0.20.0 -)` -) diff --git a/cmd/builder/internal/command.go b/cmd/builder/internal/command.go index 41b7d6e4d95..a738fb1c1f1 100644 --- a/cmd/builder/internal/command.go +++ b/cmd/builder/internal/command.go @@ -23,7 +23,6 @@ const ( skipGenerateFlag = "skip-generate" skipCompilationFlag = "skip-compilation" skipGetModulesFlag = "skip-get-modules" - skipNewGoModuleFlag = "skip-new-go-module" skipStrictVersioningFlag = "skip-strict-versioning" ldflagsFlag = "ldflags" distributionNameFlag = "name" @@ -85,7 +84,6 @@ configuration is provided, ocb will generate a default Collector. cmd.Flags().BoolVar(&cfg.SkipGenerate, skipGenerateFlag, false, "Whether builder should skip generating go code (default false)") cmd.Flags().BoolVar(&cfg.SkipCompilation, skipCompilationFlag, false, "Whether builder should only generate go code with no compile of the collector (default false)") cmd.Flags().BoolVar(&cfg.SkipGetModules, skipGetModulesFlag, false, "Whether builder should skip updating go.mod and retrieve Go module list (default false)") - cmd.Flags().BoolVar(&cfg.SkipNewGoModule, skipNewGoModuleFlag, false, "Whether builder should skip generating a new go.mod file, using the enclosing Go module instead (default false)") cmd.Flags().BoolVar(&cfg.SkipStrictVersioning, skipStrictVersioningFlag, false, "Whether builder should skip strictly checking the calculated versions following dependency resolution") cmd.Flags().BoolVar(&cfg.Verbose, verboseFlag, false, "Whether builder should print verbose output (default false)") cmd.Flags().StringVar(&cfg.LDFlags, ldflagsFlag, "", `ldflags to include in the "go build" command`) @@ -187,9 +185,6 @@ func applyCfgFromFile(flags *flag.FlagSet, cfgFromFile builder.Config) { if !flags.Changed(skipGetModulesFlag) && cfgFromFile.SkipGetModules { cfg.SkipGetModules = cfgFromFile.SkipGetModules } - if !flags.Changed(skipNewGoModuleFlag) && cfgFromFile.SkipNewGoModule { - cfg.SkipNewGoModule = cfgFromFile.SkipNewGoModule - } if !flags.Changed(skipStrictVersioningFlag) && cfgFromFile.SkipStrictVersioning { cfg.SkipStrictVersioning = cfgFromFile.SkipStrictVersioning } diff --git a/cmd/builder/internal/command_test.go b/cmd/builder/internal/command_test.go index c7d1b27e535..d071efb312d 100644 --- a/cmd/builder/internal/command_test.go +++ b/cmd/builder/internal/command_test.go @@ -248,54 +248,6 @@ func Test_applyCfgFromFile(t *testing.T) { }, wantErr: false, }, - { - name: "Skip new go mod false", - args: args{ - flags: flag.NewFlagSet("version=1.0.0", 1), - cfgFromFile: builder.Config{ - Logger: zap.NewNop(), - SkipGenerate: true, - SkipCompilation: true, - SkipGetModules: true, - SkipNewGoModule: false, - Distribution: testDistribution, - }, - }, - want: builder.Config{ - Logger: zap.NewNop(), - SkipGenerate: true, - SkipCompilation: true, - SkipGetModules: true, - SkipStrictVersioning: true, - SkipNewGoModule: false, - Distribution: testDistribution, - }, - wantErr: false, - }, - { - name: "Skip new go mod true", - args: args{ - flags: flag.NewFlagSet("version=1.0.0", 1), - cfgFromFile: builder.Config{ - Logger: zap.NewNop(), - SkipGenerate: true, - SkipCompilation: true, - SkipGetModules: true, - SkipNewGoModule: true, - Distribution: testDistribution, - }, - }, - want: builder.Config{ - Logger: zap.NewNop(), - SkipGenerate: true, - SkipCompilation: true, - SkipGetModules: true, - SkipStrictVersioning: true, - SkipNewGoModule: true, - Distribution: testDistribution, - }, - wantErr: false, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {