使用git_hooks庫助力Flutter團隊編碼規範

JSShou發表於2021-03-15

原文連結

前言

隨著Flutter 2.0的釋出,越來越多的公司和個人都在嘗試使用Flutter來編寫效能優異、跨平臺、渲染一致性好的App。當然,在追求效率的同時,也不要忘了給你的程式碼新增更多嚴謹的限制,來保證程式碼的質量。今天我給大家推薦一個外掛,用於給提交程式碼到Github或者GitLab時,在本地使用dart語言,即可限制提交程式碼的質量。

Git Hooks

Git Hooks是什麼,Hooks顧名思義,就是鉤子。它在Git中的作用就是在我們通過git命令操作倉庫或者新增專案檔案時,執行一些指令碼,指令碼通過即可完成事件,如果失敗就被終止事件。這裡是官方定義的所有鉤子,有興趣的可以一一檢視。比如我們在.git/hooks/下新建了一個pre-commit檔案,並輸入以下內容

#!/bin/sh

echo '檔案正在提交'
exit(-1)
複製程式碼

然後我們在命令列中執行

git add test
git commit -m '提交資訊'
複製程式碼

然後我們就會在命令列看到檔案正在提交,並且檔案最後沒有提交到本地倉庫,因為上面我exit了。

這樣,我們就可以在這個檔案中寫一些校驗,比如通過dartanalyzer檢視本地專案語法是否有語法問題。

git_hooks

這是一個Dart命令列外掛,也是一個Dart外掛。我們看到上面使用shell指令碼來寫校驗,它存在一些問題:

  • 每個人的.git資料夾是不通過版本管理的,所以一個人第一次拉了程式碼,在.git/hooks資料夾下是不會存在能執行的hooks檔案的
  • shell指令碼比較生澀難寫,上手難度高

git_hooks庫就是為了解決上面問題。它的作用就是能通過命令生成所有hooks,然後在我們通過git命令提交程式碼時,可以通過dart來進行提交前或者提交資訊的校驗。它讓我們程式設計師可以忽略hooks檔案存在,在dart程式碼中實現對所有鉤子的操作。

這裡我們定一個我們能看懂的術語

hooks檔案:指在.git/hooks資料夾下生成的鉤子檔案 dart鉤子檔案:指在專案中生成的使用dart語言來操作hooks檔案的dart檔案

我們可以通過下面命令來安裝它,安裝它前請保證你的dart已經安裝且已經配置了環境變數,還要保證你的 dart 版本大於 2.1.0

執行命令dart --version檢視dart版本號

然後執行pub global activate git_hooks即可全域性安裝git_hooks命令

建立hooks專案檔案

當我們開啟一個擁有git版本管理的專案(在專案中可看到.git資料夾)

在專案中的pubspec.yaml檔案中新增

dev_dependencies:
  git_hooks: ^0.1.5
複製程式碼

建立hooks檔案dart鉤子檔案的命令是:

git_hooks create {{targetFileName}}
複製程式碼
  • targetFileName指的是dart鉤子檔案,它可以是專案中任何位置,比如在根目錄下的git_hooks.dart檔案(這也是如果此引數不傳預設會建立的檔案)

那我們來執行:

git_hooks create git_hooks.dart
複製程式碼

如果輸出

create files...                        
All files wrote successful!
0.2s
複製程式碼

那說明我們已經建立成功。我們來檢查一下檔案是否生成成功,檢視.git/hooks檔案下是否有多個檔案例如pre-commit,pre-push等等,檢視根目錄下是否已生成git_hooks.dart檔案

開啟git_hooks.dart檔案會看到如下

import 'package:git_hooks/git_hooks.dart';
// import 'dart:io';

void main(List arguments) {
  // ignore: omit_local_variable_types
  Map<Git, UserBackFun> params = {
    Git.commitMsg: commitMsg,
    Git.preCommit: preCommit
  };
  GitHooks.call(arguments, params);
}

Future<bool> commitMsg() async {
  // String rootDir = Directory.current.path;
  // String commitMsg = Utils.getCommitEditMsg();
  // if (commitMsg.startsWith('fix:')) {
  //   return true; // you can return true let commit go
  // } else
  //   return false;
  return true;
}

Future<bool> preCommit() async {
  // try {
  //   ProcessResult result = await Process.run('dartanalyzer', ['bin']);
  //   print(result.stdout);
  //   if (result.exitCode != 0) return false;
  // } catch (e) {
  //   return false;
  // }
  return true;
}
複製程式碼

解釋:

  • main方法下的params是一個Map,是我們想要自定義的鉤子集合,每個鉤子對應下面具體的函式
  • GitHooks.call 是固定寫法,庫的內部會執行鉤子函式並校驗
  • commitMsg函式是一個例子,當執行git的commit-msg指令碼時,會執行此函式,如果返回false,會終止git操作

我們嘗試把註釋開啟

Future<bool> commitMsg() async {
  var commitMsg = Utils.getCommitEditMsg();
  if (commitMsg.startsWith('fix:')) {
    return true; // you can return true let commit go
  } else  {
    print('you should add `fix` in the commit message');
    return false;
  }
}
複製程式碼

然後在專案路徑的命令列下執行:

git add git_hooks.dart
git commit -m '提交資訊'
複製程式碼

指令碼輸出如下

you should add `fix` in the commit message
複製程式碼

並且檔案沒有被提交到本地倉庫。

大功告成!

刪除所有hooks檔案

當我們有一天被自己寫的鉤子折磨,不想再用此校驗,我們有兩個方式來刪除鉤子

  1. 刪除.git/hooks資料夾,注意是hooks資料夾而不是.git資料夾
  2. 通過命令git_hooks uninstall來刪除

其它鉤子的列舉

你可以通過下面的列舉,新增更多的鉤子操作

enum Git {
  applypatchMsg,
  preApplypatch,
  postApplypatch,
  preCommit,
  prepareCommitMsg,
  commitMsg,
  postCommit,
  preRebase,
  postCheckout,
  postMerge,
  prePush,
  preReceive,
  update,
  postReceive,
  postUpdate,
  pushToCheckout,
  preAutoGc,
  postRewrite,
  sendemailValidate
}
複製程式碼

具體含義可以參考git官方文件

結語

上面是我的一個例子,當然我們可以使用該工具做更多的事情,比如使用dartanalyzer檢查程式碼質量,使用dartfmt來檢查程式碼檔案格式是否對齊等等。

pub倉庫地址

github地址

git hooks 官方文件

相關文章