Skip to content

Commit 5f98290

Browse files
committed
refactor(linecount): enhance binary search with platform-specific paths
Improve findBinary method to support multiple search paths for different operating systems (macOS, Linux, Windows) with proper priority ordering. Add fallback mechanisms when which/where commands fail and include executable permission checks.
1 parent ddd5455 commit 5f98290

File tree

1 file changed

+63
-13
lines changed
  • core/src/main/kotlin/cc/unitmesh/devti/agent/tool/linecount

1 file changed

+63
-13
lines changed

core/src/main/kotlin/cc/unitmesh/devti/agent/tool/linecount/CmdWrapper.kt

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,29 +50,79 @@ interface CmdWrapper<T> {
5050
return parseResult(stdout.toString())
5151
}
5252

53-
5453
@Throws(IOException::class)
5554
fun findBinary(name: String): Path? {
5655
val osName = System.getProperty("os.name").lowercase(Locale.getDefault())
5756
val binName = if (osName.contains("win")) "$name.exe" else name
5857

59-
// try get from /usr/local/bin/$name if macOS
60-
if (osName.contains("mac")) {
61-
val path = Paths.get("/usr/local/bin/$name")
62-
if (path.toFile().exists()) {
63-
return path
58+
// 定义要搜索的路径列表(按优先级排序)
59+
val searchPaths = mutableListOf<String>()
60+
61+
when {
62+
osName.contains("mac") -> {
63+
// macOS 路径按优先级排序
64+
searchPaths.addAll(listOf(
65+
"/opt/homebrew/bin", // Apple Silicon Homebrew
66+
"/usr/local/bin", // Intel Homebrew 或其他本地安装
67+
"/usr/bin", // 系统自带工具
68+
"/bin", // 核心系统工具
69+
"/Library/Developer/CommandLineTools/usr/bin", // Xcode Command Line Tools
70+
"/opt/local/bin", // MacPorts
71+
"/sw/bin" // Fink
72+
))
73+
}
74+
osName.contains("linux") -> {
75+
// Linux 路径
76+
searchPaths.addAll(listOf(
77+
"/usr/local/bin", // 本地安装
78+
"/usr/bin", // 系统工具
79+
"/bin", // 核心系统工具
80+
"/snap/bin", // Snap packages
81+
"/usr/local/sbin", // 本地系统管理工具
82+
"/usr/sbin", // 系统管理工具
83+
"/sbin" // 核心系统管理工具
84+
))
85+
}
86+
osName.contains("win") -> {
87+
// Windows 路径(如果需要的话)
88+
searchPaths.addAll(listOf(
89+
"C:\\Program Files\\Git\\bin",
90+
"C:\\msys64\\usr\\bin",
91+
"C:\\cygwin64\\bin"
92+
))
6493
}
6594
}
6695

67-
val pb = ProcessBuilder("which", binName)
68-
val process = pb.start()
96+
// 首先尝试使用 which/where 命令在 PATH 中查找
97+
val whichCommand = if (osName.contains("win")) "where" else "which"
6998
try {
70-
if (process.waitFor(1, TimeUnit.SECONDS) && process.exitValue() == 0) {
71-
val path = String(process.inputStream.readAllBytes(), StandardCharsets.UTF_8).trim { it <= ' ' }
72-
return Paths.get(path)
99+
val pb = ProcessBuilder(whichCommand, binName)
100+
val process = pb.start()
101+
if (process.waitFor(2, TimeUnit.SECONDS) && process.exitValue() == 0) {
102+
val path = String(process.inputStream.readAllBytes(), StandardCharsets.UTF_8).trim()
103+
if (path.isNotEmpty()) {
104+
val pathObj = Paths.get(path)
105+
if (pathObj.toFile().exists() && pathObj.toFile().canExecute()) {
106+
return pathObj
107+
}
108+
}
73109
}
74-
} catch (_: InterruptedException) {
75-
return null
110+
} catch (e: Exception) {
111+
// 如果 which/where 命令失败,继续使用路径搜索
112+
}
113+
114+
// 如果 which/where 失败,尝试在预定义路径中查找
115+
for (searchPath in searchPaths) {
116+
val fullPath = Paths.get(searchPath, binName)
117+
if (fullPath.toFile().exists() && fullPath.toFile().canExecute()) {
118+
return fullPath
119+
}
120+
}
121+
122+
// 最后尝试在当前工作目录查找
123+
val currentDirPath = Paths.get(".", binName)
124+
if (currentDirPath.toFile().exists() && currentDirPath.toFile().canExecute()) {
125+
return currentDirPath.toAbsolutePath()
76126
}
77127

78128
return null

0 commit comments

Comments
 (0)