1

我们开发企业软件,我们希望在我们的开发人员之间促进更多的代码重用(为了使这个问题简单,让我们假设所有的.NET)。我们即将迁移到一个新的 VCS 系统(很可能是 mercurial),我希望制定一个策略来共享库。

管理满足以下用例的共享库的最佳流程是什么:

  1. 黑盒 - 只有库的公共 API 是已知的,并且没有假设消费开发人员将能够“进入”或在库中设置断点。图书馆是一个黑匣子。开发人员通常不关心细节,只需给我一直“工作”的 lib 版本。
  2. 调试 - 开发人员至少应该能够在开发过程中“进入”库。设置断点也是一个好处。
  3. 并行开发 - 虽然很可能是少数,但似乎有一些有效的用例可以与消费应用程序并行开发库。库和组件的作者通常是同一个开发者。无论好坏,应用程序和库通常可以紧密耦合。能够对两者进行更改和调试可能是我们开发的一种非常有效的方式。

需要注意的是,求解 3,可能会隐式求解 2。

解决方案可能涉及其他工具(例如 NuGet 等)。

4

2 回答 2

1

通过共享库,您必须区分:

  • 源依赖(您正在共享,意味着在您的项目中重新编译)
  • 二进制依赖项(您共享交付,从公共来源编译)并从您的项目链接到它。

关于这两者,NuGet (2.0) 最终引入了“构建期间的包还原”,以便提交任何构建LibExternalDependencies文件夹的源代码控制。

NuGet(尤其是其新的分层配置NuGet 2.1)非常适合 C# 项目中的模块管理,并将与 git 和 Mercurial 交互。

将其与Mercurial subrepos结合使用,您应该能够在其自己的 repo 中隔离您想要重用的公共代码库。

于 2012-10-25T11:37:30.097 回答
1

对于这个问题,我有两种可能的解决方案,但似乎都不理想(因此我发布了这个问题)。

  1. 使用 VCS 管理依赖项。具体来说,使用 mercurial subrepos 并始终按源共享。
    • 优点:
      1. 所有 3 个用例都已解决。
      2. 源代码控制和依赖管理只需要一个工具
    • 缺点:
      1. Subrepos 功能被 Mercurial 开发人员认为是不得已的功能,从实验和阅读来看,存在以下问题:
        • 标签不能轻易或原子地应用于多个 repos。
        • Root/Shell 存储库本质上是脆弱的(如果到子存储库的路径发生变化,可能会被破坏)。Mercurial 开发人员建议通过在 shell 存储库中不包含任何内容并仅使用它来定义(和跟踪修订)子存储库来缓解此问题。因此,即使 subrepo 路径被破坏,开发人员也可以手动重新创建一个时刻。
        • 分支不能跨越 repo 边界(很可能不是一个大问题,因为有人可能会争辩说分支应该只出现在给定的 subrepo 中)。
  2. 使用IvyNuGet来管理依赖项。有两种方法可以工作。
    1. 依赖项/包可以简单地包含官方二进制文件。当开发人员提交新版本的构建时,构建服务器可以配置为将新的依赖项/包发布到公司存储库中。这解决了案例 1。Nuget 似乎支持可以解决案例 2 的符号包。案例 3 没有解决,并且在这种情况下让开发人员干涸并提出自己的解决方案(基本上没有办法将应用程序提交给 VCS包括按来源的依赖项)。这似乎是使用依赖管理工具的传统方式。
    2. Dependencies/Packages 可以包含一个从 mercurial 获取源的脚本。该脚本可以在安装依赖项/包时自动执行。为了让 .NET 解决方案包含按项目(而不是通过浏览文件系统)的引用,已经执行了一些魔法,但理论上这可能发生在 NuGet安装脚本中,而在卸载脚本中则相反
      • 在“源”和“二进制”依赖项之间切换似乎是一个手动步骤。我认为开发人员应该切换到发布的二进制依赖项,也许这可以在创建发布时在构建服务器上强制执行。由于需要修改 VS 解决方案以引用项目与二进制文件,这进一步复杂化了。
      • 有多少个源包?每个二进制包是否都包含用于获取构建它的源代码的脚本?或者我们是否创建单独的源包,使用安装脚本魔法来获取源?这就引出了一个问题,mercurial 中的每个标签是否都有一个源包?每个变更集?或者只是 1 个源包,它只是克隆和更新到提示并让开发人员更新到以前的修订版(但这会产生知道要更新到哪个修订版的问题)。
      • 如果开发人员随后使用 mercurial 更改源的版本,这如何反映在消费应用程序中?用于获取源的依赖项/包没有改变,但源本身已经......
于 2012-10-25T11:40:06.350 回答