CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

Check in all your binary dependencies into Source Control

In the vein of "getting started," the question came up today about how to access shared binary tools like NUnit or NAnt.  I'd say that the best practice is to have all the binary dependencies checked into your source control repository and use those copies of the tools (operating systems & database servers obviously don't apply).  Don't depend on a GAC-ed copy of NUnit or NAnt.

WHY? 

One of the tenets of a Continuous Integration strategy is a single, authoritative source repository for the application, including binary dependencies.  There are two end goals:

  1. Know exactly which versions of what (NUnit, NAnt, NHibernate, NEtc.) your code depends on
  2. Be able to walk up to a clean machine, checkout the code tree, run the automated build, and voila -- you're ready to go.  Depending on a GAC-ed copy of NUnit, for example, defeats this goal. 


Comments

Chad Myers said:

We usually have our SVN structured like this:

/project

  /tags

      /...

  /trunk

      /lib

      /src

So that the lib (binary dependencies) get versioned with the src so it's recompile-able throughout history.

How do you (Jeremey and community) structure it?

# October 4, 2006 8:31 PM

Chad Myers said:

Oops, 'Jeremy', rather. Sorry, too many 'e''s in there.

# October 4, 2006 8:31 PM

Jeremy D. Miller said:

I do it like that, just with /bin and /source instead of /lib and /src.  TreeSurgeon basically does the same thing.

# October 4, 2006 8:38 PM

Tim Dallmann said:

I fully agree.  When using VS.Net 2005 with Team System source control, I include a /lib folder in my project, and let the /bin stay out of source control.  Project references are made to the /lib folder, and so the automated build also finds them easily.  

I go one step further, and include all internally developed dependancies in /lib as well.  This way, each project includes the specific version of the dependancy that it was compiled with.  When the dependant dll is updated, the maintenance developers of the projects that use that dll can decide when to implement the new version.

# October 5, 2006 7:59 AM

Carlton said:

What Tim said

# October 5, 2006 11:16 AM

Jim Bolla said:

We use a similar structure:

/Engagement Name 1/

   Main Development/

       Solution Name.build

       Solution Name.fxcop

       Solution Name.sln

       Application/

           Project.Domain/

           Project.Persistence/

           Project.Presentation/

           Project.WebApplication/

       Databases/

           Schema Scripts/

           Queries/

       Dependencies/

           Atlas/

           NHibernate/

       Project Stuff/

       Tests/

           Project.Domain.Tests/

           Project.Persistence.Tests/

           Project.Presentation.Tests/

       Tools/

           FxCop/

           NAnt/

           NMock2/

           NUnit/

   Release Candidate Stabilization/

        (branch of main)

   Production Bug Fixes/

        (branch of main)

/Engagement Name 2/

   ....

We've broken the bonds of the cryptic abbreviated folder names. :) All the tools are there for CruiseControl.NET to build/test/analyze each commit. Note the "project stuff" folder; that's where we keep requirements, estimates, developer notes, client messages... whatever is important.

PS: I hope the comments engine doesn't chew up my indenting because this would look like crap.

# October 8, 2006 10:47 PM

Andy said:

You should have a look at the Maven projects for Java. Their dependency management scheme is quite nice and obviates the need to place binaries in an SCM. What I never liked about storing dlls, etc in an SCM is when you have multiple projects that use the same binaries-- you end up having copies of the same binary throughout an SCM.

# October 29, 2006 6:21 AM

AdamVandenberg said:

jimbolla (or anyone), where do you put your build outputs?

The Visual Studio default of adding obj + bin folders to every project seems less than optimal.

Also, what's a good list of svn:ignore patterns for Visual Studio work?

I'm used to letting Visual Studio handle its own ignores (via the source control provider), but in this case I'm not using one.

# November 9, 2006 10:35 PM

Adam Tybor said:

We keep our dependencies in vendor branches and use the svn:external property to include them in source control.  This allows for auto updates of dependencies, if the build breaks we just have to point the svn:external to previous version.  It works nice and it helps us resolve issues with dependency versions much quicker.  The only downside is when we tag we need to ensure the libs point to the correct revision of the dependency.

/projects/projectA

 /trunk

   /lib

     nhibernate=https://repo/vendor-bin/nhibernate/latest

     rhino-commons=https://repo/vendor-bin/rhino-commons/latest

   /src

/vendor-bin/

 /nhibernate

   /latest

   /1.2.0-CR1

   /1.2.0-GA

 /rhino-commons

   /latest

# March 29, 2007 12:24 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Jeremy D. Miller

Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy previously worked as a systems architect building mission critical supply chain software for a Fortune 100 company and learned agile development practices as a .Net consultant at ThoughtWorks, one of the pioneers of agile development. Jeremy is the author of the open source StructureMap (http://structuremap.sourceforge.net) tool for Dependency Injection with .Net and the forthcoming StoryTeller (http://storyteller.tigris.org) tool for supercharged FIT testing in .Net. Jeremy's thoughts on just about everything software related can be found on his weblog "The Shade Tree Developer" at http://codebetter.com/blogs/jeremy.miller, part of the popular CodeBetter site. Jeremy is a Microsoft MVP for C#. Check out Devlicio.us!

This Blog

Syndication

News

All opinions expressed here constitute my (Jeremy D. Miller's) personal opinion, and do not necessarily represent the opinion of any other organization or person, including (but not limited to) my fellow employees, my employer, its clients or their agents.

About Me

"Best Of" Compendium

StructureMap (Dependency Injection for .Net)

StoryTeller (Supercharged Fit)

Build your own Cab

TestDriven

MVP