Apply Versioning to Features: A How To for SharePoint Developers

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 :: "

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
        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
            descParts = Split(description, "|")

            if uBound(descParts) > 1 then
               newDescription = descParts(0)
               for i = 1 to uBound(descParts) - 1 
                    newDescription = newDescription & "|" & descParts(i)
                newDescription = descParts(0)
            end if

            newDescription = newDescription & "| " & assemblyInfo        

        end if

        node.setAttribute "Description", newDescription
    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

    Set ts = nothing
    Set fso = nothing

end function 

function errQuit(message)
    WScript.Echo fileHeader & message
    WScript.Quit 1
end function
  • Facebook
  • DZone It!
  • Digg It!
  • StumbleUpon
  • Technorati
  • NewsVine
  • Reddit
  • Blinklist
  • Furl it!
Post a comment!
  1. Formatting options

Rss Feed
    follow me on Twitter

    Where I'm Going

    Some Writing I've Done

    Chat With Me