ตรวจสอบคุณภาพโค้ดก่อน commit ด้วย pre-commit
ในการพัฒนาซอฟต์แวร์ คุณภาพของโค้ดเป็นสิ่งสำคัญอย่างยิ่ง โค้ดที่ดีควรเป็นไปตามมาตรฐานที่กำหนด ผ่านการทดสอบ และปราศจากข้อผิดพลาด หากโค้ดมีคุณภาพดีก็จะทำให้การพัฒนาซอฟต์แวร์เป็นไปอย่างราบรื่น และลดปัญหาที่อาจเกิดขึ้นในอนาคต
หนึ่งในเครื่องมือที่ผมนำมาใช้พัฒนาโค้ดให้มีคุณภาพยิ่งขึ้นคือ pre-commit ซึ่งเป็น Git hook ที่ทำงานก่อนที่จะมีการ commit โค้ด โดย pre-commit สามารถทำงานได้หลากหลายอย่าง เช่น ตรวจสอบความถูกต้องของโค้ดตามมาตรฐานที่กำหนด ทำการทดสอบโค้ด หรือตรวจสอบความเรียบร้อยของไฟล์ต่างๆ
โดยผมอยากจะแนะนำให้นักพัฒนาซอฟแวร์ทุกคนมาใช้ pre-commit กัน
การติดตั้ง pre-commit
สำหรับ osx
$ brew install pre-commit
หรือใช้ pip ติดตั้ง
$ pip install pre-commit
ตรวจสอบ version
$ pre-commit --version
pre-commit 3.3.3
การกำหนด hook ให้กับ pre-commit
เมื่อติดตั้ง pre-commit เรียบร้อยแล้ว เราต้องกำหนด hook ให้กับ pre-commit โดยสร้างไฟล์ .pre-commit-config.yaml
ในโฟลเดอร์หลักของโปรเจ็กต์ ไฟล์นี้จะใช้กำหนด hook ต่างๆ ที่เราจะต้องการให้ pre-commit ทำงาน
ไฟล์ .pre-commit-config.yaml จะมีโครงสร้างดังนี้
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: check-added-large-files
args: ['--maxkb=750']
- id: check-yaml
args: ["--allow-multiple-documents"]
- id: check-json
- id: detect-private-key
- id: double-quote-string-fixer
- id: end-of-file-fixer
- id: mixed-line-ending
- id: check-merge-conflict
ในไฟล์นี้เราจะกำหนด hook ต่างๆ ให้กับ pre-commit โดย hook แต่ละตัวจะมี id กำกับอยู่ ซึ่งเราสามารถกำหนด hook ต่างๆ ได้ดังนี้
ID | อธิบาย |
---|---|
trailing-whitespace | ตรวจสอบว่ามี whitespace ที่ท้ายบรรทัดหรือไม่ |
check-added-large-files-files | ตรวจสอบว่ามีไฟล์ขนาดใหญ่ที่ถูกเพิ่มเข้ามาหรือไม่ |
check-yaml | ตรวจสอบความถูกต้องของไฟล์ YAML |
check-json | ตรวจสอบความถูกต้องของไฟล์ json |
detect-private-key | ตรวจสอบว่ามี private key เข้ามาหรือไม่ |
double-quote-string-fixer | แก้ไขให้ใช้ "" กับ String |
end-of-file-fixer | ตรวจสอบว่ามีไฟล์ที่ไม่มีจุดสิ้นสุดบรรทัดหรือไม่ และแก้ไขให้ถูกต้อง |
mixed-line-ending | ตาวจสอบถูกต้องของบรรทัดตอนท้ายสุด |
check-merge-conflict | ตรวจสอบว่ามีไฟล์ที่มีความขัดแย้งระหว่างการ merge หรือไม่ |
นอกจาก hook เหล่านี้แล้ว เรายังสามารถกำหนด hook อื่นๆ ได้ตามต้องการ โดยสามารถดูตัวอย่าง hook ต่างๆ ได้ที่ https://pre-commit.com/hooks.html
การเพิ่มคำสั่ง Hook เอง
จากตัวอย่างด้านบนเราจะเห็นว่ามันมี Hook ที่เขาทำมาให้เราใช้งานได้เลยทันที แต่ถ้าเราอยากทำ Hook ขึ้นมาเองเช่นให้มัน npm run test
ทุกครั้งก่อน Commit สามารถเขียนได้ดังนี้
repos:
- repo: local
hooks:
- id: unitest
name: Run Unitest
pass_filenames: false
language: system
entry: npm run test
- id คือ ชื่อ hook
- nam คือ คำอธิบาย
- entry คือ คำสั่งที่เราต้องการให้มันทำงาน
การใช้งาน pre-commit
เมื่อกำหนด hook ให้กับ pre-commit เรียบร้อยแล้ว เราจะสามารถใช้งาน pre-commit ได้ โดยทุกครั้งที่เราทำการ commit โค้ด pre-commit จะทำงานตรวจสอบโค้ดตาม hook ที่เรากำหนดไว้ หากโค้ดผ่านการตรวจสอบ pre-commit ก็จะทำการ commit โค้ดให้สำเร็จ แต่ถ้าโค้ดไม่ผ่านการตรวจสอบ pre-commit ก็จะแจ้งให้เราแก้ไขโค้ดก่อนทำการ commit
ทุกครั้งที่มีการ clone project ลงมาที่เครื่องเราใหม่ โดย project นั้นต้องมีไฟล์ .pre-commit-config.yaml
อยู่ ให้พิมพ์คำสั่งตามนี้
$ pre-commit install
$ pre-commit install --hook-type commit-msg
$ pre-commit autoupdate
ตัวอย่างการใช้งาน pre-commit ดังนี้
$ git commit -m "Add a new feature"
หากโค้ดของเราผ่านการตรวจสอบ pre-commit ก็จะทำการ commit โค้ดให้สำเร็จ แต่ถ้าโค้ดไม่ผ่านการตรวจสอบ pre-commit ก็จะแจ้งให้เราแก้ไขโค้ดก่อนทำการ commit ดังนี้
The following files would be affected by this commit:
src/main.js
There were some warnings:
trailing-whitespace: src/main.js:1: trailing whitespace
Please fix the warnings and try again.
และถ้าเราใช้งาน Commit ผ่าน vscode หรือ text editor ที่ใช้งานอยู่ประจำ ก็จะเรียกใช้ pre-commit ด้วยเช่นกัน
ประโยชน์ของการใช้ pre-commit
การใช้ pre-commit มีประโยชน์มากมายดังนี้
- ช่วยให้เราพัฒนาโค้ดให้มีคุณภาพยิ่งขึ้น โดย pre-commit จะตรวจสอบโค้ดตามมาตรฐานที่กำหนด ทำการทดสอบโค้ด และตรวจสอบความเรียบร้อยของไฟล์ต่างๆ
- ช่วยให้เราประหยัดเวลาในการแก้ไขโค้ด เนื่องจาก pre-commit จะแจ้งให้เราแก้ไขโค้ดก่อนทำการ commit ทำให้เราสามารถแก้ไขโค้ดได้ทันทีก่อนที่จะทำการ commit
- ช่วยให้เราลดปัญหาที่อาจเกิดขึ้นในอนาคต เนื่องจาก pre-commit จะตรวจสอบโค้ดให้ถูกต้องตั้งแต่เริ่มต้น
- สามารถนำไปใช้งานตรวจสอบโค้ดได้ทุกภาษา เช่น python, golang, nodejs เป็นต้น
หากเราพัฒนาซอฟต์แวร์อยู่เป็นประจำ การใช้ pre-commit จะช่วยให้คุณพัฒนาโค้ดให้เป็นไปตามมาตรฐานที่กำหนด ซึ่งจะช่วยให้โค้ดของคุณอ่านง่าย เข้าใจง่าย และนำไปใช้งานต่อได้ง่ายขึ้น นอกจากนี้ การใช้ pre-commit ยังช่วยตรวจสอบความถูกต้องของโค้ดก่อนทำการ commit ทำให้คุณสามารถมั่นใจได้ว่าโค้ดของคุณไม่มีข้อผิดพลาด และพร้อมที่จะนำไปใช้งานจริง
ตัวอย่างไฟล์ pre-commit ที่ใช้ประจำ
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: check-added-large-files
args: ['--maxkb=750']
- id: check-yaml
args: ["--allow-multiple-documents"]
- id: check-json
- id: detect-private-key
- id: double-quote-string-fixer
- id: end-of-file-fixer
- id: mixed-line-ending
- id: check-merge-conflict
- repo: https://github.com/commitizen-tools/commitizen
rev: 3.6.0
hooks:
- id: commitizen
stages: [commit-msg]
- repo: https://github.com/hadolint/hadolint
rev: v2.12.1-beta
hooks:
- id: hadolint-docker
args: ['--ignore=DL3018']
- repo: https://github.com/gitleaks/gitleaks
rev: v8.17.0
hooks:
- id: gitleaks
นำไปปรับแต่งใช้งานกันนะ...
Comments ()