Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
BuildTasks.TDSExcludeRulesValidator / MSBuild Task for monitoring the Exclude Rules in a Sitecore TDS Project file.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace BuildTasks.TdsExcludeRulesValidator
{
/// <summary>
/// MSBuild Task for monitoring the Exclude Rules in a Sitecore TDS Project file.
/// </summary>
/// <remarks>
/// We use TDS Deployment straigt to production and UAT, therefore we require build safety for validating that no content from the Content and Media Nodes is released to these environments.
/// </remarks>
/// <example>
/// Add the msbuild task to the relevant csproj project file with using task directive in the header and insert the command in the appropriate Target
/// -- UsingTask TaskName="BuildTasks.TdsExcludeRulesValidator.TdsExcludeRulesValidator" AssemblyFile="..\Lib\BuildTasks.TDSExcludeRulesValidator.dll"
/// -- TdsExcludeRulesValidator MonitorSitecorePaths="sitecore\content|sitecore\media" RequireExcludes="Prod.Cms|UAT" TdsProjectPath="..\Client.Sitecore.Master\Client.Sitecore.Master.scproj"
/// </example>
public class TdsExcludeRulesValidator : Task
{
private static List<string> _errorList;
/// <summary>
/// File Path to the Tds Project file
/// </summary>
/// <example>..\sitecore.master\sitecore.master.csproj</example>
[Required]
public string TdsProjectPath { get; set; }
/// <summary>
/// Sitecore Paths to be monitored for exclude rules
/// </summary>
/// <example>sitecore\content|sitecore\media</example>
[Required]
public string MonitorSitecorePaths { get; set; }
/// <summary>
/// Exclude environments required to be present on Items from the monitored Paths
/// </summary>
/// <example>Prod.Cms|UAT</example>
[Required]
public string RequireExcludes { get; set; }
public override bool Execute()
{
if (!File.Exists(TdsProjectPath))
{
Log.LogMessage(MessageImportance.High, "Could not find Sitecore.Master csproj filePath in msbuild parameters for TdsExcludeRulesValidator - unable to validate");
return false;
}
var validationErrors = ValidateProjectFile(TdsProjectPath, new ValidationArgs(MonitorSitecorePaths, RequireExcludes));
if (validationErrors.Any())
{
validationErrors.ForEach(v => Log.LogError("TdsExcludeRulesValidator","Invalid Tds Exclude Rule",string.Empty, TdsProjectPath, 0,0,0,0,v,null));
return false;
}
Log.LogMessage(MessageImportance.High, string.Format("TdsExcludeRulesValidator OK - all Sitecore Items in {0} have been marked as Excluded {1} in Paths {2}.", TdsProjectPath, RequireExcludes, MonitorSitecorePaths));
return true;
}
public static List<string> ValidateProjectFile(string projectFilePath, ValidationArgs validationArgs)
{
var xmlDocument = new XmlDocument();
xmlDocument.Load(projectFilePath);
var nsmgr = new XmlNamespaceManager(xmlDocument.NameTable);
nsmgr.AddNamespace("ns", "http://schemas.microsoft.com/developer/msbuild/2003");
var xmlElements = xmlDocument.SelectNodes("/ns:Project/ns:ItemGroup/ns:SitecoreItem", nsmgr);
_errorList = new List<string>();
if (xmlElements != null)
{
foreach (XmlElement xmlElement in xmlElements)
{
ValidateSitecoreItemNode(xmlElement, validationArgs);
}
}
return _errorList;
}
public static void ValidateSitecoreItemNode(XmlElement xmlElement, ValidationArgs validationArgs)
{
// Search Pattern
//// <Project
//// <ItemGroup>
////<SitecoreItem Include="sitecore\content.item">
//// <Icon>/temp/IconCache/People/16x16/cubes_blue.png</Icon>
//// <ChildItemSynchronization>NoChildSynchronization</ChildItemSynchronization>
//// <ItemDeployment>DeployOnce</ItemDeployment>
//// <ExcludeItemFrom>Prod.Cms|UAT</ExcludeItemFrom>
////</SitecoreItem>
string sitecorePath = HttpUtility.UrlDecode(xmlElement.GetAttribute("Include").Replace("+", "%2b"));
if (!validationArgs.MonitorSitecorePaths.Any(s => sitecorePath.StartsWith(s, StringComparison.InvariantCultureIgnoreCase)))
{
return;
}
var selectSingleNode = xmlElement["ExcludeItemFrom"];
if (selectSingleNode == null)
{
return;
}
var excludeItemFrom = selectSingleNode.InnerText;
validationArgs.RequiredExcludeBuilds.FindAll(s => excludeItemFrom.IndexOf(s, StringComparison.InvariantCultureIgnoreCase) < 0)
.ForEach(a => _errorList.Add(string.Format("Invalid Tds Exclude Rule for {0} must contain environment {1} (ExcludeItemFrom:{2}) ", sitecorePath, a, excludeItemFrom)));
}
public class ValidationArgs
{
public ValidationArgs(string monitoredPaths, string requiredExcludeBuilds)
{
MonitorSitecorePaths = new List<string>(monitoredPaths.Split(',', '|', ' '));
RequiredExcludeBuilds = new List<string>(requiredExcludeBuilds.Split(',', '|', ' '));
}
public List<string> MonitorSitecorePaths;
public List<string> RequiredExcludeBuilds;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment