.NET Enterprise Development with Shared Modules

paul_nathan at selinc.com paul_nathan at selinc.com
Wed Jul 25 22:41:21 UTC 2012


Cody,

See inline.

mercurial-bounces at selenic.com wrote on 07/24/2012 06:19:53 AM:

> From: Cody Zuschlag <cody.zuschlag at gmail.com>
> To: mercurial at selenic.com, 
> Date: 07/24/2012 08:37 AM
> Subject: .NET Enterprise Development with Shared Modules
> Sent by: mercurial-bounces at selenic.com
> 
> I?m having some challenges putting together a workflow using 
> Mercurial for our development. We develop shared modules and then 
> consume those modules in several products. Modules may have 
> dependencies on other modules.

This is pretty normal in enterprise development, AFAICT.

> 
> Subrepos, while a ?feature of last resort? seems to be the best way 
> to handle shared modules. This is because our modules are often (for
> better or worse) tightly coupled and developed simultaneously. 
> Furthermore, it is perfectly acceptable for a developer to make (and
> commit) changes to a shared module while working on a consuming 
> product or module. Therefore, we need access to the source of the 
> shared modules at while developing a new product and be able to 
> modify and commit to that source. Therefore, I do not see it as 
> something that can be handled by the build system.
> 
> Our modules really become dependencies. When I consume a module in a
> product, I need to get that module (perhaps including it as a 
> subrepo) and all of its dependencies (more subrepos?) recursively. 
> Now one might suggest a dependency management tool. We?re doing .NET
> so, that most likely rules out some of the elegant Java solutions. 
> There is NuGet for Visual Studio. However, as far as I know, this 
> only works for getting dependencies. If I need to make a change to 
> that shared module, there is no way to commit those changes back to 
> source control. And in the case of NuGet, we would now have to 
> manage a feed for our internal modules and if those are being 
> actively developed, this could be substantial overhead.
> 
> If I use subrepos, and follow the suggestion of having a ?shell? 
> repo that wraps all subrepos as siblings, I have the following 
challenges:
> 
> 1) If I want to add a shared module to a new product as a subrepo, 
> how can I know what it?s dependencies are (and preferably auto-
> magically get said dependencies as other subrepos)? That shared 
> module may have its own ?shell? located somewhere that tracks all of
> its dependencies (sibling subrepos), but my new product ?shell? 
> should not include that. The module subrepo could reference a 
> revision in its ?shell? and with some custom tool or scripts I could
> go get the .hgsub and .hgsubstate from the module?s parent shell and
> parse the required dependencies (and get them), but this gets messy 
> fast and seems wrong to have a child reference a rev in his parent.

Yes, that would be a terrible idea. I don't even want to think what a 
circular tagging algorithm would look like. 

> 
> 2) If two shared modules reference different versions of a third 
> shared module, the developer including the two modules should be 
> notified of a version conflict. Using the ?shell? repo suggestion 
> with all subrepos as siblings, there can only be 1 version of the 
> third shared module present, so the conflict needs to be resolved 
> manually by the developer (updating one of the modules).

Notifications, hg can not provide out of the box. You could write a 
recursive walker to analyze this, though.


> 
> I realize some would say that my question are beyond the scope of hg
> or source control tools in general. However, if we want to allow 
> tightly coupled and actively developed dependencies, it only seems 
> natural that our source control tool should aid with this. Does 
> anyone have any ideas or suggestions?

I don't think you want a shell, per se. While it's arguable that a full 
decoupling is the better SW engineering of your system (as others are 
arguing), we have to deal with the present reality.

I believe you have at least 3 levels of subrepo. This is going to be very 
difficult to manage. I guess the consideration to be asking is- what are 
you "wanting" hg to do? 

In our my projects where I had multilevels of subrepos, each component got 
a different SR, sometimes they included each other other and the trees 
started looking a bit ridiculous.

Example (cribbed from memory):

  A 
/   \
B    C
|   / \
E  B   D
   |
   E

Note that B and E differed in version.  Also, this plays merry horrors 
with recursive tagging, which is something we've been unable to solve and 
get a consistent answer for it (loosely, the problem is tags need to be a 
relation, not a function).

The advantage is that when you pull A, you *get* everything needed to 
build A. A disadvantage is that your versioning will get out of whack - B 
from A is a different B from C, and has to be treated slightly 
differently.  Note that this adds friction around having continual 
development, you have to constantly be repointing your versions to the 
latest version of a subrepo.

One solution that might be used for a flat repo structure is some kind of 
versioning system inherent in your build system- ie, each package version 
claims it depends on some few other versions of other packages; building 
becomes a topological sort & a build inward. This may be completely 
impossible for you. Some systems can pull it off.

We have internally worked on a subreo replacement, but I don't think most 
of its concepts solve the problem you have. 
http://www.selenic.com/pipermail/mercurial/2012-June/043312.html


- - -
Regards,
Paul Nathan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurial-scm.org/pipermail/mercurial/attachments/20120725/fc7871ce/attachment-0002.html>


More information about the Mercurial mailing list