已合并
feat(pre-commit): 拦截类钩子报告统一落盘 pre-commit_reports + 健壮性与策略对齐 #12834
景明创建于 9月23日
feat(pre-commit): 拦截类钩子报告统一落盘 pre-commit_reports + 健壮性与策略对齐 #12834
已合并
共 8 个文件变更+58-28
| @@ -1,5 +1,5 @@ | |||
| 1 | # ----------------------------------------------------------------------------------------------------------- | 1 | # ----------------------------------------------------------------------------------------------------------- |
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. |
| 3 | # This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | # This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | # CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | # CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | # Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | # Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -56,7 +56,7 @@ PackConstructorInitializers: Never | |||
| 56 | 56 | ||
| 57 | # pointer aligment | 57 | # pointer aligment |
| 58 | DerivePointerAlignment: false | 58 | DerivePointerAlignment: false |
| 59 | -PointerAlignment: Right | 59 | +PointerAlignment: Left |
| 60 | 60 | ||
| 61 | # single line layout | 61 | # single line layout |
| 62 | AllowShortBlocksOnASingleLine: false | 62 | AllowShortBlocksOnASingleLine: false |
| @@ -51,4 +51,4 @@ third_party/ | |||
| 51 | 51 | ||
| 52 | # pre-commit log | 52 | # pre-commit log |
| 53 | log/ | 53 | log/ |
| 54 | -oat_reports/ | 54 | +pre-commit_reports/ |
| @@ -21,6 +21,8 @@ repos: | |||
| 21 | rev: v4.6.0 | 21 | rev: v4.6.0 |
| 22 | hooks: | 22 | hooks: |
| 23 | - id: trailing-whitespace | 23 | - id: trailing-whitespace |
| 24 | + # md 保留行尾双空格(markdown 硬换行语法),其余尾随空白照删 | ||
| 25 | + args: ["--markdown-linebreak-ext=md"] | ||
| 24 | - id: end-of-file-fixer | 26 | - id: end-of-file-fixer |
| 25 | - id: check-yaml | 27 | - id: check-yaml |
| 26 | args: ["--allow-multiple-documents"] | 28 | args: ["--allow-multiple-documents"] |
| @@ -57,6 +59,8 @@ repos: | |||
| 57 | rev: v2.4.1 | 59 | rev: v2.4.1 |
| 58 | hooks: | 60 | hooks: |
| 59 | - id: codespell | 61 | - id: codespell |
| 62 | + # 包装 entry:输出 tee 到 pre-commit_reports/codespell.log(仍跑在托管 venv) | ||
| 63 | + entry: bash scripts/run_codespell.sh | ||
| 60 | args: [ | 64 | args: [ |
| 61 | "-L", | 65 | "-L", |
| 62 | "CANN,cann,NNAL,nnal,ASCEND,ascend,EnQue,CopyIn,ArchType,AND,ND,tbe,copyin,alog,wIh,dout,indexs,inH,padD,outWeight", | 66 | "CANN,cann,NNAL,nnal,ASCEND,ascend,EnQue,CopyIn,ArchType,AND,ND,tbe,copyin,alog,wIh,dout,indexs,inH,padD,outWeight", |
| @@ -25,6 +25,8 @@ | |||
| 25 | <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/--> | 25 | <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/--> |
| 26 | </filefilter> | 26 | </filefilter> |
| 27 | <filefilter name="defaultPolicyFilter" desc="Filters for compatibility,license header policies"> | 27 | <filefilter name="defaultPolicyFilter" desc="Filters for compatibility,license header policies"> |
| 28 | + <filteritem type="filename" name="requirements*.txt" desc="Dependency manifest files, license header not applicable"/> | ||
| 29 | + <filteritem type="filename" name="*.info" desc="CMake help info files, no license header"/> | ||
| 28 | <!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/--> | 30 | <!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/--> |
| 29 | <!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/--> | 31 | <!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/--> |
| 30 | <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/--> | 32 | <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/--> |
| @@ -33,6 +35,8 @@ | |||
| 33 | <filteritem type="filename" name="*.csv" desc="CSV test case files, no license header required"/> | 35 | <filteritem type="filename" name="*.csv" desc="CSV test case files, no license header required"/> |
| 34 | </filefilter> | 36 | </filefilter> |
| 35 | <filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies"> | 37 | <filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies"> |
| 38 | + <filteritem type="filename" name="requirements*.txt" desc="Dependency manifest files, copyright header not applicable"/> | ||
| 39 | + <filteritem type="filename" name="*.info" desc="CMake help info files, copyright header not applicable"/> | ||
| 36 | <!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/--> | 40 | <!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/--> |
| 37 | <!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/--> | 41 | <!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/--> |
| 38 | <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/--> | 42 | <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/--> |
| @@ -75,6 +75,8 @@ git commit --no-verify -m "msg" | |||
| 75 | 75 | ||
| 76 | 搜索输出中的 `Failed` 定位失败项,查看该 hook 下方输出处理,或粘贴给 AI 获取修复建议。 | 76 | 搜索输出中的 `Failed` 定位失败项,查看该 hook 下方输出处理,或粘贴给 AI 获取修复建议。 |
| 77 | 77 | ||
| 78 | +拦截类钩子的报告同时落盘在 `pre-commit_reports/`(不入 git):`codespell.log`(拼写命中清单)、`oat_result.txt`(合规违规明细),可随时复查。 | ||
| 79 | + | ||
| 78 | | 报错 | 原因 | 处理方式 | | 80 | | 报错 | 原因 | 处理方式 | |
| 79 | |-----------------------|--------------------|---------------------------------------------------| | 81 | |-----------------------|--------------------|---------------------------------------------------| |
| 80 | | clang-format Failed | 代码存在规范问题 | 钩子会自动修复文件,重新 `git add` 后再次 commit 即可 | | 82 | | clang-format Failed | 代码存在规范问题 | 钩子会自动修复文件,重新 `git add` 后再次 commit 即可 | |
| @@ -94,7 +96,7 @@ git pc <commit>^ # 某一笔提交 | |||
| 94 | ## 七、检查项说明 | 96 | ## 七、检查项说明 |
| 95 | 97 | ||
| 96 | 1. **pre-commit-hooks** (v4.6.0):trailing-whitespace、end-of-file-fixer、check-yaml/json、check-added-large-files、check-merge-conflict、detect-private-key | 98 | 1. **pre-commit-hooks** (v4.6.0):trailing-whitespace、end-of-file-fixer、check-yaml/json、check-added-large-files、check-merge-conflict、detect-private-key |
| 97 | -2. **clang-format** (v18.1.8):遵循项目 `.clang-format`(Google 风格,4 空格缩进,不限列宽不自动拆行,枚举逐行,构造函数初始化列表逐行换行,函数定义大括号换行,指针右对齐 `int *ptr`) | 99 | +2. **clang-format** (v18.1.8):遵循项目 `.clang-format`(Google 风格,4 空格缩进,不限列宽不自动拆行,枚举逐行,构造函数初始化列表逐行换行,函数定义大括号换行,指针左对齐 `int* ptr`) |
| 98 | 3. **ruff** (v0.14.14):ruff-check(`--fix` 自动修复)+ ruff-format | 100 | 3. **ruff** (v0.14.14):ruff-check(`--fix` 自动修复)+ ruff-format |
| 99 | 4. **codespell** (v2.4.1):拼写检查,CANN、ascend、EnQue 等术语已加白名单 | 101 | 4. **codespell** (v2.4.1):拼写检查,CANN、ascend、EnQue 等术语已加白名单 |
| 100 | 5. **OAT**:基于 oat-py,检查许可证头(YAML/CSV 已豁免)、禁止二进制和归档文件 | 102 | 5. **OAT**:基于 oat-py,检查许可证头(YAML/CSV 已豁免)、禁止二进制和归档文件 |
| @@ -16,7 +16,8 @@ REPO_ROOT=$(dirname "$SCRIPT_DIR") | |||
| 16 | 16 | ||
| 17 | FORMAT_DIR="${1:-${REPO_ROOT}}" | 17 | FORMAT_DIR="${1:-${REPO_ROOT}}" |
| 18 | if [[ ! -d ${FORMAT_DIR} ]]; then | 18 | if [[ ! -d ${FORMAT_DIR} ]]; then |
| 19 | - echo "Please specify a directory." | 19 | + echo "Error: directory not found: ${FORMAT_DIR}" >&2 |
| 20 | + exit 1 | ||
| 20 | fi | 21 | fi |
| 21 | 22 | ||
| 22 | CLANG_FORMAT="${CLANG_FORMAT:-clang-format}" | 23 | CLANG_FORMAT="${CLANG_FORMAT:-clang-format}" |
| @@ -36,10 +37,10 @@ echo "Using $CLANG_FORMAT ..." | |||
| 36 | "$CLANG_FORMAT" --version | 37 | "$CLANG_FORMAT" --version |
| 37 | 38 | ||
| 38 | EXCLUDE_DIRS=( | 39 | EXCLUDE_DIRS=( |
| 39 | - "build/" | 40 | + "build" |
| 40 | - "build_out/" | 41 | + "build_out" |
| 41 | - "third_party/" | 42 | + "third_party" |
| 42 | - ".git/" | 43 | + ".git" |
| 43 | ) | 44 | ) |
| 44 | 45 | ||
| 45 | FIND_EXPR=() | 46 | FIND_EXPR=() |
| @@ -82,14 +82,14 @@ fi | |||
| 82 | REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) | 82 | REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) |
| 83 | REPO_NAME=$(basename "$REPO_ROOT") | 83 | REPO_NAME=$(basename "$REPO_ROOT") |
| 84 | OAT_REPORT_DIR="${TMPDIR:-/tmp}/oat_reports_$$" | 84 | OAT_REPORT_DIR="${TMPDIR:-/tmp}/oat_reports_$$" |
| 85 | -OAT_RESULT_DIR="$REPO_ROOT/oat_reports" | 85 | +OAT_RESULT_DIR="$REPO_ROOT/pre-commit_reports" |
| 86 | 86 | ||
| 87 | # --------------------------------------------------------------------------- | 87 | # --------------------------------------------------------------------------- |
| 88 | # 2a. PR-range deduplication (pure git, no CI env vars required) | 88 | # 2a. PR-range deduplication (pure git, no CI env vars required) |
| 89 | # | 89 | # |
| 90 | # Strategy: | 90 | # Strategy: |
| 91 | # 1. Find the merge-base between HEAD and the upstream branch (origin/master | 91 | # 1. Find the merge-base between HEAD and the upstream branch (origin/master |
| 92 | -# or similar). If found, this is a feature-branch context ??collect ALL | 92 | +# or similar). If found, this is a feature-branch context →collect ALL |
| 93 | # files changed since the branch diverged (full PR diff). | 93 | # files changed since the branch diverged (full PR diff). |
| 94 | # 2. Key a done-marker on the HEAD SHA. The first invocation runs the scan; | 94 | # 2. Key a done-marker on the HEAD SHA. The first invocation runs the scan; |
| 95 | # every subsequent invocation for the same HEAD exits 0 immediately. | 95 | # every subsequent invocation for the same HEAD exits 0 immediately. |
| @@ -134,6 +134,7 @@ if [ -n "$_HEAD_SHA" ]; then | |||
| 134 | if [ -n "$_PR_MERGE_BASE" ] && [ "$_PR_MERGE_BASE" != "$(git rev-parse HEAD 2>/dev/null)" ]; then | 134 | if [ -n "$_PR_MERGE_BASE" ] && [ "$_PR_MERGE_BASE" != "$(git rev-parse HEAD 2>/dev/null)" ]; then |
| 135 | mkdir -p "$OAT_RESULT_DIR" | 135 | mkdir -p "$OAT_RESULT_DIR" |
| 136 | _DONE_MARKER="$OAT_RESULT_DIR/.done_${_HEAD_SHA}" | 136 | _DONE_MARKER="$OAT_RESULT_DIR/.done_${_HEAD_SHA}" |
| 137 | + # 显式文件清单调用永不跳过(args 模式扫的是 staged 子集,与全量 marker 无关) | ||
| 137 | if [ $# -eq 0 ] && [ -f "$_DONE_MARKER" ]; then | 138 | if [ $# -eq 0 ] && [ -f "$_DONE_MARKER" ]; then |
| 138 | echo "[OAT] [SKIP] Already scanned HEAD=${_HEAD_SHA}. Skipping duplicate invocation." | 139 | echo "[OAT] [SKIP] Already scanned HEAD=${_HEAD_SHA}. Skipping duplicate invocation." |
| 139 | exit 0 | 140 | exit 0 |
| @@ -157,6 +158,7 @@ if command -v flock >/dev/null 2>&1; then | |||
| 157 | flock -w 120 9 | 158 | flock -w 120 9 |
| 158 | # Re-check done marker: if the scanning instance completed normally, skip. | 159 | # Re-check done marker: if the scanning instance completed normally, skip. |
| 159 | # If it exited abnormally (no marker), fall through and run the scan ourselves. | 160 | # If it exited abnormally (no marker), fall through and run the scan ourselves. |
| 161 | + # 显式文件清单调用不参与并行去重 | ||
| 160 | if [ $# -eq 0 ] && [ -n "$_DONE_MARKER" ] && [ -f "$_DONE_MARKER" ]; then | 162 | if [ $# -eq 0 ] && [ -n "$_DONE_MARKER" ] && [ -f "$_DONE_MARKER" ]; then |
| 161 | echo "[OAT] Scan already completed by another instance. Skipping." | 163 | echo "[OAT] Scan already completed by another instance. Skipping." |
| 162 | exit 0 | 164 | exit 0 |
| @@ -167,12 +169,12 @@ if command -v flock >/dev/null 2>&1; then | |||
| 167 | # This instance now owns the lock and will run the scan. | 169 | # This instance now owns the lock and will run the scan. |
| 168 | fi | 170 | fi |
| 169 | 171 | ||
| 170 | -echo "[OAT] Running OAT scan (Python Edition) ??INCREMENTAL MODE" | 172 | +echo "[OAT] Running OAT scan (Python Edition) →INCREMENTAL MODE" |
| 171 | echo "[OAT] Project: $REPO_NAME" | 173 | echo "[OAT] Project: $REPO_NAME" |
| 172 | if [ -n "$_PR_MERGE_BASE" ]; then | 174 | if [ -n "$_PR_MERGE_BASE" ]; then |
| 173 | - echo "[OAT] Mode: PR range ??scanning all files changed since merge-base" | 175 | + echo "[OAT] Mode: PR range →scanning all files changed since merge-base" |
| 174 | else | 176 | else |
| 175 | - echo "[OAT] Mode: staged files ??scanning only currently staged files" | 177 | + echo "[OAT] Mode: staged files →scanning only currently staged files" |
| 176 | fi | 178 | fi |
| 177 | 179 | ||
| 178 | # --------------------------------------------------------------------------- | 180 | # --------------------------------------------------------------------------- |
| @@ -255,27 +257,27 @@ mkdir -p "$OAT_REPORT_DIR" | |||
| 255 | mkdir -p "$OAT_RESULT_DIR" | 257 | mkdir -p "$OAT_RESULT_DIR" |
| 256 | 258 | ||
| 257 | # --------------------------------------------------------------------------- | 259 | # --------------------------------------------------------------------------- |
| 258 | -# 5. Build oat command — use OAT.xml if present in repo root | 260 | +# 5. Build oat command →use OAT.xml if present in repo root |
| 259 | # --------------------------------------------------------------------------- | 261 | # --------------------------------------------------------------------------- |
| 260 | -_OAT_BASE_CMD="$_PYTHON -m oat -mode s -s $REPO_ROOT -r $OAT_REPORT_DIR -n $REPO_NAME -w 1" | 262 | +_OAT_ARGS=(-mode s -s "$REPO_ROOT" -r "$OAT_REPORT_DIR" -n "$REPO_NAME" -w 1) |
| 261 | 263 | ||
| 262 | _OAT_XML="$REPO_ROOT/OAT.xml" | 264 | _OAT_XML="$REPO_ROOT/OAT.xml" |
| 263 | if [ -f "$_OAT_XML" ]; then | 265 | if [ -f "$_OAT_XML" ]; then |
| 264 | - _OAT_BASE_CMD="$_OAT_BASE_CMD -oatconfig $_OAT_XML" | 266 | + _OAT_ARGS+=(-oatconfig "$_OAT_XML") |
| 265 | fi | 267 | fi |
| 266 | 268 | ||
| 267 | # --------------------------------------------------------------------------- | 269 | # --------------------------------------------------------------------------- |
| 268 | -# 6. Run oat scan — batch file list if -f argument exceeds OS single-arg limit | 270 | +# 6. Run oat scan |
| 269 | -# (Linux MAX_ARG_STRLEN ≈ 128KB; exit code 126 = E2BIG when exceeded) | ||
| 270 | # --------------------------------------------------------------------------- | 271 | # --------------------------------------------------------------------------- |
| 271 | _MAX_F_LEN=120000 | 272 | _MAX_F_LEN=120000 |
| 272 | _SCAN_FAILED=0 | 273 | _SCAN_FAILED=0 |
| 273 | _BATCH_ISSUES=0 | 274 | _BATCH_ISSUES=0 |
| 275 | +_BATCH_COUNT=0 | ||
| 274 | 276 | ||
| 275 | _run_oat_batch() { | 277 | _run_oat_batch() { |
| 276 | echo "[OAT] Running compliance scan..." | 278 | echo "[OAT] Running compliance scan..." |
| 277 | set +e | 279 | set +e |
| 278 | - eval "$_OAT_BASE_CMD -f $1" >/dev/null 2>&1 | 280 | + "$_PYTHON" -m oat "${_OAT_ARGS[@]}" -f "$1" >/dev/null 2>&1 |
| 279 | _OAT_RC=$? | 281 | _OAT_RC=$? |
| 280 | set -e | 282 | set -e |
| 281 | if [ "$_OAT_RC" -ne 0 ] && [ "$_OAT_RC" -ne 1 ]; then | 283 | if [ "$_OAT_RC" -ne 0 ] && [ "$_OAT_RC" -ne 1 ]; then |
| @@ -302,7 +304,6 @@ else | |||
| 302 | echo "[OAT] File list exceeds ${_MAX_F_LEN} bytes, scanning in batches..." | 304 | echo "[OAT] File list exceeds ${_MAX_F_LEN} bytes, scanning in batches..." |
| 303 | rm -f "$OAT_RESULT_DIR/batch_details.txt" 2>/dev/null || true | 305 | rm -f "$OAT_RESULT_DIR/batch_details.txt" 2>/dev/null || true |
| 304 | _BATCH="" | 306 | _BATCH="" |
| 305 | - _BATCH_COUNT=0 | ||
| 306 | _IFS_BAK="$IFS" | 307 | _IFS_BAK="$IFS" |
| 307 | IFS="," | 308 | IFS="," |
| 308 | for _f in $FILE_LIST; do | 309 | for _f in $FILE_LIST; do |
| @@ -340,7 +341,7 @@ if [ "$_SCAN_FAILED" -ne 0 ]; then | |||
| 340 | fi | 341 | fi |
| 341 | 342 | ||
| 342 | # Batch mode: use accumulated issue count to decide | 343 | # Batch mode: use accumulated issue count to decide |
| 343 | -if [ -n "$_BATCH_COUNT" ] && [ "$_BATCH_COUNT" -gt 1 ] 2>/dev/null; then | 344 | +if [ "$_BATCH_COUNT" -gt 1 ] 2>/dev/null; then |
| 344 | if [ "$_BATCH_ISSUES" -gt 0 ]; then | 345 | if [ "$_BATCH_ISSUES" -gt 0 ]; then |
| 345 | echo "" | 346 | echo "" |
| 346 | echo "====================================================================" | 347 | echo "====================================================================" |
| @@ -362,11 +363,11 @@ if [ -n "$_BATCH_COUNT" ] && [ "$_BATCH_COUNT" -gt 1 ] 2>/dev/null; then | |||
| 362 | cat "$OAT_RESULT_DIR/batch_details.txt" | 363 | cat "$OAT_RESULT_DIR/batch_details.txt" |
| 363 | fi | 364 | fi |
| 364 | echo "===================================" | 365 | echo "===================================" |
| 365 | - } > "$OAT_RESULT_DIR/result.txt" | 366 | + } > "$OAT_RESULT_DIR/oat_result.txt" |
| 366 | echo "[OAT] Found $_BATCH_ISSUES compliance issue(s) across $_BATCH_COUNT batches." | 367 | echo "[OAT] Found $_BATCH_ISSUES compliance issue(s) across $_BATCH_COUNT batches." |
| 367 | echo "[OAT] Details (also saved to: $OAT_RESULT_DIR/batch_details.txt):" | 368 | echo "[OAT] Details (also saved to: $OAT_RESULT_DIR/batch_details.txt):" |
| 368 | echo "---" | 369 | echo "---" |
| 369 | - cat "$OAT_RESULT_DIR/result.txt" | 370 | + cat "$OAT_RESULT_DIR/oat_result.txt" |
| 370 | echo "---" | 371 | echo "---" |
| 371 | echo "" | 372 | echo "" |
| 372 | echo "Fix the issues and recommit, or skip with:" | 373 | echo "Fix the issues and recommit, or skip with:" |
| @@ -391,7 +392,7 @@ fi | |||
| 391 | # Only: Invalid File Type + License Header Invalid (no copyright) | 392 | # Only: Invalid File Type + License Header Invalid (no copyright) |
| 392 | # --------------------------------------------------------------------------- | 393 | # --------------------------------------------------------------------------- |
| 393 | REPORT_FILE="$OAT_REPORT_DIR/PlainReport_${REPO_NAME}.txt" | 394 | REPORT_FILE="$OAT_REPORT_DIR/PlainReport_${REPO_NAME}.txt" |
| 394 | -RESULT_FILE="$OAT_RESULT_DIR/result.txt" | 395 | +RESULT_FILE="$OAT_RESULT_DIR/oat_result.txt" |
| 395 | 396 | ||
| 396 | # Section headers used as stop-boundaries when extracting sections | 397 | # Section headers used as stop-boundaries when extracting sections |
| 397 | _ALL_HEADERS="Invalid File Type Total Count:|License Not Compatible Total Count:|License Header Invalid Total Count:|Copyright Header Invalid Total Count:|No License File Total Count:|No Readme.OpenSource Total Count:|No Readme Total Count:|Import Invalid Total Count:|Redundant License File Total Count:|Third Party Software Info Total Count:" | 398 | _ALL_HEADERS="Invalid File Type Total Count:|License Not Compatible Total Count:|License Header Invalid Total Count:|Copyright Header Invalid Total Count:|No License File Total Count:|No Readme.OpenSource Total Count:|No Readme Total Count:|Import Invalid Total Count:|Redundant License File Total Count:|Third Party Software Info Total Count:" |
| @@ -424,7 +425,9 @@ if [ ! -f "$REPORT_FILE" ]; then | |||
| 424 | if [ "$_OAT_RC" -eq 0 ]; then | 425 | if [ "$_OAT_RC" -eq 0 ]; then |
| 425 | # oat exited cleanly with no report: all staged files were filtered out | 426 | # oat exited cleanly with no report: all staged files were filtered out |
| 426 | echo "[OAT] [OK] All checks passed ($FILE_COUNT file(s) checked)." | 427 | echo "[OAT] [OK] All checks passed ($FILE_COUNT file(s) checked)." |
| 427 | - [ -n "$_DONE_MARKER" ] && touch "$_DONE_MARKER" 2>/dev/null || true | 428 | + if [ $# -eq 0 ] && [ -n "$_DONE_MARKER" ]; then |
| 429 | + touch "$_DONE_MARKER" 2>/dev/null || true | ||
| 430 | + fi | ||
| 428 | rm -rf "$OAT_REPORT_DIR" | 431 | rm -rf "$OAT_REPORT_DIR" |
| 429 | exit 0 | 432 | exit 0 |
| 430 | else | 433 | else |
| @@ -434,7 +437,7 @@ if [ ! -f "$REPORT_FILE" ]; then | |||
| 434 | echo "[OAT] [ERROR] oat exited with code $_OAT_RC but no report was generated." | 437 | echo "[OAT] [ERROR] oat exited with code $_OAT_RC but no report was generated." |
| 435 | echo "[OAT] This may indicate a disk error or an oat internal bug." | 438 | echo "[OAT] This may indicate a disk error or an oat internal bug." |
| 436 | echo "[OAT] To investigate, run manually:" | 439 | echo "[OAT] To investigate, run manually:" |
| 437 | - echo " $_OAT_CMD" | 440 | + echo " python3 -m oat -mode s -s <repo> -f <files>" |
| 438 | echo "[OAT] Blocking commit to prevent silent compliance bypass." | 441 | echo "[OAT] Blocking commit to prevent silent compliance bypass." |
| 439 | echo "" | 442 | echo "" |
| 440 | rm -rf "$OAT_REPORT_DIR" | 443 | rm -rf "$OAT_REPORT_DIR" |
| @@ -442,7 +445,7 @@ if [ ! -f "$REPORT_FILE" ]; then | |||
| 442 | fi | 445 | fi |
| 443 | fi | 446 | fi |
| 444 | 447 | ||
| 445 | -# Parse counts ??use || true to prevent set -e from triggering if grep finds no match | 448 | +# Parse counts →use || true to prevent set -e from triggering if grep finds no match |
| 446 | _INVALID_TYPE=$(grep "^Invalid File Type Total Count:" "$REPORT_FILE" | grep -oE '[0-9]+' | head -1 || true) | 449 | _INVALID_TYPE=$(grep "^Invalid File Type Total Count:" "$REPORT_FILE" | grep -oE '[0-9]+' | head -1 || true) |
| 447 | _LICENSE_INVALID=$(grep "^License Header Invalid Total Count:" "$REPORT_FILE" | grep -oE '[0-9]+' | head -1 || true) | 450 | _LICENSE_INVALID=$(grep "^License Header Invalid Total Count:" "$REPORT_FILE" | grep -oE '[0-9]+' | head -1 || true) |
| 448 | _INVALID_TYPE=${_INVALID_TYPE:-0} | 451 | _INVALID_TYPE=${_INVALID_TYPE:-0} |
| @@ -505,6 +508,7 @@ echo "[OAT] [OK] All checks passed ($FILE_COUNT file(s) checked)." | |||
| 505 | echo "[OAT] Summary: cat $RESULT_FILE" | 508 | echo "[OAT] Summary: cat $RESULT_FILE" |
| 506 | echo "" | 509 | echo "" |
| 507 | # Mark scan as done for CI range mode (prevents redundant re-runs on same PR head) | 510 | # Mark scan as done for CI range mode (prevents redundant re-runs on same PR head) |
| 511 | +# 仅无参 PR-range 全量扫描才落 marker;args 模式(staged 子集)不得冒充全量覆盖 | ||
| 508 | if [ $# -eq 0 ] && [ -n "$_DONE_MARKER" ]; then | 512 | if [ $# -eq 0 ] && [ -n "$_DONE_MARKER" ]; then |
| 509 | touch "$_DONE_MARKER" 2>/dev/null || true | 513 | touch "$_DONE_MARKER" 2>/dev/null || true |
| 510 | echo "[OAT] Done-marker created: $_DONE_MARKER" | 514 | echo "[OAT] Done-marker created: $_DONE_MARKER" |
| @@ -0,0 +1,15 @@ | |||
| 1 | +#!/bin/bash | ||
| 2 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 3 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 4 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 5 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 6 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 7 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 8 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 9 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 10 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 11 | +# codespell 输出留证:终端打印的同时写入 pre-commit_reports/codespell.log | ||
| 12 | +REPORT_DIR="pre-commit_reports" | ||
| 13 | +mkdir -p "$REPORT_DIR" | ||
| 14 | +codespell "$@" 2>&1 | tee "$REPORT_DIR/codespell.log" | ||
| 15 | +exit "${PIPESTATUS[0]}" | ||