|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
IntroductionI have been using TortoiseSVN for a while now and it has proven a great way to use Subversion in the Windows / Visual Studio environment. I recently discovered how use SVN Keywords in my projects. If you enable SVN Keywords then every time you check in the project Subversion scans your files for certain "keywords" and replaces the keywords with some information. For example, At the top of my source files I would create a header contain the following keywords: '$Author: paulbetteridge $ I thought that if I take the $Rev$ keyword I could use this as part of my software version so that I could keep track of the version and the build when it is released. I would have a version that would look like 1.0.0.145. The limitation of using the $Rev$ keyword is that it only gives you the revision of the file and not the entire project so using $rev$ keyword cannot work as part of my software versioning. Reading the Tortoise help files I found a tool supplied with Tortoise SVN called SubWCRev.exe. SubWCRev is Windows console program which can be used to read the status of a Subversion working copy and perform keyword substitution in a template file. This article shows you how you can use SubWCRev to embed the top level revision number into your projects. Using the codeThe code performs three tasks: [1] Creates a template file containing keywords that are read by SubWCRev [2] Runs the SubWCRev.exe which produces an output text file containing subversion information based on the keywords from the template file. [3] Reads the output file and returns values from the file into an array for use by your project. The project attached is written in VB.Net but I have also provided the C# implementation in this article. Template FileThe template file is created by this code and will contain ALL available commands that are read by SubWCRev:
VB.NET
Dim strTemplateFile As String = "SvnTemplate.txt"
Dim bAns As Boolean = False
Dim objReader As StreamWriter
Dim strData As String
strData = "$WCREV$" + vbCrLf + _
"$WCDATE$" + vbCrLf + _
"$WCNOW$" + vbCrLf + _
"$WCRANGE$" + vbCrLf + _
"$WCMIXED?Mixed update revision:Not mixed$" + vbCrLf + _
"$WCMODS?Modified:Not modified$" + vbCrLf + _
"$WCURL$" + vbCrLf + _
"$WCNOW$" + vbCrLf + _
"$WCINSVN?Versioned:Not Versioned$" + vbCrLf + _
"$WCNEEDSLOCK?Lock Required:Lock not required$" + vbCrLf + _
"$WCISLOCKED?Locked:Not Locked$" + vbCrLf + _
"$WCLOCKDATE$" + vbCrLf + _
"$WCLOCKOWNER$" + vbCrLf + _
"$WCLOCKCOMMENT$" + vbCrLf
Try
objReader = New StreamWriter(strTemplateFile)
objReader.Write(strData)
objReader.Close()
Catch Ex As Exception
Console.WriteLine(Ex.Message)
End Try
C#
string strTemplateFile = @"SvnTemplate.txt"
bool bAns = false;
StreamWriter objReader;
string strData;
strData = "$WCREV$" + Constants.vbCrLf +
"$WCDATE$" + Constants.vbCrLf +
"$WCNOW$" + Constants.vbCrLf +
"$WCRANGE$" + Constants.vbCrLf +
"$WCMIXED?Mixed update revision:Not mixed$" + Constants.vbCrLf +
"$WCMODS?Modified:Not modified$" + Constants.vbCrLf +
"$WCURL$" + Constants.vbCrLf +
"$WCNOW$" + Constants.vbCrLf +
"$WCINSVN?Versioned:Not Versioned$" + Constants.vbCrLf +
"$WCNEEDSLOCK?Lock Required:Lock not required$" + Constants.vbCrLf +
"$WCISLOCKED?Locked:Not Locked$" + Constants.vbCrLf +
"$WCLOCKDATE$" + Constants.vbCrLf +
"$WCLOCKOWNER$" + Constants.vbCrLf +
"$WCLOCKCOMMENT$" + Constants.vbCrLf;
try {
objReader = new StreamWriter(strTemplateFile);
objReader.Write(strData);
objReader.Close();
}
catch (Exception Ex) {
Console.WriteLine(Ex.Message);
}
Create the Revision InformationOnce you have your template file you need to run the command line tool SubWCRev.exe passing in three parameters - the Working Directory of your source code, the template file location and the location you want to store your output file containing your revision information. VB.NET
Dim strRev As String = ""
' Input file containing the SubWcRev keywords
Dim strTemplateFile As String = "svntemplate.txt"
' Output file that will contain the SVN revisions after calling SubWcRev.exe
Dim strRevOutputFile As String = "svnrev.txt"
' If we are running as an exe (i.e. not in the Visual Studio IDE)
' then we dont want to create the revisions but read what is
' already there. This assumes that the exe is being used on a
' non-subversion machine
' Check for the IDE, True is it is or false if it is not
' (assume false is running as an exe)
If System.Diagnostics.Debugger.IsAttached Then
' Get the working directory of the application exe - not the most
' glamourous way to do this so need to rethink this!!!
Dim dirInfo As New DirectoryInfo(Application.ExecutablePath)
Dim dirinfoSourceWorkingDir As DirectoryInfo
dirinfoSourceWorkingDir = dirInfo.Parent().Parent().Parent()
Dim strSourceWorkingDir As String = dirinfoSourceWorkingDir.FullName
' The template file is a text file containing some
' keyword that are recognised by SubWcRev.exe when it
' is run against the root project directory.
' Creates the template file is it is not already there
SvnCreateTemplate(strTemplateFile)
' Now create a process to run the SubWcRec.exe
Try
Dim p As New Process
With p.StartInfo
.UseShellExecute = True
.FileName = "subwcrev.exe"
.Arguments = """" + strSourceWorkingDir + """ """ + _
strTemplateFile + """ """ + _
strRevOutputFile + """"
.UseShellExecute = False
.RedirectStandardOutput = True
End With
' Execute the process and wait for it to exit
If p.Start() Then
Dim output As String = p.StandardOutput.ReadToEnd()
Console.WriteLine(output)
p.WaitForExit()
End If
Catch ex As Exception
Console.WriteLine(ex.Message)
' Probably because Subversion not installed
' and SubWcRev.exe was not found
End Try
End If
C#
string strRev = "";
// Input file containing the SubWcRev keywords
string strTemplateFile = "svntemplate.txt"
// Output file that will contain the SVN revisions after calling SubWcRev.exe
string strRevOutputFile = "svnrev.txt";
// If we are running as an exe (i.e. not in the Visual Studio IDE)
// then we dont want to create the revisions but read what
// is already there. This assumes that the exe is being used
// on a non-subversion machine
// Check for the IDE, True is it is or false if it is not
// (assume false is running as an exe)
if (System.Diagnostics.Debugger.IsAttached) {
// Get the working directory of the application exe - not the most
// glamourous way to do this so need to rethink this!!!
DirectoryInfo dirInfo = new DirectoryInfo(Application.ExecutablePath);
DirectoryInfo dirinfoSourceWorkingDir;
dirinfoSourceWorkingDir = dirInfo.Parent().Parent().Parent();
string strSourceWorkingDir = dirinfoSourceWorkingDir.FullName;
// The template file is a text file containing some keyword that are ~
// recognised by SubWcRev.exe when it
// is run against the root project directory.
// Creates the template file is it is not already there
SvnCreateTemplate(strTemplateFile);
// Now create a process to run the SubWcRec.exe
try {
Process p = new Process();
{
p.StartInfo.UseShellExecute = true;
p.StartInfo.FileName = "subwcrev.exe";
p.StartInfo.Arguments = "\"" + strSourceWorkingDir +
"\" \"" + strTemplateFile + "\" \"" +
strRevOutputFile + "\"";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
}
// Execute the process and wait for it to exit
if (p.Start()) {
string output = p.StandardOutput.ReadToEnd();
Console.WriteLine(output);
p.WaitForExit();
}
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
// Probably because Subversion not installed and SubWcRev.exe was not found
}
}
You now have the output file created so next you need to read this file into your application so you can start using the revision information. VB.Net
' The revison should now be available in the output file -
' reading this will get the revision
' There are three lines (Rev, Modifed status and Rev Date)
Dim strContents As String = ""
Dim objReader As StreamReader
Try
objReader = New StreamReader(strRevOutputFile)
strContents = objReader.ReadToEnd()
objReader.Close()
' Get the revision from the contents of the file
aRevData = Split(strContents, vbCrLf)
Catch Ex As Exception
Console.WriteLine(Ex.Message)
' Probably because Subversion is not installed or this
' project has not been checked into
' subversion yet. You muct make sure it is checked in to create a revision
If System.Diagnostics.Debugger.IsAttached Then
MessageBox.Show(Ex.Message + vbCrLf + vbCrLf + _
"This is probably because this project is not " + _
"under subversion revision control yet or the " + _
"output file was not created by ""subwcrev.exe""")
Else
MessageBox.Show(Ex.Message + vbCrLf + vbCrLf + _
"This is probably because the output file " + _
"""svnrev.txt"" has not been created yet - need " + _
"run this using the Visual Studio IDE first to " + _
"create the svnrev.txt file containing the SVN values!")
End If
aRevData(0) = """svnrev.txt"" file not Found"
End Try
C#
{
// The revison should now be available in the output file - reading this
// will get the revision
// There are three lines (Rev, Modifed status and Rev Date)
string strContents = "";
StreamReader objReader;
try {
objReader = new StreamReader(strRevOutputFile);
strContents = objReader.ReadToEnd();
objReader.Close();
// Get the revision from the contents of the file
aRevData = Strings.Split(strContents, Constants.vbCrLf);
}
catch (Exception Ex) {
Console.WriteLine(Ex.Message);
// Probably because Subversion is not installed or this project
// has not been checked into
// subversion yet. You muct make sure it is checked in to create a revision
if (System.Diagnostics.Debugger.IsAttached) {
MessageBox.Show(Ex.Message + Constants.vbCrLf + Constants.vbCrLf +
"This is probably because this project is not under subversion " +
"revision control yet or the output file was not " +
"created by \"subwcrev.exe\"");
}
else {
MessageBox.Show(Ex.Message + Constants.vbCrLf + Constants.vbCrLf +
"This is probably because the output file \"svnrev.txt\" " +
"has not been created yet - need run this using the " +
"Visual Studio IDE first to create the svnrev.txt file " +
"containing the SVN values!");
}
aRevData(0) = "\"svnrev.txt\" file not Found";
}
}
I return the contents of the file into a string array called "aRevData". I pre-initialised this array first with values in case the template file is not created or
there was a problem somewhere. This would then allow you to use the
pre-initialised values in your project if you are unable to get hold of the SVN values (an example is if you dont have subversion installed or you havent checked your project into subversion yet). Using the Revision DataWrapping this article up below shows you show I would use the code - please take a look at the project posted. I use the variable "AppVersion" in my About forms / Splash Screens etc and as my software version for official releases of the application. VB.NET
' Create the revision data array - initialise to initial values - date will be
' overwritten if reading the svn file is ok
Dim aRevHeaders() As String = {"$WCREV$", _
"$WCDATE$", _
"$WCNOW$", _
"$WCRANGE$", _
"$WCMIXED$", _
"$WCMODS$", _
"$WCURL$", _
"$WCNOW$", _
"$WCINSVN?Versioned:Not Versioned$", _
"$WCNEEDSLOCK$", _
"$WCISLOCKED$", _
"$WCLOCKDATE$", _
"$WCLOCKOWNER$", _
"$WCLOCKCOMMENT$"}
Dim aRevData() As String = {"0", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}
' Read and write to the svnrevisions text file so that it forces subversion to update
' the file with the latest revision - there are no global revisions keyword so this
' is an alternative!
Try
SvnGetlatestRev(aRevData) ' Create and read the svn revision file
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Dim strVersion As String() = Split(Application.ProductVersion, ".")
Dim AppVersion As String = String.Format("{0}.{1}.{2}.{3}", _
strVersion(0), _
strVersion(1), _
strVersion(2), _
aRevData(0))
C#
// Create the revision data array - initialise to initial values - date will be
// overwritten if reading the svn file is ok
string[] aRevHeaders = {"$WCREV$",
"$WCDATE$",
"$WCNOW$",
"$WCRANGE$",
"$WCMIXED$",
"$WCMODS$",
"$WCURL$",
"$WCNOW$",
"$WCINSVN?Versioned:Not Versioned$",
"$WCNEEDSLOCK$",
"$WCISLOCKED$",
"$WCLOCKDATE$",
"$WCLOCKOWNER$",
"$WCLOCKCOMMENT$"};
string[] aRevData = {"0", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};
// Read and write to the svnrevisions text file so that it forces subversion to update
// the file with the latest revision - there are no global revisions keyword so this
// is an alternative!
try {
SvnGetlatestRev(aRevData);
// Create and read the svn revision file
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
string[] strVersion = Strings.Split(Application.ProductVersion, ".");
string AppVersion = string.Format("{0}.{1}.{2}.{3}", strVersion(0), strVersion(1), strVersion(2), aRevData(0));
I have seen in the Tortoise help files that I could make use of the COM interface - this is something for another day. Thank you for reading this article. Please leave your comments and ways I can improve this. HistorypbRevsion v1.0
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||