Friday, February 10, 2012

New files on Visual Studio project added to Perforce

I worked with a few different source control systems. The first was Visual Source Safe, then CVS, Subversion (SVN) and for two years I was working with Team Foundation Server, and its Source Control. Great integration TFS has, just like any other Microsoft product working with each other.

Now I started working on a project with a different source control: Perforce
Wouldn't dare to talk badly about it, scalability is quite impressive and it has good features too.
There is also plugin to integrate your project to Visual Studio, which for example, adds to your pending list on Perforce, files you add to your Visual Studio project.

But what if your project is not integrated (or you don't have the plugin)?

Well, it was my case, and it means that every time you add files to your project on Visual Studio, using the Wizard for example, you have to open p4 client, browse to the file and click: Mark for Add. Only then, the files are shown in your changelist.

Not a problem. Every time I add something to the project, I have to remember to go to p4 and Mark for Add.
Obviously it didn't take long, I forgot to Mark for Add one file, submitted my changes and CruiseControl tray application went red. I broke the build!

Foreseen that would not be the only occasion, I decided to spend an hour or so doing some quick and dirty solution to serve as a patch for this lack of memory I might eventually have.

So the first thing that popped in my head was parsing the csproj file (would have to parse .sln too, in case I add a new project). That probably would take sometime to make work well.
And to know when it is changed, I would have to monitor it anyway. So I decided that monitoring the  project folder with FileSystemWatcher was the best effort/benefit ratio.

Considering my layout skills are great, I decided not to try to make a UI! :)
Well, there's a Context Menu, since defining the paths to monitors and Regular Expressions to ignore are required to make it work.

Path that match one if this Regex are ignored


But let's ignore that part and see it working:
I select Add file within Visual Studio, the file is written to the disk and immediately I get the popup, on top of Visual Studio:

Notification that file was added. Hit enter to add it to your Change list within Perforce
Despite the UI related code, which stayed in the Form1 code-behind, there's only 1 class, as I mentioned before Quick-and-dirty, that does the business. For each path you specify to be monitored, a new instance is created:


namespace AddToPerforce
{
    internal class Watcher : IDisposable
    {
        private IEnumerable<string> _exceptions { get; set; }
        private FileSystemWatcher _fileWatchers = null;

        public string PathToMonitor { get; private set; }

        public Watcher(IEnumerable<string> exceptions, string pathToMonitor)
        {
            _exceptions = exceptions;
            PathToMonitor = pathToMonitor;
        }

        public void Start()
        {
            _fileWatchers = new FileSystemWatcher(PathToMonitor);
            _fileWatchers.Created += CreatedHandler;
            _fileWatchers.Error += (s, e) => MessageBox.Show(string.Format("Error has occured: {0}", e.GetException().Message));
            _fileWatchers.EnableRaisingEvents = _fileWatchers.IncludeSubdirectories = true;
        }

        public bool PauseContinue()
        {
            return _fileWatchers.EnableRaisingEvents = !_fileWatchers.EnableRaisingEvents;
        }

        void CreatedHandler(object sender, FileSystemEventArgs e)
        {
            if (_exceptions.Any(p => Regex.IsMatch(e.FullPath, p))) return;

            var msg = string.Format(@"File created: 

{0}

Do you want to add it to your perforce Changelist?", e.FullPath);

            if (DialogResult.Yes == MessageBox.Show(msg, "File added!",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Warning,
                MessageBoxDefaultButton.Button1,
                MessageBoxOptions.DefaultDesktopOnly))
                Process.Start("p4", string.Format("add -f -c default \"{0}\"", e.FullPath));
        }

        public void Dispose()
        {
            if (_fileWatchers != null)
                _fileWatchers.Dispose();
        }
    }
}

So now every time I add a file to the project (or write any file on the path I setup to be monitored), I get that Notification where I can choose to add it to Perforce changelist.

You can download the sources here.

1 comment: