void Read(MemoryStream bytes, HttpClient httpClient) { SizeInBytes = bytes.Length; Archive = new ZipArchive(bytes, ZipArchiveMode.Read); TargetFrameworks.Clear(); ZipArchiveEntry nuspecEntry = null; foreach (var e in Archive.Entries.Where(x => x.Name != "_._").OrderBy(x => x.FullName)) { var n = e.FullName; var isBuild = n.StartsWith("build/", StringComparison.InvariantCultureIgnoreCase); var isLib = n.StartsWith("lib/", StringComparison.InvariantCultureIgnoreCase); if ((isBuild || isLib) && (n.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase) || n.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase) || n.EndsWith(".xml", StringComparison.InvariantCultureIgnoreCase))) { var parts = n.Split('/', StringSplitOptions.RemoveEmptyEntries); string tfm; if (parts.Length >= 3) { tfm = Uri.UnescapeDataString(parts[1].Trim().ToLowerInvariant()); } else { tfm = "net"; } var tf = TargetFrameworks.FirstOrDefault(x => x.Moniker == tfm); if (tf == null) { tf = new PackageTargetFramework(this, httpClient) { Moniker = tfm, }; TargetFrameworks.Add(tf); } if (n.EndsWith(".xml", StringComparison.InvariantCultureIgnoreCase)) { var docs = new PackageAssemblyXmlDocs(e); if (string.IsNullOrEmpty(docs.Error)) { // System.Console.WriteLine(docs.AssemblyName); tf.AssemblyXmlDocs[docs.AssemblyName] = docs; } } else if (isBuild) { tf.BuildAssemblies.Add(new PackageAssembly(e, tf)); } else { tf.Assemblies.Add(new PackageAssembly(e, tf)); } } else if (n.EndsWith(".nuspec", StringComparison.InvariantCultureIgnoreCase)) { nuspecEntry = e; } else if (n.StartsWith("content/", StringComparison.InvariantCultureIgnoreCase)) { Content.Add(new PackageFile(e)); } else if (n.StartsWith("tools/", StringComparison.InvariantCultureIgnoreCase)) { Tools.Add(new PackageFile(e)); } else { // System.Console.WriteLine(e); } } if (nuspecEntry != null) { ReadNuspec(nuspecEntry); } TargetFrameworks.Sort((a, b) => string.Compare(a.Moniker, b.Moniker, StringComparison.Ordinal)); }
/// <nodoc /> private bool TryParseDependenciesFromNuSpec() { var dependencyNodes = m_nuSpec .Elements() .Where(el => string.Equals(el.Name.LocalName, "package", StringComparison.Ordinal)) .Elements() .Where(el => string.Equals(el.Name.LocalName, "metadata", StringComparison.Ordinal)) .Elements() .Where(el => string.Equals(el.Name.LocalName, "dependencies", StringComparison.Ordinal)) .Elements(); // Namespace independent query, nuget has about 6 different namespaces as of may 2016. var dependencies = new List <INugetPackage>(); var skipIdLookupTable = new HashSet <string>(this.DependentPackageIdsToSkip); var ignoreIdLookupTable = new HashSet <string>(this.DependentPackageIdsToIgnore); bool skipAllDependencies = skipIdLookupTable.Contains("*"); bool ignoreAllDependencies = ignoreIdLookupTable.Contains("*"); foreach (var dependency in dependencyNodes.Where(el => string.Equals(el.Name.LocalName, "dependency", StringComparison.Ordinal))) { var genericDependency = ReadDependencyElement(dependency); if (genericDependency == null && !(ignoreAllDependencies || ignoreIdLookupTable.Contains(dependency.Attribute("id")?.Value?.Trim()))) { return(false); } if (genericDependency != null && !skipAllDependencies && !skipIdLookupTable.Contains(genericDependency.GetPackageIdentity())) { dependencies.Add(genericDependency); } } var dependenciesPerFramework = new MultiValueDictionary <PathAtom, INugetPackage>(); var groups = dependencyNodes.Where(el => string.Equals(el.Name.LocalName, "group", StringComparison.Ordinal)); foreach (var group in groups) { if (group.Attribute("targetFramework") != null && NugetFrameworkMonikers.TargetFrameworkNameToMoniker.TryGetValue(group.Attribute("targetFramework").Value, out Moniker targetFramework)) { if (group.Elements().Any()) { // If there is at least one valid dependency for a known framework, then the package is defined as managed IsManagedPackage = true; // Only add the group dependency target framework if the nuget package itself also contains specific assemblies of the same version if (!TargetFrameworks.Contains(targetFramework) && (References.Keys.Any(tfm => tfm.Moniker == targetFramework) || Libraries.Keys.Any(tfm => tfm.Moniker == targetFramework))) { TargetFrameworks.Add(targetFramework); } // If the package has a pinned tfm and the groups tfm does not match, skip the groups dependency resolution if (!string.IsNullOrEmpty(this.Tfm) && NugetFrameworkMonikers.TargetFrameworkNameToMoniker.TryGetValue(this.Tfm, out Moniker pinnedTfm) && !PathAtom.Equals(pinnedTfm, targetFramework)) { continue; } foreach ( var dependency in group.Elements().Where( el => string.Equals(el.Name.LocalName, "dependency", StringComparison.Ordinal))) { var grouppedDependency = ReadDependencyElement(dependency); if (grouppedDependency == null && !(ignoreAllDependencies || ignoreIdLookupTable.Contains(dependency.Attribute("id")?.Value?.Trim()))) { return(false); } if (grouppedDependency != null && !skipAllDependencies && !skipIdLookupTable.Contains(grouppedDependency.GetPackageIdentity())) { dependenciesPerFramework.Add(targetFramework, grouppedDependency); } } } } } Dependencies = dependencies; DependenciesPerFramework = dependenciesPerFramework; IsNetStandardPackageOnly = !TargetFrameworks.Any(tfm => NugetFrameworkMonikers.FullFrameworkVersionHistory.Contains(tfm)) && !TargetFrameworks.Any(tfm => NugetFrameworkMonikers.NetCoreAppVersionHistory.Contains(tfm)); return(true); }
private void ParseManagedSemantics() { var stringTable = m_context.PathTable.StringTable; var magicNugetMarker = PathAtom.Create(stringTable, "_._"); var dllExtension = PathAtom.Create(stringTable, ".dll"); foreach (var relativePath in PackageOnDisk.Contents.OrderBy(path => path.ToString(stringTable))) { // This is a dll. Check if it is in a lib folder or ref folder. // This code handles two layouts // Case 1: /runtimes/{targetRuntime}/[lib|ref]/{targetFramework}/{fileName} // Case 2: /[lib|ref]/{targetFramework}/{fileName} // In case 1, /runtimes/{targetRuntime} is removed and then rest of string is processed as in // case 2. // Case 2 treats files under 'lib' folder as runtime dependencies (and optionally compile-time // references if missing a corresponding set of compile-time references for the target framework // under the 'ref' folder). Files under 'ref' folder are treated strictly as compile-time only references. var atoms = new ReadOnlySpan <PathAtom>(relativePath.GetAtoms()); if (atoms.Length == 5) { var isRuntime = NugetFrameworkMonikers.RuntimesFolderName.CaseInsensitiveEquals(stringTable, atoms[0]) && NugetFrameworkMonikers.SupportedTargetRuntimeAtoms.Contains(atoms[1].StringId); if (isRuntime) { atoms = atoms.Slice(2); } } if (atoms.Length == 3) { var libOrRef = atoms[0]; var targetFrameworkFolder = atoms[1]; var fileName = atoms[2]; var isLib = NugetFrameworkMonikers.LibFolderName.CaseInsensitiveEquals(stringTable, libOrRef); var isRef = NugetFrameworkMonikers.RefFolderName.CaseInsensitiveEquals(stringTable, libOrRef); if (isLib || isRef) { if (!TryGetKnownTargetFramework(targetFrameworkFolder, out NugetTargetFramework targetFramework)) { // We skip unknown frameworks, packages are not necessarily well constructed. We log this // as a verbose message (i.e., this is not an error). Logger.Log.NugetUnknownFramework(m_context.LoggingContext, PackageOnDisk.Package.Id, targetFrameworkFolder.ToString(stringTable), relativePath.ToString(stringTable)); continue; } var isManagedEntry = false; var ext = fileName.GetExtension(stringTable); if (dllExtension.CaseInsensitiveEquals(stringTable, ext)) { isManagedEntry = true; if (isRef) { References.Add(targetFramework, relativePath); } if (isLib) { Libraries.Add(targetFramework, relativePath); } } else if (fileName == magicNugetMarker) { isManagedEntry = true; } if (isManagedEntry) { IsManagedPackage = true; if (!TargetFrameworks.Contains(targetFramework.Moniker)) { TargetFrameworks.Add(targetFramework.Moniker); } // The magic marker is there so the framework is declared as supported, but no actual files are listed // So we don't want to add a magic marker as a real artifact that can be referenced. if (fileName != magicNugetMarker) { AssemblyToTargetFramework.Add(fileName, targetFramework); } } } } } if (TargetFrameworks.Count == 0) { var history = ForceFullFrameworkQualifiersOnly ? NugetFrameworkMonikers.FullFrameworkVersionHistory : NugetFrameworkMonikers.WellknownMonikers.ToList(); foreach (var moniker in history) { TargetFrameworks.Add(moniker); } } // For the refs without lib, copy them to refs. foreach (var kv in Libraries) { if (!References.ContainsKey(kv.Key)) { References.Add(kv.Key, kv.Value.ToArray()); } } }
private void ParseManagedSemantics() { var stringTable = m_context.PathTable.StringTable; var magicNugetMarker = PathAtom.Create(stringTable, "_._"); var dllExtension = PathAtom.Create(stringTable, ".dll"); var refs = new MultiValueDictionary <NugetTargetFramework, RelativePath>(); var libs = new MultiValueDictionary <NugetTargetFramework, RelativePath>(); var assemblyToTargetFramework = new MultiValueDictionary <PathAtom, NugetTargetFramework>(); foreach (var relativePath in PackageOnDisk.Contents.OrderBy(path => path.ToString(stringTable))) { // This is a dll. Check if it is in a lib folder or ref folder. var atoms = relativePath.GetAtoms(); if (atoms.Length == 3) { var libOrRef = atoms[0]; var targetFrameworkFolder = atoms[1]; var fileName = atoms[2]; var isLib = NugetFrameworkMonikers.LibFolderName.CaseInsensitiveEquals(stringTable, libOrRef); var isRef = NugetFrameworkMonikers.RefFolderName.CaseInsensitiveEquals(stringTable, libOrRef); if (isLib || isRef) { if (!TryGetKnownTargetFramework(targetFrameworkFolder, out NugetTargetFramework targetFramework)) { // We skip unknown frameworks, packages are not necessarily well constructed. We log this // as a verbose message (i.e., this is not an error). Logger.Log.NugetUnknownFramework(m_context.LoggingContext, PackageOnDisk.Package.Id, targetFrameworkFolder.ToString(stringTable), relativePath.ToString(stringTable)); continue; } var isManagedEntry = false; var ext = fileName.GetExtension(stringTable); if (dllExtension.CaseInsensitiveEquals(stringTable, ext)) { isManagedEntry = true; if (isRef) { refs.Add(targetFramework, relativePath); } if (isLib) { libs.Add(targetFramework, relativePath); } } else if (fileName == magicNugetMarker) { isManagedEntry = true; } if (isManagedEntry) { IsManagedPackage = true; if (!TargetFrameworks.Contains(targetFramework.Moniker)) { TargetFrameworks.Add(targetFramework.Moniker); } // The magic marker is there so the framework is declared as supported, but no actual files are listed // So we don't want to add a magic marker as a real artifact that can be referenced. if (fileName != magicNugetMarker) { assemblyToTargetFramework.Add(fileName, targetFramework); } } } } } if (TargetFrameworks.Count == 0) { var history = ForceFullFrameworkQualifiersOnly ? NugetFrameworkMonikers.FullFrameworkVersionHistory : NugetFrameworkMonikers.WellknownMonikers.ToList(); foreach (var moniker in history) { TargetFrameworks.Add(moniker); } } // For the refs without lib, copy them to refs. foreach (var kv in libs) { if (!refs.ContainsKey(kv.Key)) { refs.Add(kv.Key, kv.Value.ToArray()); } } References = refs; Libraries = libs; AssemblyToTargetFramework = assemblyToTargetFramework; }
async Task ReadAsync(HttpClient httpClient, string packageUri) { this.Client = httpClient; var entries = await ReadEntriesAsync(httpClient, packageUri); TargetFrameworks.Clear(); Content.Clear(); Tools.Clear(); Entry nuspecEntry = null; foreach (var e in entries.Where(x => Path.GetFileName(x.FullName) != "_._").OrderBy(x => x.FullName)) { var n = e.FullName; var isBuild = n.StartsWith("build/", StringComparison.InvariantCultureIgnoreCase); var isLib = n.StartsWith("lib/", StringComparison.InvariantCultureIgnoreCase); var isResources = n.EndsWith(".resources.dll", StringComparison.InvariantCultureIgnoreCase); if ((isBuild || isLib) && (n.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase) || n.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase) || n.EndsWith(".xml", StringComparison.InvariantCultureIgnoreCase)) && !isResources) { var parts = n.Split('/', StringSplitOptions.RemoveEmptyEntries); string tfm; if (parts.Length >= 3) { tfm = Uri.UnescapeDataString(parts[1].Trim().ToLowerInvariant()); } else { tfm = "net"; } var tf = TargetFrameworks.FirstOrDefault(x => x.Moniker == tfm); if (tf == null) { tf = new PackageTargetFramework(this, httpClient) { Moniker = tfm, }; TargetFrameworks.Add(tf); } if (n.EndsWith(".xml", StringComparison.InvariantCultureIgnoreCase)) { var docs = new PackageAssemblyXmlLanguageDocs(e); if (string.IsNullOrEmpty(docs.Error)) { // System.Console.WriteLine(docs.AssemblyName); if (!tf.AssemblyXmlDocs.TryGetValue(docs.AssemblyName, out var allLanguageDocs)) { allLanguageDocs = new PackageAssemblyXmlDocs(docs.AssemblyName); tf.AssemblyXmlDocs[docs.AssemblyName] = allLanguageDocs; } allLanguageDocs.AddLanguage(docs.LanguageCode, docs); } } else if (isBuild) { tf.BuildAssemblies.Add(new PackageAssembly(e, tf)); } else { tf.Assemblies.Add(new PackageAssembly(e, tf)); } } else if (n.EndsWith(".nuspec", StringComparison.InvariantCultureIgnoreCase)) { nuspecEntry = e; } else if (n.StartsWith("content/", StringComparison.InvariantCultureIgnoreCase)) { Content.Add(new PackageFile(e)); } else if (n.StartsWith("tools/", StringComparison.InvariantCultureIgnoreCase)) { Tools.Add(new PackageFile(e)); } else { // System.Console.WriteLine(e); } } if (nuspecEntry != null) { ReadNuspec(nuspecEntry); } TargetFrameworks.Sort((a, b) => string.Compare(a.Moniker, b.Moniker, StringComparison.Ordinal)); }