views:

86

answers:

2

In my web projects (Django framework) I typically have a few internally developed javascript files that are shared among them. These web projects are stored in seperate mercurial source code repositories. Here's the relevant directory structure:

+ static
--+ css
--+ images
--+ js
-----+ thirdparty
-----+ mycompany
--------+ shared_lib1.js
--------+ shared_lib2.js
--------+ project_only_lib.js
-----+ tests

Linking to the scripts in html looks like so:

<script src="/static/js/mycompany/shared_lib1.js" type="text/javascript"></script>

Currently, when I make a change (say fix a bug) in one of the shared libs and check it in, the updated code only exists in the one repository. So for now I manually copy the changes over to the other repositories and check it in.

This seems pretty dumb.

Is there something else I should be doing that allows me to change the javascript, commit it to source control, and have the changes reflected in the other web projects?

+3  A: 

You could consider storing the shared libraries in a central repository and on a central web server (e.g. http://domain.com/shared_libs/), having a directory for each revision (or tag, or revision that is a release), and embedding the libs directly from there.

For revision 45, you would have:

http://domain.com/shared_libs/45/lib1.js
http://domain.com/shared_libs/45/lib2.js

for the tag (or whatever the Mercurial equivalent is...) named "0.8-beta3", you would have

http://domain.com/shared_libs/0.8-beta3/lib1.js
http://domain.com/shared_libs/0.8-beta3/lib2.js

etc. etc.

The process of creating a new directory for each (meaningful) revision and exporting the right files should be comparably easy on any operating system.

In each project, you would only have references to the central server like this:

<script src="http://domain.com/shared_libs/45/lib1.js"&gt;

that way, every in-house project can choose which version of the shared libraries to use - great in case of incompatible changes, or production releases that needs to be deployed straight away and that can't risk using a new unknown version of the shared libraries.

Also, the shared libraries are completely separated from the projects' revision history this way.

If an important update occurs in the shared library, you would have to change the references in each project (e.g. from /45/lib1.js to /52/lib2.js - but a controlled switch to the each version will be the safer way anyway in the long run, in case a new release contains bugs that break the other projects.

Another option would be having a central repo for the shared libraries, and using whatever Mercurial's equivalent of Subversion's externals are to "link" to the libraries from each project, keeping up to date with frequent updates of the external.

(I'm making the assumption here that Mercurial deals with revision numbers just as Subversion does, creating a new one on each commit - I hope that is correct.)

Pekka
Your assumption is somewhat wrong.. hg doesn't have directories for tags. It does, however, have changeset hash ids for each commit.
Paul Nathan
@Paul ah, that makes things a bit less straightforward then. Cheers for the info.
Pekka
Yup, I got it now. That subrepositories feature is what I needed. Since you're suggestion for externals lead to this discovery, I'm just going to accept this answer.Thanks!
Eric Palakovich Carr
+2  A: 

Have you investigated on symbolic links?

Syd
The problem is that the code would be duplicated among multiple repositories. I'd like the source code's revision history to exist in only one repository (whether a part of a larger project or its own repository).
Eric Palakovich Carr
@Eric doesn't Hg have something equivalent to subversion's externals? They should be the right thing for you then. An external is a reference to another repository or a part of it.
Pekka
Ah! You gave me an avenue to look down, and subrepos appears to be the equivalent feature. http://mercurial.selenic.com/wiki/subrepos. I'll let you know if it's what I'm looking for in a bit.
Eric Palakovich Carr