public AssemblyInfoUpdate(IFileSystem fileSystem, GitHubFlowVersionContext context)
        {
            if (!context.Arguments.UpdateAssemblyInfo)
            {
                return;
            }

            var assemblyInfoFiles = fileSystem.GetFiles(context.RepositoryRoot, "AssemblyInfo.cs",
                                                        SearchOption.AllDirectories);

            foreach (var assemblyInfoFile in assemblyInfoFiles)
            {
                var destFileName   = assemblyInfoFile + ".bak";
                var sourceFileName = assemblyInfoFile;
                fileSystem.Copy(assemblyInfoFile, destFileName, true);
                _restoreBackupTasks.Add(() => fileSystem.Move(destFileName, sourceFileName, true));
                _cleanupBackupTasks.Add(() => fileSystem.DeleteFile(destFileName));

                var assemblyVersion     = context.Variables[VariableProvider.AssemblyVersion];
                var assemblyInfoVersion = context.Variables[VariableProvider.AssemblyInformationalVersion];
                var assemblyFileVersion = context.Variables[VariableProvider.AssemblyFileVersion];
                var fileContents        = fileSystem.ReadAllText(sourceFileName)
                                          .RegexReplace(@"AssemblyVersion\(""\d+.\d+.\d+(.\d+|\*)?""\)", string.Format("AssemblyVersion(\"{0}\")", assemblyVersion))
                                          .RegexReplace(@"AssemblyInformationalVersion\(""\d+.\d+.\d+(.\d+|\*)?""\)", string.Format("AssemblyInformationalVersion(\"{0}\")", assemblyInfoVersion))
                                          .RegexReplace(@"AssemblyFileVersion\(""\d+.\d+.\d+(.\d+|\*)?""\)", string.Format("AssemblyFileVersion(\"{0}\")", assemblyFileVersion));

                fileSystem.WriteAllText(sourceFileName, fileContents);
            }
        }
        private static GitHubFlowVersionContext CreateContext(GitHubFlowArguments arguments)
        {
            var context = new GitHubFlowVersionContext
            {
                Arguments        = arguments,
                WorkingDirectory =
                    arguments.WorkingDirectory ??
                    Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
            };
            var fallbackStrategy = new LocalBuild();
            var buildServers     = new IBuildServer[] { new TeamCity(context) };

            context.CurrentBuildServer = buildServers.FirstOrDefault(s => s.IsRunningInBuildAgent()) ?? fallbackStrategy;

            context.GitDirectory = GitDirFinder.TreeWalkForGitDir(context.WorkingDirectory);
            if (string.IsNullOrEmpty(context.GitDirectory))
            {
                if (context.CurrentBuildServer.IsRunningInBuildAgent()) //fail the build if we're on a TC build agent
                {
                    // This exception might have to change when more build servers are added
                    throw new Exception("Failed to find .git directory on agent. " +
                                        "Please make sure agent checkout mode is enabled for you VCS roots - " +
                                        "http://confluence.jetbrains.com/display/TCD8/VCS+Checkout+Mode");
                }

                throw new Exception("Failed to find .git directory.");
            }

            Console.WriteLine("Git directory found at {0}", context.GitDirectory);
            context.RepositoryRoot = Directory.GetParent(context.GitDirectory).FullName;

            return(context);
        }
        private static void WriteResults(GitHubFlowVersionContext context)
        {
            var outputStrategies = new IOutputStrategy[]
            {
                new BuildServerOutputStrategy(context.CurrentBuildServer),
                new JsonFileOutputStrategy(),
                new EnvironmentalVariablesOutputStrategy()
            };

            foreach (var outputStrategy in outputStrategies)
            {
                outputStrategy.Write(context);
            }
        }
        private static void Run(GitHubFlowVersionContext context)
        {
            var gitHelper = new GitHelper();
            var gitRepo   = new Repository(context.GitDirectory);
            var lastTaggedReleaseFinder = new LastTaggedReleaseFinder(gitRepo, gitHelper, context.WorkingDirectory);
            var nextSemverCalculator    = new NextSemverCalculator(new NextVersionTxtFileFinder(context.RepositoryRoot),
                                                                   lastTaggedReleaseFinder);
            var buildNumberCalculator = new BuildNumberCalculator(nextSemverCalculator, lastTaggedReleaseFinder, gitHelper,
                                                                  gitRepo, context.CurrentBuildServer);

            context.NextBuildNumber = buildNumberCalculator.GetBuildNumber();

            var variableProvider = new VariableProvider();

            context.Variables = variableProvider.GetVariables(context.NextBuildNumber);
            WriteResults(context);
        }
        private static bool RunExecCommandIfNeeded(GitHubFlowVersionContext context)
        {
            if (string.IsNullOrEmpty(context.Arguments.Exec))
            {
                return(false);
            }

            Console.WriteLine("Launching {0} {1}", context.Arguments.Exec, context.Arguments.ExecArgs);
            var results = ProcessHelper.Run(
                Console.WriteLine, Console.Error.WriteLine,
                null, context.Arguments.Exec, context.Arguments.ExecArgs, context.RepositoryRoot);

            if (results != 0)
            {
                throw new Exception("MsBuild execution failed, non-zero return code");
            }
            return(true);
        }
        private static bool RunMsBuildIfNeeded(GitHubFlowVersionContext context)
        {
            if (string.IsNullOrEmpty(context.Arguments.ProjectFile))
            {
                return(false);
            }

            var targetsArg = context.Arguments.Targets == null ? null : " /target:" + context.Arguments.Targets;

            Console.WriteLine("Launching {0} \"{1}\"{2}", MsBuild, context.Arguments.ProjectFile, targetsArg);
            var results = ProcessHelper.Run(
                Console.WriteLine, Console.Error.WriteLine,
                null, MsBuild, string.Format("\"{0}\"{1}", context.Arguments.ProjectFile, targetsArg), context.RepositoryRoot);

            if (results != 0)
            {
                throw new Exception("MsBuild execution failed, non-zero return code");
            }

            return(true);
        }