在PowerShell模块之间管理共享代码

时间:2015-04-16 05:05:11

标签: powershell module build-process chocolatey

我最近一直在深入研究PowerShell模块的一些更高级的功能和清单,以便处理比基本导出一些功能更先进的场景。这听起来应该是显而易见的,但是我很难找到一个很好的解决方案来分享普通的帮助者'在几个大的非平凡模块中键入函数。特别是,我正在寻找一个解决方案:

  • 允许分享'帮助'输入函数而不必由任何人导出
  • 允许通过PsGet从本地仓库路径安装

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

首先,据我所知,PsGet does not handle module dependencies很好。这意味着在模块之间共享将是一场斗争。也许解决方法是避免使用PsGet,并使用自定义脚本来安装'模块到本地模块路径,这可能更容忍依赖关系和加载顺序。

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

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

想象一下文件夹结构:

  • 模块
    • utils的
      • console_helpers.ps1
    • moduleA
      • moduleA.psm1
      • moduleA.psd1
    • moduleB
      • moduleB.psm1
      • moduleB.psd1
    • packed_modules
      • moduleA.zip
      • moduleB.zip

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

这是一个可怕的疯狂想法吗?我是对的,ps模块和PsGet真的没有得到合适的依赖支持吗?我很想听到任何调查过这个领域的人的反馈。我认为我希望得到粗略优先考虑的答案可能是:

  • 这是一个在不暴露代码的情况下共享代码的示例(可能是构建/包级解决方案)
  • 这里是如何使用PsGet
  • 使模块依赖性很好地工作
  • 以下是如何使模块依赖项运行良好,但您无法使用PsGet
  • 只展示模块中的所有内容
  • 这是一个可怕的想法,你很可怕

谢谢!

CalebB

建议更新

这是另一个例子来说明我试图解决的问题。我发现结束'&'使用包装函数执行命令的样式,以处理检查退出代码等内容。如果我构建了六个模块,他们中的许多人都希望使用该帮助程序(显然)。

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

如果我正在建造'所有的模块一下子(有一些不错的psake和pester基础设施),也许我可以在这一点上使用hack将脚本嵌入到我的压缩模块中以解决'所有这些问题?

2 个答案:

答案 0 :(得分:1)

  

允许分享'帮助'输入函数而不必由任何人导出

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

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

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

Chocolatey使用NuGet,因此handles dependencies可以从本地商店加载。作为一个好处,OneGet支持它,这是每个人最终将使用的东西。

答案 1 :(得分:0)

我已经在github上发布了我提出的解决方案。在构建模块时,我已经介绍了其他一些我想要的功能,但这个问题的关键解决方案是使用读取和更新每个模块的psd1。

您包含要嵌入清单的NestedModules属性的脚本。我的构建阶段将找到每个脚本并将其复制到模块文件夹中以进行打包和压缩。程序包中包含的清单将脚本路径转换为现在的本地文件名。 我仍然不确定这是否理想,但在这里处理问题似乎是一个很好的妥协。

我遇到的一个关键问题是ScriptsToProcess列表在模块 import 时按字面执行,因此它仅用于引导您的功能导入。 NestedModules属性实际上是您想要的其他脚本的列表。使用模块时获取并可用。