Skip to content

Commit d232e66

Browse files
committed
make suffixes configurable
1 parent c1a6a58 commit d232e66

File tree

3 files changed

+57
-33
lines changed

3 files changed

+57
-33
lines changed

buildSrc/src/main/kotlin/datadog/gradle/plugin/naming/InstrumentationNamingExtension.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.gradle.api.provider.Property
1111
* instrumentationNaming {
1212
* instrumentationsDir.set(file("dd-java-agent/instrumentation"))
1313
* exclusions.set(listOf("http-url-connection", "sslsocket"))
14+
* suffixes.set(listOf("-common", "-stubs""))
1415
* }
1516
* ```
1617
*/
@@ -27,8 +28,16 @@ abstract class InstrumentationNamingExtension {
2728
*/
2829
abstract val exclusions: ListProperty<String>
2930

31+
/**
32+
* List of allowed suffixes for module names (e.g., "-common", "-stubs").
33+
* Module names must end with either one of these suffixes or a version number.
34+
* Defaults to ["-common", "-stubs"].
35+
*/
36+
abstract val suffixes: ListProperty<String>
37+
3038
init {
3139
instrumentationsDir.convention("dd-java-agent/instrumentation")
3240
exclusions.convention(emptyList())
41+
suffixes.convention(listOf("-common", "-stubs"))
3342
}
3443
}

buildSrc/src/main/kotlin/datadog/gradle/plugin/naming/InstrumentationNamingPlugin.kt

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,18 @@ class InstrumentationNamingPlugin : Plugin<Project> {
3636
doLast {
3737
val instrumentationsDir = target.rootProject.file(extension.instrumentationsDir.get())
3838
val exclusions = extension.exclusions.get().toSet()
39+
val suffixes = extension.suffixes.get()
3940

4041
if (!instrumentationsDir.exists() || !instrumentationsDir.isDirectory) {
4142
throw GradleException(
4243
"Instrumentations directory not found: ${instrumentationsDir.absolutePath}"
4344
)
4445
}
4546

46-
val violations = validateInstrumentations(instrumentationsDir, exclusions)
47+
val violations = validateInstrumentations(instrumentationsDir, exclusions, suffixes)
4748

4849
if (violations.isNotEmpty()) {
50+
val suffixesStr = suffixes.joinToString("', '", "'", "'")
4951
val errorMessage = buildString {
5052
appendLine("\nInstrumentation naming convention violations found:")
5153
appendLine()
@@ -55,13 +57,14 @@ class InstrumentationNamingPlugin : Plugin<Project> {
5557
appendLine()
5658
}
5759
appendLine("Naming rules:")
58-
appendLine(" 1. Module name must end with a version (e.g., '2.0', '3.1') OR end with '-common'")
60+
appendLine(" 1. Module name must end with a version (e.g., '2.0', '3.1') OR one of: $suffixesStr")
5961
appendLine(" 2. Module name must include the parent directory name")
6062
appendLine(" Example: 'couchbase/couchbase-2.0' ✓ (contains 'couchbase')")
6163
appendLine()
62-
appendLine("To exclude specific modules, configure the plugin:")
64+
appendLine("To exclude specific modules or customize suffixes, configure the plugin:")
6365
appendLine(" instrumentationNaming {")
6466
appendLine(" exclusions.set(listOf(\"module-name\"))")
67+
appendLine(" suffixes.set(listOf(\"-common\", \"-stubs\"))")
6568
appendLine(" }")
6669
}
6770
throw GradleException(errorMessage)
@@ -74,7 +77,8 @@ class InstrumentationNamingPlugin : Plugin<Project> {
7477

7578
private fun validateInstrumentations(
7679
instrumentationsDir: File,
77-
exclusions: Set<String>
80+
exclusions: Set<String>,
81+
suffixes: List<String>
7882
): List<NamingViolation> {
7983
val violations = mutableListOf<NamingViolation>()
8084

@@ -96,7 +100,7 @@ class InstrumentationNamingPlugin : Plugin<Project> {
96100
if (hasBuildFile) {
97101
// This is a leaf module, validate only the version/common suffix requirement
98102
if (parentName !in exclusions) {
99-
validateLeafModuleName(parentName, parentDir.relativeTo(instrumentationsDir).path)?.let {
103+
validateLeafModuleName(parentName, parentDir.relativeTo(instrumentationsDir).path, suffixes)?.let {
100104
violations.add(it)
101105
}
102106
}
@@ -116,7 +120,7 @@ class InstrumentationNamingPlugin : Plugin<Project> {
116120
} ?: false
117121

118122
if (hasModuleBuildFile && moduleName !in exclusions) {
119-
validateModuleName(moduleName, parentName, moduleDir.relativeTo(instrumentationsDir).path)?.let {
123+
validateModuleName(moduleName, parentName, moduleDir.relativeTo(instrumentationsDir).path, suffixes)?.let {
120124
violations.add(it)
121125
}
122126
}
@@ -130,21 +134,13 @@ class InstrumentationNamingPlugin : Plugin<Project> {
130134
private fun validateModuleName(
131135
moduleName: String,
132136
parentName: String,
133-
relativePath: String
137+
relativePath: String,
138+
suffixes: List<String>
134139
): NamingViolation? {
135-
// Rule 1: Module name must end with version pattern (X.Y, X.Y.Z, etc.) or "-common"
136-
val endsWithCommon = moduleName.endsWith("-common")
137-
val endsWithVersion = versionPattern.containsMatchIn(moduleName)
138-
139-
if (!endsWithVersion && !endsWithCommon) {
140-
return NamingViolation(
141-
relativePath,
142-
"Module name '$moduleName' must end with a version (e.g., '2.0', '3.1.0') or '-common'"
143-
)
144-
}
140+
// Rule 1: Module name must end with version pattern or one of the configured suffixes
141+
validateVersionOrSuffix(moduleName, relativePath, suffixes)?.let { return it }
145142

146143
// Rule 2: Module name must contain parent directory name
147-
// Extract the base name (without version or -common suffix)
148144
if (!moduleName.contains(parentName, ignoreCase = true)) {
149145
return NamingViolation(
150146
relativePath,
@@ -157,20 +153,32 @@ class InstrumentationNamingPlugin : Plugin<Project> {
157153

158154
/**
159155
* Validates naming for leaf modules (modules at the top level with no parent grouping).
160-
* These only need to check the version/common suffix requirement.
156+
* These only need to check the version/suffix requirement.
161157
*/
162158
private fun validateLeafModuleName(
163159
moduleName: String,
164-
relativePath: String
160+
relativePath: String,
161+
suffixes: List<String>
162+
): NamingViolation? {
163+
return validateVersionOrSuffix(moduleName, relativePath, suffixes)
164+
}
165+
166+
/**
167+
* Validates that a module name ends with either a version or one of the configured suffixes.
168+
*/
169+
private fun validateVersionOrSuffix(
170+
moduleName: String,
171+
relativePath: String,
172+
suffixes: List<String>
165173
): NamingViolation? {
166-
// Rule: Module name must end with version pattern (X.Y, X.Y.Z, etc.) or "-common"
167-
val endsWithCommon = moduleName.endsWith("-common")
174+
val endsWithSuffix = suffixes.any { moduleName.endsWith(it) }
168175
val endsWithVersion = versionPattern.containsMatchIn(moduleName)
169176

170-
if (!endsWithVersion && !endsWithCommon) {
177+
if (!endsWithVersion && !endsWithSuffix) {
178+
val suffixesStr = suffixes.joinToString("', '", "'", "'")
171179
return NamingViolation(
172180
relativePath,
173-
"Module name '$moduleName' must end with a version (e.g., '2.0', '3.1.0') or '-common'"
181+
"Module name '$moduleName' must end with a version (e.g., '2.0', '3.1.0') or one of: $suffixesStr"
174182
)
175183
}
176184

buildSrc/src/main/kotlin/datadog/gradle/plugin/naming/README.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ A Gradle plugin that validates naming conventions for instrumentation modules un
66

77
The plugin enforces the following rules:
88

9-
1. **Version or Common suffix**: Module names must end with either:
9+
1. **Version or suffix**: Module names must end with either:
1010
- A version number (e.g., `2.0`, `3.1`, `4.0.5`)
11-
- The suffix `-common`
11+
- One of the configured suffixes (default: `-common`, `-stubs`)
1212

1313
2. **Parent directory inclusion**: Module names must include the parent directory name
1414
- Example: `couchbase/couchbase-2.0` ✓ (module name contains "couchbase")
@@ -47,22 +47,29 @@ instrumentationNaming {
4747
"sslsocket",
4848
"classloading"
4949
))
50+
51+
// Optional: configure allowed suffixes (default: ["-common", "-stubs"])
52+
suffixes.set(listOf(
53+
"-common",
54+
"-stubs",
55+
"-utils"
56+
))
5057
}
5158
```
5259

5360
## Examples
5461

5562
### Valid module names:
56-
- `couchbase/couchbase-2.0`
57-
- `couchbase/couchbase-2.6`
58-
- `couchbase/couchbase-3.1`
59-
- `kafka/kafka-common`
60-
- `apache-httpclient/apache-httpclient-4.0`
63+
- `couchbase/couchbase-2.0` (ends with version)
64+
- `couchbase/couchbase-2.6` (ends with version)
65+
- `couchbase/couchbase-3.1` (ends with version)
66+
- `kafka/kafka-common` (ends with -common suffix)
67+
- `apache-httpclient/apache-httpclient-4.0` (ends with version)
6168

6269
### Invalid module names:
6370
- `couchbase/foo-2.0` ✗ (doesn't contain parent name "couchbase")
64-
- `kafka/kafka` ✗ (missing version or -common suffix)
65-
- `kafka/kafka-latest` ✗ (not a valid version number)
71+
- `kafka/kafka` ✗ (missing version or allowed suffix)
72+
- `kafka/kafka-latest` ✗ (not a valid version number or allowed suffix)
6673

6774
## Integration with CI
6875

0 commit comments

Comments
 (0)