Skip to content

Commit 47588b7

Browse files
Support replace directives in otel readme mage command (#7456) (#7616)
* Support pseudo-versions in otel readme mage command * Move otel dependency handling to a separate package (cherry picked from commit 9071254) # Conflicts: # go.mod Co-authored-by: Mikołaj Świątek <[email protected]>
1 parent 5bd3d3c commit 47588b7

File tree

5 files changed

+372
-185
lines changed

5 files changed

+372
-185
lines changed

NOTICE.txt

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18468,6 +18468,43 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1846818468
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1846918469

1847018470

18471+
--------------------------------------------------------------------------------
18472+
Dependency : golang.org/x/mod
18473+
Version: v0.23.0
18474+
Licence type (autodetected): BSD-3-Clause
18475+
--------------------------------------------------------------------------------
18476+
18477+
Contents of probable licence file $GOMODCACHE/golang.org/x/[email protected]/LICENSE:
18478+
18479+
Copyright 2009 The Go Authors.
18480+
18481+
Redistribution and use in source and binary forms, with or without
18482+
modification, are permitted provided that the following conditions are
18483+
met:
18484+
18485+
* Redistributions of source code must retain the above copyright
18486+
notice, this list of conditions and the following disclaimer.
18487+
* Redistributions in binary form must reproduce the above
18488+
copyright notice, this list of conditions and the following disclaimer
18489+
in the documentation and/or other materials provided with the
18490+
distribution.
18491+
* Neither the name of Google LLC nor the names of its
18492+
contributors may be used to endorse or promote products derived from
18493+
this software without specific prior written permission.
18494+
18495+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18496+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18497+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18498+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18499+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18500+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
18501+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
18502+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
18503+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18504+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
18505+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18506+
18507+
1847118508
--------------------------------------------------------------------------------
1847218509
Dependency : golang.org/x/net
1847318510
Version: v0.37.0
@@ -104716,43 +104753,6 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104716104753
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104717104754

104718104755

104719-
--------------------------------------------------------------------------------
104720-
Dependency : golang.org/x/mod
104721-
Version: v0.23.0
104722-
Licence type (autodetected): BSD-3-Clause
104723-
--------------------------------------------------------------------------------
104724-
104725-
Contents of probable licence file $GOMODCACHE/golang.org/x/[email protected]/LICENSE:
104726-
104727-
Copyright 2009 The Go Authors.
104728-
104729-
Redistribution and use in source and binary forms, with or without
104730-
modification, are permitted provided that the following conditions are
104731-
met:
104732-
104733-
* Redistributions of source code must retain the above copyright
104734-
notice, this list of conditions and the following disclaimer.
104735-
* Redistributions in binary form must reproduce the above
104736-
copyright notice, this list of conditions and the following disclaimer
104737-
in the documentation and/or other materials provided with the
104738-
distribution.
104739-
* Neither the name of Google LLC nor the names of its
104740-
contributors may be used to endorse or promote products derived from
104741-
this software without specific prior written permission.
104742-
104743-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
104744-
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
104745-
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
104746-
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
104747-
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
104748-
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
104749-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
104750-
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
104751-
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104752-
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
104753-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104754-
104755-
104756104756
--------------------------------------------------------------------------------
104757104757
Dependency : golang.org/x/oauth2
104758104758
Version: v0.25.0

dev-tools/mage/otel/deps.go

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License 2.0;
3+
// you may not use this file except in compliance with the Elastic License 2.0.
4+
5+
package otel
6+
7+
import (
8+
"fmt"
9+
"os"
10+
"path/filepath"
11+
"sort"
12+
"strings"
13+
14+
"golang.org/x/mod/modfile"
15+
"golang.org/x/mod/module"
16+
)
17+
18+
// GetOtelDependencies returns the Otel dependencies from the given go.mod. This function applies replace directives.
19+
func GetOtelDependencies(goModPath string) (*OtelDependencies, error) {
20+
// read go.mod
21+
goModBytes, err := os.ReadFile(goModPath)
22+
if err != nil {
23+
return nil, err
24+
}
25+
26+
goModFileName := filepath.Base(goModPath)
27+
28+
modFile, err := modfile.Parse(goModFileName, goModBytes, nil)
29+
if err != nil {
30+
return nil, err
31+
}
32+
33+
var receivers, extensions, exporters, processors, connectors []*otelDependency
34+
// process imports
35+
pathToDep := make(map[string]*otelDependency)
36+
for _, req := range modFile.Require {
37+
dependency := newOtelDependency(req)
38+
if dependency == nil {
39+
continue
40+
}
41+
pathToDep[req.Mod.Path] = dependency
42+
43+
if dependency.ComponentType == "connector" {
44+
connectors = append(connectors, dependency)
45+
} else if dependency.ComponentType == "exporter" {
46+
exporters = append(exporters, dependency)
47+
} else if dependency.ComponentType == "extension" {
48+
extensions = append(extensions, dependency)
49+
} else if dependency.ComponentType == "processor" {
50+
processors = append(processors, dependency)
51+
} else if dependency.ComponentType == "receiver" {
52+
receivers = append(receivers, dependency)
53+
}
54+
}
55+
56+
for _, list := range [][]*otelDependency{connectors, exporters, extensions, processors, receivers} {
57+
sort.Slice(list, func(i, j int) bool { return list[i].Name < list[j].Name })
58+
}
59+
60+
// take care of replaces
61+
for _, rep := range modFile.Replace {
62+
otelDep, ok := pathToDep[rep.Old.Path]
63+
if ok {
64+
otelDep.applyReplace(rep)
65+
}
66+
}
67+
68+
return &OtelDependencies{
69+
Connectors: connectors,
70+
Exporters: exporters,
71+
Extensions: extensions,
72+
Processors: processors,
73+
Receivers: receivers,
74+
}, nil
75+
}
76+
77+
type otelDependency struct {
78+
ComponentType string
79+
Name string
80+
Version string
81+
Link string
82+
req *modfile.Require
83+
}
84+
85+
func newOtelDependency(r *modfile.Require) *otelDependency {
86+
if !strings.Contains(r.Mod.Path, "go.opentelemetry.io/") &&
87+
!strings.Contains(r.Mod.Path, "github.com/open-telemetry/") &&
88+
!strings.Contains(r.Mod.Path, "github.com/elastic/opentelemetry-collector-components/") {
89+
return nil
90+
}
91+
92+
if r.Indirect {
93+
return nil
94+
}
95+
96+
componentName := getOtelComponentName(r.Mod.Path)
97+
componentType := getOtelComponentType(r.Mod.Path)
98+
link := getOtelDependencyLink(r.Mod.Path, r.Mod.Version)
99+
100+
return &otelDependency{
101+
ComponentType: componentType,
102+
Name: componentName,
103+
Version: r.Mod.Version,
104+
Link: link,
105+
req: r,
106+
}
107+
}
108+
109+
func (d *otelDependency) applyReplace(rep *modfile.Replace) {
110+
if rep == nil || rep.Old != d.req.Mod {
111+
return
112+
}
113+
d.Version = rep.New.Version
114+
d.req.Mod = rep.New
115+
d.Link = getOtelDependencyLink(rep.New.Path, rep.New.Version)
116+
}
117+
118+
func getOtelComponentName(dependencyName string) string {
119+
parts := strings.Split(dependencyName, "/")
120+
return parts[len(parts)-1]
121+
}
122+
123+
func getOtelComponentType(dependencyName string) string {
124+
if strings.Contains(dependencyName, "/connector/") {
125+
return "connector"
126+
} else if strings.Contains(dependencyName, "/exporter/") {
127+
return "exporter"
128+
} else if strings.Contains(dependencyName, "/extension/") {
129+
return "extension"
130+
} else if strings.Contains(dependencyName, "/processor/") {
131+
return "processor"
132+
} else if strings.Contains(dependencyName, "/receiver/") {
133+
return "receiver"
134+
}
135+
return ""
136+
}
137+
138+
func getOtelDependencyLink(dependencyURI string, version string) string {
139+
dependencyRepository := getDependencyRepository(dependencyURI)
140+
dependencyPath := strings.TrimPrefix(dependencyURI, dependencyRepository+"/")
141+
gitRevision := fmt.Sprintf("%s/%s", dependencyPath, version)
142+
repositoryURL := getOtelRepositoryURL(dependencyURI)
143+
// if the version is a pseudo-version pointing to a revision without a tag, we need to extract the revision
144+
if module.IsPseudoVersion(version) {
145+
revision, err := module.PseudoVersionRev(version)
146+
if err == nil { // this should never return an error, as we check it earlier
147+
gitRevision = revision
148+
}
149+
}
150+
return fmt.Sprintf("https://%s/blob/%s/%s/README.md", repositoryURL, gitRevision, dependencyPath)
151+
}
152+
153+
func getDependencyRepository(dependencyURI string) string {
154+
dependencyURIChunks := strings.Split(dependencyURI, "/")
155+
if len(dependencyURIChunks) < 2 {
156+
return ""
157+
}
158+
var dependencyRepository string
159+
if dependencyURIChunks[0] == "go.opentelemetry.io" {
160+
dependencyRepository = dependencyURIChunks[0] + "/" + dependencyURIChunks[1]
161+
} else {
162+
dependencyRepository = dependencyURIChunks[0] + "/" + dependencyURIChunks[1] + "/" + dependencyURIChunks[2]
163+
}
164+
return dependencyRepository
165+
}
166+
167+
func getOtelRepositoryURL(dependencyURI string) string {
168+
if strings.HasPrefix(dependencyURI, "go.opentelemetry.io/") {
169+
return "github.com/open-telemetry/opentelemetry-collector"
170+
} else if strings.HasPrefix(dependencyURI, "github.com/") {
171+
parts := strings.SplitN(dependencyURI, "/", 4)
172+
hostPart := parts[0]
173+
orgPart := parts[1]
174+
repoPart := parts[2]
175+
return fmt.Sprintf("%s/%s/%s", hostPart, orgPart, repoPart)
176+
}
177+
return ""
178+
}
179+
180+
type OtelDependencies struct {
181+
Connectors []*otelDependency
182+
Exporters []*otelDependency
183+
Extensions []*otelDependency
184+
Processors []*otelDependency
185+
Receivers []*otelDependency
186+
}

0 commit comments

Comments
 (0)