在Mercurial中组织具有共享依赖项的项目的好方法是什么? [英] What's a good way to organize projects with shared dependencies in Mercurial?

查看:45
本文介绍了在Mercurial中组织具有共享依赖项的项目的好方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在从旧版版本控制系统转移,并将我团队的项目转移到普通项目.作为我要移动的代码种类的一个示例,我有一个超过25个项目的Visual Studio解决方案,其中包含几个独立的应用程序领域,这些领域都依赖于通用代码.查看Stack Overflow,我发现最接近的问题是这个问题,但是它仅提到版本控制.我正在寻找更多有关使用Mercurial管理这些依赖项的具体实现技术的建议.

Currently, I'm moving from a legacy version control system and moving my group's project to mercurial. As one example of the kinds of code I'm moving, I have a 25+ project Visual Studio solution, containing several separate application areas that all depend on common code. Looking over Stack Overflow, the closest question I found was this one, but it merely mentioned version control. I'm looking for a bit further advice, on specific implementation techniques of using Mercurial to manage these dependencies.

依赖关系的简化视图如下所示. (这仅用于说明和示例;实际的依赖关系要复杂得多,但本质上是相似的.)

A simplified view of the dependencies look something like the following. (This is for illustration and example only; the actual dependencies are significantly more complex but similar in nature.)

                     Common Lib 1
                    /      |      \
                ----       |       -----   
               /           |        \   \
            App 1    Common Lib 2    \ App 2
                       /   |   \      \
                -------    |    ------ |
               /           |          \|
             App 3       App 4      App 5

Common Lib模块将是共享代码-这将是DLL或SO或将在所有应用程序之间同时使用的某些其他库-在编译和运行时.否则,应用程序将能够彼此独立运行.

The Common Lib modules would be shared code - this would be a DLL or SO or some other library that would be used between all the apps simultaneously - both at compile and run time. Applications would otherwise be able to run independently from each other.

设置商品库有两个目标:

I have a couple goals with setting up my mercurial repositories:

  • 为每个重要的应用程序或组件组提供自己的存储库.
  • 使每个存储库自成一体.
  • 使项目的总和自成一体.
  • 使立即构建整个代码库变得容易. (最终,所有这些程序和库最终都在单个安装程序中.)
  • 保持简单.

另一点是,我建立了一个服务器,其中每个项目都有单独的存储库.

One other point is that I have a server set up where I have separate repositories for each of these projects.

我看到了布置这些项目的几种方法.

I see a couple ways of laying these projects out.

这将使用基于url的子存储库(例如,在.hgsub中,我将执行类似App1 = https://my.server/repo/app1的操作.)进行了布局,它看起来像以下内容:

This would use url-based subrepos (eg, in the .hgsub, I'd do something like App1 = https://my.server/repo/app1.) Laid out, it would look like the following:

+---------------------------+
| Main Repository           |
| | +---------------------+ |
| +-| Build               | |
| | +---------------------+ |
| | +---------------------+ |
| +-| Common Lib 1        | |
| | +---------------------+ |
| | +---------------------+ |
| +-| Common Lib 2        | |
| | +---------------------+ |
| | +---------------------+ |
| +-| App 1               | |
| | +---------------------+ |
| | +---------------------+ |
| +-| App 2               | |
| | +---------------------+ |
| | +---------------------+ |
| +-| App 3               | |
| | +---------------------+ |
| | +---------------------+ |
| +-| App 4               | |
| | +---------------------+ |
| | +---------------------+ |
| +-| App 5               | |
|   +---------------------+ |
+---------------------------+

shell存储库中的每个主文件夹都将包含一个子存储库,每个项目区域一个.依赖关系是相对的:例如,由于App 4需要Common Lib 2,因此它将仅使用相对路径来引用该公共库.

Each main folder in the shell repository would contain a subrepo, one for each project area. Dependencies would be relative: Eg, since App 4 needs Common Lib 2, it would simply use relative paths to reference that common library.

这种方法的优点:

  • 每个库仅被拉下一次.
  • Mercurial的子仓库将确保在所有项目中自动使用相同版本的库,因为在项目中仅存在该子仓库的一个版本.
  • 很容易找到每种资源.

这种方法的缺点:

  • 我无法独立开发App.例如,如果我使用App 2,并且需要更改公共库,则所有其他应用都必须立即进行这些更改.
  • 如果我自己拉一个应用程序回购,我必须弄清楚(或知道)如果要构建它,需要手工处理其他依赖回购.
  • 依赖关系并不是紧密分开的,由于很容易获得所有功能,因此很容易在任何地方插入新功能.

在这种方法中,每个应用程序将拥有自己的存储库(与以前一样),但是这次还包含子存储库:一个用于其自身的源,一个用于每个从属子存储库.然后,整个存储库将包含这些项目存储库中的每一个,并且知道如何构建整个解决方案.如下所示:

In this approach, each application would have its own repository (as before) but this time also contain subrepositories: one for its own source, and one for each dependent subrepository. An overall repository would then contain each of these project repositories, and know how to build the entire solution. This would look like the following:

+-----------------------------------------------------------------------+
| Main Repository                                                       |
| +--------------------+ +--------------------+ +--------------------+  |
| | Build              | | Common Lib 1       | | Common Lib 2       |  |
| +--------------------+ | | +--------------+ | | | +--------------+ |  |
|                        | +-| Lib 1 Source | | | +-| Common Lib 1 | |  |
|                        |   +--------------+ | | | +--------------+ |  |
|                        |                    | | | +--------------+ |  |
|                        |                    | | +-| Lib 2 Source | |  |
|                        |                    | |   +--------------+ |  |
|                        +--------------------+ +--------------------+  |
| +--------------------+ +--------------------+ +---------------------+ |
| | App 1              | | App 2              | |  App 3              | |
| | | +--------------+ | | | +--------------+ | |  | +--------------+ | |
| | +-| Common Lib 1 | | | +-| Common Lib 1 | | |  +-| Common Lib 2 | | |
| | | +--------------+ | | | +--------------+ | |  | +--------------+ | |
| | | +--------------+ | | | +--------------+ | |  | +--------------+ | |
| | +-| App 1 Source | | | +-| App 2 Source | | |  +-| App 3 Source | | |
| |   +--------------+ | |   +--------------+ | |    +--------------+ | |
| +--------------------+ +--------------------+ +---------------------+ |
| +--------------------+ +--------------------+                         |
| | App 4              | | App 5              |                         |
| | | +--------------+ | | | +--------------+ |                         |
| | +-| Common Lib 2 | | | +-| Common Lib 1 | |                         |
| | | +--------------+ | | | +--------------+ |                         |
| | | +--------------+ | | | +--------------+ |                         |
| | +-| App 4 Source | | | +-| Common Lib 2 | |                         |
| |   +--------------+ | | | +--------------+ |                         |
| +--------------------+ + | +--------------+ |                         |
|                        | +-| App 5 Source | |                         |
|                        |   +--------------+ |                         |
|                        +--------------------+                         |
+-----------------------------------------------------------------------+

优点:

  • 每个应用程序都可以自己构建,彼此独立.
  • 可以逐个应用而不是全局地跟踪依赖库的版本.采取了明确的动作,即在项目中插入子仓库以添加新的依赖项.

缺点:

  • 进行最终构建时,每个应用程序可能使用不同版本的共享库. (可能需要编写工具来同步通用的lib子存储库.Eww.)
  • 如果我想构建整个源,最终会多次拉下共享库.对于Common Lib 1,我将不得不将其拉八(!)次.

此方法与方法1极为相似,只是公共库仅作为构建的一部分进行拉取.每个应用程序都会知道需要什么存储库,并将它们放置在公共位置.

This approach would look much like approach 1, except the common libraries would only be pulled as part of the build. Each app would know what repos it needed, and put them in the common location.

优点:

  • 每个应用都可以自行构建.
  • 公用库只需要被拉一次.

缺点:

  • 我们必须跟踪每个应用程序当前使用的库的版本.这会复制子仓库功能.
  • 我们必须构建一个基础架构来支持这一点,这意味着将更多内容纳入构建脚本中.嗯.

还有另一种处理方式吗?有更好的方法吗?您尝试并成功了哪些方法,您尝试了哪些但又讨厌的方法?我目前倾向于1,但是缺少应用程序独立性(应该能够使用)确实让我感到困扰.

Is there another way of handling it? A better way? What ways have you tried and succeeded, what ways have you tried but hated? I'm currently leaning towards 1, but the lack of application independence, when it should be able to, really bothers me. Is there a way to get the nice separation of method 2 without the massive duplicate code pull and dependency maintenance nightmare, while not having to write scripts to handle it (like in option 3)?

推荐答案

依赖管理是项目组织的重要方面.您基于Mercurial的subrepos功能详细介绍了各种解决方案,并且我同意您给出的所有优点/缺点.

Dependencies management is an important aspect of a project's organization, to my eyes. You exposed in great details various solutions, based on the subrepos feature of Mercurial, and I agree with all the pros/cons that you gave.

我认为SCM不太适合依赖关系管理.我更喜欢为此使用专用工具(这将是您的解决方案3).

I think SCMs are not well suited for dependencies management. I prefer having a dedicated tool for that (this would be your solution n°3).

我当前的项目是Java.它是使用 Apache Ant 构建的,我首先设置了

My current project is in Java. It was built with Apache Ant, and I first set up Apache Ivy as a dependencies management tool. In the end, the setup consisted of some Ivy configuration files in a shared directory, and one XML file listing the dependencies for each module of the project. Ivy can be invoked by Ant targets, so I added two new actions in each module : "resolve dependencies", and "deploy the built artifact". The deployment adds the result of the buid (called an artifact) in the shared directory. The dependencies resolution means transitively resolving the dependencies of the module, and copying the resolved artifacts in the "lib" folder of the module's sources.

该解决方案适用于C ++项目,因为Ivy并非特定于管理Java依赖项:工件可以是任何东西.在C ++中,模块产生的工件为:

This solution is applicable to a C++ project, since Ivy is not specific to managing Java dependencies : artifacts can be anything. In C++, the artifacts produced by a module would be :

  1. 运行时的so/dll
  2. 在编译时的头文件.

这不是一个完美的解决方案:Ivy设置起来并不容易,您仍然必须告诉构建脚本要使用哪些依赖项,并且您不能直接访问依赖项的源以进行调试.但是您最终还是拥有独立的SCM存储库.

This is not a perfect solution: Ivy is not easy to set up, you still have to tell your build script what dependencies to use, and you do not have direct access to the sources of the dependencies for debugging purpose. But you do end up with independent SCM repositories.

在我们的项目中,我们将Ant + Ivy的形式切换为 Apache Maven ,这将解决构建和依赖项管理.这些工件部署在 Apache Archiva 中,而不是共享文件夹中.这是一个巨大的改进,但仅适用于Java项目.

In our project, we then switched form Ant+Ivy to Apache Maven, which takes care of both the build and the dependencies management. The artifacts are deployed in an Apache Archiva instead of a shared folder. This is a huge improvement, but it will work well for Java projects only.

这篇关于在Mercurial中组织具有共享依赖项的项目的好方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆