Parse latestDepTestLibrary and use as library upper bound (#13478)
This commit is contained in:
parent
ffeb80eb26
commit
c7676bddd4
|
@ -58,7 +58,7 @@ apache:
|
|||
srcPath: instrumentation/apache-httpclient/apache-httpclient-4.3
|
||||
target_versions:
|
||||
library:
|
||||
- org.apache.httpcomponents:httpclient:4.3
|
||||
- org.apache.httpcomponents:httpclient:[4.3,4.+)
|
||||
- name: apache-httpclient-4.0
|
||||
srcPath: instrumentation/apache-httpclient/apache-httpclient-4.0
|
||||
target_versions:
|
||||
|
@ -137,7 +137,7 @@ aws:
|
|||
- com.amazonaws:aws-java-sdk-sqs:[1.10.33,)
|
||||
- com.amazonaws:aws-java-sdk-core:[1.10.33,)
|
||||
library:
|
||||
- com.amazonaws:aws-java-sdk-sqs:1.11.106
|
||||
- com.amazonaws:aws-java-sdk-sqs:[1.11.106,1.12.583)
|
||||
- com.amazonaws:aws-java-sdk-core:1.11.0
|
||||
- name: aws-sdk-2.2
|
||||
srcPath: instrumentation/aws-sdk/aws-sdk-2.2
|
||||
|
@ -352,7 +352,7 @@ graphql:
|
|||
javaagent:
|
||||
- com.graphql-java:graphql-java:[12,20)
|
||||
library:
|
||||
- com.graphql-java:graphql-java:12.0
|
||||
- com.graphql-java:graphql-java:[12.0,19.+)
|
||||
- name: graphql-java-20.0
|
||||
srcPath: instrumentation/graphql-java/graphql-java-20.0
|
||||
target_versions:
|
||||
|
@ -651,7 +651,7 @@ jetty:
|
|||
javaagent:
|
||||
- org.eclipse.jetty:jetty-client:[9.2,10)
|
||||
library:
|
||||
- org.eclipse.jetty:jetty-client:9.2.0.v20140526
|
||||
- org.eclipse.jetty:jetty-client:[9.2.0.v20140526,9.+)
|
||||
- name: jetty-11.0
|
||||
srcPath: instrumentation/jetty/jetty-11.0
|
||||
target_versions:
|
||||
|
@ -765,8 +765,8 @@ ktor:
|
|||
- io.ktor:ktor-client-core:[2.0.0,3.0.0)
|
||||
- io.ktor:ktor-server-core:[2.0.0,3.0.0)
|
||||
library:
|
||||
- io.ktor:ktor-server-core:2.0.0
|
||||
- io.ktor:ktor-client-core:2.0.0
|
||||
- io.ktor:ktor-client-core:[2.0.0,2.+)
|
||||
- io.ktor:ktor-server-core:[2.0.0,2.+)
|
||||
- name: ktor-3.0
|
||||
srcPath: instrumentation/ktor/ktor-3.0
|
||||
target_versions:
|
||||
|
@ -780,7 +780,7 @@ ktor:
|
|||
srcPath: instrumentation/ktor/ktor-1.0
|
||||
target_versions:
|
||||
library:
|
||||
- io.ktor:ktor-server-core:1.0.0
|
||||
- io.ktor:ktor-server-core:[1.0.0,1.+)
|
||||
kubernetes:
|
||||
instrumentations:
|
||||
- name: kubernetes-client-7.0
|
||||
|
@ -1049,7 +1049,7 @@ oshi:
|
|||
javaagent:
|
||||
- com.github.oshi:oshi-core:[5.3.1,)
|
||||
library:
|
||||
- com.github.oshi:oshi-core:$oshiVersion
|
||||
- com.github.oshi:oshi-core:5.3.1
|
||||
payara:
|
||||
instrumentations:
|
||||
- name: payara
|
||||
|
@ -1069,8 +1069,11 @@ pekko:
|
|||
srcPath: instrumentation/pekko/pekko-http-1.0
|
||||
target_versions:
|
||||
javaagent:
|
||||
- com.softwaremill.sttp.tapir:tapir-pekko-http-server_3:[1.7,)
|
||||
- com.softwaremill.sttp.tapir:tapir-pekko-http-server_2.12:[1.7,)
|
||||
- org.apache.pekko:pekko-http_2.12:[1.0,)
|
||||
- org.apache.pekko:pekko-http_3:[1.0,)
|
||||
- com.softwaremill.sttp.tapir:tapir-pekko-http-server_2.13:[1.7,)
|
||||
- org.apache.pekko:pekko-http_2.13:[1.0,)
|
||||
play:
|
||||
instrumentations:
|
||||
|
@ -1233,7 +1236,7 @@ restlet:
|
|||
javaagent:
|
||||
- org.restlet:org.restlet:[1.1.0, 1.2-M1)
|
||||
library:
|
||||
- org.restlet:org.restlet:1.1.5
|
||||
- org.restlet:org.restlet:[1.1.5,1.+)
|
||||
- com.noelios.restlet:com.noelios.restlet:1.1.5
|
||||
- name: restlet-2.0
|
||||
srcPath: instrumentation/restlet/restlet-2.0
|
||||
|
@ -1301,7 +1304,7 @@ rxjava:
|
|||
javaagent:
|
||||
- io.reactivex.rxjava3:rxjava:[3.0.0,3.1.0]
|
||||
library:
|
||||
- io.reactivex.rxjava3:rxjava:3.0.12
|
||||
- io.reactivex.rxjava3:rxjava:[3.0.12,3.1.0)
|
||||
scala:
|
||||
instrumentations:
|
||||
- name: scala-fork-join-2.8
|
||||
|
@ -1446,7 +1449,7 @@ spring:
|
|||
javaagent:
|
||||
- org.springframework.integration:spring-integration-core:[4.1.0.RELEASE,)
|
||||
library:
|
||||
- org.springframework.integration:spring-integration-core:4.1.0.RELEASE
|
||||
- org.springframework.integration:spring-integration-core:[4.1.0.RELEASE,5.+)
|
||||
- name: spring-jms-2.0
|
||||
srcPath: instrumentation/spring/spring-jms/spring-jms-2.0
|
||||
target_versions:
|
||||
|
|
|
@ -53,11 +53,7 @@ public class SpringWebInstrumentationModule extends InstrumentationModule
|
|||
|
||||
### Versions targeted
|
||||
|
||||
Javaagent versions are determined by the `muzzle` plugin, so we can attempt to parse the gradle files
|
||||
We parse gradle files in order to determine the target versions.
|
||||
|
||||
Library versions are determined by the library versions used in the gradle files.
|
||||
|
||||
### TODO / Notes
|
||||
|
||||
- Is the `library` dependency actually the target version? Is there a better way to present the information?
|
||||
- How to handle oshi target version with a conditional?
|
||||
- Javaagent versions are determined by the `muzzle` plugin configurations
|
||||
- Library versions are determined by the library dependency versions
|
||||
|
|
|
@ -13,18 +13,23 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
class GradleParser {
|
||||
private static final Pattern passBlockPattern =
|
||||
Pattern.compile("pass\\s*\\{(.*?)}", Pattern.DOTALL);
|
||||
|
||||
private static final Pattern libraryPattern =
|
||||
Pattern.compile("library\\(\"([^\"]+:[^\"]+:[^\"]+)\"\\)");
|
||||
|
||||
private static final Pattern variablePattern =
|
||||
Pattern.compile("val\\s+(\\w+)\\s*=\\s*\"([^\"]+)\"");
|
||||
|
||||
private static final Pattern muzzlePassBlockPattern =
|
||||
Pattern.compile("pass\\s*\\{(.*?)}", Pattern.DOTALL);
|
||||
|
||||
private static final Pattern libraryPattern =
|
||||
Pattern.compile("library\\(\"([^\"]+:[^\"]+):([^\"]+)\"\\)");
|
||||
|
||||
private static final Pattern compileOnlyPattern =
|
||||
Pattern.compile(
|
||||
"compileOnly\\(\"([^\"]+)\"\\)\\s*\\{\\s*version\\s*\\{(?:\\s*//.*\\n)*\\s*strictly\\(\"([^\"]+)\"\\)\\s*}\\s*}");
|
||||
"compileOnly\\(\"([^\"]+:[^\"]+)(?::[^\"]+)?\"\\)\\s*\\{\\s*version\\s*\\{.*?strictly\\(\"([^\"]+)\"\\).*?}\\s*",
|
||||
Pattern.DOTALL);
|
||||
|
||||
private static final Pattern latestDepTestLibraryPattern =
|
||||
Pattern.compile("latestDepTestLibrary\\(\"([^\"]+:[^\"]+):([^\"]+)\"\\)");
|
||||
|
||||
/**
|
||||
* Parses gradle files for muzzle and dependency information
|
||||
|
@ -55,7 +60,7 @@ class GradleParser {
|
|||
*/
|
||||
private static Set<String> parseMuzzle(String gradleFileContents, Map<String, String> variables) {
|
||||
Set<String> results = new HashSet<>();
|
||||
Matcher passBlockMatcher = passBlockPattern.matcher(gradleFileContents);
|
||||
Matcher passBlockMatcher = muzzlePassBlockPattern.matcher(gradleFileContents);
|
||||
|
||||
while (passBlockMatcher.find()) {
|
||||
String passBlock = passBlockMatcher.group(1);
|
||||
|
@ -74,7 +79,8 @@ class GradleParser {
|
|||
|
||||
/**
|
||||
* Parses the "dependencies" block from the given Gradle file content and extracts information
|
||||
* about what library versions are supported.
|
||||
* about what library versions are supported. Looks for library() and compileOnly() blocks for
|
||||
* lower bounds, and latestDepTestLibrary() for upper bounds.
|
||||
*
|
||||
* @param gradleFileContents Contents of a Gradle build file as a String
|
||||
* @param variables Map of variable names to their values
|
||||
|
@ -82,18 +88,41 @@ class GradleParser {
|
|||
*/
|
||||
private static Set<String> parseLibraryDependencies(
|
||||
String gradleFileContents, Map<String, String> variables) {
|
||||
Set<String> results = new HashSet<>();
|
||||
Map<String, String> versions = new HashMap<>();
|
||||
|
||||
Matcher libraryMatcher = libraryPattern.matcher(gradleFileContents);
|
||||
|
||||
while (libraryMatcher.find()) {
|
||||
String dependency = libraryMatcher.group(1);
|
||||
results.add(interpolate(dependency, variables));
|
||||
String groupAndArtifact = libraryMatcher.group(1);
|
||||
String version = libraryMatcher.group(2);
|
||||
versions.put(groupAndArtifact, version);
|
||||
}
|
||||
|
||||
Matcher compileOnlyMatcher = compileOnlyPattern.matcher(gradleFileContents);
|
||||
while (compileOnlyMatcher.find()) {
|
||||
String dependency = compileOnlyMatcher.group(1) + ":" + compileOnlyMatcher.group(2);
|
||||
results.add(interpolate(dependency, variables));
|
||||
String groupAndArtifact = compileOnlyMatcher.group(1);
|
||||
String version = compileOnlyMatcher.group(2);
|
||||
versions.put(groupAndArtifact, version);
|
||||
}
|
||||
|
||||
Matcher latestDepTestLibraryMatcher = latestDepTestLibraryPattern.matcher(gradleFileContents);
|
||||
while (latestDepTestLibraryMatcher.find()) {
|
||||
String groupAndArtifact = latestDepTestLibraryMatcher.group(1);
|
||||
String version = latestDepTestLibraryMatcher.group(2);
|
||||
if (versions.containsKey(groupAndArtifact)) {
|
||||
versions.put(groupAndArtifact, versions.get(groupAndArtifact) + "," + version);
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> results = new HashSet<>();
|
||||
for (Map.Entry<String, String> entry : versions.entrySet()) {
|
||||
if (entry.getValue().contains(",")) {
|
||||
results.add(interpolate(entry.getKey() + ":[" + entry.getValue() + ")", variables));
|
||||
} else {
|
||||
results.add(interpolate(entry.getKey() + ":" + entry.getValue(), variables));
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,11 +32,7 @@ class GradleParserTest {
|
|||
@Test
|
||||
void testExtractLibraryVersion() {
|
||||
String gradleBuildFileContent =
|
||||
"dependencies {\n"
|
||||
+ " library(\"org.apache.httpcomponents:httpclient:4.3\")\n"
|
||||
+ " testImplementation(project(\":instrumentation:apache-httpclient:apache-httpclient-4.3:testing\"))\n"
|
||||
+ " latestDepTestLibrary(\"org.apache.httpcomponents:httpclient:4.+\") // see apache-httpclient-5.0 module\n"
|
||||
+ "}";
|
||||
"dependencies {\n" + " library(\"org.apache.httpcomponents:httpclient:4.3\")\n" + "}";
|
||||
Set<String> versions =
|
||||
GradleParser.parseGradleFile(gradleBuildFileContent, InstrumentationType.LIBRARY);
|
||||
assertThat(versions.size()).isEqualTo(1);
|
||||
|
@ -44,6 +40,22 @@ class GradleParserTest {
|
|||
.isEqualTo("org.apache.httpcomponents:httpclient:4.3");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExtractLibraryUpperVersion() {
|
||||
String gradleBuildFileContent =
|
||||
"dependencies {\n"
|
||||
+ " library(\"org.apache.httpcomponents:httpclient:4.3\")\n"
|
||||
+ " testImplementation(project(\":instrumentation:apache-httpclient:apache-httpclient-4.3:testing\"))\n"
|
||||
+ " latestDepTestLibrary(\"org.apache.httpcomponents:httpclient:4.+\") // see apache-httpclient-5.0 module\n"
|
||||
+ "}";
|
||||
|
||||
Set<String> versions =
|
||||
GradleParser.parseGradleFile(gradleBuildFileContent, InstrumentationType.LIBRARY);
|
||||
assertThat(versions.size()).isEqualTo(1);
|
||||
assertThat(versions.stream().findFirst().get())
|
||||
.isEqualTo("org.apache.httpcomponents:httpclient:[4.3,4.+)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExtractMuzzleVersions_MultiplePassBlocks() {
|
||||
String gradleBuildFileContent =
|
||||
|
|
Loading…
Reference in New Issue