一种优雅的开发环境洁癖解决方案
我是一个有“洁癖”的工程师。我无法忍受我的源代码目录里,混杂着 __pycache__、.pytest_cache,以及各种虚拟环境工具(如 .venv, .pixi)生成的、动辄几百 MB 的“垃圾”。.gitignore 是一个伟大的发明,但它只是“眼不见为净”——这些文件依然物理地躺在我的项目文件夹里。
这在平时没什么,但当某些场景出现时,这种“同居”状态就变得无法忍受。比如,我最近在用一个自研的 snapshot 工具,它是一个 Web 应用,是通过文件上传弹窗来选择项目目录用来生产 AI 可以消费的snapshot.md文件用于通过 ai 迅速了解一个项目的大概情况并让 ai 获悉项目的结构和细节等信息的工具,并且可以递归解析.gitignore 文件并为每个文件夹独立解析。问题来了:浏览器和 Node.js 的文件 API,根本不鸟 .gitignore!
每次为了生成一个干净的代码快照,我都必须手动地、临时地将 .pixi 文件夹移出去,完事后再移回来。这太蠢了,不仅麻烦,而且极易出错。我忍不了了。我必须找到一个一劳永逸的解决方案。
失败的尝试:复杂的符号链接
我最初的想法很复杂。我想建立一个“纯净”的 src 目录和一个“肮脏”的 work 目录,然后在 work 目录里,为 src 目录下的每一个文件和文件夹,都创建一个符号链接。
这个方案很快就暴露了致命缺陷:.git 目录怎么办?如果链接了 .git,那么 work 目录里生成的新文件就会污染 git status;如果不链接 .git,git 命令又无法在 work 目录里正常工作。这是一个无法调和的矛盾。
我意识到,我把问题想得太复杂了。我试图用复杂的“魔法”去解决一个只需要“物理”就能解决的问题。
顿悟:从“链接源码”到“链接环境”
问题的根源,是 .pixi 这个“肮脏”的环境目录,物理地出现在了我的项目文件夹里。那我为什么不直接把它“请”出去呢?
于是,我“重新发明”了一个极其简单、粗暴,但优雅到极致的解决方案。我称之为**“环境外置化 (Environment Externalization)”**。
整个流程,只需要四行命令:
1 | # 假设我们已经 clone 了一个项目,并 cd 了进去 |
成功了。
这套方案为什么是无敌的?
让我们来分析一下这套操作的精妙之处:
物理隔离: 包含了虚拟环境、编译产物的
.pixi文件夹,现在物理地存在于项目目录的外部。任何不遵守.gitignore的工具(比如我的snapshot工具、操作系统的文件搜索),都再也看不到它了。我的源代码目录,终于实现了物理意义上的“纯净”。无缝欺骗: 我们在原地留下了一个名为
.pixi的符号链接。对于pixi工具本身来说,一切都没有变。它依然在当前目录找到了它期望的.pixi,然后愉快地、毫无察觉地,顺着链接跑到项目目录外面去工作。所有的依赖安装、命令执行,都和以前一模一样。Git 友好:
.gitignore文件里,我们早就写了.pixi。Git 在处理时,会直接忽略掉这个符号链接,git status永远是一片干净。
固化为最佳实践
为了让这个流程可复现,我们可以把它封装成一个简单的 setup_workspace.sh 脚本,放在项目的 scripts/ 目录下:
1 |
|