public Task <IEnumerable <string> > Execute( string id, bool?includePrerelease = false, string semVerLevel = null) { if (string.IsNullOrWhiteSpace(id)) { throw new ArgumentNullException(nameof(id)); } // Create SQL filter on SemVerLevel // By default, we filter out SemVer v2.0.0 package versions. var semVerLevelSqlFilter = "p.[SemVerLevelKey] IS NULL"; if (!string.IsNullOrEmpty(semVerLevel)) { var semVerLevelKey = SemVerLevelKey.ForSemVerLevel(semVerLevel); if (semVerLevelKey == SemVerLevelKey.SemVer2) { semVerLevelSqlFilter = $"(p.[SemVerLevelKey] IS NULL OR p.[SemVerLevelKey] <= {SemVerLevelKey.SemVer2})"; } } var prereleaseFilter = string.Empty; if (!includePrerelease.HasValue || !includePrerelease.Value) { prereleaseFilter = "AND p.IsPrerelease = 0"; } return(RunSqlQuery(string.Format(CultureInfo.InvariantCulture, _sqlFormat, semVerLevelSqlFilter, prereleaseFilter), id)); }
public Task <IReadOnlyList <string> > Execute( string id, bool?includePrerelease = false, string semVerLevel = null) { if (string.IsNullOrWhiteSpace(id)) { throw new ArgumentNullException(nameof(id)); } // default filters var query = _packageRepository.GetAll() .Include(p => p.PackageRegistration) .Where(p => p.PackageRegistration.Id == id) .Where(p => p.PackageStatusKey == PackageStatus.Available && p.Listed) .Where(SemVerLevelKey.IsPackageCompliantWithSemVerLevelPredicate(semVerLevel)); // prerelease filter if (!includePrerelease.HasValue || !includePrerelease.Value) { query = query.Where(p => !p.IsPrerelease); } var versions = query.Select(p => p.Version).ToList(); // return the result of the query return(Task.FromResult <IReadOnlyList <string> >(versions)); }
public Task <IEnumerable <string> > Execute( string partialId, bool?includePrerelease = false, string semVerLevel = null) { // Create SQL filter on SemVerLevel // By default, we filter out SemVer v2.0.0 package versions. var semVerLevelSqlFilter = "p.[SemVerLevelKey] IS NULL"; if (!string.IsNullOrEmpty(semVerLevel)) { var semVerLevelKey = SemVerLevelKey.ForSemVerLevel(semVerLevel); if (semVerLevelKey == SemVerLevelKey.SemVer2) { semVerLevelSqlFilter = "p.[SemVerLevelKey] = " + SemVerLevelKey.SemVer2; } } if (string.IsNullOrWhiteSpace(partialId)) { return(RunSqlQuery(string.Format(CultureInfo.InvariantCulture, _noPartialIdSql, semVerLevelSqlFilter))); } var prereleaseFilter = string.Empty; if (!includePrerelease.HasValue || !includePrerelease.Value) { prereleaseFilter = "AND p.IsPrerelease = {1}"; } var sql = string.Format(CultureInfo.InvariantCulture, _partialIdSqlFormat, semVerLevelSqlFilter, prereleaseFilter); return(RunSqlQuery(sql, partialId + "%", includePrerelease ?? false)); }
public void DefaultsToUnknownKeyWhenVersionStringIsNull() { // Act var semVerLevelKey = SemVerLevelKey.ForSemVerLevel(null); // Assert Assert.Equal(SemVerLevelKey.Unknown, semVerLevelKey); }
public void ReturnsSemVer2KeyWhenVersionStringAtLeastVersion200(string semVerLevel) { // Act var semVerLevelKey = SemVerLevelKey.ForSemVerLevel(semVerLevel); // Assert Assert.Equal(SemVerLevelKey.SemVer2, semVerLevelKey); }
public void DefaultsToUnknownKeyWhenVersionStringIsInvalidOrLowerThanVersion200(string semVerLevel) { // Act var semVerLevelKey = SemVerLevelKey.ForSemVerLevel(semVerLevel); // Assert Assert.Equal(SemVerLevelKey.Unknown, semVerLevelKey); }
private static void AssertPackageIsComplianceWithSemVerLevel(int?packageSemVerLevelKey, string semVerLevel, bool shouldBeCompliant) { var package = new Package { SemVerLevelKey = packageSemVerLevelKey }; var compiledFunction = SemVerLevelKey.IsPackageCompliantWithSemVerLevel(semVerLevel).Compile(); Assert.Equal(shouldBeCompliant, compiledFunction(package)); }
private SearchResults SearchCore(SearchFilter searchFilter) { // Get index timestamp DateTime timestamp = File.GetLastWriteTimeUtc(LuceneCommon.GetIndexMetadataPath()); int numRecords = searchFilter.Skip + searchFilter.Take; var searcher = new IndexSearcher(_directory, readOnly: true); var query = ParseQuery(searchFilter.SearchTerm); // IF searching by relevance, boost scores by download count. if (searchFilter.SortOrder == SortOrder.Relevance) { var downloadCountBooster = new FieldScoreQuery("DownloadCount", FieldScoreQuery.Type.INT); query = new CustomScoreQuery(query, downloadCountBooster); } string filterTerm; if (SemVerLevelKey.ForSemVerLevel(searchFilter.SemVerLevel) == SemVerLevelKey.SemVer2) { filterTerm = searchFilter.IncludePrerelease ? "IsLatestSemVer2" : "IsLatestStableSemVer2"; } else { filterTerm = searchFilter.IncludePrerelease ? "IsLatest" : "IsLatestStable"; } Query filterQuery = new TermQuery(new Term(filterTerm, Boolean.TrueString)); if (searchFilter.CuratedFeed != null) { var feedFilterQuery = new TermQuery(new Term("CuratedFeedKey", searchFilter.CuratedFeed.Key.ToString(CultureInfo.InvariantCulture))); BooleanQuery conjunctionQuery = new BooleanQuery(); conjunctionQuery.Add(filterQuery, Occur.MUST); conjunctionQuery.Add(feedFilterQuery, Occur.MUST); filterQuery = conjunctionQuery; } Filter filter = new QueryWrapperFilter(filterQuery); var results = searcher.Search(query, filter: filter, n: numRecords, sort: new Sort(GetSortField(searchFilter))); if (results.TotalHits == 0 || searchFilter.CountOnly) { return(new SearchResults(results.TotalHits, timestamp)); } var packages = results.ScoreDocs .Skip(searchFilter.Skip) .Select(sd => PackageFromDoc(searcher.Doc(sd.Doc))) .ToList(); return(new SearchResults( results.TotalHits, timestamp, packages.AsQueryable())); }
public void ReturnsSemVer2ForSemVer2CompliantPackagesThatAreNotSemVer1Compliant(string originalVersionString) { // Arrange var nugetVersion = NuGetVersion.Parse(originalVersionString); // Act var key = SemVerLevelKey.ForPackage(nugetVersion, null); // Assert Assert.Equal(SemVerLevelKey.SemVer2, key); }
public void IsUnknown(int?semVerLevelKey, bool expected) { var package = new Package { SemVerLevelKey = semVerLevelKey }; var compiledFunction = SemVerLevelKey.IsUnknownPredicate().Compile(); var actual = compiledFunction(package); Assert.Equal(expected, actual); }
public void ReturnsUnknownForNonSemVer2CompliantPackages(string originalVersionString) { // Arrange var nugetVersion = NuGetVersion.Parse(originalVersionString); // Act var key = SemVerLevelKey.ForPackage(nugetVersion, null); // Assert Assert.Equal(SemVerLevelKey.Unknown, key); }
private static PackageUploadService CreateService( Mock <IPackageService> packageService = null, Mock <IReservedNamespaceService> reservedNamespaceService = null, Mock <IValidationService> validationService = null) { if (packageService == null) { packageService = new Mock <IPackageService>(); } packageService.Setup(x => x.FindPackageRegistrationById(It.IsAny <string>())).Returns((PackageRegistration)null); packageService.Setup(x => x .CreatePackageAsync(It.IsAny <PackageArchiveReader>(), It.IsAny <PackageStreamMetadata>(), It.IsAny <User>(), It.IsAny <User>(), It.IsAny <bool>())) .Returns((PackageArchiveReader packageArchiveReader, PackageStreamMetadata packageStreamMetadata, User owner, User currentUser, bool isVerified) => { var packageMetadata = PackageMetadata.FromNuspecReader( packageArchiveReader.GetNuspecReader(), strict: true); var newPackage = new Package(); newPackage.PackageRegistration = new PackageRegistration { Id = packageMetadata.Id, IsVerified = isVerified }; newPackage.Version = packageMetadata.Version.ToString(); newPackage.SemVerLevelKey = SemVerLevelKey.ForPackage(packageMetadata.Version, packageMetadata.GetDependencyGroups().AsPackageDependencyEnumerable()); return(Task.FromResult(newPackage)); }); if (reservedNamespaceService == null) { reservedNamespaceService = new Mock <IReservedNamespaceService>(); reservedNamespaceService .Setup(r => r.GetReservedNamespacesForId(It.IsAny <string>())) .Returns(new ReservedNamespace[0]); } if (validationService == null) { validationService = new Mock <IValidationService>(); } var packageUploadService = new Mock <PackageUploadService>( packageService.Object, new Mock <IPackageFileService>().Object, new Mock <IEntitiesContext>().Object, reservedNamespaceService.Object, validationService.Object); return(packageUploadService.Object); }
public void ReturnsUnknownForNonSemVer2CompliantDependenciesThatAreNotSemVer1Compliant(string versionSpec) { // Arrange var packageVersion = NuGetVersion.Parse("1.0.0"); var dependency = new PackageDependency { VersionSpec = versionSpec }; // Act var key = SemVerLevelKey.ForPackage(packageVersion, new[] { dependency }); // Assert Assert.Equal(SemVerLevelKey.Unknown, key); }
public Task <IReadOnlyList <string> > Execute( string partialId, bool?includePrerelease = false, bool?includeTestData = false, // ignored on this implementation string semVerLevel = null) { var query = _packageRepository.GetAll() .Include(p => p.PackageRegistration) .Where(p => p.PackageStatusKey == PackageStatus.Available && p.Listed) .Where(SemVerLevelKey.IsPackageCompliantWithSemVerLevelPredicate(semVerLevel)); // prerelease filter if (!includePrerelease.HasValue || !includePrerelease.Value) { query = query.Where(p => !p.IsPrerelease); } var ids = new List <string>(); // filters added for partialId if (!string.IsNullOrWhiteSpace(partialId)) { ids = query.Where(p => p.PackageRegistration.Id.StartsWith(partialId)) .GroupBy(p => p.PackageRegistration.Id) .Select(group => group.Key) .OrderBy(id => id) .Take(MaxResults) .ToList(); } else { ids = query .Select(p => p.PackageRegistration) .Distinct() .OrderByDescending(pr => pr.DownloadCount) .Select(pr => pr.Id) .Take(MaxResults) .ToList(); } return(Task.FromResult <IReadOnlyList <string> >(ids)); }
private static PackageUploadService CreateService( Mock <IPackageService> packageService = null, Mock <IReservedNamespaceService> reservedNamespaceService = null) { { if (packageService == null) { packageService = new Mock <IPackageService>(); } packageService.Setup(x => x.FindPackageRegistrationById(It.IsAny <string>())).Returns((PackageRegistration)null); packageService.Setup(x => x.CreatePackageAsync(It.IsAny <PackageArchiveReader>(), It.IsAny <PackageStreamMetadata>(), It.IsAny <User>(), It.IsAny <bool>(), It.IsAny <bool>())). Returns((PackageArchiveReader packageArchiveReader, PackageStreamMetadata packageStreamMetadata, User user, bool isVerified, bool commitChanges) => { var packageMetadata = PackageMetadata.FromNuspecReader(packageArchiveReader.GetNuspecReader()); var newPackage = new Package(); newPackage.PackageRegistration = new PackageRegistration { Id = packageMetadata.Id, IsVerified = isVerified }; newPackage.Version = packageMetadata.Version.ToString(); newPackage.SemVerLevelKey = SemVerLevelKey.ForPackage(packageMetadata.Version, packageMetadata.GetDependencyGroups().AsPackageDependencyEnumerable()); return(Task.FromResult(newPackage)); }); } if (reservedNamespaceService == null) { reservedNamespaceService = new Mock <IReservedNamespaceService>(); IReadOnlyCollection <ReservedNamespace> userOwnedMatchingNamespaces = new List <ReservedNamespace>(); reservedNamespaceService.Setup(s => s.IsPushAllowed(It.IsAny <string>(), It.IsAny <User>(), out userOwnedMatchingNamespaces)) .Returns(true); } var packageUploadService = new Mock <PackageUploadService>( packageService.Object, reservedNamespaceService.Object); return(packageUploadService.Object); }
public virtual async Task UpdateIsLatestAsync(PackageRegistration packageRegistration, bool commitChanges = true) { if (!packageRegistration.Packages.Any()) { return; } // TODO: improve setting the latest bit; this is horrible. Trigger maybe? var currentUtcTime = DateTime.UtcNow; foreach (var pv in packageRegistration.Packages.Where(p => p.IsLatest || p.IsLatestStable || p.IsLatestSemVer2 || p.IsLatestStableSemVer2)) { pv.IsLatest = false; pv.IsLatestStable = false; pv.IsLatestSemVer2 = false; pv.IsLatestStableSemVer2 = false; pv.LastUpdated = currentUtcTime; } // If the last listed package was just unlisted, then we won't find another one var latestPackage = FindPackage( packageRegistration.Packages.AsQueryable(), ps => ps .Where(SemVerLevelKey.IsUnknownPredicate()) .Where(p => p.PackageStatusKey == PackageStatus.Available && p.Listed)); var latestSemVer2Package = FindPackage( packageRegistration.Packages.AsQueryable(), ps => ps .Where(SemVerLevelKey.IsSemVer2Predicate()) .Where(p => p.PackageStatusKey == PackageStatus.Available && p.Listed)); if (latestPackage != null) { latestPackage.IsLatest = true; latestPackage.LastUpdated = currentUtcTime; if (latestPackage.IsPrerelease) { // If the newest uploaded package is a prerelease package, we need to find an older package that is // a release version and set it to IsLatest. var latestReleasePackage = FindPackage(packageRegistration .Packages .AsQueryable() .Where(SemVerLevelKey.IsUnknownPredicate()) .Where(p => !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available && p.Listed)); if (latestReleasePackage != null) { // We could have no release packages latestReleasePackage.IsLatestStable = true; latestReleasePackage.LastUpdated = currentUtcTime; } } else { // Only release versions are marked as IsLatestStable. latestPackage.IsLatestStable = true; } } if (latestSemVer2Package != null) { latestSemVer2Package.IsLatestSemVer2 = true; latestSemVer2Package.LastUpdated = currentUtcTime; if (latestSemVer2Package.IsPrerelease) { // If the newest uploaded package is a prerelease package, we need to find an older package that is // a release version and set it to IsLatest. var latestSemVer2ReleasePackage = FindPackage(packageRegistration .Packages .AsQueryable() .Where(SemVerLevelKey.IsSemVer2Predicate()) .Where(p => !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available && p.Listed)); if (latestSemVer2ReleasePackage != null) { // We could have no release packages latestSemVer2ReleasePackage.IsLatestStableSemVer2 = true; latestSemVer2ReleasePackage.LastUpdated = currentUtcTime; } } else { // Only release versions are marked as IsLatestStable. latestSemVer2Package.IsLatestStableSemVer2 = true; } } if (commitChanges) { await _packageRepository.CommitChangesAsync(); } }
public virtual Package EnrichPackageFromNuGetPackage( Package package, PackageArchiveReader packageArchive, PackageMetadata packageMetadata, PackageStreamMetadata packageStreamMetadata, User user) { // Version must always be the exact string from the nuspec, which OriginalVersion will return to us. // However, we do also store a normalized copy for looking up later. package.Version = packageMetadata.Version.OriginalVersion; package.NormalizedVersion = packageMetadata.Version.ToNormalizedString(); package.Description = packageMetadata.Description; package.ReleaseNotes = packageMetadata.ReleaseNotes; package.HashAlgorithm = packageStreamMetadata.HashAlgorithm; package.Hash = packageStreamMetadata.Hash; package.PackageFileSize = packageStreamMetadata.Size; package.Language = packageMetadata.Language; package.Copyright = packageMetadata.Copyright; package.FlattenedAuthors = packageMetadata.Authors.Flatten(); package.IsPrerelease = packageMetadata.Version.IsPrerelease; package.Listed = true; package.RequiresLicenseAcceptance = packageMetadata.RequireLicenseAcceptance; package.Summary = packageMetadata.Summary; package.Tags = PackageHelper.ParseTags(packageMetadata.Tags); package.Title = packageMetadata.Title; package.User = user; package.IconUrl = packageMetadata.IconUrl.ToEncodedUrlStringOrNull(); package.LicenseUrl = packageMetadata.LicenseUrl.ToEncodedUrlStringOrNull(); package.ProjectUrl = packageMetadata.ProjectUrl.ToEncodedUrlStringOrNull(); package.MinClientVersion = packageMetadata.MinClientVersion.ToStringOrNull(); #pragma warning disable 618 // TODO: remove Package.Authors completely once production services definitely no longer need it foreach (var author in packageMetadata.Authors) { package.Authors.Add(new PackageAuthor { Name = author }); } #pragma warning restore 618 var supportedFrameworks = GetSupportedFrameworks(packageArchive) .ToArray(); if (!supportedFrameworks.Any(fx => fx != null && fx.IsAny)) { var supportedFrameworkNames = supportedFrameworks .Select(fn => fn.ToShortNameOrNull()) .Where(fn => fn != null) .ToArray(); ValidateSupportedFrameworks(supportedFrameworkNames); foreach (var supportedFramework in supportedFrameworkNames) { package.SupportedFrameworks.Add(new PackageFramework { TargetFramework = supportedFramework }); } } package.Dependencies = packageMetadata .GetDependencyGroups() .AsPackageDependencyEnumerable() .ToList(); package.PackageTypes = packageMetadata .GetPackageTypes() .AsPackageTypeEnumerable() .ToList(); package.FlattenedDependencies = package.Dependencies.Flatten(); package.FlattenedPackageTypes = package.PackageTypes.Flatten(); // Identify the SemVerLevelKey using the original package version string and package dependencies package.SemVerLevelKey = SemVerLevelKey.ForPackage(packageMetadata.Version, package.Dependencies); return(package); }
public virtual async Task UpdateIsLatestAsync(PackageRegistration packageRegistration, bool commitChanges = true) { if (!packageRegistration.Packages.Any()) { return; } // TODO: improve setting the latest bit; this is horrible. Trigger maybe? var currentUtcTime = DateTime.UtcNow; foreach (var pv in packageRegistration.Packages.Where(p => p.IsLatest || p.IsLatestStable || p.IsLatestSemVer2 || p.IsLatestStableSemVer2)) { pv.IsLatest = false; pv.IsLatestStable = false; pv.IsLatestSemVer2 = false; pv.IsLatestStableSemVer2 = false; pv.LastUpdated = currentUtcTime; } // If the last listed package was just unlisted, then we won't find another one var latestPackage = FindPackage( packageRegistration.Packages.AsQueryable(), ps => ps .Where(SemVerLevelKey.IsUnknownPredicate()) .Where(p => p.PackageStatusKey == PackageStatus.Available && p.Listed)); var latestSemVer2Package = FindPackage( packageRegistration.Packages.AsQueryable(), ps => ps .Where(SemVerLevelKey.IsSemVer2Predicate()) .Where(p => p.PackageStatusKey == PackageStatus.Available && p.Listed)); if (latestPackage != null) { latestPackage.IsLatest = true; latestPackage.LastUpdated = currentUtcTime; if (latestPackage.IsPrerelease) { // If the newest uploaded package is a prerelease package, we need to find an older package that is // a release version and set it to IsLatest. var latestReleasePackage = FindPackage(packageRegistration .Packages .AsQueryable() .Where(SemVerLevelKey.IsUnknownPredicate()) .Where(p => !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available && p.Listed)); if (latestReleasePackage != null) { // We could have no release packages latestReleasePackage.IsLatestStable = true; latestReleasePackage.LastUpdated = currentUtcTime; } } else { // Only release versions are marked as IsLatestStable. latestPackage.IsLatestStable = true; } } if (latestSemVer2Package != null) { latestSemVer2Package.IsLatestSemVer2 = true; latestSemVer2Package.LastUpdated = currentUtcTime; if (latestSemVer2Package.IsPrerelease) { // If the newest uploaded package is a prerelease package, we need to find an older package that is // a release version and set it to IsLatest. var latestSemVer2ReleasePackage = FindPackage(packageRegistration .Packages .AsQueryable() .Where(SemVerLevelKey.IsSemVer2Predicate()) .Where(p => !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available && p.Listed)); if (latestSemVer2ReleasePackage != null) { // We could have no release packages latestSemVer2ReleasePackage.IsLatestStableSemVer2 = true; latestSemVer2ReleasePackage.LastUpdated = currentUtcTime; } } else { // Only release versions are marked as IsLatestStable. latestSemVer2Package.IsLatestStableSemVer2 = true; } } // Update the ID on the PackageRegistration if the value differs only by case from the absolute latest // (stable or prerelease) SemVer 2.0.0 package. This is a best effort flow because in general package IDs // are compared in a case-insensitive manner and therefore the PackageRegistration ID casing should not // have any functional impact. The specific casing is only a display concern. if (latestSemVer2Package != null && string.Equals(latestSemVer2Package.Id, packageRegistration.Id, StringComparison.OrdinalIgnoreCase) && !string.Equals(latestSemVer2Package.Id, packageRegistration.Id, StringComparison.Ordinal)) { packageRegistration.Id = latestSemVer2Package.Id; } if (commitChanges) { await _packageRepository.CommitChangesAsync(); } }
public void ThrowsArgumentNullWhenOriginalVersionStringIsNull() { Assert.Throws <ArgumentNullException>(() => SemVerLevelKey.ForPackage(null, null)); }