@@ -23,6 +23,7 @@ import org.eclipse.aether.spi.connector.transport.TransporterFactory
2323import org.eclipse.aether.transport.http.HttpTransporterFactory
2424import org.eclipse.aether.util.version.GenericVersionScheme
2525import org.eclipse.aether.version.Version
26+ import java.io.File
2627import java.net.URL
2728import java.net.URLClassLoader
2829import java.util.stream.StreamSupport
@@ -37,13 +38,30 @@ val RANGE_COUNT_LIMIT = Integer.getInteger("otel.javaagent.muzzle.versions.limit
3738
3839// Read pinned latest-dep versions to cap muzzle's open-ended version ranges,
3940// preventing failures when new library versions are released to Maven Central.
40- val muzzlePinnedVersions: Map <String , String > by lazy {
41- val file = rootProject.file(" .github/config/latest-dep-versions.json" )
42- if (! file.exists()) {
43- throw GradleException (" Pinned latest-dep versions file is missing: ${file} ." )
41+ //
42+ // External users of the muzzle plugin may not have this pinned versions file in their project
43+ // layout. In that case, fall back to the old behavior and resolve versions directly from
44+ // configured repositories.
45+ val muzzlePinnedVersions: Map <String , String >? by lazy {
46+ val file = generateSequence(rootProject.projectDir) { it.parentFile }
47+ .flatMap {
48+ sequenceOf(
49+ File (it, " .github/config/latest-dep-versions.json" ),
50+ File (it, " config/latest-dep-versions.json" )
51+ )
52+ }
53+ .firstOrNull { it.exists() }
54+ if (file == null ) {
55+ logger.info(
56+ " Pinned latest-dep versions file is missing under ${rootProject.projectDir} ; falling back to repository " +
57+ " version resolution for muzzle checks."
58+ )
59+ null
60+ } else {
61+ logger.info(" Using pinned latest-dep versions file: ${file} " )
62+ @Suppress(" UNCHECKED_CAST" )
63+ groovy.json.JsonSlurper ().parse(file) as Map <String , String >
4464 }
45- @Suppress(" UNCHECKED_CAST" )
46- groovy.json.JsonSlurper ().parse(file) as Map <String , String >
4765}
4866
4967/* *
@@ -58,16 +76,19 @@ val muzzlePinnedVersions: Map<String, String> by lazy {
5876 * the agent uses shaded/in-repo classes rather than the external library). With "0.0" as the
5977 * upper bound, {@code filterVersions} rejects all real versions (none are <= 0.0), so no
6078 * muzzle tasks are created and the directive is silently skipped. To add a sentinel entry,
61- * manually add {@code "group:module#+": "0.0"} to
62- * {@code .github/config/latest-dep-versions.json}.
79+ * manually add {@code "group:module#+": "0.0"} to the pinned latest-dep versions file.
80+ *
81+ * <p>Returns {@code null} when the pinned versions file is not present, which preserves the old
82+ * behavior of resolving the full version range from configured repositories.
6383 */
64- fun resolveUpperBound (group : String , module : String ): Version {
84+ fun resolveUpperBound (group : String , module : String ): Version ? {
85+ val pinnedVersions = muzzlePinnedVersions ? : return null
6586 val key = " $group :$module #+"
66- val pinnedVersion = muzzlePinnedVersions [key]
87+ val pinnedVersion = pinnedVersions [key]
6788 ? : throw GradleException (
6889 " Pinned version missing for muzzle artifact \" $key \" . " +
6990 " Run ./gradlew resolveLatestDepVersions -PtestLatestDeps=true -PresolveLatestDeps=true " +
70- " to regenerate .github/config/ latest-dep- versions.json "
91+ " to regenerate the pinned latest-dep versions file "
7192 )
7293 return GenericVersionScheme ().parseVersion(pinnedVersion)
7394}
@@ -198,9 +219,12 @@ tasks.register("printMuzzleReferences") {
198219val hasRelevantTask = gradle.startParameter.taskNames.any {
199220 // removing leading ':' if present
200221 val taskName = it.removePrefix(" :" )
201- val projectPath = project.path.substring(1 )
222+ val projectPath = project.path.removePrefix(" :" )
223+ val muzzleTaskName = if (projectPath.isEmpty()) " muzzle" else " $projectPath :muzzle"
202224 // Either the specific muzzle task in this project or a top level muzzle task.
203- taskName == " ${projectPath} :muzzle" || taskName.startsWith(" instrumentation:muzzle" ) ||
225+ taskName == muzzleTaskName ||
226+ taskName.startsWith(" instrumentation:muzzle" ) ||
227+ taskName.startsWith(" muzzle-Assert" ) ||
204228 taskName.contains(" :muzzle-Assert" )
205229}
206230
@@ -442,9 +466,10 @@ fun inverseOf(muzzleDirective: MuzzleDirective, system: RepositorySystem, sessio
442466 return inverseDirectives
443467}
444468
445- fun filterVersions (range : VersionRangeResult , skipVersions : Set <String >, upperBound : Version ) = sequence {
469+ fun filterVersions (range : VersionRangeResult , skipVersions : Set <String >, upperBound : Version ? ) = sequence {
446470 val predicate = AcceptableVersions (skipVersions)
447- fun accept (version : Version ? ): Boolean = version != null && predicate.test(version) && version <= upperBound
471+ fun accept (version : Version ? ): Boolean =
472+ version != null && predicate.test(version) && (upperBound == null || version <= upperBound)
448473 if (accept(range.lowestVersion)) {
449474 yield (range.lowestVersion.toString())
450475 }
0 commit comments