How to upgrade the packages and existing repositories from Subversion 1.4 to 1.6.6 on CentOS 5.
# File: Subversion_1.6_Upgrade.notes
# Auth: burly
# Date: 12/01/2009
# Refs: http://svnbook.red-bean.com/nightly/en/index.html
# http://dev/antoinesolutions.com/subversion
# Desc: Upgrading from subversion 1.4 to 1.6.6 on CentOS 5
# NOTE:These instructions are actually fairly generic
# in regards to the version of SVN you are upgrading
# from/to. At the time of writing, it just happened
# to be 1.4 -> 1.6.6
# Backup each repository
svnadmin dump /srv/svn/<repo> > /backup/svn/<Repo>_20091201_rXXXX.dump
# Backup any hooks or configuration files in
# /srv/svn/<repo>/hooks and /srv/svn/conf
# Setup yum to allow the package to come in from
# RPMforge (must setup RPMforge repo first).
vim /etc/yum.repos.d/Centos-Base.repo
# Add the following line at the end of each section
# in the Centos-Base.repo
exclude=subversion mod_dav_svn
# Restart the yum update daemon
service yum-updatesd restart
# Upgrade subversion
yum upgrade subversion
# For each repository
# delete the existing repo
rm -rf /srv/svn/<repo>
# Create a new repo
svnadmin create /srv/svn/<repo> --fs-type fsfs
# Import the data
svnadmin load /srv/svn/<repo> < /backup/srv/<Repo>_20091201_rXXXX.dump
# Restore any hooks or configuration files in
# /srv/svn/<repo>/hooks and /srv/svn/<repo>/conf
# If you are using Trac, you'll need to resync the repo
trac-admin /srv/trac/<repo> resync
In our final post in this series, we’ll be discussing how to integrate the Subversion information into the file version automatically with .NET. Building on these previousposts, I’ll be discussing how to do this for a .NET project using Visual Studio 2010 Professional and TortoiseSVN.
I find adding a specific Version project to the solution is beneficial. The reason is that we are generating common version info to be used across the entire solution, however the first project in the build order needs to be the one to generate this info. Depending on your project dependencies there may not be an obvious or good place to do this. By adding a Version project and making all other projects depend on it we have an easy place to generate the necessary files.
Add a project named Version to your Solution
Add a reference to Version from all the other projects in your Solution
Create a file named GlobalAssemblyInfo.cs.tmpl in the Properties folder of the Version project. Copy the code below into the template and make any desired customizations to match your environment.
Notice the $WCNOW$, $WCNOW$ and $WCMODS?M:$ tokens. We’ll use these to place the necessary Subversion information in the file we generate using SubWCRev.exe.
NOTE: Originally I also had set the AssemblyFileVersion in the template as well. However, for .NET projects, placing string data in this attribute will generate a warning (like the one below), unlike the FileVersionStr in native projects.
[assembly: AssemblyFileVersion(“1.0.0.$WCREV$$WCMODS?M:$”)]
Warning 1 Assembly generation — The version ‘1.0.0.118M’ specified for the ‘file version’ is not in the normal ‘major.minor.build.revision’ format Version
Next we need to add a pre-build step to our Version project to generate the GlobalAssemblyInfo.cs file from the template using the TortoiseSVN tool called SubWCRev.
The extracted version info includes the revision number, the date time of the build and if there are any local modifications to the working copy. Note that in counter-intuitive fashion, the AssemblyTitle attribute is what sets the Description field when viewed from the Details tab of the Properties pane in Explorer. Meanwhile the AssemblyDescription field isn’t displayed at all and rather is only accessible through API calls against the binary. Why MS did this, I do not know…
Right-click on the Version project
Select Properties
Select the Build Events tab
In the Pre-build event command line box, enter: subwcrev.exe "$(SolutionDir)\" "$(ProjectDir)Properties\GlobalAssemblyInfo.cs.tmpl" "$(SolutionDir)Code\App\GlobalAssemblyInfo.cs"
In order to avoid duplicate annotations for assembly information, you must remove entries from the AssemblyInfo.cs file that appear in the GlobalAssemblyInfo.cs file. In our example here, this is what we end up with:
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyDescription("")] // This is not visible on the Details tab of the Explorer pane
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("dad09178-814d-43f4-b76d-0fbe29a32544")]
The basics of how to accomplish this are much the same as in the mercurial example. The major difference is that I don’t use WSH to generate the version file. Unlike TortoiseHg, which includes the CLI tools for Mercurial, TortoiseSVN does not. Therefore you have two choices:
Download a CLI SVN implementation like SlikSVN and implement a script similar to the one that we did for Hg.
Use the SubWCRev.exe utility that comes with TortoiseSVN to generate your version file from a template
Since I already use TortoiseSVN and SubWCRev has already done the heavy-lifting for me, I’ve decided to go that route. As usual, I’ll be doing my example using Visual Studio 2010 Professional although these techniques should work on other versions of VS as well.
Next we create a file named svn_version.h.tmpl in our project. I generally keep it under the Resources filter. This file serves as the basis of the SVN version header that we ultimately want to include in our project. The tokens (e.g. $WCREV$) will be automatically replaced by the SubWCRev utility later.
#ifndef _SVN_VERSION_H_
#define _SVN_VERSION_H_
#define SVN_LOCAL_MODIFICATIONS $WCMODS?1:0$ // 1 if there are modifications to the local working copy, 0 otherwise
#define SVN_REVISION $WCREV$ // Highest committed revision number in the working copy
#define SVN_TIME_NOW $WCNOW$ // Current system date & time
#endif
Finally we need to add a pre-build step which will execute the SubWCRev tool, thus generating the svn_version.h file prior to the binary being built.
Right-click on your project
Select Properties
Click Build Events
Click Pre-Build Event
In the Configuration drop-down, select All Configurations
In the Command Line field, enter: SubWCRev.exe $(SolutionDir) $(ProjectDir)\svn_version.h.tmpl $(ProjectDir)\svn_version.h
In the Description field, add a comment such as: Generate the svn_version.h file with the necessary repo identify info for versioning
NOTE:If you have multiple projects in the same solution that all need to use the same information from Subversion you have a few choices. One is to put the template and pre-build event in one project which all the other projects depend on and add a link to the svn_version.h file that gets generated. Another option is to create a specific version project that all it does is generate the svn_version.h file and define common version information and then have every project in the solution depends on it so it’s executed first in the build order.
The version.h file we created in the basic versioning post needs to be updated to include the generated svn_version.h file and to make use of its defines.
Finally, we need to go ahead and add an svn:ignore on svn_version.h because we don’t want its difference checking in every commit and we don’t want it constantly marking the working copy as modified if it’s tracked.
Now when each time you build your projects, the latest Subversion information of the working copy is automatically included in the file version information.
So there you have it, you can now automatically include all the necessary information from your Subversion working copy in your build to map them one-to-one with the source code that was used.
Andrew from customer support walks down to your cubicle (wait, you have an office?! jealous.) and tells you that he has Joanne on the line from Widgets and Wrenches Unlimited. She says that your remote login software is crashing and they can’t access the server that controls the CNC machine which means they can’t make tools. One of the first things you are going to want to know, is “What version of the app are you running?”
Usually if it’s a product or mature application, there will be a straightforward way to get this information – an About page or the version name right in the application shortcut for instance. When it’s a smaller app or library, or when you need more specific information than “v1.2” though, you might be up a creek. Numerous times I’ve run into this problem on an internal application where there is no installer, about page, or any other information on the version of the binary I’m looking at and what it’s origins might be. Sometimes it’s as simple as “let’s just grab the latest version and try that”, but other times that’s not an option. My solution to this problem on many projects has been to include the version information in the binary or assembly itself. At the very least someone can view the Details tab on the Properties window in Explorer and get the info directly. Best of all it works on all versions of Windows, even if the application won’t run.
Three things have been key for making this work for me:
Make the least significant number (BUILD in my example above) correspond to the revision number from the source control repository.
Note if the binary was built from a working copy with local modifications
Make it happen automatically.
With these three things, we can take a binary and know exactly what revision we need to grab from source control to reproduce the problem. Before we release a binary to anyone, we can make sure it wasn’t built with local modifications (and thus potentially seriously complicating reproducing the problem). And since it all happens automatically, we don’t have to remember jump through any hoops. Yay!
The basic concept is that a pre-build step runs which grabs the version information from the source control tool for the working copy and generates an file which is included in our project. From there we include the information into our version scheme and then it’s just applied to a normal resource version file or AssemblyInfo.cs.
Another policy I try follow on my projects is having everything build on checkout with as minimal a development environment as possible (usually just Visual Studio and the source control tools). To that end, I try to avoid bringing a scripting engine like Python into the development environment just to allow a simple build script. So to accomplish that pre-build step, I use the Javascript engine for the Windows Script Host (WSH) which is built-in since Windows 98.
Over the next several posts, I’m going to explain how to accomplish this in Visual Studio. I’ll explain how to do it for a native C/C++ binary and a C# assembly as well as automating the BUILD number from Subversion and Mercurial.