---
# System prepended metadata

title: Git-Hook(pre-commit) 代碼格式檢查和格式化
tags: [Git, Maven, Java]

---

---
title: 'Git-Hook(pre-commit) 代碼格式檢查和格式化'
disqus: hackmd
---
# 前置
* **Maven插件**：
    ```xml
        <groupId>net.revelc.code.formatter</groupId>
        <artifactId>formatter-maven-plugin</artifactId>
        <version>2.17.0</version>
    ```
    * **注意**：該插件**僅支援**讀取 Eclipse 代碼格式化設定檔，無法直接解析 IntelliJ IDEA 的代碼樣式設定
    * **兩個指令**
        * `formatter:validate`：**格式驗證**
        * `formatter:format`：**格式化**
* **格式化文件**：從IDEA匯出
    * Editor > Code Style > Java
    * 點齒輪 > Export > Eclipse XML Profile

# 引入Maven插件
* **代碼**：引入Maven插件 + 設定格式化文件路徑(`檔名自行設定`)
    ```xml=
        <build>
            <plugins>
                <plugin>
                    <groupId>net.revelc.code.formatter</groupId>
                    <artifactId>formatter-maven-plugin</artifactId>
                    <version>2.17.0</version>
                    <configuration>
                        <configFile>${basedir}/intellij-java-formatter.xml</configFile>
                        <encoding>UTF-8</encoding>
                        <lineEnding>LF</lineEnding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    ```
    * **注意**：不要 **Maven build過程**中**格式化文件**
        * 因此就沒有使用**executions標籤**

# 格式化腳本(bash)
* **使用 Maven 指令和插件**
    * 如果是使gradle，**改用**gradle的**指令**和**插件**即可
* **格式化腳本**
    ```bash
    #!/bin/sh

    echo "Running on Unix-like environment."
    # 如果有設定Maven Home 可以用mvn替代
    MVN_PATH="/c/Users/Xxx/apache-maven-3.6.3/bin/mvn.cmd"
    
    # 驗證格式是否正確
    "$MVN_PATH" formatter:validate
    if [ $? -ne 0 ]; then 
        echo "Code formatting failed. Please fix the issues before commit."
        
        # 格式不合規，執行格式化
        "$MVN_PATH" formatter:format
        
        # 格式化後阻擋 commit，讓開發者重新檢查
        exit 1 
    fi
    # 格式正確，允許 commit
    exit 0
    ```
    * **返回非 0 狀態碼，commit 會被取消**
* **其他**： 
    * 默認該專案下會有`pom.xml`，如果沒有可以使用`-f 路徑`來**指定pom.xml的位置**
        * **例**：`mvn -f xxx/xxx/pom.xml formatter:validate`
    * **Windows環境**：PowerShell要執行的腳本需要在調整 或 設定成**預設使用git bash執行**
    
# 設定 git-hook
* **被觸發的git-hook**：**pre-commit**
    * **時機**：**提交commit前觸發**
* **步驟**：
    1. 將腳本改名為`pre-commit` (無副檔名)
         * `pre-commit`（無副檔名）給 Bash 或類 Unix shell 用
         * `pre-commit.ps1` 給 PowerShell 用
    3. 將腳本放到當前專案下的 **.git/hooks**目錄中
        *  **.git/hooks**目錄：Git**本地倉庫**的 **hooks 存放位置**
            *  每個 hook 都是 一個**可執行檔**（`shell script / PowerShell / Python…`），在特定事件觸發
            *  預設 Git 會提供 .sample 範例，必須移除 .sample 才會生效
            * **本地專案專用**，**不會被 Git push 到遠端**（除非你用特殊機制，比如 husky、lefthook 等）