internal static bool ShouldCuratePackage( CuratedFeed curatedFeed, Package galleryPackage, PackageReader nugetPackage) { var nuspec = nugetPackage.GetNuspecReader(); return // Must have min client version of null or <= 2.2 ((nuspec.GetMinClientVersion() == null || nuspec.GetMinClientVersion() <= new NuGetVersion(2, 2, 0)) && // Must be latest stable galleryPackage.IsLatestStable && // Must support net40 SupportsNet40(galleryPackage) && ( // Must have AspNetWebPages tag ContainsAspNetWebPagesTag(galleryPackage) || // OR: Must not contain powershell or T4 DoesNotContainUnsupportedFiles(nugetPackage) ) && // Dependencies on the gallery must be curated DependenciesAreCurated(galleryPackage, curatedFeed)); }
public static void RewritingTheNuSpecDoesNotMessUpTheNuspecStream() { var packageStream = CreateTestPackageStream(); var manifestStreamLengthOriginal = GetManifestStreamLength(packageStream); var longValue = new String('x', 200); var shortValue = "y"; // Act 1 - Make the stream bigger NupkgRewriter.RewriteNupkgManifest(packageStream, new List <Action <ManifestEdit> > { metadata => { metadata.Description = longValue; }, metadata => { metadata.Summary = longValue; } }); // Assert 1 var manifestStreamLength1 = GetManifestStreamLength(packageStream); Assert.True(manifestStreamLength1 > manifestStreamLengthOriginal); using (var nupkg = new PackageReader(packageStream, leaveStreamOpen: true)) { var nuspec = nupkg.GetNuspecReader(); Assert.Equal("TestPackage", nuspec.GetId()); Assert.Equal(NuGetVersion.Parse("0.0.0.1"), nuspec.GetVersion()); Assert.Equal(longValue, nuspec.GetMetadata().First(kvp => kvp.Key == "description").Value); Assert.Equal(longValue, nuspec.GetMetadata().First(kvp => kvp.Key == "summary").Value); } // Act 2 - Make the stream smaller NupkgRewriter.RewriteNupkgManifest(packageStream, new List <Action <ManifestEdit> > { metadata => { metadata.Description = shortValue; }, metadata => { metadata.Summary = shortValue; } }); // Assert 2 var manifestStreamLength2 = GetManifestStreamLength(packageStream); Assert.True(manifestStreamLength2 < manifestStreamLength1); using (var nupkg = new PackageReader(packageStream, leaveStreamOpen: true)) { var nuspec = nupkg.GetNuspecReader(); Assert.Equal("TestPackage", nuspec.GetId()); Assert.Equal(NuGetVersion.Parse("0.0.0.1"), nuspec.GetVersion()); Assert.Equal(shortValue, nuspec.GetMetadata().First(kvp => kvp.Key == "description").Value); Assert.Equal(shortValue, nuspec.GetMetadata().First(kvp => kvp.Key == "summary").Value); } }
public void EnsureValid(PackageReader packageReader) { var packageMetadata = PackageMetadata.FromNuspecReader(packageReader.GetNuspecReader()); ValidateNuGetPackageMetadata(packageMetadata); var supportedFrameworks = GetSupportedFrameworks(packageReader).Select(fn => fn.ToShortNameOrNull()).ToArray(); if (!supportedFrameworks.AnySafe(sf => sf == null)) { ValidateSupportedFrameworks(supportedFrameworks); } }
public Package CreatePackage(PackageReader nugetPackage, PackageStreamMetadata packageStreamMetadata, User user, bool commitChanges = true) { var packageMetadata = PackageMetadata.FromNuspecReader(nugetPackage.GetNuspecReader()); ValidateNuGetPackageMetadata(packageMetadata); var packageRegistration = CreateOrGetPackageRegistration(user, packageMetadata); var package = CreatePackageFromNuGetPackage(packageRegistration, nugetPackage, packageMetadata, packageStreamMetadata, user); packageRegistration.Packages.Add(package); UpdateIsLatest(packageRegistration, false); if (commitChanges) { _packageRegistrationRepository.CommitChanges(); NotifyIndexingService(); } return(package); }
public static void CanReadBasicMetadataProperties() { var packageStream = CreateTestPackageStream(); var nupkg = new PackageReader(packageStream, leaveStreamOpen: false); var nuspec = nupkg.GetNuspecReader(); // Act var packageMetadata = PackageMetadata.FromNuspecReader(nuspec); // Assert Assert.Equal("TestPackage", packageMetadata.Id); Assert.Equal(NuGetVersion.Parse("0.0.0.1"), packageMetadata.Version); Assert.Equal("Package A", packageMetadata.Title); Assert.Equal(2, packageMetadata.Authors.Count); Assert.Equal("ownera, ownerb", packageMetadata.Owners); Assert.False(packageMetadata.RequireLicenseAcceptance); Assert.Equal("package A description.", packageMetadata.Description); Assert.Equal("en-US", packageMetadata.Language); Assert.Equal("http://www.nuget.org/", packageMetadata.ProjectUrl.ToString()); Assert.Equal("http://www.nuget.org/", packageMetadata.IconUrl.ToString()); Assert.Equal("http://www.nuget.org/", packageMetadata.LicenseUrl.ToString()); }
public static void CanRewriteTheNuspecInANupkg() { var packageStream = CreateTestPackageStream(); // Act NupkgRewriter.RewriteNupkgManifest(packageStream, new List <Action <ManifestEdit> > { metadata => { metadata.Authors = "Me and You"; }, metadata => { metadata.Tags = "Peas In A Pod"; } }); // Assert using (var nupkg = new PackageReader(packageStream, leaveStreamOpen: false)) { var nuspec = nupkg.GetNuspecReader(); Assert.Equal("TestPackage", nuspec.GetId()); Assert.Equal(NuGetVersion.Parse("0.0.0.1"), nuspec.GetVersion()); Assert.Equal("Me and You", nuspec.GetMetadata().First(kvp => kvp.Key == "authors").Value); Assert.Equal("Peas In A Pod", nuspec.GetMetadata().First(kvp => kvp.Key == "tags").Value); } }
/// <summary> /// Given the nupkg file as a read-write stream with random access (e.g. MemoryStream), /// This will replace the .nuspec file with a new .nuspec generated from /// a) the old .nuspec file /// b) supplied edits /// /// This function leaves readWriteStream open. /// </summary> public static void RewriteNupkgManifest(Stream readWriteStream, IEnumerable <Action <ManifestEdit> > edits) { if (!readWriteStream.CanRead) { throw new ArgumentException("Must be a readable stream", "readWriteStream"); } if (!readWriteStream.CanWrite) { throw new ArgumentException("Must be a writeable stream", "readWriteStream"); } if (!readWriteStream.CanSeek) { throw new ArgumentException("Must be a seekable stream", "readWriteStream"); } using (var packageReader = new PackageReader(readWriteStream, leaveStreamOpen: true)) { var nuspecReader = packageReader.GetNuspecReader(); // Read <metadata> node from nuspec var metadataNode = nuspecReader.Xml.Root.Elements() .FirstOrDefault(e => StringComparer.Ordinal.Equals(e.Name.LocalName, "metadata")); if (metadataNode == null) { throw new PackagingException("The package manifest is missing the 'metadata' node."); } // Convert metadata into a ManifestEdit so that we can run it through the editing pipeline var editableManifestElements = new ManifestEdit { Title = ReadFromMetadata(metadataNode, "title"), Authors = ReadFromMetadata(metadataNode, "authors"), Copyright = ReadFromMetadata(metadataNode, "copyright"), Description = ReadFromMetadata(metadataNode, "description"), IconUrl = ReadFromMetadata(metadataNode, "iconUrl"), LicenseUrl = ReadFromMetadata(metadataNode, "licenseUrl"), ProjectUrl = ReadFromMetadata(metadataNode, "projectUrl"), ReleaseNotes = ReadFromMetadata(metadataNode, "releasenotes"), RequireLicenseAcceptance = ReadBoolFromMetadata(metadataNode, "requireLicenseAcceptance"), Summary = ReadFromMetadata(metadataNode, "summary"), Tags = ReadFromMetadata(metadataNode, "tags") }; // Perform edits foreach (var edit in edits) { edit.Invoke(editableManifestElements); } // Update the <metadata> node WriteToMetadata(metadataNode, "title", editableManifestElements.Title); WriteToMetadata(metadataNode, "authors", editableManifestElements.Authors); WriteToMetadata(metadataNode, "copyright", editableManifestElements.Copyright); WriteToMetadata(metadataNode, "description", editableManifestElements.Description); WriteToMetadata(metadataNode, "iconUrl", editableManifestElements.IconUrl); WriteToMetadata(metadataNode, "licenseUrl", editableManifestElements.LicenseUrl); WriteToMetadata(metadataNode, "projectUrl", editableManifestElements.ProjectUrl); WriteToMetadata(metadataNode, "releasenotes", editableManifestElements.ReleaseNotes); WriteToMetadata(metadataNode, "requireLicenseAcceptance", editableManifestElements.RequireLicenseAcceptance.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()); WriteToMetadata(metadataNode, "summary", editableManifestElements.Summary); WriteToMetadata(metadataNode, "tags", editableManifestElements.Tags); // Update the package stream using (var newManifestStream = new MemoryStream()) { nuspecReader.Xml.Save(newManifestStream); using (var archive = new ZipArchive(readWriteStream, ZipArchiveMode.Update, leaveOpen: true)) { var manifestEntries = archive.Entries .Where(entry => entry.FullName.IndexOf("/", StringComparison.OrdinalIgnoreCase) == -1 && entry.Name.EndsWith(".nuspec", StringComparison.OrdinalIgnoreCase)).ToList(); if (manifestEntries.Count == 0) { throw new PackagingException("Nuspec file does not exist in package."); } if (manifestEntries.Count > 1) { throw new PackagingException("Package contains multiple nuspec files."); } var manifestEntry = manifestEntries[0]; using (var manifestOutputStream = manifestEntry.Open()) { manifestOutputStream.SetLength(0); newManifestStream.Position = 0; newManifestStream.CopyTo(manifestOutputStream); } } } } }
public override void ExecuteCommand() { Log.Trace("Getting latest packages..."); var packages = GetLatestStablePackages(); Log.Trace("Getting previously curated packages..."); var alreadyCuratedPackageIds = GetAlreadyCuratedPackageIds(); Log.Trace("Calculating minimum difference set..."); var packageIdsToCurate = packages.Keys.Except(alreadyCuratedPackageIds).ToList(); var totalCount = packageIdsToCurate.Count; var processedCount = 0; Log.Trace( "Curating {0} packages for the WebMatrix curated on '{1}',", totalCount, ConnectionString); Parallel.ForEach(packageIdsToCurate, new ParallelOptions { MaxDegreeOfParallelism = 10 }, packageIdToCurate => { var package = packages[packageIdToCurate]; try { var downloadPath = DownloadPackage(package); bool shouldBeIncluded; using (var nugetPackage = new PackageReader(File.OpenRead(downloadPath))) { var nuspecReader = nugetPackage.GetNuspecReader(); var metadata = nuspecReader.GetMetadata() .ToDictionary(kvp => kvp.Key, kvp => kvp.Value, StringComparer.OrdinalIgnoreCase); string tags; shouldBeIncluded = metadata.TryGetValue("tags", out tags) && tags.ToLowerInvariant().Contains("aspnetwebpages"); if (!shouldBeIncluded) { shouldBeIncluded = true; foreach (var file in nugetPackage.GetFiles()) { var fi = new FileInfo(file); if (fi.Extension == ".ps1" || fi.Extension == ".t4") { shouldBeIncluded = false; break; } } } if (shouldBeIncluded) { AddPackageToCuratedFeed(package); } } File.Delete(downloadPath); Interlocked.Increment(ref processedCount); Log.Info( "{2} package '{0}.{1}' ({3} of {4}).", package.Id, package.Version, shouldBeIncluded ? "Curated" : "Ignored", processedCount, totalCount); } catch (Exception ex) { Interlocked.Increment(ref processedCount); Log.Error( "Error curating package '{0}.{1}' ({2} of {3}): {4}.", package.Id, package.Version, processedCount, totalCount, ex.Message); } }); }
private async Task <ActionResult> CreatePackageInternal() { // Get the user var user = GetCurrentUser(); using (var packageStream = ReadPackageFromRequest()) using (var packageToPush = new PackageReader(packageStream, leaveStreamOpen: false)) { NuspecReader nuspec = null; try { nuspec = packageToPush.GetNuspecReader(); } catch (Exception ex) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, Strings.UploadPackage_InvalidNuspec, ex.Message))); } if (nuspec.GetMinClientVersion() > Constants.MaxSupportedMinClientVersion) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, Strings.UploadPackage_MinClientVersionOutOfRange, nuspec.GetMinClientVersion()))); } // Ensure that the user can push packages for this partialId. var packageRegistration = PackageService.FindPackageRegistrationById(nuspec.GetId()); if (packageRegistration != null) { if (!packageRegistration.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } // Check if a particular Id-Version combination already exists. We eventually need to remove this check. string normalizedVersion = nuspec.GetVersion().ToNormalizedString(); bool packageExists = packageRegistration.Packages.Any( p => String.Equals( p.NormalizedVersion, normalizedVersion, StringComparison.OrdinalIgnoreCase)); if (packageExists) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Conflict, String.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified, nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe()))); } } var packageStreamMetadata = new PackageStreamMetadata { HashAlgorithm = Constants.Sha512HashAlgorithmId, Hash = CryptographyService.GenerateHash(packageStream.AsSeekableStream()), Size = packageStream.Length, }; var package = PackageService.CreatePackage(packageToPush, packageStreamMetadata, user, commitChanges: false); AutoCuratePackage.Execute(package, packageToPush, commitChanges: false); EntitiesContext.SaveChanges(); using (Stream uploadStream = packageStream) { uploadStream.Position = 0; await PackageFileService.SavePackageFileAsync(package, uploadStream.AsSeekableStream()); IndexingService.UpdatePackage(package); } } return(new HttpStatusCodeResult(HttpStatusCode.Created)); }