/// <summary> /// Gets package metadata from a the provided <see cref="NuspecReader"/> instance. /// </summary> /// <param name="nuspecReader">The <see cref="NuspecReader"/> instance used to read the <see cref="PackageMetadata"/></param> /// <param name="strict"> /// Whether or not to be strict when reading the <see cref="NuspecReader"/>. This should be <code>true</code> /// on initial ingestion but false when a package that has already been accepted is being processed.</param> /// <exception cref="PackagingException"> /// We default to use a strict version-check on dependency groups. /// When an invalid dependency version range is detected, a <see cref="PackagingException"/> will be thrown. /// </exception> public static PackageMetadata FromNuspecReader(NuspecReader nuspecReader, bool strict) { var strictNuspecReader = new StrictNuspecReader(nuspecReader.Xml); var metadataLookup = strictNuspecReader.GetMetadataLookup(); if (strict) { var duplicates = metadataLookup .Where(g => g.Count() > 1) .Select(g => g.Key) .ToList(); if (duplicates.Any()) { throw new PackagingException(string.Format( CoreStrings.Manifest_DuplicateMetadataElements, string.Join("', '", duplicates))); } } // Reject invalid metadata element names. Today this only rejects element names that collide with // properties generated downstream. var metadataKeys = new HashSet <string>(metadataLookup.Select(g => g.Key)); metadataKeys.IntersectWith(RestrictedMetadataElements); if (metadataKeys.Any()) { throw new PackagingException(string.Format( CoreStrings.Manifest_InvalidMetadataElements, string.Join("', '", metadataKeys.OrderBy(x => x)))); } // Reject non-boolean values for boolean metadata. foreach (var booleanName in BooleanMetadataElements) { foreach (var unparsedBoolean in metadataLookup[booleanName]) { if (!bool.TryParse(unparsedBoolean, out var parsedBoolean)) { throw new PackagingException(string.Format( CoreStrings.Manifest_InvalidBooleanMetadata, booleanName)); } } } return(new PackageMetadata( nuspecReader.GetMetadata().ToDictionary(kvp => kvp.Key, kvp => kvp.Value), nuspecReader.GetDependencyGroups(useStrictVersionCheck: strict), nuspecReader.GetFrameworkReferenceGroups(), nuspecReader.GetPackageTypes(), nuspecReader.GetMinClientVersion(), nuspecReader.GetRepositoryMetadata(), nuspecReader.GetLicenseMetadata())); }
private static async Task WritePackageNotice(StreamWriter writer, NuspecReader package) { await writer.WriteAsync("License notice for ").ConfigureAwait(false); await writer.WriteAsync(package.GetId()).ConfigureAwait(false); await writer.WriteAsync(" (v").ConfigureAwait(false); await writer.WriteAsync(package.GetVersion().ToFullString()).ConfigureAwait(false); await writer.WriteLineAsync(")").ConfigureAwait(false); await writer.WriteLineAsync("------------------------------------").ConfigureAwait(false); var repository = package.GetRepositoryMetadata(); if (!string.IsNullOrEmpty(repository?.Url)) { await writer.WriteLineAsync().ConfigureAwait(false); await writer.WriteAsync(repository.Url).ConfigureAwait(false); if (!string.IsNullOrEmpty(repository.Commit)) { await writer.WriteAsync(" at ").ConfigureAwait(false); await writer.WriteAsync(repository.Commit).ConfigureAwait(false); } await writer.WriteLineAsync().ConfigureAwait(false); } string projectUrl = package.GetProjectUrl(); if (projectUrl != repository?.Url) { await WriteIfNotEmpty(writer, string.Empty, projectUrl).ConfigureAwait(false); } string copyright = package.GetCopyright(); string copyrightPrefix = string.Empty; if (copyright?.Length > 0 && copyright[0] == '©') { copyrightPrefix = "Copyright "; } await WriteIfNotEmpty(writer, copyrightPrefix, copyright).ConfigureAwait(false); var license = package.GetLicenseMetadata(); if (license != null) { string licenseExpression = license.LicenseExpression?.ToString(); await WriteIfNotEmpty(writer, "Licensed under ", licenseExpression).ConfigureAwait(false); await WriteIfNotEmpty(writer, "Available at ", license.LicenseUrl?.AbsoluteUri).ConfigureAwait(false); if (license.License != licenseExpression) { await WriteIfNotEmpty(writer, string.Empty, license.License).ConfigureAwait(false); } } else { await WriteIfNotEmpty(writer, "License available at ", package.GetLicenseUrl()).ConfigureAwait(false); } await writer.WriteLineAsync().ConfigureAwait(false); await writer.WriteLineAsync().ConfigureAwait(false); }