十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Lefthook `rc` 配置项完全指南:为 GUI 触发的 Git Hooks 注入环境变量

Lefthook `rc` 配置项完全指南:为 GUI 触发的 Git Hooks 注入环境变量 Lefthookrc配置项完全指南为 GUI 触发的 Git Hooks 注入环境变量【免费下载链接】lefthookFast and powerful Git hooks manager for any type of projects.项目地址: https://gitcode.com/GitHub_Trending/le/lefthook导读Lefthook 是面向任意类型项目的快速、强大的 Git Hooks 管理器。当你通过终端运行 Git 命令时hook 脚本继承的是你当前 shell 的环境变量但当你使用 VSCode 等 GUI 程序触发 Git 操作时hook 运行在一个干净的非 shell 环境中~/.bashrc、~/.zshrc中的$PATH扩展如 nvm、rbenv、fnm 管理的可执行文件路径完全不可用常常导致command not found。Lefthook 的顶层rc配置项正是为此而生它允许你指定一个简单的sh脚本作为 rc 文件在 hook 被触发时先行加载从而为 GUI 启动的 hook 进程注入正确的环境变量。读完本文你将掌握rc的配置语法、路径写法、加载时机与底层实现原理彻底解决 GUI 环境下 hook 找不到可执行文件的问题。rc是什么一个被 hook 加载的sh脚本rc是 Lefthook 的顶层配置项与pre-commit、pre-push等 hook 配置平级其作用在官方文档中的定义是Provide an rc file, which is actually a simpleshscript. Currently it can be used to set ENV variables that are not accessible from non-shell programs.即rc指向一个简单的sh脚本它的典型用途是设置那些从非 shell 程序中不可访问的环境变量。注意这里的非 shell 程序正是下面要说的 GUI 程序。在配置结构中rc是一个字符串字段。从源码可见其定义internal/config/config.goRc string json:rc,omitempty jsonschema:descriptionProvide an rc file - a simple sh script mapstructure:rc,omitempty同时它也收录在配置 JSON Schema 中internal/config/jsonschema.json因此支持 IDE 自动补全与配置校验。为什么需要rcGUI 程序触发 hook 的痛点当 hook 由 GUI 程序如 VSCode触发时环境通常存在以下问题GUI 程序运行的 git hooks 不加载你的 shell rc 文件你在~/.bashrc、~/.zshrc或~/.profile里设置的$PATH追加、export等都不生效你引用的可执行文件只能从被调整过的$PATH中访问典型如 rbenv、nvm、fnm 安装的 Ruby / Node 版本管理器其可执行文件位于版本目录下如~/.nvm/versions/node/v15.14.0/bin/npm默认$PATH中根本没有极端情况下GUI 程序甚至找不到lefthook可执行文件本身此外你还可能希望在lefthook.yml中使用能控制可执行程序行为的环境变量。rc正是针对这些场景的统一补丁点在 hook 脚本执行的一开始就加载 rc 脚本把环境补齐再运行后续的 Lefthook 命令。配置rc路径与写法rc推荐配置在lefthook-local.yml本地配置中因为它属于个人环境相关设置不适合提交到团队共享的lefthook.yml。当然作为顶层配置项它同样可以出现在主配置中。基本写法指向绝对路径的 rc 文件# lefthook-local.yml # You can choose whatever name you want. # You can share it between projects where you use lefthook. # Make sure the path is absolute. rc: ~/.lefthookrc要点rc 文件名可以任意指定.lefthookrc、lefthookrc、rc等均可你可以在多个使用 Lefthook 的项目之间共享同一个 rc 文件路径必须是绝对路径——因为 hook 脚本由 Git 在仓库根目录触发相对路径不可靠。~由 shell 展开为$HOME。包含空格或环境变量的路径务必加引号如果你的路径包含空格或希望通过变量拼接路径需要用引号包住整个值# lefthook-local.yml # If the path contains spaces, you need to quote it. rc: ${XDG_CONFIG_HOME:-$HOME/.config}/lefthookrc注意这里采用了双层引号的写法外层是 YAML 字符串内层是sh语法中的引号。最终 hook 模板中生成的是[ -f ${XDG_CONFIG_HOME:-$HOME/.config}/lefthookrc ] . ${XDG_CONFIG_HOME:-$HOME/.config}/lefthookrc交由/bin/sh执行时内部的${XDG_CONFIG_HOME:-$HOME/.config}会被 shell 正确展开从而在$XDG_CONFIG_HOME已设置时使用它否则回退到$HOME/.config。这一写法同时演示了rc 值中可以使用 shell 语法因为最终它会被嵌入到 sh 脚本中执行。编写 rc 文件导出或修改环境变量rc 文件本质上就是一个sh脚本。在 rc 文件中你可以export新的环境变量或修改已存在的变量最典型的是$PATH。nvm 方式# ~/.lefthookrc # An nvm way export NVM_DIR$HOME/.nvm [ -s $NVM_DIR/nvm.sh ] \. $NVM_DIR/nvm.sh[ -s file ]判断文件存在且非空\.是 POSIX sh 中source的等价写法等价于.反斜杠仅用于避免某些 shell 的别名干扰。加载nvm.sh后nvm函数及其管理的 node 可执行文件路径即被注入环境。fnm 方式# An fnm way export FNM_DIR$HOME/.fnm [ -s $FNM_DIR/fnm.sh ] \. $FNM_DIR/fnm.sh直接追加 PATH如果只是想补充某个二进制目录更简单的方式是直接修改$PATH# Or maybe just PATH$PATH:$HOME/.nvm/versions/node/v15.14.0/binrc 脚本中所有对环境变量的修改在脚本被.source加载后都会保留在当前 hook 进程环境中从而对后续的lefthook run及其子命令可见。一个完整的实战案例假设你使用 nvm 管理 Node.jsnpm只存在于 nvm 版本目录中# 在终端里执行 $ which npm /home/user/.nvm/versions/node/v15.14.0/bin/npm你的lefthook.yml中有一个依赖npm的命令# lefthook.yml pre-commit: commands: lint: run: npm run eslint {staged_files}如果 hook 由 VSCode 等 GUI 程序触发npm很可能找不到。此时只需提供 rc 文件让 hook 像你在~/.shellrc中一样调整环境# lefthook-local.yml rc: ~/.lefthookrc# ~/.lefthookrc export NVM_DIR$HOME/.nvm [ -s $NVM_DIR/nvm.sh ] \. $NVM_DIR/nvm.sh然后重新安装 Git Hooks这一步非常关键见下文$ lefthook install -f从此任何运行你 hooks 的程序无论终端还是 GUI都会先加载被调整过的环境nvm/npm即可正常访问。底层原理rc 如何被注入 hook 脚本安装时的模板渲染rc之所以能生效关键在于hook 脚本的生成过程。当你运行lefthook install时Lefthook 读取配置含rc字段将其作为模板参数传给 hook 模板渲染internal/command/install.gotemplateArgs : templates.Args{ Rc: cfg.Rc, AssertLefthookInstalled: cfg.AssertLefthookInstalled, Roots: roots, LefthookPath: cfg.Lefthook, } if err l.addHook(hook, templateArgs); err ! nil { return fmt.Errorf(could not add the hook: %w, err) }模板参数经由 internal/templates/templates.go 传入hook.tmpl渲染。hook 模板中的加载语句在 hook 模板internal/templates/hook.tmpl中rc 被渲染为一行 source 语句且位置在 hook 逻辑的最前面#!/bin/sh if [ $LEFTHOOK_VERBOSE 1 -o $LEFTHOOK_VERBOSE true ]; then set -x fi if [ $LEFTHOOK 0 ]; then exit 0 fi {{- if .Rc}} {{/* Load rc file, which may export ENV variables */}} [ -f {{.Rc}} ] . {{.Rc}} {{- end}} call_lefthook run {{.HookName}} $渲染后实际生成的行是[ -f ~/.lefthookrc ] . ~/.lefthookrc这段代码的含义与它体现的健壮性设计值得展开[ -f path ]先判断 rc 文件是否存在。如果文件不存在整条命令短路返回真值左侧失败则右侧不执行hook 照常运行不会因 rc 缺失而报错——这正是 rc 文件可以按需存在的原因. pathPOSIX sh 的 source 命令将 rc 脚本在当前的 hook 进程内执行而不是启动子进程。这是环境变量能够留下来传给后续call_lefthook调用的关键——如果用sh script.sh方式执行export 的变量在子进程退出后就丢失了位置在call_lefthook run ...之前确保 rc 设置的环境对 Lefthook 本体及其运行的所有命令可见。为什么必须重新运行lefthook install -frc 的生效依赖 hook 模板渲染而hook 文件是在lefthook install时生成的。如果你修改了配置新增/变更rc却没有重新安装.git/hooks/pre-commit等文件仍是旧版本不含[ -f ... ] . ...这一行。-f--force标志会覆盖已有的 hook 文件internal/command/install.go 中cleanHook(hook, force)的逻辑即使 hook 已被修改也会重新生成。因此文档强调Make sure you updated git hooks. This is important.$ lefthook install -f另外值得了解的是Lefthook 会为配置计算 MD5 校验和internal/config/config.go用于在后续运行中检测配置变化并提示是否需要重新安装 hooks这也是rc变更后建议立刻install -f的原因。rc与其他环境方案的关系在 env.md 文档中还有另一种为单个命令注入环境变量的方式——env配置项它允许你为某个 command 或 script 指定环境变量# lefthook.yml pre-commit: commands: test: env: RAILS_ENV: test run: bundle exec rspec以及针对 PATH 的局部扩展# lefthook-local.yml pre-commit: commands: test: env: PATH: $PATH:/home/me/path/to/yarn两者定位不同方案作用域适用场景rc本文所有 hook、所有命令全局GUI 环境缺$PATH、缺lefthook可执行文件、需要加载 nvm/fnm/rbenv 等版本管理器env命令级单个 command/script为特定命令设置专属环境变量或追加单个可执行文件目录如果你的需求只是某个命令多一个二进制目录用env更精准如果问题是整个 GUI 环境都不对rc是全局解决方案。二者可以同时使用rc先铺底修正全局环境env再为个别命令做精细化配置。常见问题与注意事项rc 文件不存在时会怎样不会报错。hook 模板使用[ -f ... ] . ...做了存在性判断缺失 rc 时 hook 正常执行只是环境未做调整。路径里能写环境变量吗可以。rc 值最终被嵌入sh脚本因此${VAR}、$(command)等 shell 语法都会在 hook 执行时展开如上面XDG_CONFIG_HOME的例子但要注意外层引号的配对。能分享给其他项目吗可以。rc 文件独立于项目可在多个使用 Lefthook 的项目间共享也正因如此它更应放在lefthook-local.yml中而非提交进仓库的共享配置。为什么一定要绝对路径因为 hook 由 Git 在任意工作目录下触发只有绝对路径含~展开才能保证定位正确。修改了rc配置后别忘了lefthook install -f否则新配置不会渲染进已安装的 hook 文件。小结rc是 Lefthook 解决GUI 程序触发 hook 时环境缺失问题的关键配置它在lefthook-local.yml中指向一个简单的sh脚本推荐~/.lefthookrclefthook install时被渲染进每个 hook 模板见 internal/templates/hook.tmpl通过[ -f ... ] . ...在 hook 执行前 source 该脚本从而把 nvm/fnm/rbenv 等版本管理器的路径或任意自定义环境变量注入当前进程保证 VSCode 等 GUI 环境下npm、lefthook等可执行文件依然可用。配置后请务必执行lefthook install -f重新生成 hooks让rc真正生效。【免费下载链接】lefthookFast and powerful Git hooks manager for any type of projects.项目地址: https://gitcode.com/GitHub_Trending/le/lefthook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表