Beispiel #1
0
        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"));
        }
Beispiel #2
0
        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
            });
        }
Beispiel #3
0
        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);
        }