public override async Task <int> Execute() { // Identify all roots ICollection <FileInfo> wantedProjects = ProjectUtility.GetAllMatchedProjects(_options.RootDir, _options.FileTypes, _options.Include, _options.Exclude).ToList(); // Add all dependencies wantedProjects = wantedProjects .Concat(wantedProjects.SelectMany(projectFile => ProjectUtility.GetProjectDependencies(_projectStore, projectFile))) .Distinct(FileInfoComparer.Instance) .ToList(); FileInfo slnFilePath = new FileInfo(Path.GetFullPath(_options.SolutionFile, _options.RootDir.FullName)); ICollection <FileInfo> currentProjects = LoadCurrentProjects(slnFilePath); List <FileInfo> toRemove = currentProjects.Except(wantedProjects, FileInfoComparer.Instance).ToList(); List <FileInfo> toAdd = wantedProjects.Except(currentProjects, FileInfoComparer.Instance).ToList(); if (!toAdd.Any() && !toRemove.Any()) { Log.Debug("Nothing to do - sln is up to date"); return(0); } foreach (FileInfo path in toRemove) { Log.Debug("Will remove {Project}", Path.GetRelativePath(_options.RootDir.FullName, path.FullName)); } foreach (FileInfo path in toAdd) { Log.Debug("Will add {Project}", Path.GetRelativePath(_options.RootDir.FullName, path.FullName)); } Log.Information("Will add {CountAdd:N0} and remove {CountRemove:N0} projects", toAdd.Count, toRemove.Count); // Build commandlines List <string[]> argumentSets = new List <string[]>(); if (!slnFilePath.Exists) { // Create sln file argumentSets.Add(new[] { "new", "sln", "-o", slnFilePath.DirectoryName, "-n", Path.GetFileNameWithoutExtension(slnFilePath.Name) }); } if (toRemove.Any()) { argumentSets.AddRange(ProcessUtility.CreateArguments(new[] { "sln", slnFilePath.Name, "remove" }, toRemove.Select(s => Path.GetRelativePath(slnFilePath.DirectoryName, s.FullName)))); } if (toAdd.Any()) { argumentSets.AddRange(ProcessUtility.CreateArguments(new[] { "sln", slnFilePath.Name, "add" }, toAdd.Select(s => Path.GetRelativePath(slnFilePath.DirectoryName, s.FullName)))); } // Execute Log.Debug("Executing {Count} commands to bring {SlnFile} up to date", argumentSets.Count, slnFilePath); foreach (string[] arguments in argumentSets) { (int exitCode, IList <string> stdOut, IList <string> stdErr) = await ProcessUtility.Execute("dotnet", slnFilePath.DirectoryName, arguments); foreach (string line in stdErr) { Log.Warning("Error running command: {Output}", line); } if (exitCode != 0) { Log.Error("Unable to modify sln file, exit code: {ExitCode}", exitCode); return(10); } } return(0); }