4

最近,我一直在深入研究 powershell 模块和清单的一些更高级的功能,以处理比一些功能的基本导出更高级的场景。听起来应该很明显,但我正在努力寻找一个很好的解决方案来在几个大型非平凡模块之间共享常见的“帮助”类型函数。特别是,我正在寻找一种解决方案:

  • 允许共享“助手”类型的功能,而不必由任何人导出
  • 允许从本地 repo 路径通过 PsGet 安装

让我谈谈我看到的一些挑战。

首先,据我所知,PsGet不能很好地处理模块依赖关系这意味着模块之间的共享将是一场斗争。也许对此的解决方案是避免使用 PsGet,并使用自定义脚本将模块“安装”到本地模块路径,这可能更能容忍依赖关系和加载顺序。

我关于不使用模块导出来共享辅助函数的观点似乎也是一个问题。我可以看到的原因是希望别名、助手等用于常见的内部操作(在有用的函数中需要),这些操作要么是无用的,要么是不安全的。例如,用于获取本地脚本路径的简短别名(常用,比它应该的更嘈杂)。或者我最近用更少的选项围绕 PromptForChoice 做了一个简单的包装器。也许这整件事都不是一个真正的问题。但我不禁觉得,发布一个“utils”模块,它导出在真实模块中有用但对最终用户有用的低级函数,似乎是错误的方式。

我一直在玩的是一个小型构建结构,它可以测试然后打包模块,我希望能够实现一些代码共享。我一直在寻找在清单中使用 ScriptsToProcess 的替代方法,但这些似乎是绝对路径,而不是相对路径。

想象一个文件夹结构:

  • 模块
    • 实用程序
      • console_helpers.ps1
    • 模块A
      • 模块A.psm1
      • 模块A.psd1
    • 模块B
      • 模块B.psm1
      • 模块B.psd1
    • 打包模块
      • 模块A.zip
      • 模块B.zip

我正在考虑的是你可以在每个 ScriptsToProcess 中列出相对路径,然后我的打包阶段将把这些相对路径拖到每个 zip 中。

这是一个可怕的疯狂想法吗?我对 ps 模块和 PsGet 真的没有像样的依赖支持吗?我很想听听任何研究过这个领域的人的反馈。我认为我希望获得粗略优先级的答案可能是:

  • 这是共享代码而不公开代码的示例(可能是构建/打包级别的解决方案)
  • 以下是如何使用 PsGet 使模块依赖项正常工作
  • 以下是如何使模块依赖关系很好地工作,但你不能使用 PsGet
  • 只需公开模块中的所有内容
  • 这是一个糟糕的主意,你很糟糕

谢谢!

CalebB建议的更新

这是另一个示例来说明我要解决的问题。我发现用包装函数包装'&'风格的命令执行,处理检查退出代码等事情很有用。如果我正在构建六个模块,他们中的许多人会想要使用那个助手(明显地)。

我今天的选择似乎是把它放在一个模块中并导出它,但也许我不想把它导出,我想要更多的 . 源样式访问。如果我有一系列模块都在尝试使用这些东西,那么模块依赖管理的选项是有限的(PsGet 限制等)。

如果我一次“构建”所有模块(使用一些不错的 psake 和纠缠基础设施),也许我可以在此时使用 hack 将脚本嵌入到我的压缩模块中以“解决”所有这些问题?

4

2 回答 2

1

允许共享“助手”类型的功能,而不必由任何人导出

嗯......在特定模块中点源您需要的脚本有什么问题?你可以 :

  • 保留您的文件夹结构并将所需的功能符号链接到模块文件夹中。
  • 例如,尝试将 AbsolutePath 与其中包含“相对部分”的 ScriptProcess 一起使用%PSScriptRoot%\..\utils(未在该上下文中尝试过,但通常有效)。如果没有,如果它不起作用,你可以随时添加预处理器来为你修复路径
  • function:通过、alias:和提供程序手动删除不需要的导入元素var:
  • 仅在您使用它们时才导入额外的实用程序,然后在最后删除它们?如果希望用户看不到它们,您可以加密它们。

以下是如何使模块依赖关系很好地工作,但你不能使用 PsGet

Chocolatey 使用 NuGet,因此它可以处理依赖项并可以从本地存储加载。作为一个好处,OneGet 支持它,这是每个人最终都会使用的东西。

于 2015-04-16T12:25:00.553 回答
0

I've posted the solution I've come up with on github. I've rolled in a few other features I want when building modules, but the key solution for this question here uses reading and updating the psd1 of each module.

You include scripts that you want to embed in the NestedModules property of your manifest. My build phase will find each script and copy it into the module folder for packing and zipping. The manifest that ships in the package has the script paths converted to the now local file name. I'm still not sure of this is ideal, but it seems to be a nice compromise to deal with the issues here.

A key issue I encountered along the way was that the ScriptsToProcess list is executed literally at module import time, so it is only useful for bootstrapping the import of your functionality. The NestedModules property is actually the list of additional scripts you want to be . sourced and available when your module is used.

于 2015-04-18T10:59:52.453 回答