【问题标题】:Managing shared code amongst PowerShell modules管理 PowerShell 模块之间的共享代码
【发布时间】:2015-04-16 05:05:10
【问题描述】:

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

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

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

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

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

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

想象一个文件夹结构:

  • 模块
    • 实用程序
      • console_helpers.ps1
    • 模块A
      • moduleA.psm1
      • moduleA.psd1
    • 模块B
      • 模块B.psm1
      • moduleB.psd1
    • packed_modules
      • moduleA.zip
      • 模块B.zip

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

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

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

谢谢!

按照CalebB的建议更新

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

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

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

【问题讨论】:

  • 对于初学者来说,你的问题并不可怕,而且组织得比较好。但是,这是相当主观的,您的问题相当模糊。澄清更准确的问题和期望的结果行为将是沟通您的问题的更好选择。 :)

标签: powershell module build-process chocolatey


【解决方案1】:

允许共享“帮助”类型的函数,而不必由任何人导出

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

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

这里是如何让模块依赖很好地工作,但是你不能使用 PsGet

Chocolatey 使用 NuGet,所以它@98​​7654321@ 并且可以从本地存储加载。作为一个好处,OneGet 支持它,这是每个人最终都会使用的东西。

【讨论】:

  • 我希望避免更多的洋葱层,但巧克力似乎是能够处理此模型中依赖关系的最接近的可用层。此外,一旦您进行投资,它还会提供其他好处。我将不得不在这里尝试路径技巧,符号链接是一个潜在的解决方案,谢谢。
  • 感谢 SymLink 助手,这是一个丰富的实现 :) 我已经采用了翻译相对路径的解决方案,但符号链接方法是另一个有趣的解决方案
【解决方案2】:

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

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

我在此过程中遇到的一个关键问题是 ScriptsToProcess 列表是在模块 import 时执行的,因此它仅对引导功能的导入有用。 NestedModules 属性实际上是您想要成为的附加脚本的列表。使用您的模块时来源和可用。

【讨论】:

    猜你喜欢
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 2020-06-25
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多