checkin policy to disallow certain patterns (for instance, particular extensions)

A request that's come up a couple of times is to have a checkin policy help guide developers about certain file extensions that they shouldn't check in to version control.  While making a policy with "forbidden extensions" is certainly possible, it's basically the same amount of work to make "forbidden regular expressions" and give more power to the user - extensions are just a subset, like "\.tmp$" for "don't check in any files end in .tmp".

The only "interesting" part to the policy is that it leverages the fact that Regex is serializable.  The form isn't included in the source here (I'm going to try and post the zip of the policy project), but it's what you would expect (I just used DataGridView since it handles the heavy lifting for add/delete/edit of the entries).

using System;

using System.Collections.Generic;

using System.Text.RegularExpressions;

using System.Windows.Forms;

using Microsoft.TeamFoundation.VersionControl.Client;

namespace ForbiddenPatternsPolicy

{

    [Serializable]

    public class ForbiddenPatternsPolicy : PolicyBase

    {

        private List<Regex> m_forbiddenRegexes = new List<Regex>();

        public override string Description

        {

            get { return "Checks pending changes against configured list of forbidden patterns"; }

        }

        public override string Type

        {

            get { return "Forbidden Patterns Policy"; }

        }

        public override string TypeDescription

        {

            get { return "This policy allows you to specify regular expressions that should never be allowed to be checked in"; }

  }

        public override bool Edit(IPolicyEditArgs policyEditArgs)

        {

            using (ForbiddenPatternsForm form = new ForbiddenPatternsForm())

            {

                form.ForbiddenPatterns = m_forbiddenRegexes;

                if (form.ShowDialog() == DialogResult.OK)

                {

                    m_forbiddenRegexes = form.ForbiddenPatterns;

                    return true;

                }

                return false;

            }

        }

        public override PolicyFailure[] Evaluate()

        {

            List<PolicyFailure> failures = new List<PolicyFailure>();

            foreach (PendingChange pendingChange in PendingCheckin.PendingChanges.CheckedPendingChanges)

            {

                foreach (Regex forbiddenRegex in m_forbiddenRegexes)

                {

                    if (forbiddenRegex.IsMatch(pendingChange.ServerItem))

                    {

                        failures.Add(new PolicyFailure(

                            String.Format("Pending change on {0} matches forbidden regex {1}",

                                          pendingChange.ServerItem, forbiddenRegex), this));

                    }

                }

            }

            return failures.ToArray();

        }

    }

}

ForbiddenPatternsPolicy.zip