Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Connecting Visual SourceSafe 2005 and Bugzilla

0.00/5 (No votes)
5 Jan 2010 1  
A plug-in for Visual SourceSafe 2005 that allows for attaching comments to Bugzilla bug entries when committing changes.

Introduction

Connecting a source code repository with other systems is not uncommon today; e.g., when committing changes, comments can be attached to bug entries, listing the files changed or added with the revision and the comment attached by the developer. The Open Source bug tracking tool Bugzilla supports integration of a variety of SCM systems, and there are many issue tracking systems around that provide VSS integration. With the use of the VSS automation interface, the common interfaces of Bugzilla, and the tool Bugzilla itself, this article describes how and in what manner it is possible to integrate VSS 2005 with Bugzilla.

Background

Bugzilla and SCM integration

By using the integration daemon scmbug, Bugzilla can be integrated with CVS or Subversion (scmbug supports a variety of bug tracking and source code management systems). But, what does integration mean? It means that, when committing a change in Subversion (or CVS), a bug ID can be provided and a comment is added to the bug, containing the list of files changed, added, removed, and the comment attached to the commit. The comment in Subversion gets added with the link to the corresponding bug in Bugzilla. When setting up scmbug on a Subversion repository, some scripts are added to the Subversion hooks that do the actual comment entering to Bugzilla. The bug ID in Subversion can either be provided via Subversion's bugtraq fields (when using Tortoise SVN client) or via a hint in the comment. But there is no such integration with Bugzilla and VSS 2005 yet.

Bugzilla and Visual SourceSafe 2005

VSS 2005 provides the SourceSafe automation layer, a collection of COM based interfaces which provides a mechanism to write add-ins that react on specific VSS 2005 events like before check-in or before add. That means, when reacting on events via the plug-in, some comment entry to Bugzilla can be written. For the plug-in, connection to Bugzilla and modification of Bugzilla entries is done through the bugzproxy library (also requires xml-rpc.net), a library written in C# that uses Bugzilla's Web Service interface:

Using the code

The plug-in consists of the following parts:

  • The main class derived from IVSSEventHandler and IVSSEvents
  • A small form to enter bug entries
  • A very simple ini file handler
  • A very simple log file handler

The main class reacts on the events that are fired before checking in a file and before adding a file. What happens is, depending on the configuration, either a small dialog is shown to enter the bug ID, or the bug ID is to be extracted from a comment. Certain options are evaluated, whether a bug ID is always required or optional, or whether a bug ID may/need also be entered when adding a file. If the bug ID has to be extracted out of a comment, this will be done using Regular Expressions.

public bool BeforeAdd(VSSItem vssItem, string localSpec, string comment)
{
    if (iniFile.Sections["Plugin"]["RequestBugIDWhenAddingFile"] == "1")
    {
        return ProcessBugInformation(vssItem, localSpec, comment, true);
    }
    else
        return true;
}

public bool BeforeCheckin(VSSItem vssItem, string localSpec, string comment)
{
    return ProcessBugInformation(vssItem, localSpec, comment, false);
}

/// Does all preprocessing: show the bugID dialog or exctract the bugID
/// out of the comment information
private bool ProcessBugInformation(VSSItem vssItem, 
             string localSpec, string comment, bool isFileAdd)
{
    // The dialog is used to enter the BugID
    if (iniFile.Sections["Plugin"]["UseBugIDDialog"] == "1")
    {
        FormEnterBugID form = 
          new FormEnterBugID(vssItem, localSpec, comment, isFileAdd);
        // The dialog to enter the BugID (if shown) is non modal
        // so checkin can be aborted, if Bugzilla was not available or
        // refused entering a bug id
        if (form.ShowDialog() == DialogResult.OK)
        {
            form = null;
            return true;
        }
        else
        {
            form = null;
            return false;
        }
    }
    else 
    {
        // If not, then, a bug ID might be expected
        // at the beginning of a comment

        // Try to get the BugID form the comment
        Regex BugIDRegExp = new Regex(
          iniFile.Sections["Plugin"]["BugIDRegExp"]);
        Match bugID = BugIDRegExp.Match(comment);

        if (bugID.Value.Length > 0)
        {
            BOEnterComment bo = new BOEnterComment();
            // Exctract the ID only of the previous extracted bugID
            Regex BugNumber = new Regex("[0-9]*");
            Match bugNum = BugNumber.Match(bugID.Value);
            if (bo.AppendComment(vssItem, localSpec, comment, 
                                 bugNum.Value, isFileAdd))
            {
                bo = null;
                return true;
            }
            else
            {
                bo = null;
                return false;
            }
        }
        else
        {
            // A Bug ID is required always
            if (iniFile.Sections["Plugin"]["AlwaysRequireValidBugID"] == "1")
            {
                LogFileHandler.writeToLogFile(LogSeverity.ERROR, 
                  "No valid Bug ID was provided in the comment");
                MessageBox.Show("No valid Bug ID was provided in the comment", 
                    "VSSBugzilla Plugin: Error", 
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            else
                return true;
        }
    }
}

The actual comment submission is done within the class BOAppendComment. First, the connection information for Bugzilla is read from the configuration file, and the connection via the bugzproxy library established. Depending on whether a new file is submitted or a change to an existing file is checked in, the project path is retrieved from either localSpec or the vssItem object and the comment submitted to the given bug ID.

/// Appends a comment to a given bugzilla bug entry
public bool AppendComment(VSSItem vssItem, string localSpec, 
            string comment, string BugID, bool isFileAdd)
{
    IniFileHandler iniFile = IniFileHandler.Instance;

    string host = String.Empty;
    string path = String.Empty;

    try
    {
        host = iniFile.Sections["Bugzilla"]["Host"];
    }
    catch(Exception e)
    {
        LogFileHandler.writeToLogFile(LogSeverity.ERROR, 
          "No host value defined in ini file\n" + e.Message);
        MessageBox.Show("No host value defined in ini file", 
          "VSSBugzilla Plugin: Error", 
          MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

    uint port = Convert.ToUInt32(iniFile.Sections["Bugzilla"]["Port"]);

    // Path may be undefined - so catch an eventually thrown exception
    // and assign the empty string value
    try
    {
        path = iniFile.Sections["Bugzilla"]["Path"];
    }
    catch (Exception e)
    {
        path = String.Empty;
    }

    string user = iniFile.Sections["Bugzilla"]["User"];
    string pass = iniFile.Sections["Bugzilla"]["Pass"];

    int bugID;

    //Convert the bugID form text to integer
    try
    {
        bugID = System.Convert.ToInt32(BugID);
    }
    catch (Exception e)
    {
        LogFileHandler.writeToLogFile(LogSeverity.ERROR, e.Message);
        MessageBox.Show(e.Message, "VSSBugzilla Plugin: Error", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
    }

    Server server = new Server(host, port, path);

    try
    {
        // Login
        int res = server.Login(user, pass, true);
        if (res <= 0)
        {
            LogFileHandler.writeToLogFile(LogSeverity.ERROR, 
                  "Could not login to " + host + path);
            MessageBox.Show("Could not login to " + host + path, 
               "VSSBugzilla Plugin: Error", 
               MessageBoxButtons.OK, MessageBoxIcon.Error);
            return false;
        }
        LogFileHandler.writeToLogFile(LogSeverity.INFO, "Login to " + 
          host + path + " with user " + user + " successful");
        // This statement will throw an exception, if the bug is not valid
        if (isFileAdd)
            server.GetBug(bugID).AppendComment("The following file(s) " + 
              "has/have been added by a visual source safe commit:\n\n" + 
              vssItem.Spec + "/" + ExtractFileName(localSpec) + 
              "\n\nReason:\n" + comment, null, null);                
        else
            server.GetBug(bugID).AppendComment("The following file(s) " + 
              "has/have been changed by a visual source safe commit:\n\n" + 
              vssItem.Spec + "\tat Version " + 
              (vssItem.VersionNumber + 1).ToString() + 
              "\n\nReason:\n" + comment, null, null);                
        if (isFileAdd)
            LogFileHandler.writeToLogFile(LogSeverity.INFO, 
              "Comment appended to Bug " + bugID + 
              " when commiting file " + vssItem.Spec + 
              "/" + ExtractFileName(localSpec));
        else
            LogFileHandler.writeToLogFile(LogSeverity.INFO, 
              "Comment appended to Bug " + bugID + 
              " when commiting file " + vssItem.Spec + 
              " at Version " + (vssItem.VersionNumber + 1).ToString());
    }
    catch (Exception e)
    {
        LogFileHandler.writeToLogFile(LogSeverity.ERROR, e.Message);
        MessageBox.Show(e.Message, "VSSBugzilla Plugin: Error", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
    }
    
    return true;
}

Using the plug-in

The plug-in has been tested against Bugzilla 3.2.4.

Installation

  1. Copy CookComputing.XmlRpcV2.dll, bugzproxy.dll, VSSBugzillaPlugin.dll, and VSSBugzillaPlugin.ini into the VSS 2005 installation directory, e.g., "C:\\Program Files\Microsoft Visual Sourcesafe".
  2. Register VSSBugzillaPlugin.dll issuing the following command: "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe" "C:\Program Files\Microsoft Visual SourceSafe\VSSBugzillaPlugin.dll" (adapt path of RegAsm.exe and plug-in if located in different locations).
  3. Create or edit the file ssaddin.ini and add the line Microsoft.SourceSafe.VSSBugzillaPlugin = 1.
  4. Edit the settings in the VSSBugzillaPlugin.ini configuration file (the settings are explained below).

Configuration

This section describes the settings that must be provided via VSSBugzillaPlugin.ini.

  • Host - The server where Bugzilla is installed, without the leading http://.
  • Port - The server port.
  • Path - The path to Bugzilla on the server; e.g., Bugzilla may be installed under http://someserver/bugzilla, so the path must be set to bugzilla.
  • User - The Bugzilla username.
  • Pass - Password.
  • Logging - Setting this to 1 turns logging on; 0 turns logging of.
  • LogFilePath - The full path to the log file, e.g., C:\temp\VSSBugzillaPlugin.log.
  • UseBugIDDialog - Setting this variable to 1 will show the dialog to enter the bug ID, 0 will require the bug ID to be entered at the beginning of a comment.
  • AlwaysRequireValidBugID - Setting this variable to 1 will require a bug ID to be given on every check-in.
  • RequestBugIDWhenAddingFile - Setting this variable to 1 will turn on bug ID processing when adding files to the repository.
  • BugIDRegExp - The Regular Expression that is to be used when bug IDs are to be recognized via comment information.

Limitations

There are two main limitations to using the Visual SourceSafe 2005 Automation layer plug-in mechanism together with Bugzilla.

  • Although Visual SourceSafe 2005 actually knows that it is checking in multiple files (by showing a dialog named "Checkin multiple"), it does not provide this information to the vssItem when the checkin event is fired. It is clear that the checkin event is fired for every item checked in, but there is no proper way to find out which files belong to the same check-in.
  • Although the "before..." events are caught, there is no way to change either comment or VSS item information. Therefore, it is not possible to add the bug ID information to the actual Visual SourceSafe 2005 commit.

References

History

  • 4th January, 2010: First version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here