It's a well known fact that versioning webparts is a real pain in the butt. Big Jim in DC and I have been pondering, searching the Internet and discussing what are some good ways to version web parts and features. Today we decided to do something about it and came up with a simple strategy. Use pre-build events to call a script that writes a value to the AssemblyFileVersion attribute of the assebmlyInfo.cs (sorry vb'ers your just going to have to modify the scripts on your own ). Then with another script read that value from the assemblyInfo.cs and write it to the feature.xml. The description attribute to be specific. That way from the user interface you can see the version and time built.
Jim wrote the script to update the Assembly and it can be found here.
This is what my pre-build events look like:
CD "$(ProjectDir)UTILS"
cscript /nologo UpdateAssemblyFileVersion.vbs "$(ProjectDir)properties\AssemblyInfo.cs"
cscript /nologo UpdateFeatureDescriptionVersion.vbs "$(ProjectDir)TEMPLATE\FEATURES\$(SolutionName)\Feature.xml" "$(ProjectDir)properties\AssemblyInfo.cs"
The source below will read just about any attribute in the assemblyInfo.cs file and append it to the end of the description for the feature (the description attribute of feature.xml). Mine looks like this "| AssemblyFileVersion: 1.0.62223.1901 Built: 10/23/2007 7:01:03 PM". It's pretty easy to see where the variable assemblyInfo is being create and modify as you meet your needs.
' VBScript source code
'------------------------------------------------------------------------------
'--- UpdateFeatureDescriptionVersion.vbs
'------------------------------------------------------------------------------
'--- Author - Stacy Draper
'--- Date - 2007.10.23
'------------------------------------------------------------------------------
'--- This updates the description attribute of the feature node found in
'--- feature.xml with the information found in AssebmlyInfo.cs.
'------------------------------------------------------------------------------
Option Explicit
Dim fileHeader
fileHeader = "UpdateAssemblyFileVersion.vbs :: "
EnsureCommandLineArgumentExists
EnsureFileExists WScript.Arguments(0), "Feature.xml"
EnsureFileExists WScript.Arguments(1), "AssemblyInfo.cs"
UpdateFeatureXml WScript.Arguments(0), WScript.Arguments(1)
Private Sub EnsureCommandLineArgumentExists()
If WScript.Arguments.Count <> 2 Then
WScript.Echo fileHeader & "You must supply the path to the AssemblyInfo.cs and feature.xml files as arguments."
WScript.Quit 1
End If
End Sub
Private Sub EnsureFileExists(path, fileName)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists(path) Then
WScript.Echo fileHeader & fileName & " does not exist at the path provided -> " & path
WScript.Quit 1
End If
Set fso = Nothing
End Sub
Function UpdateFeatureXml(featurePath, assemblyInfoPath)
Dim node, xmlDoc, description, newDescription, descParts, assemblyInfo, posPipe, i
Set xmlDoc = CreateObject("Msxml2.DOMDocument.3.0")
xmlDoc.async = False
xmlDoc.Load featurePath
If (xmlDoc.parseError.errorCode <> 0) Then
Dim myErr
Set myErr = xmlDoc.parseError
errQuit "An error occured -> " & myErr.reason
Else
Set node = xmlDoc.selectSingleNode("//Feature")
if isNull(node) or (node is nothing) then
errQuit "Missing Feature node in feature.xml "
end if
description = node.getAttribute("Description")
if isNull(description) or (len(trim(description)) = 0) then
errQuit "Missing description attribute of Feature node in feature.xml "
end if
assemblyInfo = ""
assemblyInfo = assemblyInfo & "AssemblyFileVersion: " & getAttribValue(assemblyInfoPath, "AssemblyFileVersion")
assemblyInfo = assemblyInfo & " Built: " & Now()
posPipe = inStr(description, "|")
if isNull(posPipe) or posPipe = 0 then
newDescription = description & " | " & assemblyInfo
else
descParts = Split(description, "|")
if uBound(descParts) > 1 then
newDescription = descParts(0)
for i = 1 to uBound(descParts) - 1
newDescription = newDescription & "|" & descParts(i)
next
else
newDescription = descParts(0)
end if
newDescription = newDescription & "| " & assemblyInfo
end if
node.setAttribute "Description", newDescription
xmlDoc.save(featurePath)
End If
End Function
function getAttribValue(path, attrib)
Dim fso, f1, ts, s
Dim startAttrib, startAttribValue, endAttribValue, strAttribValue
Const ForReading = 1
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(path, ForReading)
s = ts.ReadAll
startAttrib = inStr (s, attrib)
if (isNull(startAttrib) or startAttrib = 0) then
errQuit attrib & " doesn't exist in AssemblyInfo.cs "
end if
startAttribValue = startAttrib + len(attrib) + 2
endAttribValue = inStr(startAttribValue, s, ")") -1
if (isNull(endAttribValue) or endAttribValue = 0) then
errQuit attrib & " didn't end as expected in AssemblyInfo.cs "
end if
strAttribValue = mid(s, startAttribValue, endAttribValue - startAttribValue)
getAttribValue = strAttribValue
ts.Close
Set ts = nothing
Set fso = nothing
end function
function errQuit(message)
WScript.Echo fileHeader & message
WScript.Echo
WScript.Quit 1
end function