Skip to content

Commit 38eeb7a

Browse files
committed
use snakeyml instead of creating yaml manually, improve library parsing to account for logback
1 parent 7ac4181 commit 38eeb7a

File tree

10 files changed

+1659
-1490
lines changed

10 files changed

+1659
-1490
lines changed

docs/instrumentation-list.yaml

Lines changed: 1405 additions & 1400 deletions
Large diffs are not rendered by default.

instrumentation-docs/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ otelJava {
77
}
88

99
dependencies {
10+
implementation("org.yaml:snakeyaml:2.0")
11+
1012
testImplementation(enforcedPlatform("org.junit:junit-bom:5.12.0"))
1113
testImplementation("org.assertj:assertj-core:3.27.3")
1214
testImplementation("org.junit.jupiter:junit-jupiter-api")

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/DocGeneratorApplication.java

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,14 @@
66
package io.opentelemetry.instrumentation.docs;
77

88
import io.opentelemetry.instrumentation.docs.utils.FileManager;
9+
import io.opentelemetry.instrumentation.docs.utils.YamlHelper;
910
import java.io.BufferedWriter;
1011
import java.io.IOException;
1112
import java.nio.charset.Charset;
1213
import java.nio.file.Files;
1314
import java.nio.file.Paths;
1415
import java.util.List;
15-
import java.util.Map;
16-
import java.util.Set;
17-
import java.util.TreeMap;
1816
import java.util.logging.Logger;
19-
import java.util.stream.Collectors;
2017

2118
public class DocGeneratorApplication {
2219

@@ -25,53 +22,11 @@ public class DocGeneratorApplication {
2522
public static void main(String[] args) {
2623
FileManager fileManager = new FileManager("instrumentation/");
2724
List<InstrumentationEntity> entities = new InstrumentationAnalyzer(fileManager).analyze();
28-
printInstrumentationList(entities);
29-
}
30-
31-
private static void printInstrumentationList(List<InstrumentationEntity> list) {
32-
Map<String, List<InstrumentationEntity>> groupedByGroup =
33-
list.stream()
34-
.collect(
35-
Collectors.groupingBy(
36-
InstrumentationEntity::getGroup, TreeMap::new, Collectors.toList()));
3725

3826
try (BufferedWriter writer =
3927
Files.newBufferedWriter(
4028
Paths.get("docs/instrumentation-list.yaml"), Charset.defaultCharset())) {
41-
groupedByGroup.forEach(
42-
(group, entities) -> {
43-
try {
44-
String groupHeader = group + ":\n instrumentations:\n";
45-
writer.write(groupHeader);
46-
47-
for (InstrumentationEntity entity : entities) {
48-
String entityDetails =
49-
String.format(
50-
" - name: %s\n srcPath: %s\n",
51-
entity.getInstrumentationName(), entity.getSrcPath());
52-
writer.write(entityDetails);
53-
54-
if (entity.getTargetVersions() == null || entity.getTargetVersions().isEmpty()) {
55-
String targetVersions = " target_versions: {}\n";
56-
writer.write(targetVersions);
57-
} else {
58-
String targetVersions = " target_versions:\n";
59-
writer.write(targetVersions);
60-
for (Map.Entry<InstrumentationType, Set<String>> entry :
61-
entity.getTargetVersions().entrySet()) {
62-
String typeHeader = " " + entry.getKey() + ":\n";
63-
writer.write(typeHeader);
64-
for (String version : entry.getValue()) {
65-
String versionDetail = " - " + version + "\n";
66-
writer.write(versionDetail);
67-
}
68-
}
69-
}
70-
}
71-
} catch (IOException e) {
72-
logger.severe("Error writing instrumentation list: " + e.getMessage());
73-
}
74-
});
29+
YamlHelper.printInstrumentationList(entities, writer);
7530
} catch (IOException e) {
7631
logger.severe("Error writing instrumentation list: " + e.getMessage());
7732
}

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/GradleParser.java

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,48 +14,86 @@
1414

1515
class GradleParser {
1616
private static final Pattern passBlockPattern =
17-
Pattern.compile("pass\\s*\\{(.*?)\\}", Pattern.DOTALL);
17+
Pattern.compile("pass\\s*\\{(.*?)}", Pattern.DOTALL);
1818

1919
private static final Pattern libraryPattern =
2020
Pattern.compile("library\\(\"([^\"]+:[^\"]+:[^\"]+)\"\\)");
2121

2222
private static final Pattern variablePattern =
2323
Pattern.compile("val\\s+(\\w+)\\s*=\\s*\"([^\"]+)\"");
2424

25+
private static final Pattern compileOnlyPattern =
26+
Pattern.compile(
27+
"compileOnly\\(\"([^\"]+)\"\\)\\s*\\{\\s*version\\s*\\{(?:\\s*//.*\\n)*\\s*strictly\\(\"([^\"]+)\"\\)\\s*}\\s*}");
28+
2529
/**
26-
* Parses the "muzzle" block from the given Gradle file content and extracts information about
27-
* each "pass { ... }" entry, returning a set of version summary strings.
30+
* Parses gradle files for muzzle and dependency information
2831
*
2932
* @param gradleFileContents Contents of a Gradle build file as a String
3033
* @return A set of strings summarizing the group, module, and version ranges
3134
*/
32-
public static Set<String> parseMuzzleBlock(String gradleFileContents, InstrumentationType type) {
35+
public static Set<String> parseGradleFile(String gradleFileContents, InstrumentationType type) {
3336
Set<String> results = new HashSet<>();
3437
Map<String, String> variables = extractVariables(gradleFileContents);
3538

3639
if (type.equals(InstrumentationType.JAVAAGENT)) {
37-
Matcher passBlockMatcher = passBlockPattern.matcher(gradleFileContents);
40+
results.addAll(parseMuzzle(gradleFileContents, variables));
41+
} else {
42+
results.addAll(parseLibraryDependencies(gradleFileContents, variables));
43+
}
3844

39-
while (passBlockMatcher.find()) {
40-
String passBlock = passBlockMatcher.group(1);
45+
return results;
46+
}
4147

42-
String group = extractValue(passBlock, "group\\.set\\(\"([^\"]+)\"\\)");
43-
String module = extractValue(passBlock, "module\\.set\\(\"([^\"]+)\"\\)");
44-
String versionRange = extractValue(passBlock, "versions\\.set\\(\"([^\"]+)\"\\)");
48+
/**
49+
* Parses the "muzzle" block from the given Gradle file content and extracts information about
50+
* each "pass { ... }" entry, returning a set of version summary strings.
51+
*
52+
* @param gradleFileContents Contents of a Gradle build file as a String
53+
* @param variables Map of variable names to their values
54+
* @return A set of strings summarizing the group, module, and version ranges
55+
*/
56+
private static Set<String> parseMuzzle(String gradleFileContents, Map<String, String> variables) {
57+
Set<String> results = new HashSet<>();
58+
Matcher passBlockMatcher = passBlockPattern.matcher(gradleFileContents);
4559

46-
if (group != null && module != null && versionRange != null) {
47-
String summary = group + ":" + module + ":" + interpolate(versionRange, variables);
48-
results.add(summary);
49-
}
50-
}
51-
} else {
52-
Matcher dependencyMatcher = libraryPattern.matcher(gradleFileContents);
53-
while (dependencyMatcher.find()) {
54-
String dependency = dependencyMatcher.group(1);
55-
results.add(interpolate(dependency, variables));
60+
while (passBlockMatcher.find()) {
61+
String passBlock = passBlockMatcher.group(1);
62+
63+
String group = extractValue(passBlock, "group\\.set\\(\"([^\"]+)\"\\)");
64+
String module = extractValue(passBlock, "module\\.set\\(\"([^\"]+)\"\\)");
65+
String versionRange = extractValue(passBlock, "versions\\.set\\(\"([^\"]+)\"\\)");
66+
67+
if (group != null && module != null && versionRange != null) {
68+
String summary = group + ":" + module + ":" + interpolate(versionRange, variables);
69+
results.add(summary);
5670
}
5771
}
72+
return results;
73+
}
5874

75+
/**
76+
* Parses the "dependencies" block from the given Gradle file content and extracts information
77+
* about what library versions are supported.
78+
*
79+
* @param gradleFileContents Contents of a Gradle build file as a String
80+
* @param variables Map of variable names to their values
81+
* @return A set of strings summarizing the group, module, and versions
82+
*/
83+
private static Set<String> parseLibraryDependencies(
84+
String gradleFileContents, Map<String, String> variables) {
85+
Set<String> results = new HashSet<>();
86+
Matcher libraryMatcher = libraryPattern.matcher(gradleFileContents);
87+
while (libraryMatcher.find()) {
88+
String dependency = libraryMatcher.group(1);
89+
results.add(interpolate(dependency, variables));
90+
}
91+
92+
Matcher compileOnlyMatcher = compileOnlyPattern.matcher(gradleFileContents);
93+
while (compileOnlyMatcher.find()) {
94+
String dependency = compileOnlyMatcher.group(1) + ":" + compileOnlyMatcher.group(2);
95+
results.add(interpolate(dependency, variables));
96+
}
5997
return results;
6098
}
6199

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/InstrumentationAnalyzer.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
package io.opentelemetry.instrumentation.docs;
77

8-
import static io.opentelemetry.instrumentation.docs.GradleParser.parseMuzzleBlock;
8+
import static io.opentelemetry.instrumentation.docs.GradleParser.parseGradleFile;
99

1010
import io.opentelemetry.instrumentation.docs.utils.FileManager;
1111
import io.opentelemetry.instrumentation.docs.utils.InstrumentationPath;
@@ -45,10 +45,8 @@ public static List<InstrumentationEntity> convertToEntities(List<Instrumentation
4545
path.srcPath().replace("/javaagent", "").replace("/library", ""),
4646
path.instrumentationName(),
4747
path.namespace(),
48-
path.group(),
49-
new ArrayList<>()));
48+
path.group()));
5049
}
51-
entityMap.get(key).getTypes().add(path.type());
5250
}
5351

5452
return new ArrayList<>(entityMap.values());
@@ -77,12 +75,12 @@ void analyzeVersions(List<String> files, InstrumentationEntity entity) {
7775
String fileContents = fileSearch.readFileToString(file);
7876

7977
if (file.contains("/javaagent/")) {
80-
Set<String> results = parseMuzzleBlock(fileContents, InstrumentationType.JAVAAGENT);
78+
Set<String> results = parseGradleFile(fileContents, InstrumentationType.JAVAAGENT);
8179
versions
8280
.computeIfAbsent(InstrumentationType.JAVAAGENT, k -> new HashSet<>())
8381
.addAll(results);
8482
} else if (file.contains("/library/")) {
85-
Set<String> results = parseMuzzleBlock(fileContents, InstrumentationType.LIBRARY);
83+
Set<String> results = parseGradleFile(fileContents, InstrumentationType.LIBRARY);
8684
versions.computeIfAbsent(InstrumentationType.LIBRARY, k -> new HashSet<>()).addAll(results);
8785
}
8886
}

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/InstrumentationEntity.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,35 @@
55

66
package io.opentelemetry.instrumentation.docs;
77

8-
import java.util.List;
98
import java.util.Map;
109
import java.util.Set;
1110

12-
class InstrumentationEntity {
11+
public class InstrumentationEntity {
1312
private final String srcPath;
1413
private final String instrumentationName;
1514
private final String namespace;
1615
private final String group;
17-
private final List<InstrumentationType> types;
1816
private Map<InstrumentationType, Set<String>> targetVersions;
1917

18+
public InstrumentationEntity(
19+
String srcPath, String instrumentationName, String namespace, String group) {
20+
this.srcPath = srcPath;
21+
this.instrumentationName = instrumentationName;
22+
this.namespace = namespace;
23+
this.group = group;
24+
}
25+
2026
public InstrumentationEntity(
2127
String srcPath,
2228
String instrumentationName,
2329
String namespace,
2430
String group,
25-
List<InstrumentationType> types) {
31+
Map<InstrumentationType, Set<String>> targetVersions) {
2632
this.srcPath = srcPath;
2733
this.instrumentationName = instrumentationName;
2834
this.namespace = namespace;
2935
this.group = group;
30-
this.types = types;
36+
this.targetVersions = targetVersions;
3137
}
3238

3339
public String getSrcPath() {
@@ -46,10 +52,6 @@ public String getGroup() {
4652
return group;
4753
}
4854

49-
public List<InstrumentationType> getTypes() {
50-
return types;
51-
}
52-
5355
public Map<InstrumentationType, Set<String>> getTargetVersions() {
5456
return targetVersions;
5557
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.docs.utils;
7+
8+
import io.opentelemetry.instrumentation.docs.InstrumentationEntity;
9+
import java.io.BufferedWriter;
10+
import java.util.ArrayList;
11+
import java.util.List;
12+
import java.util.Map;
13+
import java.util.TreeMap;
14+
import java.util.stream.Collectors;
15+
import org.yaml.snakeyaml.DumperOptions;
16+
import org.yaml.snakeyaml.Yaml;
17+
import org.yaml.snakeyaml.representer.Representer;
18+
19+
public class YamlHelper {
20+
21+
public static void printInstrumentationList(
22+
List<InstrumentationEntity> list, BufferedWriter writer) {
23+
Map<String, List<InstrumentationEntity>> groupedByGroup =
24+
list.stream()
25+
.collect(
26+
Collectors.groupingBy(
27+
InstrumentationEntity::getGroup, TreeMap::new, Collectors.toList()));
28+
29+
Map<String, Object> output = new TreeMap<>();
30+
groupedByGroup.forEach(
31+
(group, entities) -> {
32+
Map<String, Object> groupMap = new TreeMap<>();
33+
List<Map<String, Object>> instrumentations = new ArrayList<>();
34+
for (InstrumentationEntity entity : entities) {
35+
Map<String, Object> entityMap = new TreeMap<>();
36+
entityMap.put("name", entity.getInstrumentationName());
37+
entityMap.put("srcPath", entity.getSrcPath());
38+
39+
Map<String, Object> targetVersions = new TreeMap<>();
40+
if (entity.getTargetVersions() != null && !entity.getTargetVersions().isEmpty()) {
41+
entity
42+
.getTargetVersions()
43+
.forEach(
44+
(type, versions) -> {
45+
targetVersions.put(type.toString(), new ArrayList<>(versions));
46+
});
47+
}
48+
entityMap.put("target_versions", targetVersions);
49+
instrumentations.add(entityMap);
50+
}
51+
groupMap.put("instrumentations", instrumentations);
52+
output.put(group, groupMap);
53+
});
54+
55+
DumperOptions options = new DumperOptions();
56+
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
57+
Representer representer = new Representer(options);
58+
representer.getPropertyUtils().setSkipMissingProperties(true);
59+
Yaml yaml = new Yaml(representer, options);
60+
yaml.dump(output, writer);
61+
}
62+
63+
private YamlHelper() {}
64+
}

0 commit comments

Comments
 (0)