# 记录一次代码提交前的拦截操作

背景

由于一次路由地址的改动,从而其他系统无法正确跳转,导致引发线上事故.故而希望在代码提交之前,判断如果修改了路由文件,则给出警告提示,这样也降低了新人接手项目时出错的概率.

思路

由于之前做过代码提交前的 eslint 格式审查功能,因此首先想到的便是同样方式,在代码 commit 之前执行脚本操作.

尝试

新增脚本文件 test.sh :
echo "hello world";exit 1

1. husky + lint-staged

husky: git hooks,提供 git 各种操作的钩子,如 pre-commit, pre-merge-commit, pre-push 等.
lint-staged: 一个在 git 暂存区运行 linters 的工具.因为只需要对改动的文件做拦截,因此引入.
首先安装两个 package
npm i husky lint-staged -S -D
安装成功之后在 package.js 中配置:

  "husky": {
    "pre-commit": "lint-staged"
  },
  "lint-staged": {
    "*": ["./test.sh"]
  }
复制代码

这里我的期望是在 commit 的时候被 pre-commit 钩子拦截然后执行 lint-staged 配置好的脚本 test.sh. 正常的话控制台会输出 hello world .

husky > pre-commit (node v14.15.1)
✔ Preparing...
✔ Hiding unstaged changes to partially staged files...
❯ Running tasks...
  ❯ Running tasks for *
    ⠇ ./routerRule.sh
◼ Applying modifications...
◼ Restoring unstaged changes to partially staged files...
◼ Cleaning up...
复制代码

然鹅事情没有我想的那么简单.简单分析: 正常触发 pre-commit 钩子,但是在执行 test.sh 脚本的时候卡住了.
调整姿势,尝试在触发 pre-commit 钩子后直接执行脚本,修改配置文件:

  "husky": {
    "hooks": {
      "pre-commit": "./routerRule.sh"
    }
  },
复制代码

尝试提交 commit 控制台输出如下:

hello world
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! xxx xxx: `./test.sh`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the xxx test-router script.

![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e06e944a427f43cdbb77718b2b04f85f~tplv-k3u1fbpfcp-watermark.image)
husky > pre-commit hook failed (add --no-verify to bypass)
复制代码

可以看出,因为脚本非0 退出,因此成功拦截,符合预期,可以进行下一步.
思考: 为什么在 pre-commit 钩子里能正常执行却在 lint-staged 内执行异常?这里我也不知道具体原因,猜测是因为 lint-staged 环境问题导致.

2. 去掉 lint-staged

由于在 lint-staged 内执行脚本异常,因此尝试用代码来获取 git 暂存区文件,以路由页面为例,代码为STAGE_FILES=$(git diff --cached --name-only --diff-filter=ACM -- './src/router/')
test.sh 脚本全部代码为:

STAGE_FILES=$(git diff --cached --name-only --diff-filter=ACM -- './src/router/')

if [ ! -n "${STAGE_FILES}" ]
  then exit 0
fi

echo "修改的路由文件:\n${STAGE_FILES[0]}"

SHAN='\E[33;5m'

for((i=0;i<=5;i++))
do
  printf  "${SHAN} 注意: 修改路由地址可能会导致其他平台跳转失败(尽量考虑新增路由而不是修改)!!!\n"
done

read -n1 -p "确定修改路由文件? [y/n]" doit < /dev/tty
if [ ${doit} == 'y' ];then exit 0; else exit 1; fi
复制代码

修改路由文件提交测试:

husky > pre-commit (node v14.15.1)
修改的路由文件:
src/router/index.ts
src/router/userInfo.ts
 注意: 修改路由地址可能会导致其他平台跳转失败(尽量考虑新增路由而不是修改)!!!
 注意: 修改路由地址可能会导致其他平台跳转失败(尽量考虑新增路由而不是修改)!!!
 注意: 修改路由地址可能会导致其他平台跳转失败(尽量考虑新增路由而不是修改)!!!
 注意: 修改路由地址可能会导致其他平台跳转失败(尽量考虑新增路由而不是修改)!!!
 注意: 修改路由地址可能会导致其他平台跳转失败(尽量考虑新增路由而不是修改)!!!
 注意: 修改路由地址可能会导致其他平台跳转失败(尽量考虑新增路由而不是修改)!!!
确定修改路由文件? [y/n]
复制代码

按预期执行了脚本并提示修改,输入 y 提交成功!

总结

  • 本文 husky 测试版本为 4.x, 高版本可能无效
  • 脚本非 0 输出即为失败
  • 控制台没有出现用户输入交互,需要添加指令 < /dev/tty ,详细信息点击这里
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享