为项目提供目录级 PowerShell 配置。进入目录时加载 .ps.envrc 中的环境变量、普通变量、函数和别名,离开时恢复原有状态。支持父子目录逐层覆盖,适用于 Windows、Linux 和 macOS,需要 PowerShell 7.4 或更高版本。
在 PowerShell 7.4 或更高版本中运行以下命令,从 PowerShell Gallery 安装。
Install-Module -Name Napreth.PSDirEnv -Scope CurrentUser-Scope CurrentUser 指定只为当前用户安装。省略时,默认安装范围会受 PowerShellGet 版本和是否以管理员身份运行影响。
也可以从本仓库的 Releases 下载 .nupkg 安装包,按下面的步骤手动安装。
Windows 上先对下载的文件运行 Unblock-File ./Napreth.PSDirEnv.0.1.0.nupkg。将 .nupkg 扩展名改为 .zip 并解压,删除 NuGet 元数据 _rels/、package/、[Content_Types].xml 和 Napreth.PSDirEnv.nuspec,保留模块文件、README 和许可证。
用下面的命令查看模块搜索目录,从中选择当前用户的模块目录。
$env:PSModulePath -split [IO.Path]::PathSeparator在该目录下创建 Napreth.PSDirEnv/<版本号>/,将保留的文件放进去。以 0.1.0 为例,目录结构应如下,.psd1 和 .psm1 直接位于版本目录中。
<当前用户的模块目录>/
└── Napreth.PSDirEnv/
└── 0.1.0/
├── Napreth.PSDirEnv.psd1
├── Napreth.PSDirEnv.psm1
├── README.md
├── LICENSE
├── THIRD_PARTY_NOTICES.md
└── LICENSES/
在 $PROFILE 中导入并启用模块。使用 Oh My Posh、Starship 或自定义 prompt 时,将这两行放在提示符初始化之后。
Import-Module Napreth.PSDirEnv
Enable-DirEnv项目根目录的 .ps.envrc 使用 UTF-8 编码和普通 PowerShell 语法。下面的 Node.js 配置将项目的可执行文件加入 PATH,并提供构建、测试命令。
$env:NODE_ENV = 'development'
$env:PATH = (Join-Path $PSScriptRoot 'node_modules' '.bin') + [IO.Path]::PathSeparator + $env:PATH
$ProjectName = 'MyProject'
function Build-Project {
npm run build @args
}
function Test-Project {
npm test @args
}
Set-Alias build Build-Project
Set-Alias test Test-Project审阅脚本后,在项目目录运行 Approve-DirEnv,配置会立即生效。此后每次显示 prompt 时自动检查目录和文件内容。修改 .ps.envrc 后需要重新授权,删除文件则卸载对应配置。
| 命令 | 作用 |
|---|---|
Enable-DirEnv |
启用自动加载并立即刷新 |
Disable-DirEnv |
卸载配置并恢复原来的 prompt |
Approve-DirEnv |
授权 .ps.envrc 当前内容并刷新 |
Revoke-DirEnv |
撤销授权并卸载该文件及其子层 |
Update-DirEnv |
按当前位置手动刷新 |
Update-DirEnv -Force |
重新加载,或重试失败的脚本 |
Get-DirEnv |
查看加载状态和最近一次刷新结果 |
Approve-DirEnv 和 Revoke-DirEnv 默认针对当前目录,可用 -Path 指定目录或 .ps.envrc 文件,支持 -WhatIf 和 -Confirm。授权只针对指定文件,父目录和子目录需要各自授权。
Get-DirEnv 返回最近一次刷新结果,文件状态包括 Unapproved、Blocked、Loaded 和 Failed。需要即时检查时先运行 Update-DirEnv。授权记录保存在用户数据目录,可通过 Enable-DirEnv -StatePath 指定其他位置;切换前先运行 Disable-DirEnv。
模块沿当前目录的祖先链查找 .ps.envrc,按父目录到子目录的顺序加载。父层必须获得授权并成功执行,子层才会生效。退出子目录时恢复父层,退出项目时恢复原始会话;在共用同一份配置的目录间切换不会重复执行脚本。
卸载时,只恢复仍等于该层所设值的项目。进入目录后手动修改的变量、函数或别名会保留;如果手动设置的值与配置相同,模块无法区分两者。所有环境变量修改都限定在当前进程。
授权绑定文件路径和 SHA-256,检查与执行使用同一次读取的内容。解析错误、未处理的非终止错误或异常会触发本次加载的回滚,保留已加载的父层并阻止子层。同一份失败内容不会在每次显示 prompt 时重试,可用 Update-DirEnv -Force 主动重试。配置读取失败或授权数据库损坏时,已有配置会卸载并报告错误。
自动刷新发生在下一次 prompt 显示之前。同一条命令中切换目录并立即运行程序时,需要主动刷新,例如 Set-Location ./project; Update-DirEnv; npm run dev。脚本中切换目录也遵循这一规则。
.ps.envrc 在临时模块中执行,顶层变量、函数和别名会发布到交互会话,无需使用 global:。函数保留对原模块变量的引用,$PSScriptRoot 和 $PSCommandPath 指向原始文件。执行时的工作目录是该文件所在目录,结束后恢复原位置。局部 $ErrorActionPreference 默认为 Stop,不会发布到全局。
普通变量发布的是值绑定。在交互会话中重新赋值,不会同步修改函数所在模块的同名变量;需要共享变化的状态时,可显式使用全局变量或共享对象。数组、字典和对象的原地修改不做深度复制,顶层变量的类型约束等自定义属性也不会复制到全局。
受管理的状态包括环境变量和普通变量、函数、别名的新增、覆盖与删除。自动变量、PSDefaultParameterValues、模块导入、补全器、PSDrive 和事件订阅不在其中。prompt、模块公开命令以及以 Pde 开头或包含 -Pde 的名称由模块保留;配置中请勿使用 Constant、AllScope 定义或 Export-ModuleMember。
授权后的脚本可以执行任意 PowerShell 代码。文件操作、外部程序及其他副作用无法回滚,脚本加载的其他文件也不在授权哈希中。如果启用后替换了 prompt,先运行 Disable-DirEnv,再重新启用。移除模块同样会卸载配置并清理 hook。
提示文案和配色沿用 direnv,前缀为 psdirenv:。错误使用红色,普通状态提示使用终端默认色;TERM=dumb、非空 NO_COLOR、$PSStyle.OutputRendering = 'PlainText' 或不支持 ANSI 的终端使用纯文本。
变更摘要中的 +、~、- 分别表示新增、修改和移除。环境变量直接显示名称,普通变量带 $,函数和别名分别带 function:、alias: 前缀。摘要只显示名称,不显示值。
提示写入 PowerShell 信息流,不影响命令或 prompt 的返回值。Update-DirEnv -Quiet 和 Disable-DirEnv -Quiet 可以关闭对应操作的提示,-InformationVariable 可以收集提示。相同的阻止或失败提示只报告一次,-Force 会清除去重记录。参考项目见 THIRD_PARTY_NOTICES.md,许可证见 LICENSES/direnv-LICENSE。
打包需要 Microsoft.PowerShell.PSResourceGet 1.1.0 或更高版本。build.ps1 先在无 profile 子进程中运行测试,再将模块、README 和许可证打包到 dist/。加上 -Publish 可发布到已注册的仓库。
./build.ps1
./build.ps1 -Publish发布仓库名依次从 -Repository 参数、PS_DIRENV_REPOSITORY 环境变量、项目根目录 .env 读取。仓库须事先通过 Register-PSResourceRepository 注册,地址由 PowerShell 的仓库配置管理。发布所需的 API Key 从环境变量或 .env 中的 PS_DIRENV_API_KEY 读取,配置格式见 .env.example。.env 只读取配置值,不执行代码或展开表达式,也不会进入版本控制和包文件。
打包使用模块清单中的版本,不自动递增。重新发布同版本的本地包时,运行 ./build.ps1 -Publish -Force;-Force 仅用于替换本地仓库中的包。
测试使用临时目录和独立授权记录,结束后自动清理。建议在无 profile 的进程中运行。
pwsh -NoLogo -NoProfile -File ./tests/Run-Tests.ps1