
Auto review code & report lên Github với SwiftLint và LinterBot
TutorialsContents
Để đảm bảo chất lượng của 1 dự án thì mã nguồn phải được kiểm tra thường xuyên. Nhưng với một team dự án lớn, nhiều người thì lượng task sẽ tăng theo, cũng như áp lực deadline. Thì việc đảm bảo review code là điều rất khó khăn. Bên cạnh đó chúng ta có thể hạn chế các lỗi typo, lỗi ngớ ngẫn, cũng nhưng tất cả phải tuân theo conventions … bằng cách sử dụng các tools tự động.
Hôm nay, mình xin giới thiệu cho các bạn 1 tool (có lẽ không mới cho lắm) để auto review code và report lên GitHub. Tất nhiên, nó phải kết hợp được với CI thì mới phát huy được hiệu quả tốt nhất.
Nếu bạn chưa đọc bài cấu hình Travis CI thì có thể kích vào đây để đọc trước, rồi mới tiếp tục sang bài này. Còn trước khi bắt đầu thì mình hãy đọc sơ qua vài khái niệm sau:
1. Coding Coventions
Nôm na thì Coding conventions là tập hợp những nguyên tắc chung khi lập trình nhằm làm cho code dễ đọc, dễ hiểu, từ đó dễ quản lý, bảo trì project hơn.
Là một tập quy tắt ứng xử cộng đồng. Trong trường hợp này là team dev của bạn. Với mỗi loại ngôn ngữ lập trình thì chúng ta có một loại Coding conventions. Và chúng không phải cố định mà nó tùy thuộc vào mỗi team dự án đặt ra và quy định cho các thành viên tuân theo.
Với Swift thì bạn có thể tham khảo tại đây: https://github.com/raywenderlich/swift-style-guide
2. SwiftLint
2.1 Khái niệm
- Là một tool dùng để kiểm tra code (hay gọi là review code) theo conventions của Swift
- Có thể bắt gặp nhiều Lint khác cho nhiều loại ngôn ngữ khác
- Về conventions thì mình có thể sử dụng các
rule
mặc định hoặc có thể tựcustom
theo conventions của team hay của dự án - Link: https://github.com/realm/SwiftLint
2.2 Cài đặt
Có rất nhiều cách cài đặt khác nhau, tùy thuộc vào cấu hình iOS Project của bạn. Với bài viết này mình sẽ hướng dẫn sử dụng với CocoaPod.
- Mở Podfile và thêm vào:
pod 'SwiftLint'
- Install, tùy thuộc vào cái bạn đang dùng là gì (CocoaPod hay Bundle).
- Thêm
script
vào Xcode để chạyswiftlint
- Vào Build Phase > New Run Script Phase
- Chép đoạn script sau:
"${PODS_ROOT}/SwiftLint/swiftlint"
Build project và sẽ thấy Swiftlint
thông báo các warning
và error
2.3 Test SwiftLint
- Thử kiểm tra hoạt động của SwiftLint thì bạn có thể thử như sau, thêm 1 đoạn code nào đó vào 1 file nào đó.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // test comment var namesOfIntegers: [Int: String] = [Int: String]() return true }
- Kết quả
- Có 2 warning cho 2 dòng trống
- Convention sai cho việc khởi tạo array
3. Tích hợp SwiftLint với CI
- Để sử dụng được
SwiftLint
với CI hay ở đây làTravis CI
thì:- Tạo 1
yaml file
và đặt ở thư mục gốc. CI sẽ tự động quét và chạy - Đặt tên sau
.swiftlint.yml
- Tạo 1
- Nội dung file tham khảo:
disabled_rules: # rule identifiers to exclude from running - colon - comma - control_statement opt_in_rules: # some rules are only opt-in - empty_count # Find all the available rules by running: # swiftlint rules excluded: # paths to ignore during linting. Takes precedence over `included`. - Carthage - Pods - vendor analyzer_rules: # Rules run by `swiftlint analyze` (experimental) - explicit_self # configurable rules can be customized from this configuration file # binary rules can set their severity level force_cast: warning # implicitly force_try: severity: warning # explicitly # rules that have both warning and error levels, can set just the warning level # implicitly line_length: 110 # they can set both implicitly with an array type_body_length: - 300 # warning - 400 # error # or they can set both explicitly file_length: warning: 500 error: 1200 # naming rules can set warnings/errors for min_length and max_length # additionally they can set excluded names type_name: min_length: 4 # only warning max_length: # warning and error warning: 40 error: 50 excluded: iPhone # excluded via string identifier_name: min_length: # only min_length error: 3 # only error excluded: # excluded via string array - id - URL - GlobalAPIKey reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit, html, emoji, sonarqube, markdown)
- Ý nghĩa các từ khoá và lệnh trong file trên thì các bạn từ tìm hiểu và nói chung thì cũng không khó mấy, nên vọc vọc tí là ra
- Chú ý:
- Rule & Custom Rule : các luật (rule) mặc định và tùy biến theo team dự án cho conventions của Project. Ví dụ:
custom_rules: id_suffix_naming: name: "Wrong name" regex: "(ID)" match_kinds: - comment - identifier message: "Use 'Id' instead 'ID'" severity: error uiwebview_disabled: included: ".*.swift" name: "UIWebView Usage Disabled" regex: 'UIWebView' message: "Do not use UIWebView. Use WKWebView Instead. https://developer.apple.com/reference/uikit/uiwebview" severity: error
-
- Thư mục và đường dẫn : nếu bạn có sử dụng thì hãy check, vì ghi thư mục trong file nhưng nó ko có trong repo thì không
pass
đc CI
- Thư mục và đường dẫn : nếu bạn có sử dụng thì hãy check, vì ghi thư mục trong file nhưng nó ko có trong repo thì không
- Các trường hợp chạy
SwiftLint
oke thì bản build sẽ được kiểm tra, nếu bản buildfailed
thì sẽ báo như sau:
Testing failed: Identifier Name Violation: Variable name should be between 4 and 40 characters long: 'key' (identifier_name) Testing cancelled because the build failed. ** TEST FAILED **
Build chạy đúng thì âm thầm không show ra gì, nên cứ bình tĩnh mà tiến tới tiếp bước sau. 😎
4. Report & Comment lên GitHub với LinterBot
Để có thể post/comment các kết quả của SwiftLint
lên GitHub thì chúng ta sử dụng LinterBot
4.1 Khái niệm
- Linterbot
- Là 1 con
BOT
, nhiệm vụ của nó là đọcout put
củaSwiftLint
và comment vàopull request
trên GitHub - Cần có được
access_token
từ account của dev mới có thể post comment vào
- Là 1 con
- Link tham khảo: https://github.com/guidomb/linterbot
4.2 Cài đặt
- Thêm vào
GemFile
gem 'linterbot'
- Install
gem install linterbot
4.3 Sử dụng ở Local
swiftlint lint --reporter json | linterbot REPOSITORY PULL_REQUEST_NUMBER
4.4 Sử dụng với Travis CI
- Create bash script (bash là gì thì tự tìm hiểu nha)
- Tạo thư mục
scripts
(trong thư mục gốc) > tạo 1 file (ko có đuôi) và edit như sau:
- Tạo thư mục
#!/bin/bash if [ "$TRAVIS_PULL_REQUEST" != "false" ] then ./Pods/SwiftLint/swiftlint --reporter json > swiftlint-report.json || false linterbot $TRAVIS_REPO_SLUG $TRAVIS_PULL_REQUEST < swiftlint-report.json fi
-
- Chú ý đường dẫn sau
./Pods/SwiftLint/swiftlint
Vì đó là nơi mà mìnhpod
swiftlint về nên trỏ vào đúng nó mới chạy được. Lỗi ngu ngu này mất cả tiếng đồng hồ nếu copy dán không suy nghĩ. - Saved file lại với tên là
linter
- Edit quyền để tránh các lỗi về
Permission denied
như sau (khi chạy trên CI)
- Chú ý đường dẫn sau
0.01s$ ./bin/linter /Users/travis/.travis/functions: line 104: ./bin/linter: Permission denied The command “./bin/linter” exited with 126.
-
- Lệnh set lại quyền truy cập như sau (dành cho các thanh niên không biết)
chmod +x ./scripts/linter
- Edit
.travis.yml
- Thêm các lệnh cài đặt
linterbot
- Thêm các lệnh cài đặt
before_install: - bundle install - gem install linterbot - bundle exec pod install --repo-update
-
- Thêm lệnh thực hiện
script
linter
- Thêm lệnh thực hiện
script: - ./scripts/linter
- File
.travis.yml
đẹp như sau:
language: objective-c osx_image: xcode10.1 cache: - bundler - cocoapods xcode_workspace: TheLastProject.xcworkspace xcode_scheme: TheLastProject_Development xcode_destination: platform=iOS Simulator,OS=12.1,name=iPhone X before_install: - bundle install - gem install linterbot - bundle exec pod install --repo-update install: - set -o pipefail - sudo systemsetup -settimezone Asia/Ho_Chi_Minh - bundle install --path=vendor/bundle --jobs 4 --retry 3 before_script: - chmod a+x ./scripts/linter script: - ./scripts/linter
4.4 Access Key
- Để có thể
post/comment
lên được GitHub thì cần có quyền truy cập từ GitHub - Tham khảo cách tạo
access_key
: https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line - Để đảm bảo tính bảo mật thì các
key
sẽ được lưu trữ trên trangTravis CI
. Vào setting > tạo 1GITHUB_ACCESS_TOKEN
- Mặc định thì LinterBot sẽ tự đồng tìm biến môi trường là
GITHUB_ACCESS_TOKEN
. Ngoài ra bạn có thể cấu hình riêng cho nó- Tạo file
.linterbot.yml
- Edit
- Tạo file
github_access_token: 'YOUR_GITHUB_ACCESS_TOKEN' linter_report_file: 'PATH/TO/SWIFTLINT/JSON/OUTPUT/FILE' project_base_path: 'BASE/PROJECT/PATH'
5. Kết quả
Tiến hành commit và gởi pull request để CI chạy và kiểm tra. Nếu đầy đủ các kết quả sau trên pull request
thì chúc mừng bạn đã pass qua bước này.
- Pass được CI
- Xuất hiện comments của
SwiftLint
thông qualinterbot
- Nếu pull request không có bất cứ lỗi chi thì sẽ như thế này
6. Tổng kết
Với bài viết này thì bạn có thể làm được những việc sau:
-
- Đảm bảo conventions của project
- Auto review code
- Tiết kiệm thời gian
- Tự động report và comment lên GitHub
Tham khảo:
- https://medium.com/cocoaacademymag/swiftlint-introduction-tutorial-cd692d41dda3
- https://github.com/guidomb/linterbot
- https://github.com/realm/SwiftLint
Related Posts:
Written by chuotfx
Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!
Leave a Reply Cancel reply
Fan page
Tags
Recent Posts
- Học vì tồn tại
- PARA – Phương pháp phân bổ tài nguyên giúp nâng cao hiệu quả sáng tạo
- Phù thủy phiên dịch ý tưởng
- XML Delimiters – Mở khóa thế giới prompt phức tạp
- Instructions – Cung cấp hướng dẫn cho các Gen AI
- SMART – Hướng dẫn dành tạo Prompt cho người mới bắt đầu
- Nhìn lại năm 2024
- CO-STAR – Công thức vàng để viết Prompt hiệu quả cho LLM
- Prompt Engineering trong 10 phút
- Một số ví dụ sử dụng Prompt cơ bản khi làm việc với AI
You may also like:
Archives
- January 2025 (7)
- December 2024 (4)
- September 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (4)
- April 2024 (2)
- March 2024 (5)
- January 2024 (4)
- February 2023 (1)
- January 2023 (2)
- November 2022 (2)
- October 2022 (1)
- September 2022 (5)
- August 2022 (6)
- July 2022 (7)
- June 2022 (8)
- May 2022 (5)
- April 2022 (1)
- March 2022 (3)
- February 2022 (5)
- January 2022 (4)
- December 2021 (6)
- November 2021 (8)
- October 2021 (8)
- September 2021 (8)
- August 2021 (8)
- July 2021 (9)
- June 2021 (8)
- May 2021 (7)
- April 2021 (11)
- March 2021 (12)
- February 2021 (3)
- January 2021 (3)
- December 2020 (3)
- November 2020 (9)
- October 2020 (7)
- September 2020 (17)
- August 2020 (1)
- July 2020 (3)
- June 2020 (1)
- May 2020 (2)
- April 2020 (3)
- March 2020 (20)
- February 2020 (5)
- January 2020 (2)
- December 2019 (12)
- November 2019 (12)
- October 2019 (19)
- September 2019 (17)
- August 2019 (10)