Vault317.cs :  » Build-Systems » CruiseControl.NET » ThoughtWorks » CruiseControl » Core » Sourcecontrol » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Build Systems » CruiseControl.NET 
CruiseControl.NET » ThoughtWorks » CruiseControl » Core » Sourcecontrol » Vault317.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Xml;
using ThoughtWorks.CruiseControl.Core.Util;
using ThoughtWorks.CruiseControl.Remote;

namespace ThoughtWorks.CruiseControl.Core.Sourcecontrol{
  /// <summary>
  /// Integrates with Vault 3.1.7 or later.
  /// </summary>
  public class Vault317 : Vault3
  {
    private long _folderVersion;
    private long _lastTxID;
    private CultureInfo culture = CultureInfo.CurrentCulture;
        private readonly IFileDirectoryDeleter fileDirectoryDeleter = new IoService();

    public Vault317(VaultVersionChecker versionCheckerShim) : base(versionCheckerShim)
    {
      _folderVersion = 0;
      _lastTxID = 0;
    }

    /// <summary>
    /// Called only by the unit tests, sets up as appropriate.
    /// </summary>
    /// <param name="versionCheckerShim"></param>
    /// <param name="historyParser"></param>
    /// <param name="executor"></param>
    public Vault317(VaultVersionChecker versionCheckerShim, IHistoryParser historyParser, ProcessExecutor executor) : base(versionCheckerShim, historyParser, executor)
    {}

    public override Modification[] GetModifications(IIntegrationResult from, IIntegrationResult to)
    {
      if (LookForChangesUsingVersionHistory(from, to))
        return GetModificationsFromItemHistory(from, to);
      else
      {
        // This has to be an empty array, not null, when there are no changes.
        Modification[] mods = {};
        return mods;
      }
    }

    private Modification[] GetModificationsFromItemHistory(IIntegrationResult from, IIntegrationResult to)
    {
      Log.Info(string.Format("Retrieving detailed change list for {0} in Vault Repository \"{1}\" between {2} and {3}", _shim.Folder, _shim.Repository, from.StartTime, to.StartTime));
      ProcessResult result = ExecuteWithRetries(ForHistoryProcessInfo(from, to));
      Modification[] itemModifications = ParseModifications(result, from.StartTime, to.StartTime);
      if (itemModifications == null || itemModifications.Length == 0)
        Log.Warning("Item history returned no changes.  Version history is supposed to determine if changes exist.  This is usually caused by clock skew between the CC.NET server and the Vault server.");

      // Unfortunately we have to go through these one more time to ensure there's nothing beyond the version we're going to retrieve.
      // We've made two history queries, and if changes were committed after our first check it's possible that they would be erroneously
      // included in the list of mods without this extra check.
            var modList = new List<Modification>(itemModifications.Length);
      foreach (Modification mod in itemModifications)
      {
        if (int.Parse(mod.ChangeNumber) <= _lastTxID)
          modList.Add(mod);
      }

            Modification[] modifications = modList.ToArray();
            base.FillIssueUrl(modifications);
            return modifications;
        }

    private bool LookForChangesUsingVersionHistory(IIntegrationResult from, IIntegrationResult to)
    {
      Log.Info(string.Format("Checking for modifications to {0} in Vault Repository \"{1}\" between {2} and {3}", _shim.Folder, _shim.Repository, from.StartTime, to.StartTime));

      bool bFoundChanges = GetFolderVersion(from, to);

      Log.Debug("The folder has" + (bFoundChanges ? " " : " not ") + "changed.");

      return bFoundChanges;
    }

    public override void GetSource(IIntegrationResult result)
    {
            result.BuildProgressInformation.SignalStartRunTask("Getting source from Vault");

      if (!_shim.AutoGetSource) return;
            if (_folderVersion <= 0)
            {
                throw new CruiseControlException("_folderVersion <= 0 when attempting to get source.  This shouldn't happen.");
            }                                                                                                                     
                                                                                                                      

      if (_shim.CleanCopy)
      {
        string cleanCopyWorkingFolder = null;
                if (string.IsNullOrEmpty(_shim.WorkingDirectory))
        {
          cleanCopyWorkingFolder = GetVaultWorkingFolder(result);
                    if (string.IsNullOrEmpty(cleanCopyWorkingFolder))
            throw new VaultException(
              string.Format("Vault user {0} has no working folder set for {1} in repository {2} and no working directory has been specified.",
                            _shim.Username, _shim.Folder, _shim.Repository));
        }
        else
          cleanCopyWorkingFolder = result.BaseFromWorkingDirectory(_shim.WorkingDirectory);

        Log.Debug("Cleaning out source folder: " + cleanCopyWorkingFolder);
                fileDirectoryDeleter.DeleteIncludingReadOnlyObjects(cleanCopyWorkingFolder);
      }

      Log.Info("Getting source from Vault");
      Execute(GetSourceProcessInfo(result));
    }

    public override void LabelSourceControl(IIntegrationResult result)
    {
      // only apply label if it's turned on and the integration was a success
      if (!_shim.ApplyLabel || result.Status != IntegrationStatus.Success) return;

            if (_folderVersion <= 0)
            {
                throw new CruiseControlException("_folderVersion <= 0 when attempting to get source.  This shouldn't happen.");
            }                                                                                                                     
                                                                                                                      

      Log.Info(string.Format("Applying label \"{0}\" to version {1} of {2} in repository {3}.",
                             result.Label, _folderVersion, _shim.Folder, _shim.Repository));
      Execute(LabelProcessInfo(result));
    }

    private ProcessInfo LabelProcessInfo(IIntegrationResult result)
    {
      var builder = new PrivateArguments();
      builder.Add("label ", _shim.Folder);
      builder.Add(result.Label);
      builder.Add(_folderVersion);
      AddCommonOptionalArguments(builder);
            return ProcessInfoFor(builder, result);
    }

    /// <summary>
    /// Gets the most recent folder version via Vault's versionhistory command.
    /// 
    /// If we don't yet have a folder version, we need to get one so getSource and LabelSource have a version to work with,
    /// whether there's been changes or not.  (On a forced build or a multi-source control setup, we might get and/or label
    /// when there's been no change.)
    /// 
    /// So if we have no folder version, we get the latest version of the folder via Vault's versionhistory command and see
    /// if the timestamp on that folder is more recent than the last build.  If we already have a folder version, we simply
    /// ask Vault to give us the most recent folder version after then one we already know about.
    /// </summary>
    /// <param name="from"></param>
    /// <param name="to"></param>
    /// <returns></returns>
    private bool GetFolderVersion(IIntegrationResult from, IIntegrationResult to)
    {
      bool bFoundChanges = false;

      // If we don't yet have a folder version, we need to just get the latest, rather than checking for a change.
      bool bForceGetLatestVersion = (_folderVersion == 0);

      // get version history
      ProcessResult result = ExecuteWithRetries(VersionHistoryProcessInfo(from, to, bForceGetLatestVersion));

      // parse out changes
      string versionHistory = Vault3.ExtractXmlFromOutput(result.StandardOutput);
      XmlDocument versionHistoryXml = new XmlDocument();
      versionHistoryXml.LoadXml(versionHistory);
      XmlNodeList versionNodeList = versionHistoryXml.SelectNodes("/vault/history/item");
      XmlNode folderVersionNode = null;
      if (bForceGetLatestVersion)
      {
                if (versionNodeList.Count != 1)
                {
                    throw new CruiseControlException("Attempted to retrieve folder's current version and got no results.");
                }
                folderVersionNode = versionNodeList.Item(0);
      }
      else
      {
                if (versionNodeList.Count != 0 && versionNodeList.Count != 1)
                {
                    throw new CruiseControlException("Vault versionhistory -rowlimit 1 returned more than 1 row.");
                }
                if (versionNodeList.Count == 1)
        {
          folderVersionNode = versionNodeList.Item(0);
          // We asked vault for only new folder versions, so if we got one, the folder has changed.
          bFoundChanges = true;
        }
      }

      if (folderVersionNode != null)
      {
        if (bForceGetLatestVersion)
        {
          // We asked Vault for the most recent folder version.  We have to check its date to
          // see if this represents a change since the last integration.
          XmlAttribute dateAttr = (XmlAttribute) folderVersionNode.Attributes.GetNamedItem("date");
                    if (dateAttr == null)
                    {
                        throw new CruiseControlException("date attribute not found in version history");
                    }
                    DateTime dtLastChange = DateTime.Parse(dateAttr.Value, culture);
          if (dtLastChange > from.StartTime)
            bFoundChanges = true;
        }
        // get the new most recent folder version
        XmlAttribute versionAttr = (XmlAttribute) folderVersionNode.Attributes.GetNamedItem("version");
                if (versionAttr == null)
                {
                    throw new CruiseControlException("version attribute not found in version history");
                }
                _folderVersion = long.Parse(versionAttr.Value);
        Log.Debug("Most recent folder version: " + _folderVersion);

        // get the new most recent TxId
        XmlAttribute txIdAttr = (XmlAttribute) folderVersionNode.Attributes.GetNamedItem("txid");
                if (txIdAttr == null)
                {
                    throw new CruiseControlException("txid attribute not found in version history");
                }
                _lastTxID = long.Parse(txIdAttr.Value);
        Log.Debug("Most recent TxID: " + _lastTxID);
      }

      return bFoundChanges;
    }

    private ProcessInfo VersionHistoryProcessInfo(IIntegrationResult from, IIntegrationResult to, bool bForceGetLatestVersion)
    {
            var builder = new PrivateArguments();
      builder.Add("versionhistory ", _shim.Folder);

      // Look only for changes, unless caller asked us to get the latest folder 
      // version regardless of whether there's been a change.
      if (!bForceGetLatestVersion)
      {
        // use folderVersion when possible because it's faster and more accurate
        if (_folderVersion != 0)
        {
          builder.Add("-beginversion ", (_folderVersion + 1).ToString());
        }
        else
        {
          builder.Add("-begindate ", from.StartTime.ToString("s"));
          builder.Add("-enddate ", to.StartTime.ToString("s"));
        }
      }

      // we only ever need the most recent change
      builder.Add("-rowlimit ", "1");

      AddCommonOptionalArguments(builder);
            return ProcessInfoFor(builder, from);
    }

    private ProcessInfo GetSourceProcessInfo(IIntegrationResult result)
    {
            var builder = new PrivateArguments();

      builder.Add("getversion ", _folderVersion.ToString());
      builder.Add(null, _shim.Folder, true);

            if (!string.IsNullOrEmpty(_shim.WorkingDirectory))
      {
        builder.Add(null, result.BaseFromWorkingDirectory(_shim.WorkingDirectory), true);
                if (_shim.UseVaultWorkingDirectory)
                {
                    builder.Add("-useworkingfolder");
                }
      }

      builder.Add("-merge ", "overwrite");
      builder.Add("-makewritable");
      builder.Add("-backup ", "no");
      builder.Add("-setfiletime ", _shim.setFileTime);
      AddCommonOptionalArguments(builder);
      return ProcessInfoFor(builder, result);
    }

  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.