NuGet would likely be my answer. After working the precursor (Nu) which was just sitting on top of RubyGems, I can say that having resources towards something helps. Now once job I ended up with a patched version of the executable because we had a local repository besides remote ones. I'm not sure if they fixed that problem yet or not, but since they are accepting patches, it should be easy to correct. On all the open source projects in the .NET arena I work on we now do all of through NuGet. It's much easier, though publishing up the chain does take a little while longer.
OpenWrap is an option, but everything needs built. Which is kinda a pain in the butt. If you can't get the project building right it takes a while to deal with. Openwrap has been trying to solve this for a long time and it's still really awkward. Binary only distribution is a lot easier (sometimes)...
The other two I'm not familiar with. So I can't comment on them a ton.
Externals can be used for what you are trying, but first you should check if you really need them. For our team, it is mostly sufficient to have our shared modules in a folder below named shared_libs
, and let all using projects reference that folder by a relative path. However, one will need externals if you are going to have the libs/shared modules in different local folders below your project folder. That way, you can handle situations where you need
both at the same time in local your development environment. By using externals, you cannot just control to have different copies at different locations in your development environment, you get also fine grained control which revision, or branch, or tagged version of the lib/module you want to have placed there.
For us, however, it is mostly sufficient to have different versions of the same lib in our production environment only (we use some externals, but not for the majority of shared libs). For testing and deployment, most of our build scripts pull the compiled results into a test or deployment folder, without the help of SVN.
The drawback of using externals is that you have increased administrative effort - you might need to update explicitly to a newer version of a lib in each project which uses it. For editing and commiting changes your libraries source code directly in the external's checkout folder you will have to utilize the peg-revision mechanism of SVN (or maybe its exactly what you want to prohibit). And if your shared libs are dependent from other shared libs, maybe recursively, you have to make sure the relative paths of all those libs in your local file system are always similar to each other. You will have to validate if this what you need and/or what you want.
Concerning your second question: SVN is not really the right tool for tracking dependencies, the only reliable place where the dependencies are stored are your make files / project files / build scripts / linker files (whatever you use for your build process), so my first suggestion would be to scan those files by a script to collect dependency information. Nevertheless, if you are going to use SVN externals consequently for every shared module dependency, I am sure you can write a script which iterates over the projects in your repo(s) and collects which externals are added there. And I do not think you will need a hook for that, just utilize svn propget svn:externals
for this, as shown here.
Best Answer
I'm not 100% sure on the positives. Here's a few negatives
You often end up adding dependencies to 3rd party servers/endpoints that might not be stable.
I've had it happen with bower that the repo of some dependencies was deleted or moved. So a new dev comes along, clones my repo, types
bower install
and gets errors for un-accessible repos. If instead I had checked in the 3rd party code into my repo that problem disappears.This is solved like the OP suggests if you're pulling deps from copies kept on a server you run.
Harder for noobs.
I work with art students with very little command line experience. They make art with Processing, arduino, Unity3D, and get by with very little tech knowledge. They wanted to use some HTML5/JavaScript I wrote. Steps because of bower
npm install -g bower
)bower install
(finally to get our dependencies)Steps 2-5 can all be deleted if we just check in the files to our github repo. Those steps likely sound super easy to you and me. To the students they were very confusing and they wanted to know what all the steps where and what they were for which might be good learning possibly but was entirely orthogonal to the class topic and so likely quickly forgotten.
It adds another step when pulling.
It's happened many times I do a
git pull origin master
and then test my code and it takes 5 to 10 minutes to remember I needed to typebower install
to get the latest deps. I'm sure that's easily solved with some pull script hook.It makes git branching harder
If 2 branches have different deps you're kind of screwed. I suppose you can type
bower install
after everygit checkout
. So much for speed.As for your positives I think there are counter examples to each of those
vs what? It's certainly not easier to distribute. Pulling one repo instead of 20 is not easier and is more likely to fail. See #1 above
Conversely it means your dependent on others for fixes. Meaning if your deps are pulling from a 3rd party source and you need a bug fixed you have to wait for them to apply your patch. Worse, you probably can't just take the version you want plus your patch, you'd have to take the latest which might not be backward compatible with your project.
You can solve that by cloning their repos separately and then you point your project deps to your copies. Then you apply any fixes to your copies. Of course you could also do that if you just copy the source into your repo
That seems arguable. Just require devs to put 3rd party libraries in their own folder under
<ProjectRoot>/3rdparty/<nameOfDep>
. It's just as easy to see what 3rd party libs are used.I'm not saying there are no positives. The last team I was on had > 100 3rdparty deps. I'm just pointing out it's not all roses. I'm evaluating if I should get rid of bower for my needs for example.