Exporting a Cangeset in Team Foundation Server TFS using Team Foundation Power Tools TFPT Part 2

Uncategorised,C#

Posted by Alex Peta on November 02, 2012 Copyright© from Bing images : Uinta ground squirrels at Tower Fall Campground in Yellowstone National Park, Wyoming (© Shin Yoshino/Minden Pictures)

As mentioned in my first post about Team Foundation Server and Team Foundation Power Tools I was working on making a Console Application to leverage tftp.exe and export a range of changesets.

Prerequisites :

  • team foundation power tools installed.
  • a directory mapped to your team foundation server.

Note: run compiled executable file INSIDE a mapped directory to your TF Server.

Lets skip right to a bunch of code:

Timer Class – is used to time the whole operation

public static class Timer
{
    public static void GetElapsedTime(Action methodToTime)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        methodToTime.Invoke();
        sw.Stop();
        Console.WriteLine(string.Format("Total duration : {0} ms", sw.ElapsedMilliseconds));
        Logger.WriteEntry(string.Format("Total duration : {0} ms", sw.ElapsedMilliseconds));
    }
}

Logger Class – small logging utility class

public class Logger
{
    #region Private Members
    public static bool HasEncounteredError = false;
    private static FileInfo _file;
    #endregion

    #region Constants
    public static string LogName = "ExportChangesetLog";
    public static string LogFullPath = string.Format("{0}\\{1}.log",Environment.GetFolderPath(Environment.SpecialFolder.Desktop),Logger.LogName);
    #endregion

    #region Constructors
    public Logger()
    {
        if (!LogFileExists())
        {
            CreateLogFile();
        }
    }
    #endregion

    #region Private Methods
    private bool LogFileExists()
    {
        try
        {
            FileInfo logFile = new FileInfo(Logger.LogFullPath);
            if (logFile.Exists)
            {
                _file = logFile;
                return true;
            }
            return false;
        }
        catch
        {
            Console.WriteLine("-- Could not check if file exists. Logging will be disabled.");
            return false;
        }
    }

    private void CreateLogFile()
    {
        try
        {
            if (_file == null)
            {
                FileInfo file = new FileInfo(Logger.LogFullPath);
                FileStream _fileStream = file.Create();
                _file = file;
                _fileStream.Close();
            }
        }
        catch (Exception)
        {
            Console.WriteLine("-- Could not create log file. Logging will be disabled.");
            Logger.HasEncounteredError = true;
        }
    }
    #endregion

    #region Statics
    public static void WriteEntry(string entry)
    {
        if (!string.IsNullOrEmpty(entry) && !Logger.HasEncounteredError)
        {
            try
            {
                if (_file != null)
                {
                    using (var writer = _file.AppendText())
                    {
                        writer.WriteLine();
                        writer.WriteLine("-----------------------------");
                        writer.WriteLine(string.Format("{0}", DateTime.Now));
                        writer.WriteLine(entry);
                        writer.WriteLine("-----------------------------");
                        writer.WriteLine();
                    }
                }
            }
            catch
            {
                Console.WriteLine("-- Error writing to log file. Logging will be disabled.");
                Logger.HasEncounteredError = true;
            }
        }
    }
    #endregion
}

Main Application Body – includes checking user inputs and handling the export

class Program
{
    private static int startChangesetNumber = 0;
    private static int endChangesetNumber = 0;

    static void Main(string[] args)
    {
        Timer.GetElapsedTime(() =>
            {
                //init logger
                Logger logger = new Logger();

                //check for command line args
                if (!HasCommandLineArgs(args))
                {
                    //check user inputs
                    GetUserInputChangesets();

                    //export
                    Export();
                }
            });  
    }

    #region Private Methods
    private static void GetUserInputChangesets()
    {
        string firstUserInput = string.Empty;
        do
        {
            Console.WriteLine("First changeset number :");
            firstUserInput = Console.ReadLine();
        }
        while (!ValidInput(firstUserInput, out startChangesetNumber));

        string secondUserInput = string.Empty;
        do
        {
            Console.WriteLine("Second changeset number :");
            secondUserInput = Console.ReadLine();
        }
        while (!ValidInput(secondUserInput, out endChangesetNumber));
    }

    private static void Export()
    {
        Console.WriteLine("===============================================");
        Console.WriteLine(System.Environment.NewLine);
        Logger.WriteEntry("-- Starting Export...");

        int currentChangeset = startChangesetNumber;
        while (currentChangeset <= endChangesetNumber)
        {
            try
            {
                Process process = new Process();
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.FileName = "tfpt.exe";
                process.StartInfo.Arguments = string.Format(" getcs /changeset:{0} /overwrite",currentChangeset);
                process.Start();
                string output = process.StandardOutput.ReadToEnd();
                process.WaitForExit();
                Console.WriteLine(output);
                Logger.WriteEntry("------------------------------");
                Logger.WriteEntry(output);
                Logger.WriteEntry("------------------------------");
                Logger.WriteEntry("--");                    
            }
            catch (Exception e)
            {
                Console.WriteLine("Error when exporting changeset {0} : {1}",currentChangeset,e.Message);
                Logger.WriteEntry(string.Format("Error when exporting changeset {0} : {1}", currentChangeset, e.Message));
                break;
            }
            currentChangeset++;
        }

        Logger.WriteEntry("-- Export finished..");
        Console.WriteLine("===============================================");
    }

    private static bool ValidInput(string input,out int param)
    {
        param = 0;

        if (string.IsNullOrWhiteSpace(input)) return false;

        if (startChangesetNumber == 0)
        {
            return int.TryParse(input, out param);
        }
        else
        {
            if (int.TryParse(input, out param) && param >= startChangesetNumber)
            {
                return true;
            }
            else
            {
                param = 0;
                return false;
            }
        }
    }

    private static bool HasCommandLineArgs(string[] args)
    {
        if (args.Count() != 2) return false;

        return ValidInput(args[0].ToString(), out startChangesetNumber) &&
                ValidInput(args[1].ToString(), out startChangesetNumber);
    }
    #endregion
}

Will upload this also to Codeplex.

Code is at your disposal at : https://exporttfschangesets.codeplex.com/