绕过检查:完善规则 —— 检查文章分类以及变更一致性

* 使用 POSIX shell 来保证脚本的可移植性
* 使用未转义的文件名(文件名中切不可有换行符)
+ 在无更改时返回错误退出
- 移除 news 文章分类
This commit is contained in:
Wenxuan Zhao 2018-11-06 20:08:10 -08:00
parent 66e579826d
commit 2b0e6c9760
No known key found for this signature in database
GPG Key ID: 0B45B13F10587A57
6 changed files with 76 additions and 8 deletions

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
# PR 检查脚本 # PR 检查脚本
set -e set -e

View File

@ -22,7 +22,12 @@ do_analyze() {
# 统计每个类别的每个操作 # 统计每个类别的每个操作
REGEX="$(get_operation_regex "$STAT" "$TYPE")" REGEX="$(get_operation_regex "$STAT" "$TYPE")"
OTHER_REGEX="${OTHER_REGEX}|${REGEX}" OTHER_REGEX="${OTHER_REGEX}|${REGEX}"
eval "${TYPE}_${STAT}=\"\$(grep -Ec '$REGEX' /tmp/changes)\"" || true CHANGES_FILE="/tmp/changes_${TYPE}_${STAT}"
eval "grep -E '$REGEX' /tmp/changes" \
| sed 's/^[^\/]*\///g' \
| sort > "$CHANGES_FILE" || true
sed 's/^.*\///g' "$CHANGES_FILE" > "${CHANGES_FILE}_basename"
eval "${TYPE}_${STAT}=$(wc -l < "$CHANGES_FILE")"
eval echo "${TYPE}_${STAT}=\$${TYPE}_${STAT}" eval echo "${TYPE}_${STAT}=\$${TYPE}_${STAT}"
done done
done done

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
# 检查脚本状态 # 检查脚本状态
set -e set -e

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
# PR 文件变更收集 # PR 文件变更收集
set -e set -e
@ -31,7 +31,16 @@ git --no-pager show --summary "${MERGE_BASE}..HEAD"
echo "[收集] 写出文件变更列表……" echo "[收集] 写出文件变更列表……"
git diff "$MERGE_BASE" HEAD --no-renames --name-status > /tmp/changes RAW_CHANGES="$(git diff "$MERGE_BASE" HEAD --no-renames --name-status -z \
| tr '\0' '\n')"
[ -z "$RAW_CHANGES" ] && {
echo "[收集] 无变更,退出……"
exit 1
}
echo "$RAW_CHANGES" | while read -r STAT; do
read -r NAME
echo "${STAT} ${NAME}"
done > /tmp/changes
echo "[收集] 已写出文件变更列表:" echo "[收集] 已写出文件变更列表:"
cat /tmp/changes cat /tmp/changes
{ [ -z "$(cat /tmp/changes)" ] && echo "(无变更)"; } || true { [ -z "$(cat /tmp/changes)" ] && echo "(无变更)"; } || true

View File

@ -10,9 +10,10 @@ export TSL_DIR='translated' # 已翻译
export PUB_DIR='published' # 已发布 export PUB_DIR='published' # 已发布
# 定义匹配规则 # 定义匹配规则
export CATE_PATTERN='(news|talk|tech)' # 类别 export CATE_PATTERN='(talk|tech)' # 类别
export FILE_PATTERN='[0-9]{8} [a-zA-Z0-9_.,() -]*\.md' # 文件名 export FILE_PATTERN='[0-9]{8} [a-zA-Z0-9_.,() -]*\.md' # 文件名
# 获取用于匹配操作的正则表达式
# 用法get_operation_regex 状态 类型 # 用法get_operation_regex 状态 类型
# #
# 状态为: # 状态为:
@ -26,5 +27,50 @@ export FILE_PATTERN='[0-9]{8} [a-zA-Z0-9_.,() -]*\.md' # 文件名
get_operation_regex() { get_operation_regex() {
STAT="$1" STAT="$1"
TYPE="$2" TYPE="$2"
echo "^${STAT}\\s+\"?$(eval echo "\$${TYPE}_DIR")/" echo "^${STAT}\\s+\"?$(eval echo "\$${TYPE}_DIR")/"
} }
# 确保两个变更文件一致
# 用法ensure_identical X类型 X状态 Y类型 Y状态 是否仅比较文件名
#
# 状态为:
# - A添加
# - M修改
# - D删除
# 类型为:
# - SRC未翻译
# - TSL已翻译
# - PUB已发布
ensure_identical() {
TYPE_X="$1"
STAT_X="$2"
TYPE_Y="$3"
STAT_Y="$4"
NAME_ONLY="$5"
SUFFIX=
[ -n "$NAME_ONLY" ] && SUFFIX="_basename"
X_FILE="/tmp/changes_${TYPE_X}_${STAT_X}${SUFFIX}"
Y_FILE="/tmp/changes_${TYPE_Y}_${STAT_Y}${SUFFIX}"
cmp "$X_FILE" "$Y_FILE" 2> /dev/null
}
# 检查文章分类
# 用法check_category 类型 状态
#
# 状态为:
# - A添加
# - M修改
# - D删除
# 类型为:
# - SRC未翻译
# - TSL已翻译
check_category() {
TYPE="$1"
STAT="$2"
CHANGES="/tmp/changes_${TYPE}_${STAT}"
! grep -Eqv "^${CATE_PATTERN}/" "$CHANGES"
}

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
# 匹配 PR 规则 # 匹配 PR 规则
set -e set -e
@ -27,31 +27,39 @@ rule_bypass_check() {
# 添加原文:添加至少一篇原文 # 添加原文:添加至少一篇原文
rule_source_added() { rule_source_added() {
[ "$SRC_A" -ge 1 ] \ [ "$SRC_A" -ge 1 ] \
&& check_category SRC A \
&& [ "$TOTAL" -eq "$SRC_A" ] && echo "匹配规则:添加原文 ${SRC_A}" && [ "$TOTAL" -eq "$SRC_A" ] && echo "匹配规则:添加原文 ${SRC_A}"
} }
# 申领翻译:只能申领一篇原文 # 申领翻译:只能申领一篇原文
rule_translation_requested() { rule_translation_requested() {
[ "$SRC_M" -eq 1 ] \ [ "$SRC_M" -eq 1 ] \
&& check_category SRC M \
&& [ "$TOTAL" -eq 1 ] && echo "匹配规则:申领翻译" && [ "$TOTAL" -eq 1 ] && echo "匹配规则:申领翻译"
} }
# 提交译文:只能提交一篇译文 # 提交译文:只能提交一篇译文
rule_translation_completed() { rule_translation_completed() {
[ "$SRC_D" -eq 1 ] && [ "$TSL_A" -eq 1 ] \ [ "$SRC_D" -eq 1 ] && [ "$TSL_A" -eq 1 ] \
&& ensure_identical SRC D TSL A \
&& check_category SRC D \
&& check_category TSL A \
&& [ "$TOTAL" -eq 2 ] && echo "匹配规则:提交译文" && [ "$TOTAL" -eq 2 ] && echo "匹配规则:提交译文"
} }
# 校对译文:只能校对一篇 # 校对译文:只能校对一篇
rule_translation_revised() { rule_translation_revised() {
[ "$TSL_M" -eq 1 ] \ [ "$TSL_M" -eq 1 ] \
&& check_category TSL M \
&& [ "$TOTAL" -eq 1 ] && echo "匹配规则:校对译文" && [ "$TOTAL" -eq 1 ] && echo "匹配规则:校对译文"
} }
# 发布译文:发布多篇译文 # 发布译文:发布多篇译文
rule_translation_published() { rule_translation_published() {
[ "$TSL_D" -ge 1 ] && [ "$PUB_A" -ge 1 ] && [ "$TSL_D" -eq "$PUB_A" ] \ [ "$TSL_D" -ge 1 ] && [ "$PUB_A" -ge 1 ] && [ "$TSL_D" -eq "$PUB_A" ] \
&& [ "$TOTAL" -eq $(($TSL_D + $PUB_A)) ] \ && ensure_identical SRC D TSL A 1 \
&& check_category TSL D \
&& [ "$TOTAL" -eq $((TSL_D + PUB_A)) ] \
&& echo "匹配规则:发布译文 ${PUB_A}" && echo "匹配规则:发布译文 ${PUB_A}"
} }