public async Task <YesNoInconclusive> UpdateNugetPackagesInRepositoryAsync(IFolder repositoryFolder, IErrorsAndInfos errorsAndInfos)
        {
            using (SimpleLogger.BeginScope(SimpleLoggingScopeId.Create(nameof(UpdateNugetPackagesInRepositoryAsync), Guid.NewGuid().ToString()))) {
                SimpleLogger.LogInformation("Determining files with uncommitted changes");
                var yesNoInconclusive = new YesNoInconclusive();
                var files             = GitUtilities.FilesWithUncommittedChanges(repositoryFolder);
                yesNoInconclusive.Inconclusive = files.Any(f => EndingsThatAllowReset.All(e => !f.EndsWith("." + e, StringComparison.InvariantCultureIgnoreCase)));
                yesNoInconclusive.YesNo        = false;
                if (yesNoInconclusive.Inconclusive)
                {
                    errorsAndInfos.Infos.Add("Not all files allow a reset");
                    SimpleLogger.LogInformation($"Returning {yesNoInconclusive}");
                    return(yesNoInconclusive);
                }

                SimpleLogger.LogInformation("Resetting repository");
                GitUtilities.Reset(repositoryFolder, GitUtilities.HeadTipIdSha(repositoryFolder), errorsAndInfos);
                if (errorsAndInfos.AnyErrors())
                {
                    errorsAndInfos.Infos.Add("Could not reset");
                    SimpleLogger.LogInformation($"Returning {yesNoInconclusive}");
                    return(yesNoInconclusive);
                }

                SimpleLogger.LogInformation("Searching for project files");
                var projectFileFullNames = Directory.GetFiles(repositoryFolder.SubFolder("src").FullName, "*.csproj", SearchOption.AllDirectories).ToList();
                if (!projectFileFullNames.Any())
                {
                    errorsAndInfos.Infos.Add("No project files found");
                    SimpleLogger.LogInformation($"Returning {yesNoInconclusive}");
                    return(yesNoInconclusive);
                }

                foreach (var projectFileFullName in projectFileFullNames)
                {
                    SimpleLogger.LogInformation($"Analyzing project file {projectFileFullName}");
                    var projectErrorsAndInfos = new ErrorsAndInfos();
                    if (!await UpdateNugetPackagesForProjectAsync(projectFileFullName, yesNoInconclusive.YesNo, projectErrorsAndInfos))
                    {
                        continue;
                    }

                    yesNoInconclusive.YesNo = true;
                }

                if (yesNoInconclusive.YesNo)
                {
                    errorsAndInfos.Infos.Add("No project was updated");
                    SimpleLogger.LogInformation($"Returning {yesNoInconclusive}");
                    return(yesNoInconclusive);
                }

                SimpleLogger.LogInformation("Resetting repository");
                GitUtilities.Reset(repositoryFolder, GitUtilities.HeadTipIdSha(repositoryFolder), errorsAndInfos);
                SimpleLogger.LogInformation($"Returning {yesNoInconclusive}");
                return(yesNoInconclusive);
            }
        }
Exemple #2
0
        public void CanUndoUncommittedChanges()
        {
            var errorsAndInfos = new ErrorsAndInfos();

            vSut.VerifyThatThereAreNoUncommittedChanges(MasterFolder, errorsAndInfos);
            Assert.IsFalse(errorsAndInfos.AnyErrors(), errorsAndInfos.ErrorsPlusRelevantInfos());
            File.WriteAllText(MasterFolder.FullName + @"\change.cs", @"This is not a change");
            vSut.VerifyThatThereAreNoUncommittedChanges(MasterFolder, errorsAndInfos);
            Assert.IsTrue(errorsAndInfos.Errors.Any(e => e.Contains(@"change.cs")));
            errorsAndInfos = new ErrorsAndInfos();
            vSut.Reset(MasterFolder, vSut.HeadTipIdSha(MasterFolder), errorsAndInfos);
            vSut.VerifyThatThereAreNoUncommittedChanges(MasterFolder, errorsAndInfos);
            Assert.IsFalse(errorsAndInfos.AnyErrors(), errorsAndInfos.ErrorsPlusRelevantInfos());
        }
        private IList <BinaryToUpdate> ListChangedBinaries(string repositoryId, string previousHeadTipIdSha, string currentHeadTipIdSha, IFolder workFolder, IErrorsAndInfos errorsAndInfos, bool doNotListFilesOfEqualLengthThatCanBeTreatedAsEqual)
        {
            var changedBinaries      = new List <BinaryToUpdate>();
            var compileFolder        = workFolder.SubFolder("Compile");
            var previousTargetFolder = workFolder.SubFolder("Previous");
            var currentTargetFolder  = workFolder.SubFolder("Current");

            foreach (var previous in new[] { true, false })
            {
                CleanUpFolder(compileFolder, errorsAndInfos);
                if (errorsAndInfos.AnyErrors())
                {
                    return(changedBinaries);
                }
                compileFolder.CreateIfNecessary();

                var url = "https://github.com/aspenlaub/" + repositoryId + ".git";
                GitUtilities.Clone(url, "master", compileFolder, new CloneOptions {
                    BranchName = "master"
                }, false, errorsAndInfos);
                if (errorsAndInfos.AnyErrors())
                {
                    return(changedBinaries);
                }

                var headTipIdSha = previous ? previousHeadTipIdSha : currentHeadTipIdSha;
                GitUtilities.Reset(compileFolder, headTipIdSha, errorsAndInfos);
                if (errorsAndInfos.AnyErrors())
                {
                    return(changedBinaries);
                }

                var csProjFiles = Directory.GetFiles(workFolder.FullName, "*.csproj", SearchOption.AllDirectories).ToList();
                foreach (var csProjFile in csProjFiles)
                {
                    var contents = File.ReadAllLines(csProjFile).ToList();
                    contents = contents.Select(AdjustLineIfVersioningRelated).ToList();
                    File.WriteAllLines(csProjFile, contents);
                }

                var solutionFileName = compileFolder.SubFolder("src").FullName + @"\" + repositoryId + ".sln";
                errorsAndInfos.Infos.Add(string.Format(Properties.Resources.Restoring, repositoryId, headTipIdSha));
                var restoreErrorsAndInfos = new ErrorsAndInfos();
                NugetPackageRestorer.RestoreNugetPackages(solutionFileName, restoreErrorsAndInfos);
                if (restoreErrorsAndInfos.AnyErrors())
                {
                    errorsAndInfos.Errors.Add(string.Format(Properties.Resources.FailedToRestore, repositoryId, headTipIdSha));
                    errorsAndInfos.Errors.AddRange(restoreErrorsAndInfos.Errors);
                    return(changedBinaries);
                }

                errorsAndInfos.Infos.Add(string.Format(Properties.Resources.Building, repositoryId, headTipIdSha));
                var buildErrorsAndInfos = new ErrorsAndInfos();
                CakeBuilder.Build(solutionFileName, false, "", buildErrorsAndInfos);
                if (buildErrorsAndInfos.AnyErrors())
                {
                    errorsAndInfos.Errors.Add(string.Format(Properties.Resources.FailedToBuild, repositoryId, headTipIdSha));
                    errorsAndInfos.Errors.AddRange(buildErrorsAndInfos.Errors);
                    return(changedBinaries);
                }

                var binFolder    = compileFolder.SubFolder("src").SubFolder("bin").SubFolder("Release");
                var targetFolder = previous ? previousTargetFolder : currentTargetFolder;
                var folderCleanUpErrorsAndInfos = new ErrorsAndInfos();
                CleanUpFolder(targetFolder, folderCleanUpErrorsAndInfos);
                if (folderCleanUpErrorsAndInfos.AnyErrors())
                {
                    errorsAndInfos.Errors.AddRange(folderCleanUpErrorsAndInfos.Errors);
                    return(changedBinaries);
                }
                targetFolder.CreateIfNecessary();
                var shortFileNames = Directory.GetFiles(binFolder.FullName, "*.*", SearchOption.AllDirectories)
                                     .Where(f => !f.StartsWith(binFolder.FullName + @"\ref\"))
                                     .Select(f => f.Substring(binFolder.FullName.Length + 1));
                foreach (var shortFileName in shortFileNames)
                {
                    var sourceFileName      = binFolder.FullName + '\\' + shortFileName;
                    var destinationFileName = targetFolder.FullName + '\\' + shortFileName;
                    try {
                        var destinationFolder = new Folder(destinationFileName.Substring(0, destinationFileName.LastIndexOf('\\')));
                        destinationFolder.CreateIfNecessary();
                        File.Copy(sourceFileName, destinationFileName, true);
                    } catch {
                        errorsAndInfos.Errors.Add(string.Format(Properties.Resources.FailedToCopy, sourceFileName, destinationFileName));
                    }
                }
            }

            foreach (var shortFileName in Directory.GetFiles(currentTargetFolder.FullName, "*.*", SearchOption.AllDirectories).Select(f => f.Substring(currentTargetFolder.FullName.Length + 1)))
            {
                var previousFileName = previousTargetFolder.FullName + '\\' + shortFileName;
                var currentFileName  = currentTargetFolder.FullName + '\\' + shortFileName;
                if (!File.Exists(previousFileName))
                {
                    changedBinaries.Add(new BinaryToUpdate {
                        FileName = shortFileName, UpdateReason = Properties.Resources.FileIsNew
                    });
                    continue;
                }

                var previousFileInfo = new FileInfo(previousFileName);
                var currentFileInfo  = new FileInfo(currentFileName);

                var previousContents = File.ReadAllBytes(previousFileName);
                var currentContents  = File.ReadAllBytes(currentFileName);
                if (previousContents.Length != currentContents.Length)
                {
                    changedBinaries.Add(new BinaryToUpdate {
                        FileName = shortFileName, UpdateReason = string.Format(Properties.Resources.FilesDifferInLength, previousContents.Length, currentContents.Length)
                    });
                    continue;
                }

                var differences = previousContents.Where((t, i) => t != currentContents[i]).Count();
                if (differences == 0)
                {
                    continue;
                }

                if (BinariesHelper.CanFilesOfEqualLengthBeTreatedEqual(FolderUpdateMethod.AssembliesButNotIfOnlySlightlyChanged, "", previousContents, currentContents, previousFileInfo,
                                                                       false, currentFileInfo, out var updateReason))
                {
                    if (!doNotListFilesOfEqualLengthThatCanBeTreatedAsEqual)
                    {
                        changedBinaries.Add(new BinaryToUpdate {
                            FileName = shortFileName, UpdateReason = Properties.Resources.OtherFilesRequireUpdateAnyway
                        });
                    }

                    continue;
                }

                changedBinaries.Add(new BinaryToUpdate {
                    FileName = shortFileName, UpdateReason = updateReason
                });
            }

            return(changedBinaries);
        }