public async Task CanListAndCopyChangedBinaries() { var lister = Container.Resolve <IChangedBinariesLister>(); var errorsAndInfos = new ErrorsAndInfos(); var changedBinaries = lister.ListChangedBinaries(RepositoryId, BeforeMajorChangeHeadTipSha, CurrentHeadTipIdSha, errorsAndInfos); Assert.AreEqual(3, changedBinaries.Count); var sourceFolder = WorkFolder.SubFolder("Source"); sourceFolder.CreateIfNecessary(); var destinationFolder = WorkFolder.SubFolder("Destination"); destinationFolder.CreateIfNecessary(); foreach (var changedBinary in changedBinaries) { await File.WriteAllTextAsync(sourceFolder.FullName + '\\' + changedBinary.FileName, changedBinary.FileName); await File.WriteAllTextAsync(destinationFolder.FullName + '\\' + changedBinary.FileName, "Old " + changedBinary.FileName); await File.WriteAllTextAsync(destinationFolder.FullName + @"\Unchanged" + changedBinary.FileName, "Unchanged " + changedBinary.FileName); } await File.WriteAllTextAsync(sourceFolder.FullName + @"\SomeNewFile.txt", "SomeNewFile"); var sut = Container.Resolve <IFolderUpdater>(); await sut.UpdateFolderAsync(RepositoryId, BeforeMajorChangeHeadTipSha, sourceFolder, CurrentHeadTipIdSha, destinationFolder, true, true, "aspenlaub.local", errorsAndInfos); Assert.IsFalse(errorsAndInfos.AnyErrors(), errorsAndInfos.ErrorsPlusRelevantInfos()); foreach (var changedBinary in changedBinaries) { Assert.AreEqual(changedBinary.FileName, await File.ReadAllTextAsync(sourceFolder.FullName + '\\' + changedBinary.FileName)); Assert.AreEqual(changedBinary.FileName, await File.ReadAllTextAsync(destinationFolder.FullName + '\\' + changedBinary.FileName)); Assert.AreEqual("Unchanged " + changedBinary.FileName, await File.ReadAllTextAsync(destinationFolder.FullName + @"\Unchanged" + changedBinary.FileName)); } Assert.IsTrue(File.Exists(destinationFolder.FullName + @"\SomeNewFile.txt")); Assert.AreEqual("SomeNewFile", await File.ReadAllTextAsync(destinationFolder.FullName + @"\SomeNewFile.txt")); }
protected async Task <YesNoInconclusive> HasPullRequestForThisBranchAndItsHeadTipAsync(IGitHubUtilities sut, ErrorsAndInfos errorsAndInfos) { var inconclusive = false; var hasOpenPullRequest = false; try { hasOpenPullRequest = await sut.HasPullRequestForThisBranchAndItsHeadTipAsync(DevelopmentFolder, errorsAndInfos); } catch (WebException) { inconclusive = true; } return(new YesNoInconclusive { YesNo = hasOpenPullRequest, Inconclusive = inconclusive }); }
protected async Task <YesNoInconclusive> HasOpenPullRequestAsync(IGitHubUtilities sut, string semicolonSeparatedListOfPullRequestNumbersToIgnore, ErrorsAndInfos errorsAndInfos) { var inconclusive = false; var hasOpenPullRequest = false; try { hasOpenPullRequest = await sut.HasOpenPullRequestAsync(MasterFolder, semicolonSeparatedListOfPullRequestNumbersToIgnore, errorsAndInfos); } catch (WebException) { inconclusive = true; } return(new YesNoInconclusive { YesNo = hasOpenPullRequest, Inconclusive = inconclusive }); }
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); }
public async Task CanAnalyzeBackbendFolders() { var folder = BackbendFoldersSecret.DefaultFolder; var archiveFolder = folder.Replace(@"\Test\", @"\TestArchive\"); if (!Directory.Exists(archiveFolder)) { Directory.CreateDirectory(archiveFolder); } var otherFolder = folder + @"Sub\"; if (!Directory.Exists(otherFolder)) { Directory.CreateDirectory(otherFolder); } var textFileName = folder + "Test.txt"; File.WriteAllText(textFileName, textFileName); var archiveFileName = archiveFolder + "Test.zip"; File.Delete(archiveFileName); var backbendFolders = new BackbendFolders { new BackbendFolder { Name = folder }, new BackbendFolder { Name = archiveFolder } }; var errorsAndInfos = new ErrorsAndInfos(); await backbendFolders.ResolveAsync(vContainer.Resolve <IFolderResolver>(), errorsAndInfos); Assert.IsFalse(errorsAndInfos.AnyErrors(), errorsAndInfos.ErrorsToString()); var secretRepositoryMock = new Mock <ISecretRepository>(); secretRepositoryMock.Setup(s => s.GetAsync(It.IsAny <ISecret <BackbendFolders> >(), It.IsAny <IErrorsAndInfos>())).Returns(Task.FromResult(backbendFolders)); secretRepositoryMock.Setup(s => s.CompileCsLambdaAsync <string, string>(It.IsAny <CsLambda>())).Returns( Task.FromResult <Func <string, string> >( s => new Folder(s).FullName == new Folder(folder).FullName ? archiveFolder : "" ) ); var secret = new ArchiveFolderFinderSecret(); secretRepositoryMock.Setup(s => s.GetAsync(It.IsAny <ArchiveFolderFinderSecret>(), It.IsAny <IErrorsAndInfos>())).Returns(Task.FromResult(secret.DefaultValue)); var sut = new BackbendFoldersAnalyser(vContainer.Resolve <IFolderResolver>(), secretRepositoryMock.Object); errorsAndInfos = new ErrorsAndInfos(); var result = await sut.AnalyzeAsync(errorsAndInfos); var resultList = result.ToList(); Assert.IsFalse(errorsAndInfos.Errors.Any(), string.Join("\r\n", errorsAndInfos.Errors)); Assert.AreEqual(1, resultList.Count); File.WriteAllText(archiveFileName, textFileName); result = await sut.AnalyzeAsync(errorsAndInfos); resultList = result.ToList(); Assert.IsFalse(errorsAndInfos.Errors.Any(), string.Join("\r\n", errorsAndInfos.Errors)); Assert.AreEqual(0, resultList.Count); var otherTextFileName = otherFolder + "Test.txt"; File.WriteAllText(otherTextFileName, otherTextFileName); File.SetLastWriteTime(otherTextFileName, DateTime.Now.AddDays(29)); result = await sut.AnalyzeAsync(errorsAndInfos); resultList = result.ToList(); Assert.IsFalse(errorsAndInfos.Errors.Any(), string.Join("\r\n", errorsAndInfos.Errors)); Assert.AreEqual(1, resultList.Count); File.Delete(textFileName); File.Delete(archiveFileName); File.Delete(otherTextFileName); Assert.AreEqual(0, Directory.GetFiles(otherFolder).Length); Directory.Delete(otherFolder); }
public async Task <IPackageToPush> FindPackageToPushAsync(string nugetFeedId, IFolder packageFolderWithBinaries, IFolder repositoryFolder, string solutionFileFullName, IErrorsAndInfos errorsAndInfos) { IPackageToPush packageToPush = new PackageToPush(); errorsAndInfos.Infos.Add(Properties.Resources.CheckingProjectVsSolution); var projectFileFullName = solutionFileFullName.Replace(".sln", ".csproj"); if (!File.Exists(projectFileFullName)) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.ProjectFileNotFound, projectFileFullName)); return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.LoadingProject); var project = ProjectFactory.Load(solutionFileFullName, projectFileFullName, errorsAndInfos); if (errorsAndInfos.Errors.Any()) { return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.LoadingNugetFeeds); var developerSettingsSecret = new DeveloperSettingsSecret(); var developerSettings = await SecretRepository.GetAsync(developerSettingsSecret, errorsAndInfos); if (errorsAndInfos.Errors.Any()) { return(packageToPush); } if (developerSettings == null) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.MissingDeveloperSettings, developerSettingsSecret.Guid + ".xml")); return(packageToPush); } var nugetFeedsSecret = new SecretNugetFeeds(); var nugetFeeds = await SecretRepository.GetAsync(nugetFeedsSecret, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.IdentifyingNugetFeed); var nugetFeed = nugetFeeds.FirstOrDefault(f => f.Id == nugetFeedId); if (nugetFeed == null) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.UnknownNugetFeed, nugetFeedId, nugetFeedsSecret.Guid + ".xml")); return(packageToPush); } if (!nugetFeed.IsAFolderToResolve()) { var nugetConfigFileFullName = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\NuGet\" + "nuget.config"; packageToPush.ApiKey = NugetConfigReader.GetApiKey(nugetConfigFileFullName, nugetFeed.Id, errorsAndInfos); if (errorsAndInfos.Errors.Any()) { return(packageToPush); } } errorsAndInfos.Infos.Add(Properties.Resources.IdentifyingFeedUrl); var source = await nugetFeed.UrlOrResolvedFolderAsync(FolderResolver, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(packageToPush); } packageToPush.FeedUrl = source; if (string.IsNullOrEmpty(packageToPush.FeedUrl)) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.IncompleteDeveloperSettings, developerSettingsSecret.Guid + ".xml")); return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.SearchingLocalPackage); var localPackageRepository = new FindLocalPackagesResourceV2(packageFolderWithBinaries.FullName); var localPackages = localPackageRepository.GetPackages(new NullLogger(), CancellationToken.None).Where(p => !p.Identity.Version.IsPrerelease).ToList(); if (!localPackages.Any()) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.NoPackageFilesFound, packageFolderWithBinaries.FullName)); return(packageToPush); } var latestLocalPackageVersion = localPackages.Max(p => p.Identity.Version.Version); errorsAndInfos.Infos.Add(string.Format(Properties.Resources.FoundLocalPackage, latestLocalPackageVersion)); errorsAndInfos.Infos.Add(Properties.Resources.SearchingRemotePackage); var packageId = string.IsNullOrWhiteSpace(project.PackageId) ? project.RootNamespace : project.PackageId; var remotePackages = await NugetFeedLister.ListReleasedPackagesAsync(nugetFeedId, packageId, errorsAndInfos); if (errorsAndInfos.Errors.Any()) { return(packageToPush); } if (!remotePackages.Any()) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.NoRemotePackageFilesFound, packageToPush.FeedUrl, packageId)); return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.LoadingPushedHeadTipShas); var pushedHeadTipShas = await PushedHeadTipShaRepository.GetAsync(nugetFeedId, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(packageToPush); } var headTipIdSha = repositoryFolder == null ? "" : GitUtilities.HeadTipIdSha(repositoryFolder); if (!string.IsNullOrWhiteSpace(headTipIdSha) && pushedHeadTipShas.Contains(headTipIdSha)) { errorsAndInfos.Infos.Add(string.Format(Properties.Resources.HeadTipShaHasAlreadyBeenPushed, headTipIdSha, nugetFeedId)); return(packageToPush); } var latestRemotePackageVersion = remotePackages.Max(p => p.Identity.Version.Version); errorsAndInfos.Infos.Add(string.Format(Properties.Resources.FoundRemotePackage, latestRemotePackageVersion)); if (latestRemotePackageVersion >= latestLocalPackageVersion) { errorsAndInfos.Infos.Add(string.Format(Properties.Resources.RemotePackageHasHigherOrEqualVersion, headTipIdSha)); return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.CheckingRemotePackageTag); var remotePackage = remotePackages.First(p => p.Identity.Version.Version == latestRemotePackageVersion); if (!string.IsNullOrEmpty(remotePackage.Tags) && !string.IsNullOrWhiteSpace(headTipIdSha)) { errorsAndInfos.Infos.Add(string.Format(Properties.Resources.TagsAre, remotePackage.Tags)); var tags = remotePackage.Tags.Split(' ').ToList(); if (tags.Contains(headTipIdSha)) { errorsAndInfos.Infos.Add(string.Format(Properties.Resources.PackageAlreadyTaggedWithHeadTipSha, headTipIdSha)); return(packageToPush); } if (tags.Count != 1) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.RemotePackageContainsSeveralTags, tags)); return(packageToPush); } var tag = tags[0]; errorsAndInfos.Infos.Add(string.Format(Properties.Resources.CheckingIfThereAreChangedBinaries, headTipIdSha, tag)); var listerErrorsAndInfos = new ErrorsAndInfos(); var changedBinaries = ChangedBinariesLister.ListChangedBinaries(packageId, headTipIdSha, tag, listerErrorsAndInfos); if (listerErrorsAndInfos.AnyErrors()) { errorsAndInfos.Infos.AddRange(listerErrorsAndInfos.Infos); errorsAndInfos.Errors.AddRange(listerErrorsAndInfos.Errors); return(packageToPush); } if (!changedBinaries.Any()) { errorsAndInfos.Infos.Add(string.Format(Properties.Resources.NoBinariesHaveChanged)); return(packageToPush); } } errorsAndInfos.Infos.Add(Properties.Resources.PackageNeedsToBePushed); packageToPush.PackageFileFullName = packageFolderWithBinaries.FullName + @"\" + packageId + "." + latestLocalPackageVersion + ".nupkg"; packageToPush.Id = packageId; packageToPush.Version = latestLocalPackageVersion?.ToString(); if (File.Exists(packageToPush.PackageFileFullName)) { return(packageToPush); } errorsAndInfos.Errors.Add(string.Format(Properties.Resources.FileNotFound, packageToPush.PackageFileFullName)); return(packageToPush); }
private async Task <bool> AreThereNugetUpdateOpportunitiesForProjectAsync(string projectFileFullName, IList <string> nugetFeedIds, IErrorsAndInfos errorsAndInfos) { var dependencyErrorsAndInfos = new ErrorsAndInfos(); var dependencyIdsAndVersions = await PackageConfigsScanner.DependencyIdsAndVersionsAsync(projectFileFullName.Substring(0, projectFileFullName.LastIndexOf('\\')), true, true, dependencyErrorsAndInfos); var secret = new SecretManuallyUpdatedPackages(); var manuallyUpdatedPackages = await SecretRepository.GetAsync(secret, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(false); } var yesNo = false; foreach (var dependencyIdsAndVersion in dependencyIdsAndVersions) { var id = dependencyIdsAndVersion.Key; if (manuallyUpdatedPackages.Any(p => p.Id == id)) { continue; } IList <IPackageSearchMetadata> remotePackages = null; foreach (var nugetFeedId in nugetFeedIds) { var listingErrorsAndInfos = new ErrorsAndInfos(); remotePackages = await NugetFeedLister.ListReleasedPackagesAsync(nugetFeedId, id, listingErrorsAndInfos); if (listingErrorsAndInfos.AnyErrors()) { continue; } if (remotePackages.Any()) { break; } } if (remotePackages?.Any() != true) { continue; } if (!Version.TryParse(dependencyIdsAndVersion.Value, out var version)) { continue; } var latestRemotePackageVersion = remotePackages.Max(p => p.Identity.Version.Version); if (latestRemotePackageVersion <= version || latestRemotePackageVersion?.ToString().StartsWith(version.ToString()) == true) { continue; } errorsAndInfos.Infos.Add(string.Format(Properties.Resources.CanUpdatePackageFromTo, id, version, latestRemotePackageVersion)); yesNo = true; } return(yesNo); }