Skip to content

Commit dbf2a93

Browse files
committed
feat(workers): Handle mirror definitions from MavenDefinition
Extend the `MavenSettingsGenerator` to include mirror configurations from `MavenDefinition` entries when generating the `settings.xml` file. Mirror definitions from both `MavenDefinition` and the global `MavenCentralMirror` are added. If multiple mirrors target the same `mirrorOf` value, the one from `MavenDefinition` is used. Signed-off-by: Onur Demirci <[email protected]>
1 parent 8cff640 commit dbf2a93

File tree

2 files changed

+221
-20
lines changed

2 files changed

+221
-20
lines changed

workers/common/src/main/kotlin/common/env/MavenSettingsGenerator.kt

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ class MavenSettingsGenerator : EnvironmentConfigGenerator<MavenDefinition> {
7070

7171
override suspend fun generate(builder: ConfigFileBuilder, definitions: Collection<MavenDefinition>) {
7272
builder.buildInUserHome(TARGET_NAME) {
73+
val isGlobalMirrorOverridden = builder.adminConfig.mavenCentralMirror?.mirrorOf?.let { globalMirrorOf ->
74+
definitions.filter { it.mirrorOf != null }.any { it.mirrorOf == globalMirrorOf }
75+
} == true
76+
7377
println("<settings $ROOT_ATTRIBUTES>")
7478
println("<servers>".prependIndent(INDENT_4_SPACES))
7579

@@ -87,33 +91,67 @@ class MavenSettingsGenerator : EnvironmentConfigGenerator<MavenDefinition> {
8791
)
8892
}
8993

90-
builder.adminConfig.mavenCentralMirror?.let { mirror ->
91-
mirror.usernameSecret?.let { username ->
92-
mirror.passwordSecret?.let { password ->
93-
println("<server>".prependIndent(INDENT_8_SPACES))
94-
printTag("id", mirror.id)
95-
printTag("username", builder.infraSecretResolverFun(Path(username)))
96-
printTag("password", builder.infraSecretResolverFun(Path(password)))
97-
println("</server>".prependIndent(INDENT_8_SPACES))
98-
99-
GeneratorLogger.entryAdded(
100-
"server '${mirror.id}': username/password",
101-
TARGET_NAME
102-
)
94+
if (!isGlobalMirrorOverridden) {
95+
builder.adminConfig.mavenCentralMirror?.let { mirror ->
96+
mirror.usernameSecret?.let { username ->
97+
mirror.passwordSecret?.let { password ->
98+
println("<server>".prependIndent(INDENT_8_SPACES))
99+
printTag("id", mirror.id)
100+
printTag("username", builder.infraSecretResolverFun(Path(username)))
101+
printTag("password", builder.infraSecretResolverFun(Path(password)))
102+
println("</server>".prependIndent(INDENT_8_SPACES))
103+
104+
GeneratorLogger.entryAdded(
105+
"server '${mirror.id}': username/password",
106+
TARGET_NAME
107+
)
108+
}
103109
}
104110
}
105111
}
106112

107113
println("</servers>".prependIndent(INDENT_4_SPACES))
108114

109-
builder.adminConfig.mavenCentralMirror?.let { mirror ->
115+
val allMirrors = buildList {
116+
addAll(
117+
definitions.mapNotNull { definition ->
118+
definition.mirrorOf?.let { mirrorOf ->
119+
MavenMirror(
120+
id = definition.id,
121+
name = definition.service.name,
122+
url = definition.service.url,
123+
mirrorOf = definition.mirrorOf
124+
)
125+
}
126+
}
127+
)
128+
129+
if (!isGlobalMirrorOverridden) {
130+
builder.adminConfig.mavenCentralMirror?.let { mirror ->
131+
add(
132+
MavenMirror(
133+
id = mirror.id,
134+
name = mirror.name,
135+
url = mirror.url,
136+
mirrorOf = mirror.mirrorOf
137+
)
138+
)
139+
}
140+
}
141+
}
142+
143+
if (allMirrors.isNotEmpty()) {
110144
println("<mirrors>".prependIndent(INDENT_4_SPACES))
111-
println("<mirror>".prependIndent(INDENT_8_SPACES))
112-
printTag("id", mirror.id)
113-
printTag("name", mirror.name)
114-
printTag("url", mirror.url)
115-
printTag("mirrorOf", mirror.mirrorOf)
116-
println("</mirror>".prependIndent(INDENT_8_SPACES))
145+
146+
allMirrors.forEach { mirror ->
147+
println("<mirror>".prependIndent(INDENT_8_SPACES))
148+
printTag("id", mirror.id)
149+
printTag("name", mirror.name)
150+
printTag("url", mirror.url)
151+
printTag("mirrorOf", mirror.mirrorOf)
152+
println("</mirror>".prependIndent(INDENT_8_SPACES))
153+
}
154+
117155
println("</mirrors>".prependIndent(INDENT_4_SPACES))
118156
}
119157

@@ -144,3 +182,13 @@ class MavenSettingsGenerator : EnvironmentConfigGenerator<MavenDefinition> {
144182
}
145183
}
146184
}
185+
186+
/**
187+
* A data class representing a Maven mirror configuration.
188+
*/
189+
private data class MavenMirror(
190+
val id: String,
191+
val name: String,
192+
val url: String,
193+
val mirrorOf: String
194+
)

workers/common/src/test/kotlin/common/env/MavenSettingsGeneratorTest.kt

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,159 @@ class MavenSettingsGeneratorTest : WordSpec({
318318
).withIndent(8)
319319
)
320320
}
321+
322+
"generate mirror section when defined in MavenDefinition" {
323+
val secUser = MockConfigFileBuilder.createSecret("userSecret")
324+
val secPass = MockConfigFileBuilder.createSecret("passSecret")
325+
val definition = MavenDefinition(
326+
MockConfigFileBuilder.createInfrastructureService(
327+
"https://repo.example.org/test.git",
328+
secUser,
329+
secPass
330+
),
331+
emptySet(),
332+
"repo",
333+
"central"
334+
)
335+
336+
val mockBuilder = MockConfigFileBuilder()
337+
338+
MavenSettingsGenerator().generate(mockBuilder.builder, listOf(definition))
339+
340+
val content = mockBuilder.generatedText()
341+
content.shouldContain(serverBlock("repo", secUser, secPass).withIndent(8))
342+
content.shouldContain(
343+
mirrorBlock(
344+
definition.id,
345+
definition.service.name,
346+
definition.service.url,
347+
definition.mirrorOf!!
348+
).withIndent(8)
349+
)
350+
}
351+
352+
"ignore global MavenCentralMirror if MavenDefinition uses same mirrorOf" {
353+
val secUser = MockConfigFileBuilder.createSecret("userSecret")
354+
val secPass = MockConfigFileBuilder.createSecret("passSecret")
355+
val definition = MavenDefinition(
356+
MockConfigFileBuilder.createInfrastructureService(
357+
"https://repo.example.org/test.git",
358+
secUser,
359+
secPass
360+
),
361+
emptySet(),
362+
"repo",
363+
"central"
364+
)
365+
366+
val username = "test-username"
367+
val infraUsernameSecret = MockConfigFileBuilder.createSecret("infra-secret-username")
368+
val password = "test-password"
369+
val infraPasswordSecret = MockConfigFileBuilder.createSecret("infra-secret-password")
370+
val mavenCentralMirror = MavenCentralMirror(
371+
id = "central",
372+
name = "Maven Central",
373+
url = "https://repo.maven.apache.org/maven2",
374+
mirrorOf = "central",
375+
usernameSecret = infraUsernameSecret.name,
376+
passwordSecret = infraPasswordSecret.name
377+
)
378+
379+
val mockBuilder = MockConfigFileBuilder()
380+
every { mockBuilder.infraSecretResolverFun.invoke(Path(infraUsernameSecret.path)) } returns username
381+
every { mockBuilder.infraSecretResolverFun.invoke(Path(infraPasswordSecret.path)) } returns password
382+
every { mockBuilder.adminConfig.mavenCentralMirror } returns mavenCentralMirror
383+
384+
MavenSettingsGenerator().generate(mockBuilder.builder, listOf(definition))
385+
386+
val content = mockBuilder.generatedText()
387+
content.shouldContain(serverBlock("repo", secUser, secPass).withIndent(8))
388+
content.shouldNotContain(
389+
serverBlock(
390+
"central",
391+
infraUsernameSecret,
392+
infraPasswordSecret,
393+
{ secret -> mockBuilder.infraSecretResolverFun.invoke(Path(secret.path)) }
394+
).withIndent(8)
395+
)
396+
content.shouldContain(
397+
mirrorBlock(
398+
definition.id,
399+
definition.service.name,
400+
definition.service.url,
401+
definition.mirrorOf!!
402+
).withIndent(8)
403+
)
404+
content.shouldNotContain(
405+
mirrorBlock(
406+
mavenCentralMirror.id,
407+
mavenCentralMirror.name,
408+
mavenCentralMirror.url,
409+
mavenCentralMirror.mirrorOf
410+
).withIndent(8)
411+
)
412+
}
413+
414+
"generate mirror sections for both MavenDefinition and MavenCentralMirror if mirrorOf values differ" {
415+
val secUser = MockConfigFileBuilder.createSecret("userSecret")
416+
val secPass = MockConfigFileBuilder.createSecret("passSecret")
417+
val definition = MavenDefinition(
418+
MockConfigFileBuilder.createInfrastructureService(
419+
"https://repo.example.org/test.git",
420+
secUser,
421+
secPass
422+
),
423+
emptySet(),
424+
"repo",
425+
"project-repository-id"
426+
)
427+
428+
val username = "test-username"
429+
val infraUsernameSecret = MockConfigFileBuilder.createSecret("infra-secret-username")
430+
val password = "test-password"
431+
val infraPasswordSecret = MockConfigFileBuilder.createSecret("infra-secret-password")
432+
val mavenCentralMirror = MavenCentralMirror(
433+
id = "central",
434+
name = "Maven Central",
435+
url = "https://repo.maven.apache.org/maven2",
436+
mirrorOf = "central",
437+
usernameSecret = infraUsernameSecret.name,
438+
passwordSecret = infraPasswordSecret.name
439+
)
440+
441+
val mockBuilder = MockConfigFileBuilder()
442+
every { mockBuilder.infraSecretResolverFun.invoke(Path(infraUsernameSecret.path)) } returns username
443+
every { mockBuilder.infraSecretResolverFun.invoke(Path(infraPasswordSecret.path)) } returns password
444+
every { mockBuilder.adminConfig.mavenCentralMirror } returns mavenCentralMirror
445+
446+
MavenSettingsGenerator().generate(mockBuilder.builder, listOf(definition))
447+
val content = mockBuilder.generatedText()
448+
content.shouldContain(serverBlock("repo", secUser, secPass).withIndent(8))
449+
content.shouldContain(
450+
serverBlock(
451+
"central",
452+
infraUsernameSecret,
453+
infraPasswordSecret,
454+
{ secret -> mockBuilder.infraSecretResolverFun.invoke(Path(secret.path)) }
455+
).withIndent(8)
456+
)
457+
content.shouldContain(
458+
mirrorBlock(
459+
definition.id,
460+
definition.service.name,
461+
definition.service.url,
462+
definition.mirrorOf!!
463+
).withIndent(8)
464+
)
465+
content.shouldContain(
466+
mirrorBlock(
467+
mavenCentralMirror.id,
468+
mavenCentralMirror.name,
469+
mavenCentralMirror.url,
470+
mavenCentralMirror.mirrorOf
471+
).withIndent(8)
472+
)
473+
}
321474
}
322475
})
323476

0 commit comments

Comments
 (0)