You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// lib/installer/bin.js// Get INIT_CWD env variablefunctiongetInitCwdEnv(){const{INIT_CWD}=process.env;if(INIT_CWD===undefined){const{ name, version }=which_pm_runs_1.default();thrownewError(`INIT_CWD is not set, please check that your package manager supports it (${name}${version})Alternatively, you could set it manually:INIT_CWD="$(pwd)" npm install husky --save-devOr upgrade to husky v5`);}debug_1.debug(`INIT_CWD is set to ${INIT_CWD}`);returnINIT_CWD;}functionrun(){constaction=process.argv[2];try{if(action==='install'){checkSkipInstallEnv();checkGitVersion_1.checkGitVersion();}constINIT_CWD=getInitCwdEnv();constuserPkgDir=getUserPkgDir(INIT_CWD);checkGitDirEnv_1.checkGitDirEnv();const{ absoluteGitCommonDir, relativeUserPkgDir }=getDirs(userPkgDir);if(action==='install'){const{name: pmName}=which_pm_runs_1.default();_1.install({
absoluteGitCommonDir,
relativeUserPkgDir,
userPkgDir,
pmName,isCI: ci_info_1.isCI,});}else{_1.uninstall({ absoluteGitCommonDir, userPkgDir });}console.log(`husky > Done`);}(err){}}
// lib/installer/index.jsfunctioninstall({ absoluteGitCommonDir, relativeUserPkgDir, userPkgDir, pmName,// package manager name
isCI,}){// Get conf from package.json or .huskyrcconstconf=getConf_1.getConf(userPkgDir);// Create hooks directory if it doesn't existconstgitHooksDir=getGitHooksDir(absoluteGitCommonDir);// 判断.git/hooks目录是否存在,如果不存在则创建if(!fs_1.default.existsSync(gitHooksDir)){fs_1.default.mkdirSync(gitHooksDir);}// 创建commit-msg等一系列hookhooks_1.createHooks(gitHooksDir);// 往.git/hooks目录内生成husky.local.sh脚本,用于执行husky具体命令localScript_1.createLocalScript(gitHooksDir,pmName,relativeUserPkgDir);// 往.git/hooks目录内生成husky.sh脚本,用于执行husky具体命令mainScript_1.createMainScript(gitHooksDir);}functionuninstall({ absoluteGitCommonDir, userPkgDir,}){if(isInNodeModules(userPkgDir)){console.log('Trying to uninstall from node_modules directory, skipping Git hooks uninstallation.');return;}// Remove hooksconstgitHooksDir=getGitHooksDir(absoluteGitCommonDir);hooks_1.removeHooks(gitHooksDir);localScript_1.removeLocalScript(gitHooksDir);mainScript_1.removeMainScript(gitHooksDir);}
install成功之后,我们可以在.git/hooks内看到生成的hook,如下图所示
具体的hook内容如下所示
#!/bin/sh# husky# Created by Husky v4.3.8 (https://github.com/typicode/husky#readme)# At: 2022-4-2 2:37:25 ├F10: PM┤# From: xxxx/node_modules/husky (https://github.com/typicode/husky#readme)."$(dirname "$0")/husky.sh"
functionrunCommand(cwd,hookName,cmd,env){console.log(`husky > ${hookName} (node ${process.version})`);const{ status }=child_process_1.spawnSync('sh',['-c',cmd],{
cwd,env: Object.assign(Object.assign({},process.env),env),stdio: 'inherit',});if(status!==0){constnoVerifyMessage=['commit-msg','pre-commit','pre-rebase','pre-push',].includes(hookName)
? '(add --no-verify to bypass)'
: '(cannot be bypassed with --no-verify due to Git specs)';console.log(`husky > ${hookName} hook failed ${noVerifyMessage}`);}// If shell exits with 127 it means that some command was not found.// However, if husky has been deleted from node_modules, it'll be a 127 too.// To be able to distinguish between both cases, 127 is changed to 1.if(status===127){return1;}returnstatus||0;}
目录
背景
基于react开发了一套通用模版,在模版内集成了,通用的eslint、prettier等规则,结合huksy+lintstaged来做代码质量与规范的检查,husky选用的是4.3.8版本,package.json如下图所示;
主要使用到husky的两个钩子
pre-commit
与commit-msg
但是在部分同事的电脑上,install之后,huksy没有初始化成功,也没有错误提示,导致无法正常使用husky的功能,为了彻底解决这个问题,决定去看一下husky的内部实现
husky4.3.8源码分析
husky是在install的时候,往.git/hooks目录下注入对应的commit钩子,那么先看package.json
关键上面这三个script hook
先看
postinstall
这个钩子就是做了一些辅助工具,无需关注重点是
install
这个钩子,install这个钩子做的事情如下检查git版本 => 从环境变量INIT_CWD中获取到当前工作目录 => 创建各种git hook => 创建husky.local.sh 与 husky.sh 用于具体执行huksy命令的脚本
初始化准备工作
在执行install or uninstall之前会做一些当前工作目录及git版本的检查,这里两个地方会中断执行,导致install失败
创建hook
当满足上述条件之后,就会执行对应的install or unstall方法
install成功之后,我们可以在.git/hooks内看到生成的hook,如下图所示
具体的hook内容如下所示
到这里我们基本已经知道为什么部分电脑husky不生效,原因主要就是git版本低于指定的2.13.0版本,还有就是无法从环境变量中获取到INIT_CWD
排查错误并手动执行install
这里把husky内的debug日志开启,便于排查问题
所以当我们提示的是git版本低于要求版本时,则可以通过升级git版本来解决该问题
husky执行命令实现
通过shell方式执行,然后通过status来判断成功还是失败,所以如果我们自己自定义了一些工具,那么如果需要借助huksy来执行,出现错误的场景,一定需要通过process.exit(code)把code向上传递出来
总结
husky的runCommand执行方式值得我们在写类似工具时借鉴一二,另外就是为什么我们在install的时候,husky如果初始化失败,为什么没有中断整个install流程?后续有时间在去了解下这里
The text was updated successfully, but these errors were encountered: