Bash实现唯一路径匹配,去重以生成Bazel Coverage执行路径
Bash实现唯一父路径筛选,用于Bazel Coverage按需执行
以下是一套完整的Bash脚本方案,能从Git变更文件中筛选出唯一的父级路径(排除重复的子路径),最终生成对应的Bazel Coverage命令:
步骤分解与脚本实现
获取并筛选Git变更文件
先拿到当前分支相对于主分支(示例用main)的所有变更文件,只保留以src/开头的路径:changed_files=$(git diff --name-only main HEAD | grep '^src/')定位每个文件对应的BUILD.bazel路径
遍历每个变更文件,从其所在目录向上查找最近的BUILD.bazel文件,记录该文件所在的目录路径:build_paths=() for file in $changed_files; do dir=$(dirname "$file") while [[ "$dir" != "/" && ! -f "$dir/BUILD.bazel" ]]; do dir=$(dirname "$dir") done if [[ -f "$dir/BUILD.bazel" ]]; then build_paths+=("$dir") fi done去重子路径,保留唯一父级路径
先对路径排序,然后逐个检查,只保留不是其他路径子路径的父级路径:sorted_paths=($(printf "%s\n" "${build_paths[@]}" | sort)) unique_parent_paths=() prev_path="" for path in "${sorted_paths[@]}"; do if [[ -z "$prev_path" || ! "$path" =~ ^"$prev_path"/ ]]; then unique_parent_paths+=("$path") prev_path="$path" fi done生成Bazel Coverage命令
将筛选后的路径转换为Bazel目标格式,拼接成最终的coverage命令:bazel_targets=$(printf "//%s " "${unique_parent_paths[@]}") echo "执行命令:bazel coverage $bazel_targets"
完整可运行脚本
#!/bin/bash # 获取变更文件并筛选src/路径 changed_files=$(git diff --name-only main HEAD | grep '^src/') if [[ -z "$changed_files" ]]; then echo "没有src/目录下的变更文件" exit 0 fi # 定位BUILD.bazel所在路径 build_paths=() for file in $changed_files; do dir=$(dirname "$file") while [[ "$dir" != "/" && ! -f "$dir/BUILD.bazel" ]]; do dir=$(dirname "$dir") done if [[ -f "$dir/BUILD.bazel" ]]; then build_paths+=("$dir") fi done # 去重子路径 sorted_paths=($(printf "%s\n" "${build_paths[@]}" | sort)) unique_parent_paths=() prev_path="" for path in "${sorted_paths[@]}"; do if [[ -z "$prev_path" || ! "$path" =~ ^"$prev_path"/ ]]; then unique_parent_paths+=("$path") prev_path="$path" fi done # 生成并输出Bazel命令 bazel_targets=$(printf "//%s " "${unique_parent_paths[@]}") echo "bazel coverage $bazel_targets"
注意事项
- 如果你的主分支不是
main,请将脚本中的main替换为对应分支名(比如master) - 脚本会自动跳过找不到
BUILD.bazel的路径,避免生成无效目标 - 最终输出的命令只会包含父级路径(如
src/common),不会包含其下的子路径(如src/common/test1)
内容的提问来源于stack exchange,提问作者AhmFM
相关产品推荐
相关产品推荐

