Skip to content

Commit

Permalink
Merge pull request #9573 from hejieehe/feat_9402
Browse files Browse the repository at this point in the history
feat: svn触发需要提供获取到触发路径的变量 #9402
  • Loading branch information
bkci-bot authored Nov 13, 2023
2 parents 7bd9b86 + 2c1626d commit 38ba720
Show file tree
Hide file tree
Showing 3 changed files with 315 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ abstract class BasePathFilter(
includedPaths.forEach userPath@{ userPath ->
if (isPathMatch(eventPath, userPath)) {
matchIncludePaths.add(eventPath)
matchUserPaths.add(userPath)
// 提取最终匹配路径
matchUserPaths.add(extractMatchUserPath(eventPath, userPath))
return@eventPath
}
}
Expand All @@ -74,7 +75,6 @@ abstract class BasePathFilter(
} else {
matchIncludePaths.addAll(triggerOnPath)
}

val matchExcludedPaths = mutableSetOf<String>()
if (excludedPaths.isNotEmpty()) {
matchIncludePaths.forEach eventPath@{ eventPath ->
Expand All @@ -97,4 +97,9 @@ abstract class BasePathFilter(
}

abstract fun isPathMatch(eventPath: String, userPath: String): Boolean

open fun extractMatchUserPath(
eventPath: String,
userPath: String
) = eventPath
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,62 @@ class PathRegexFilter(
matcher.setCaseSensitive(caseSensitive)
return matcher.match(userPath, eventPath)
}

@SuppressWarnings("CyclomaticComplexMethod")
override fun extractMatchUserPath(
eventPath: String,
userPath: String
): String {
val patternParts = userPath.split("/")
// 无视规则,直接返回空
if (isInvalidPattern(userPath) || isInvalidPattern(patternParts)) {
return ""
}
val pathParts = eventPath.split("/")
val pathList = mutableListOf<String>()
var pathIndex = 0
var segment = 0
while (segment < patternParts.size && pathIndex < pathParts.size) {
val patternPart = patternParts[segment]
// 无效字符
if (isInvalidPattern(patternPart)) {
// 以*或**结尾的规则,直接结束
if (segment == patternParts.size - 1) {
break
}
val nextPatternPart = patternParts[segment + 1]
// 后续不存在有效字符继续找
if (isInvalidPattern(nextPatternPart)) {
segment++
continue
}
while (pathIndex < pathParts.size && !matcher.match(nextPatternPart, pathParts[pathIndex])) {
val pathItem = pathParts[pathIndex++]
pathList.add(pathItem)
}
// 追加上匹配上的真实目录[nextPatternPart可能为dir_**]
if (matcher.match(nextPatternPart, pathParts[pathIndex])) {
pathList.add(pathParts[pathIndex])
}
segment++
} else {
val pathItem = pathParts[pathIndex]
pathList.add(pathItem)
}
pathIndex++
segment++
}
return pathList.joinToString("/")
}

private fun isInvalidPattern(pattern: String) = (pattern == "*" || pattern == "**")

private fun isInvalidPattern(patterns: List<String>): Boolean {
patterns.toSet().forEach {
if (!isInvalidPattern(it)) {
return false
}
}
return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

package com.tencent.devops.common.webhook.service.code.filter

import com.tencent.devops.common.webhook.pojo.code.MATCH_PATHS
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test

Expand Down Expand Up @@ -300,4 +301,253 @@ class PathRegexFilterTest {
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
}

@Test
@SuppressWarnings("LongMethod", "ComplexMethod")
fun extractMatchUserPath() {
var pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf("trunk/bin/dd.txt", "branches/bin/9.0/aa.txt", "branches/bin/doc/abc/9.0/aa.txt"),
includedPaths = listOf("*/bin/**"),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
"trunk/bin",
"branches/bin"
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf("trunk/bin/dd.txt", "trunk/bin/lobby/loterry/aa.txt"),
includedPaths = listOf("*/bin/**"),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
"trunk/bin"
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf("trunk/bin/lobby/loterry/aa.txt"),
includedPaths = listOf("*/bin/**/loterry/**"),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
"trunk/bin/lobby/loterry"
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf("trunk/bin/dd.txt", "trunk/bin/lobby/loterry/aa.txt"),
includedPaths = listOf("*/bin/**/*"),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
"trunk/bin"
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf("trunk/bin/lobby/loterry/aa.txt"),
includedPaths = listOf("*/bin/**/*.txt"),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
"trunk/bin/lobby/loterry/aa.txt"
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf("trunk/bin/lobby/loterry/aa.txt"),
includedPaths = listOf("**"),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
""
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf("trunk.txt", "hello.txt", "readme.txt", "trunk/doc/readme.md"),
includedPaths = listOf("*"),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
""
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf(
"svn/trunk/doc/install/service_1.kt",
"svn/trunk/doc/service_1.kt",
"svn/doc/api/service/api_1.kt",
"svn/doc/api/api_1.kt"
),
includedPaths = listOf(
"*/trunk/**/**/doc/service_*.kt",
"*/**/**/doc/api/api_*.kt"
),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
"svn/trunk/doc/service_1.kt",
"svn/doc/api/api_1.kt"
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf(
"svn/trunk/doc/install/service/doc/service_1.kt",
"svn/trunk/doc/install/service/doc/api_1.kt",
"svn/branch/doc/api/service/api_1.kt",
"svn/branch/version_1/doc/api/api_1.kt"
),
includedPaths = listOf(
"*/trunk/**/**/doc/*",
"*/**/**/doc/*",
"*/**/**/doc/**/**"
),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
"svn/trunk/doc",
"svn/branch/doc"
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf(
"branches/doc/dir_a/dir_a_1/dir_a_1_readme.md",
"branches/doc/doc_depth_1/doc_depth_2/dir_a/dir_a_1"
),
includedPaths = listOf("**/dir_a_1/*"),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
"branches/doc/dir_a/dir_a_1"
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf(
"branches/dir_a_1/a.kt",
"branches/dir_a_1/a_1/b.kt"
),
includedPaths = listOf("**/dir_a_1/a_1/**", "**/dir_a_1/*.kt"),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
"branches/dir_a_1/a.kt",
"branches/dir_a_1/a_1"
)
)
)
}

pathRegexFilter = PathRegexFilter(
pipelineId = "p-8a49b34bfd834adda6e8dbaad01eedea",
triggerOnPath = listOf(
"branches/dir_a/dir_b/dir_c/a.txt"
),
includedPaths = listOf("**/dir_**/*"),
excludedPaths = emptyList(),
caseSensitive = true
)
Assertions.assertTrue(pathRegexFilter.doFilter(response))
response.getParam()[MATCH_PATHS]?.let {
Assertions.assertTrue(
it.split(",").toSet().containsAll(
setOf(
"branches/dir_a"
)
)
)
}
}
}

0 comments on commit 38ba720

Please sign in to comment.