使用 husky 进行基础代码审查

news2024/10/6 14:31:41

在日常提交 PR 的过程中,我们提交的文件不应该有例如 console、debugger、test.only 等调试语句,这会影响到线上代码。那每次提交之前都检查似乎又像是一个繁琐的工作,如果有个工作能代替我们检查我们提交的代码,让不能提交到线上的代码在 commit 阶段停止下来,对 code reviewer 的工作会减少不少。这里就来跟大家探讨一下我的一个实现方式。

前言

在提交代码的时候不知道大家有没有注意命令行中会打印一些日志:

image.png

像这里的

husky > pre-commit
🔍 Finding changed files since ...
🎯 Found 3 changed files.
✅ Everything is awesome!
husky > commit-msg

这个出处大家应该都知道,来自 pretty-quick ,然后通过 packge.json 中的:

  "husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
      "pre-commit": "pretty-quick --staged"
    }
  }

这段代码在我们 commit 的时候对代码进行相关处理。

这里是 husky 调用了相关的 Git hooks ,在合适的时机处理我们提交的代码文件,从而使我们的代码达到提交的要求(如上面的是格式化相关代码)。

看到这里肯定大家就会想到,那这个是不是可以做的还有更多?

没错,下面就直接上配置,来实现我们不想让某些代码提交到线上这样的需求。

第一版

知道这个原理,那就很简单了,我们在 pre-commit 这个事件触发的时候对我们要提交代码检查一下,看其中有没有那几个关键字就可以了。

那就直接动手:

我们在项目根目录找到 .git/hooks :

image.png

可以看到,这里提供了各种触发时机,我们找到我们想要的 pre-commit (如果后缀有 .sample,需要去除掉才能让此文件生效)。打开此文件,前端的话应该看到的是(不需要阅读):

#!/bin/sh
# husky

# Hook created by Husky
#   Version: 2.7.0
#   At: 2023/2/2 13:14:26
#   See: https://github.com/typicode/husky#readme

# From
#   Directory: /Users/frank/Documents/work/worktile/wt-cronus/projects/pc-flow-sky/node_modules/husky
#   Homepage: undefined

scriptPath="node_modules/husky/run.js"
hookName=`basename "$0"`
gitParams="$*"

debug() {
  if [ "${HUSKY_DEBUG}" = "true" ] || [ "${HUSKY_DEBUG}" = "1" ]; then
    echo "husky:debug $1"
  fi
}

debug "$hookName hook started"

if [ "${HUSKY_SKIP_HOOKS}" = "true" ] || [ "${HUSKY_SKIP_HOOKS}" = "1" ]; then
  debug "HUSKY_SKIP_HOOKS is set to ${HUSKY_SKIP_HOOKS}, skipping hook"
  exit 0
fi


if ! command -v node >/dev/null 2>&1; then
  echo "Info: can't find node in PATH, trying to find a node binary on your system"
fi

if [ -f "$scriptPath" ]; then
  # if [ -t 1 ]; then
  #   exec < /dev/tty
  # fi
  if [ -f ~/.huskyrc ]; then
    debug "source ~/.huskyrc"
    . ~/.huskyrc
  fi
  node_modules/run-node/run-node "$scriptPath" $hookName "$gitParams"
else
  echo "Can't find Husky, skipping $hookName hook"
  echo "You can reinstall it using 'npm install husky --save-dev' or delete this hook"
fi

看了下,感觉没啥用,就是一个检测 husky 有没有安装的脚本。我们这里直接使用下面的替换掉:

#!/bin/sh

errorForOnly() {
  result=""
  for FILE in `git diff --name-only --cached`; do
      # 忽略检查的文件
      if [[ $FILE == *".html"* ]] ; then
          continue
      fi
      # 匹配不能上传的关键字
      grep 'serial.only\|console.log(\|alert(' $FILE 2>&1 >/dev/null
      if [ $? -eq 0 ]; then
          # 将错误输出
          echo '❌' $FILE '此文件中包含 [only]、[console]、[alert] 中的关键字, 删除后再次提交'
          # exit 1
          result=0
        else
          result=1
        fi
  done

  if [[ ${result} == 0 ]];then
        exit 1
  fi
  echo "✅ All files is OK!"

}

errorForOnly

然后我们在一些文件中添加我们不想要的关键字,然后 git commit :

image.png

可以看到错误日志以及文件已经在命令行中打印出来了,同时文件也没有进入本地仓库(Repository),让然在我们的暂存区(Index)。


使用这个方式,在一定程度上我们避免了提交一些不想要的代码到线上这种情况了发生。同时也是在本地提交代码之前就做了这个事情,也避免了使用服务端 hooks 造成提交历史混乱的问题。

这时候你肯定会产生这样的疑问:

IMG_5160.GIF

【欸,欸,欸,不对啊】

问题

这种方式有个显而易见的问题,那就是不同团队协同方面。由于 hooks 本身不跟随克隆的项目副本分发,所以必须通过其他途径把这些 hooks 分发到团队其他成员的 .git/hooks 目录并设为可执行文件。

另外一个问题是我们使用了 husky,在每次 npm i 之后都会重置 hooks 文件。也就是 .git/hooks/pre-commit 文件恢复到了最初(只有 husky 检测的代码)的样子,没有了我们写的逻辑。

这种情况是不能允许的。那就寻找解决途径。查了下相关文档,发现可以使用新版的 husky 来解决这个问题。(其他相关的工具应该也可以,这里使用 husky 来进行展示)。

最新实现

husky 在 v4 版本之后进行了大的重构,一些配置方式不一样了,至于为什么重构,大家可以去

安装

安装 npm install husky --save-dev

安装最新版本为 8.0.3 ,安装完成后启用 Git hooks: npx husky install

image.png

在团队协作的情景下,得让本团队的其他人也能自动的启用相关 hooks ,所以添加下面这个命令,在每次 npm install 之后执行:

npm pkg set scripts.prepare="husky install"

我们就在 package.json 得到了这样的命令:

image.png

yarn2+ 不支持 prepare 生命周期脚本命令, 安装方式在此处

使用

先按照官方文档测试一下,执行 npx husky add .husky/pre-commit "npm test" 在相关目录我们就看到:

image.png

相应的文件以及内容已经准备就绪。这里就不运行了。

那如何将之前的流程使用新的版本配置好呢?

这里直接提供相关文件内容:

# .husky/commit-msg
# 用于 commit 信息的验证
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx --no -- commitlint --edit $1

使用下面的语句生成;

npx husky add .husky/commit-msg 'npx --no -- commitlint --edit `echo "\$1"`'

另外还有 pre-commit:

# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# pretty-quick 相关
npx pretty-quick --staged

# 验证是否有调试关键字的脚本:
node bin/debugger-keywords.js

脚本内容:

// bin/debugger-keywords.js
const { execSync } = require('child_process');
const fs = require('fs');
const gitLog = execSync('git diff --name-only --cached').toString();
const fileList = gitLog.split('\n').slice(1);
const keyWordsRegex = /(console\.(log|error|info|warn))|(serial\.only)|(debugger)/g;
const result = [];

for (let i = 0; i < fileList.length; i++) {
    const filePath = fileList[i].trim();

    if (filePath.length === 0 || filePath.includes('.husky') || filePath.includes('bin/')) {
        continue;
    }
    const fileContent = fs.readFileSync(`${filePath}`, 'utf8');
    const containerKeyWords = Array.from(new Set(Array.from(fileContent.matchAll(keyWordsRegex), m => m[0])));

    if (containerKeyWords.length > 0) {
        const log = `❌  ${filePath} 中包含 \x1B[31m${containerKeyWords.join('、')}\x1B[0m 关键字`;
        result.push(log);
        console.log(log);
    }
}

if (result.length >= 1) {
    console.log(`💡  修改以上问题后再次提交  💡`);
    process.exit(1);
} else {
    console.log('✅  All files is OK! \n');
    process.exit(0);
}

为几个文件添加 console 、测试 only 等,提交 commit 后效果展示:

image.png

会提示文件中不合规的关键字是哪些。

更多

有了以上的使用示例,我们可以在随意添加脚本,比如,为 19:00 之后或周末提交代码的你来上一杯奶茶🧋和一个甜甜圈🍩:

// bin/check-time.js
const now = new Date()
const week = now.getDay()
const hour = now.getHours()
const validWeek = week >= 1 && week <= 5
const validHour = hour >= 9 && hour < 19
if (validHour && validWeek) return

console.log(`🌃  来点 🧋   🍩`);

这次为了方便也在 pre-commit hook 中执行:

# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# pretty-quick 相关
npx pretty-quick --staged

# 验证是否有调试关键字的脚本:
node bin/debugger-keywords.js

# 来杯奶茶
node bin/check-time.js

来看下结果:

image.png

结论

目前单纯使用 pre-commit hook 针对常见的 console、debugger 还有测试 only 这种。但是我们也可以看到只要我们写不同的脚本,可以实现不同的需求。

之后如果有更多的需求也能继续添加脚本,也可以产生我们 PingCode 自己的 lint 插件。

#文章/world

ps. 如果使用可视化工具提交可能会报错,大家可以自行查阅解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/363202.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 文件相关操作

文件相关操作 编辑文件 命令&#xff1a; vi 文件名 然后输入i进入编辑模式 编辑完成后输入esc退出编辑 输入:wq保存即便目录下没有这个文件&#xff0c;也可以想使用vi 文件名进行编辑&#xff0c;保存退出后会创建这个文件 查看文件内容 命令&#xff1a; cat 文件名复…

UDP报文详解

目录 &#x1f433;今日良言:走好选择的路&#xff0c;别选择好走的路&#xff0c;你才能拥有真正的自己。 &#x1f43c;一、UDP协议特点 &#x1f43c;二、UDP协议段格式详解 &#x1f433;今日良言:走好选择的路&#xff0c;别选择好走的路&#xff0c;你才能拥有真正的自…

PointNet++训练自己的数据集(附源码)

本文针对PointNet强大的三维点云分类功能&#xff0c;详细讲解怎么训练自己的数据集&#xff0c;在此之前&#xff0c;需要确保已经能够跑通源码的训练和测试&#xff0c;如果没有&#xff0c;请参考PointNet的源码运行。数据放置1.1. 在mytensor_shape_names.txt中配置自己的分…

LeetCode-40.组合总和II

目录题目思路回溯法题目来源 40.组合总和II 题目思路 这道题目和39.组合总和如下区别&#xff1a; 本题candidates 中的每个数字在每个组合中只能使用一次。本题数组candidates的元素是有重复的&#xff0c;而39.组合总和是无重复元素的数组candidates 为了理解去重我们来举…

keepalived+LVS配置详解

keepalivedLVS配置详解keepalived简介keepalived的应用场景keepalived工作原理VRRP协议核心组件分层工作工作状态LVS简介LVS三种模式NAT模式(网络地址映射)IPTUN模式(IP隧道)DR模式(直接路由)三种模式对比keepalivedLVS配置1.master配置2. keepalived配置文件3 修改keepalived配…

做主管如何规范测试团队

当你来到一个项目不规范的技术团队&#xff0c;你会怎么处理呢? 问题 Testing 流程不规范 没有需求评审和设计评审&#xff0c;需求经常是业务或者项目经理直接跟开发提&#xff0c;有时候开发自己都不明白需求&#xff0c;糊里糊涂地就要开发&#xff0c;也没有设计评审&…

插画师培训怎么选,5大插画师培训班排名

插画师培训哪里好&#xff0c;给大家推荐5大插画师培训班排名&#xff0c;各有优势和特色&#xff0c;提供大家选择&#xff01; 一&#xff1a;5大插画师培训班排名 1、轻微课&#xff08;五颗星&#xff09; 主打课程有日系插画、游戏原画、古风插画、动漫漫画&#xff0c;以…

UI自动化测试、接口测试等自动化测试策略

今天跟大家介绍UI测试、接口测试、单元测试主要内容&#xff0c;以及每种测试花费时间讨论。 UI测试【Selenium】 UI测试是最接近软件真实用户使用行为的测试类型。通常是模拟真实用户使用软件的行为&#xff0c;即模拟用户在软件界面上的各种操作&#xff0c;并验证这些操作对…

江苏专转本如何事半功倍的备考

专转本如何事半功倍的备考 一个人学习成绩的优劣取决于他的学习能力&#xff0c;学习能力包括三个要素&#xff1a;规范的学习行为&#xff1b;良好的学习习惯&#xff1b;有效的学习方法。有了规范的学习行为才能培养出良好的学习习惯&#xff0c;形成了良好的学习习惯就会形成…

Android - 代码生成远程依赖库(阿里云)

一、注册 没有注册过阿里云且没有实名认证的点这里&#xff1a;阿里云官网 二、查看库 阿里云制品仓库Packages &#xff08;注&#xff1a;如果没有创建企业或个人使用&#xff0c;按照提示&#xff0c;选个人使用&#xff09; 三、选择类型 选择其中一个&#xff08;两…

问题解决篇 | Win11网络连接上了但是无法上网(修改DNS弹出框框“出现问题”,如何通过网络检测确定并修复网络问题)

目录 问题 网络诊断 Win i 打开设置 搜索“查找并修复网络问题”并点击 "远程计算机或设备将不接受连接" 解决办法&#xff1a; Win R&#xff0c;输入 inetcpl.cpl &#xff0c;点击确定&#xff0c;打开Internet选项 选择“连接” 点击“局域网设置” 三个…

vscode下使用arduino插件开发ESP32 Heltec WiFi_Kit_32_V3

下载vsCode 添加 arduino 插件 在Arduino IDE 中添加开发板&#xff0c;注意只能用右侧的开发板管理器添加&#xff0c;自己下载之后复制进去的IDE认&#xff0c;但是vsCode不认&#xff0c;搜索ESP32 第一个库里面只有到V2的&#xff0c;没有V3&#xff0c;要安装下面那个 H…

CDH 6.3.2启用HDFS高可用

启用原因 CDH 6.3.2平台即将用于生产&#xff0c;生产平台几乎需要高可用平台&#xff0c;故需要升级CDH中的HDFS为HA。 启用准备 CDH已经成功安装并正常使用CMS的管理员账号正常登陆 HDFS启用HA 登陆CMS系统->选择HDFS服务->点击进入到HDFS服务详情页面&#xff0c…

CRC冗余校验的原理和FPGA实现思路

CRC校验码&#xff0c;顾名思义是用于校验的。它可以用于检测数据传输过程中是否出现错误&#xff08;某些位&#xff0c;或某几位&#xff0c;或者某块区域位错误&#xff09;&#xff0c;反正 可以知道数据出错了&#xff0c;但是不能纠错。 CRC校验&#xff0c;本质上是模2…

VIIRS-NPP夜间灯光遥感数据下载和预处理

VIIRS-NPP夜间灯光遥感数据下载和预处理 月和年合成产品下载网站 日数据下载网站 一、下载shp掩膜文件 下载好月合成产品后&#xff0c;在这个网站上下载矢量地图&#xff0c; 点击复制按钮&#xff0c;来到这个网站&#xff0c;ctrl v粘贴 点击右上角Export&#xff0c;…

【阿旭机器学习实战】【31】股票价格预测案例--线性回归

【阿旭机器学习实战】系列文章主要介绍机器学习的各种算法模型及其实战案例&#xff0c;欢迎点赞&#xff0c;关注共同学习交流。 注:本文模型结果不好&#xff0c;仅做学习参考使用&#xff0c;提供思路。了解数据处理思路,训练模型和预测数值的过程。 目录1. 读取数据K线图绘…

解决一打开IE浏览器就自动跳转到Edge浏览器的问题

问题说明&#xff1a; 打开Internet Explorer浏览器后会自动跳转到Microsoft Edge浏览器。 解决方法&#xff1a; 打开控制面板&#xff0c;选择“Internet选项”&#xff0c;选择【高级】选项卡&#xff0c;取消勾选“启用第三方浏览器扩展*”即可。

Java之前缀和算法

一.前缀和 1.前缀和介绍 前缀和,顾名思义,就是前n项相加之和,和我们高中时候学习的数列中的一个含义 例如一个等差数组n,那他的前n项和 也可知道- 2.编程中的前缀和 对于一个数组nums,也可以很容易求出它的前缀和数组 public int[] prefix(int[] nums) {int[] prefix …

01 | TDengine3.0部署

1 TDengine简介 TDengine 是一款开源、高性能、云原生的时序数据库&#xff0c;且针对物联网、车联网、工业互联网、金融、IT 运维等场景进行了优化。TDengine 的代码&#xff0c;包括集群功能&#xff0c;都在 GNU AGPL v3.0 下开源。除核心的时序数据库功能外&#xff0c;TD…

因子的有效性检验(IC)

使用神经网络的预测值作为因子载荷&#xff08;因子暴露&#xff0c;因子值 factor&#xff09;时&#xff0c; 我们需要知道这个因子是否是有效的&#xff0c;所以要做因子的有效性检验。 当前的学术论文给出的IC&#xff0c; rankIC 这些都是属于判断因子是否有效的metric 因…