views:

153

answers:

6

So ive got a nice Java project, builds with Ant to a /dist folder. The whole project is under version control, so I can deploy the latest version just by 'svn export' on the path to the dist folder. But my build keeps deleting the .svn folders inside my dist folder, and all its dependents, because it cleans out the folder when building instead of just overwriting. The precise culprit is JarBundler, the Ant task that builds my mac.app bundle - It deletes the whole bundle's folder before recreating it. This obviously craps up my svn, because all the .svn folders are now missing for that folder and so it says its in conflict yada yada vomit.

Anyone have any ideas for how I could solve this? I cant figure out how to stop jarbundler from deleting everything, so im going to have to do something more hacky I fear. Im pretty new to Ant aswell, just for reference.

A: 

Simple. Don't check in /dist in to version control.

Version Control really should not have any generated code/binaries/jars/what-have-you.

tunaranch
A: 

Probably I'm missing something here, but why do you have your built products checked into your source control system? Generally, that's not considered good practice.

If you do want to check in build products, copy them somewhere else (a directory called "pre-built", perhaps), and check them in from there.

Edited to add: The reason you shouldn't need to do this is because, given the current source, you ought to be able to recreate the distribution with a single build command.

Mark Bessey
A: 

@tunaranch, ok, but then what do I use for deployment instead? Its got to support differential updates, be cross platform, and be as painless to use as svn was before ant crapped on it.

dalyons
You probably ought to add this as a comment to the answer in question. In ant case, there are other tools you can use for deployment - for example, rsync. If you're happy using svn as your deployment solution, then create a parallel "dist" tree, and check your built products in there.
Mark Bessey
With maven you can configure it to deploy a compiled artefact to a repository (could be accessed over, say http) each time we release a new version. I don't know what's needed for differential updates, but you could get an ant task to upload them to a server as part of your post-build process.
tunaranch
+3  A: 

To have dist in source control can be considered as good practice if you want your source control system to be a unique referential for all:

  • developers
  • assemblers (unit-testing)
  • homologation testers (you query a bunch of dist on your integration platform and perfom there your non-regression tests, perfs tests, stress tests, and so on)
  • production release managers ...

BUT you need to have a proper release process to pull this through.

In your case, the build must be in a separate and private directory, that is a directory not in subversion. When the build is ok, you import it into subversion if it is an official release, or you import it to a shared directory if it is a temporary build, just needed by the next team (thus avoiding to commit hundreds of builds into SCM, using space for nothing).

Note: the main advantage for having the delivery (dist) in your SCM is to allow dependent project to work not with your sources, but directly with your delivery (which is bound to go at one point or another into production): if they manage to make their code work, by compiling with your delivery, chances are their own dist, when deployed with your, will work.
That way, the other teams access your delivery (your 'myProject.jar') as they access any of their sources: they can read through the SCM the version of your jar, its date, its history, its metadata, its label, and so on.

However, for one small monolithic (as in 'no other projects depend on it') project, it can be argued that dist (the final packaged delivery) could be re-build on demand and stored in an external referential system, as an external Maven repository for instance.
BUT: Maven is no SCM repository, meaning you need to sign you jar ('MyProject-1.0.jar'), you have no history, and you need to report all your metadata on a separate text file along your delivery. Any other project accessing to that delivery in that Maven repo needs to adjust its scripts and classpaths accordingly to your version naming convention.
Plus, Maven is another repository in your development architecture. Whenever you can keep the number of repos to a minimum (of '1' ;) ), it is better.

VonC
A: 

Alright, thanks all. I get now why philosophically it is a good idea to keep builds out of SCM, and will keep that in mind for the future. However, practically, in this case I am the only dev on this short (4 weeks) project. I am using svn to easily update the release build on the public webserver, over a low-speed connection such that differential update is essential. Since no-one suggested an easy alternative to updating remote deployment builds, I came up with this hacky hack to avoid my problem:

Say my versioned build folder is /dist. Well, I tell my build script to build to /dist-tmp, then recursively copy all the files from /dist-tmp over the top of /dist, then finally delete /dist-tmp.

It was a few extra lines in my Ant build script, and works great.

Next time though, ill make sure the deployment host isnt windows, and then a simple rsync script will do the trick, and then I can leave builds out of SCM.

@VonC gets the answer tick for the best explanation of philosophy.

dalyons
A: 

I would agree that it's not very good practice to put built products into SVN.

That being said, if you have some requirements to do this that you cannot get around, you can use one of the more modern version control systems like Git, Bazaar and Darcs (there are others, but I've used these three).

All three of these only put the version control metadata in the root directory, so there's no metadata in the subfolders, so I would thinks you wouldn't have this problem...

bjnortier