direnv direnv无疑是一个Go工具,因为它是用Go语言编写的,但它并不是一个像我以前的文章中所涉及的开发工具(如版本、ifacecodegen、counterfeiter或retool),然而它是你在开发程序时应该考虑使用的工具之一(实际上是用任何编程语言,不仅仅是Go),特别是如果你构建的程序有不同的二进制依赖或任何其他可以通过环境变量配置的依赖。
什么是direnv?
根据官方网页的介绍。
direnv是对你的shell的一个扩展。它为现有的shell增加了一个新功能,可以根据当前的目录加载和卸载环境变量。
(强调是我说的)
这段描述的主要内容是,当你与你的终端互动时,根据你所在的位置加载/卸载环境变量的强大能力。
为什么使用direnv是相关的?
考虑一下下面的假设情况。你正在构建的东西恰好依赖于一个工具来生成一些代码,让我们把它称为tool (v1) ,一段时间后,你开始在一个新项目上工作,这个新项目使用相同的工具,但不同的版本tool (v2) ,但与v1相比,它生成代码的方式不同。安装v1 会与v2 冲突(反之亦然),因为这两个工具都会生成不兼容的工件。
在Go的上下文中,处理这样的依赖关系很容易用Go模块来管理,然而我们的实际运行时间需求呢?我的意思是什么呢?如果我们依赖tool (v1) ,那么我们就需要在我们的PATH 中安装和使用它,同样的,tool (v2) 。
我们如何处理这种冲突?更重要的是,我们如何去让这些工具进入沙盒?
引入direnv
这就是direnv ,它允许我们对碰巧使用环境变量作为配置选项的东西进行沙盒处理,最常见的例子是创建具体的PATH 变量,使其碰巧与你的工作目录相对,其想法是只有安装在我们文件夹内的二进制文件才会被使用。有了这种配置,direnv ,就可以清楚地定义一个只适用于我们所在的文件夹的边界。
官方Github仓库包括安装和使用它的具体步骤,它的工作原理是这样的。
- 在你希望配置适用于当前目录和其他子目录的地方创建一个新的
.envrc文件,并且 - 配置该
.envrc,以定义你想应用的指令。
例如,使用我们上面的假设场景,当在project1 (使用tool (v1) )上工作时,在父目录上我们可以定义.envrc ,如下所示。
PATH_add bin
export GOBIN=$PWD/bin
这表示direnv 。
- 要更新
PATH,以指向当前工作目录下的bin/,并且。 - 也要导出
GOBIN,使之也指向该路径。
我们的想法是,当我们go install tool (v1) ,它将被安装在bin/ **,**当我们试图执行它时,它将在同一路径下可用。
如果我们为project2 (使用tool (v2) )创建一个类似的.envrc ,结果也会类似。在实践中,这意味着现在两个项目都可以引用同一个工具的不同版本,而不会相互冲突。这是一个强大的功能。
总结
我怎么推荐direnv ,它是这样一个简单而强大的工具,应该可以改善你的开发经验。
试试吧,你不会失望的。