git-pre-commit-hook:讓代碼質(zhì)量檢查自動化起來

引言:為什么我們需要代碼提交前的「安全檢查」?

作為開發(fā)者,你有沒有遇到過這些情況?

  • 不小心把調(diào)試代碼提交到了遠(yuǎn)程倉庫

  • 代碼格式混亂導(dǎo)致團(tuán)隊協(xié)作出現(xiàn)分歧

  • 因為一個簡單的語法錯誤,CI/CD 流水線反復(fù)失敗

  • 甚至無意中把敏感信息(如密鑰)推送到了公開倉庫

這些看似小問題,卻常常浪費團(tuán)隊大量時間和精力。今天我們要聊的 pre-commit 工具,就是解決這些問題的「代碼提交守門員」。

一、pre-commit 是什么?它如何保護(hù)你的代碼質(zhì)量?

理解 pre-commit 的核心概念

pre-commit 是一個 Git 鉤子管理工具,它能在你執(zhí)行 git commit 命令時,自動運行一系列檢查腳本,只有通過這些檢查,代碼才能被成功提交。

簡單來說,它就像是你代碼提交前的一道「安檢門」,幫助你在代碼進(jìn)入版本控制系統(tǒng)前就發(fā)現(xiàn)并解決潛在問題。

pre-commit 的工作原理

它利用 Git 的 pre-commit 鉤子機(jī)制,在代碼提交前攔截操作,運行配置好的檢查項(如代碼格式化、語法檢查、靜態(tài)分析等),幫助開發(fā)者在本地就發(fā)現(xiàn)并解決問題。

具體流程是這樣的:

  1. 你執(zhí)行 git commit 命令

  2. pre-commit 鉤子被觸發(fā)

  3. pre-commit 工具運行你配置的所有檢查項

  4. 如果所有檢查都通過,commit 操作繼續(xù)執(zhí)行

  5. 如果有任何檢查失敗,commit 操作被中止,你需要修復(fù)問題后重新提交

使用 pre-commit 的三大好處

  • 提前發(fā)現(xiàn)問題:在代碼進(jìn)入遠(yuǎn)程倉庫前就解決大多數(shù)質(zhì)量問題,避免把問題帶入后續(xù)流程

  • 統(tǒng)一團(tuán)隊規(guī)范:確保所有提交的代碼都符合團(tuán)隊約定的標(biāo)準(zhǔn),減少代碼審查時關(guān)于格式的討論

  • 減少 CI/CD 失?。罕苊庖虻图夊e誤導(dǎo)致的流水線反復(fù)構(gòu)建,提高開發(fā)效率

二、如何在 Windows 下快速上手 pre-commit?

安裝 pre-commit(Windows 版本)

在 Windows 系統(tǒng)上安裝 pre-commit 非常簡單,只需要幾個步驟:

  1. 確保已安裝 Python pre-commit 是一個 Python 工具,所以首先需要確保你的系統(tǒng)上已經(jīng)安裝了 Python。你可以通過在命令提示符(CMD)或 PowerShell 中運行以下命令來檢查:

python --version

如果沒有安裝 Python,可以訪問 Python 官方網(wǎng)站 下載最新版本的安裝包,并在安裝時勾選「Add Python to PATH」選項。

  1. 使用 pip 安裝 pre-commit 打開命令提示符(CMD)或 PowerShell,運行以下命令:

pip install pre-commit

  1. 驗證安裝是否成功 安裝完成后,運行以下命令來驗證:

pre-commit --version

如果能看到版本號信息,說明 pre-commit 已經(jīng)成功安裝。

創(chuàng)建并配置 pre-commit 配置文件

  1. 初始化 pre-commit 進(jìn)入你的 Git 項目目錄,在命令提示符或 PowerShell 中運行:

pre-commit install

這個命令會在你的項目的 .git/hooks 目錄下創(chuàng)建 pre-commit 鉤子腳本。

  1. 創(chuàng)建配置文件 在項目根目錄下創(chuàng)建一個名為 .pre-commit-config.yaml 的文件。這是 pre-commit 的核心配置文件,用于定義要運行的檢查項。

一個簡單的配置文件示例:


repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
    -   id: check-yaml
    -   id: check-added-large-files

  1. 理解配置文件結(jié)構(gòu)
  • repos:包含一個或多個 Git 倉庫,這些倉庫提供 pre-commit 鉤子

  • repo:鉤子倉庫的 URL

  • rev:要使用的鉤子倉庫版本

  • hooks:要使用的鉤子列表

  • id:鉤子的唯一標(biāo)識符

常用的 pre-commit 鉤子推薦

以下是一些在日常開發(fā)中非常實用的 pre-commit 鉤子:

通用檢查類

  • trailing-whitespace:刪除行尾的空白字符

  • end-of-file-fixer:確保文件以換行符結(jié)尾

  • check-yaml:檢查 YAML 文件的語法是否正確

  • check-added-large-files:避免意外將大文件引入到倉庫

代碼格式化類

black:自動格式化 Python 代碼,確保代碼風(fēng)格一致

black 是一個 Python 代碼格式化工具,它的主要功能是自動格式化 Python 代碼,確保代碼風(fēng)格一致。 注意black只能修復(fù)代碼中的格式問題,不能修復(fù)代碼中的語法錯誤。

安裝依賴:


pip install black==23.3.0

pre-commit 配置如下:


-   repo: https://github.com/psf/black
    rev: 23.3.0
    hooks:
    -   id: black

isort:自動排序 Python 導(dǎo)入語句

isort 用于自動排序和格式化 Python 文件中的導(dǎo)入語句。它的主要功能包括:

  1. 分類導(dǎo)入:自動將導(dǎo)入分為三類

    • 標(biāo)準(zhǔn)庫導(dǎo)入

    • 第三方庫導(dǎo)入

    • 本地模塊導(dǎo)入

  2. 字母排序 :在每個類別內(nèi)按字母順序排序?qū)?/p>

  3. 格式化 :處理導(dǎo)入的格式,如合并相同模塊的導(dǎo)入

安裝依賴:


pip install isort==5.12.0

運行isort:


# 檢查并修改導(dǎo)入語句

isort HelloWorld.py
# 檢查但不修改

isort --check HelloWorld.py

pre-commit 配置如下:


- repo: https://github.com/pycqa/isort
  rev: 5.12.0
  hooks:
  - id: isort

語法檢查類

flake8:檢查 Python 代碼中的語法錯誤和風(fēng)格問題

flake8 主要是一個代碼質(zhì)量檢查工具,它的核心功能是檢測代碼中的語法錯誤、編碼規(guī)范問題、潛在的邏輯問題和代碼質(zhì)量問題,但不提供自動修復(fù)這些問題的能力。 注意:

  1. 若有語法錯誤,flake8 會報告錯誤位置和類型,并停止后續(xù)檢測,因此報告語法錯誤時可能還有其他未檢測到的問題。

  2. 如果風(fēng)格問題已經(jīng)被black修復(fù),flake8就不會再報告這些問題了,因此推薦將black和flake8結(jié)合使用,使用時要注意先后順序。

安裝依賴:


pip install flake8==6.0.0

檢測語法和代碼風(fēng)格:


# 檢測 flake8_test.py 中的語法錯誤和風(fēng)格問題

flake8 flake8_test.py

# --show-source 顯示錯誤的代碼位置

flake8 --show-source flake8_test.py

pre-commit 配置如下:


- repo: https://github.com/pycqa/flake8
  rev: 6.0.0
  hooks:
  -   id: flake8

安全檢查類

detect-secrets:檢測代碼中是否包含敏感信息(如 API 密鑰、密碼等)

detect-secrets 是 Yelp 開發(fā)的一個工具,用于掃描代碼倉庫中可能包含的敏感信息,如 API 密鑰、密碼、證書等。它使用多種啟發(fā)式規(guī)則來識別潛在的敏感信息,并可以幫助團(tuán)隊避免將敏感信息意外提交到代碼倉庫中。

注意:它不是 100% 準(zhǔn)確的,可能會產(chǎn)生誤報或漏報,因此仍然需要人工審查。

安裝依賴:


pip install detect-secrets==1.5.0

檢測敏感信息:


detect-secrets scan

當(dāng)運行 pre-commit run detect-secrets --all-files 時,如果檢測到大量敏感信息(尤其是在 lock 文件中),這是正?,F(xiàn)象,因為這些文件通常包含許多看起來像敏感信息的高熵字符串。 解決方法:

  • 跳過 lock 文件

  • 添加基線文件

跳過 lock 文件

  • 可以使用 --exclude-files 參數(shù)來排除特定文件

detect-secrets scan --exclude-files "package-lock.json|pnpm-lock.yaml|yarn.lock"

  • 在 .pre-commit-config.yaml 中有兩種方式:

    • 添加排除規(guī)則,跳過 lock 文件

    • 使用--exclude-files參數(shù)來排除特定文件


- repo: https://github.com/Yelp/detect-secrets
  rev: v1.5.0
  hooks:
    - id: detect-secrets
      # 跳過lock文件,因為它們通常包含大量看起來像敏感信息的高熵字符串
      exclude: |
        (?x)^(
          package-lock.json|
          pnpm-lock.yaml|
          yarn.lock
        )$
      # 也可以使用--exclude-files參數(shù)來排除特定文件
      args: [--exclude-files, "package-lock.json|pnpm-lock.yaml|yarn.lock"]

添加基線文件

  1. 初始化基線文件(baseline),記錄當(dāng)前已知的敏感信息,這樣后續(xù)的檢查只會關(guān)注新添加的敏感信息:

# 掃描當(dāng)前目錄下所有被Git跟蹤的文件

detect-secrets scan > .secrets.baseline
# 掃描當(dāng)前目錄下 所有文件 ,包括未被Git跟蹤的文件

detect-secrets scan --all > .secrets.baseline

  1. 將當(dāng)前代碼狀態(tài)與已有的基線文件進(jìn)行比較,檢測是否引入了新的敏感信息:

detect-secrets scan --baseline .secrets.baseline

  1. .pre-commit-config.yaml中為detect-secrets鉤子添加參數(shù),指定使用這個 baseline 文件:

- repo: https://github.com/Yelp/detect-secrets
  rev: v1.5.0
  hooks:
    - id: detect-secrets
      args: [--baseline, .secrets.baseline]

這樣,pre-commit 就只會報告 baseline 文件中未記錄的新敏感信息,避免每次運行都報告大量已知的誤報,不僅僅是 lock 文件,其他已知的敏感信息也會過濾不再報告。

三、pre-commit 的進(jìn)階技巧與最佳實踐

在團(tuán)隊中推廣 pre-commit

當(dāng)你在個人項目中嘗到 pre-commit 的甜頭后,可能會想要在團(tuán)隊中推廣它。以下是一些實用的推廣技巧:

  1. 在項目 README 中添加 pre-commit 安裝指南,確保新成員能夠快速上手

  2. 將 pre-commit 配置納入版本控制,確保團(tuán)隊成員使用相同的配置

  3. 在 CI/CD 流程中強(qiáng)制執(zhí)行 pre-commit 檢查,可以使用 pre-commit run --all-files 命令

  4. 定期更新鉤子版本,以獲取最新的功能和修復(fù)

開發(fā)自定義 pre-commit 鉤子

當(dāng)現(xiàn)成的鉤子不能滿足你的特定需求時,你可以開發(fā)自己的 pre-commit 鉤子。以下是創(chuàng)建自定義鉤子的基本步驟:

  1. 創(chuàng)建一個簡單的腳本,該腳本將執(zhí)行你想要的檢查邏輯

  2. 確保腳本具有執(zhí)行權(quán)限(在 Windows 上這一步通常不是必需的)

  3. .pre-commit-config.yaml 中添加自定義鉤子:

    -   repo: local
        hooks:
        -   id: my-custom-hook
            name: My Custom Hook
            entry: path/to/your/script.py
            language: python
            types: [python]
    

與 CI/CD 流程結(jié)合

為了確保代碼質(zhì)量,最好在 CI/CD 流程中也運行 pre-commit 檢查。這樣可以避免有人繞過本地檢查直接提交代碼。

在 CI/CD 配置文件中,你可以添加類似以下的步驟:


jobs:
  lint:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: Install pre-commit
        run: pip install pre-commit
      - name: Run pre-commit checks
        run: pre-commit run --all-files

結(jié)論:讓 pre-commit 成為你的代碼質(zhì)量「第一道防線」

pre-commit 不是一個復(fù)雜的工具,但它能為你的項目帶來顯著的質(zhì)量提升。通過在代碼提交前就解決掉大多數(shù)常見問題,你和你的團(tuán)隊可以把更多精力放在真正重要的功能開發(fā)上。

無論是個人項目還是大型團(tuán)隊協(xié)作,pre-commit 都值得嘗試——它可能不會解決所有代碼質(zhì)量問題,但絕對能幫你避免大多數(shù)低級錯誤。

現(xiàn)在就給你的項目加上這道「安全門」吧!打開命令提示符或 PowerShell,按照本文的指南安裝 pre-commit,讓你的代碼提交更有保障。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容