private void AddLibraryProperties(Library library, PackageSpec packageSpec, NuGetFramework targetFramework) { var projectStyle = packageSpec.RestoreMetadata?.ProjectStyle ?? ProjectStyle.Unknown; library[KnownLibraryProperties.PackageSpec] = packageSpec; library[KnownLibraryProperties.ProjectStyle] = projectStyle; if (packageSpec.RestoreMetadata?.Files != null) { // Record all files that would be in a nupkg library[KnownLibraryProperties.ProjectRestoreMetadataFiles] = packageSpec.RestoreMetadata.Files.ToList(); } // Avoid adding these properties for class libraries // and other projects which are not fully able to // participate in restore. if (packageSpec.RestoreMetadata == null || (projectStyle != ProjectStyle.Unknown && projectStyle != ProjectStyle.PackagesConfig)) { var frameworks = new List <NuGetFramework>( packageSpec.TargetFrameworks.Select(fw => fw.FrameworkName) .Where(fw => !fw.IsUnsupported)); // Record all frameworks in the project library[KnownLibraryProperties.ProjectFrameworks] = frameworks; var targetFrameworkInfo = packageSpec.GetTargetFramework(targetFramework); // FrameworkReducer.GetNearest does not consider ATF since it is used for more than just compat if (targetFrameworkInfo.FrameworkName == null && targetFramework is AssetTargetFallbackFramework atfFramework) { targetFrameworkInfo = packageSpec.GetTargetFramework(atfFramework.AsFallbackFramework()); } if (targetFrameworkInfo.FrameworkName == null && targetFramework is DualCompatibilityFramework mcfFramework) { targetFrameworkInfo = packageSpec.GetTargetFramework(mcfFramework.AsFallbackFramework()); } library[KnownLibraryProperties.TargetFrameworkInformation] = targetFrameworkInfo; // Add framework assemblies var frameworkAssemblies = targetFrameworkInfo.Dependencies .Where(d => d.LibraryRange.TypeConstraint == LibraryDependencyTarget.Reference) .Select(d => d.Name) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); library[KnownLibraryProperties.FrameworkAssemblies] = frameworkAssemblies; // Add framework references library[KnownLibraryProperties.FrameworkReferences] = targetFrameworkInfo.FrameworkReferences; } }
internal List <LibraryDependency> GetSpecDependencies( PackageSpec packageSpec, NuGetFramework targetFramework) { var dependencies = new List <LibraryDependency>(); if (packageSpec != null) { // Add dependencies section dependencies.AddRange(packageSpec.Dependencies); // Add framework specific dependencies var targetFrameworkInfo = packageSpec.GetTargetFramework(targetFramework); if (!_useLegacyAssetTargetFallbackBehavior) { if (targetFrameworkInfo.FrameworkName == null && targetFramework is AssetTargetFallbackFramework atfFramework) { targetFrameworkInfo = packageSpec.GetTargetFramework(atfFramework.AsFallbackFramework()); } } dependencies.AddRange(targetFrameworkInfo.Dependencies); if (packageSpec.RestoreMetadata?.CentralPackageVersionsEnabled == true && packageSpec.RestoreMetadata?.CentralPackageTransitivePinningEnabled == true) { var dependencyNamesSet = new HashSet <string>(targetFrameworkInfo.Dependencies.Select(d => d.Name), StringComparer.OrdinalIgnoreCase); dependencies.AddRange(targetFrameworkInfo.CentralPackageVersions .Where(item => !dependencyNamesSet.Contains(item.Key)) .Select(item => new LibraryDependency() { LibraryRange = new LibraryRange(item.Value.Name, item.Value.VersionRange, LibraryDependencyTarget.Package), VersionCentrallyManaged = true, ReferenceType = LibraryDependencyReferenceType.None, })); } // Remove all framework assemblies dependencies.RemoveAll(d => d.LibraryRange.TypeConstraint == LibraryDependencyTarget.Reference); for (var i = 0; i < dependencies.Count; i++) { // Clone the library dependency so we can safely modify it. The instance cloned here is from the // original package spec, which should not be modified. dependencies[i] = dependencies[i].Clone(); // Remove "project" from the allowed types for this dependency // This will require that projects referenced by an msbuild project // must be external projects. dependencies[i].LibraryRange.TypeConstraint &= ~LibraryDependencyTarget.Project; } } return(dependencies); }
private static List <LibraryDependency> GetSpecDependencies( PackageSpec packageSpec, NuGetFramework targetFramework) { var dependencies = new List <LibraryDependency>(); if (packageSpec != null) { // Add dependencies section dependencies.AddRange(packageSpec.Dependencies); // Add framework specific dependencies var targetFrameworkInfo = packageSpec.GetTargetFramework(targetFramework); dependencies.AddRange(targetFrameworkInfo.Dependencies); // Remove all framework assemblies dependencies.RemoveAll(d => d.LibraryRange.TypeConstraint == LibraryDependencyTarget.Reference); for (var i = 0; i < dependencies.Count; i++) { // Clone the library dependency so we can safely modify it. The instance cloned here is from the // original package spec, which should not be modified. dependencies[i] = dependencies[i].Clone(); // Remove "project" from the allowed types for this dependency // This will require that projects referenced by an msbuild project // must be external projects. dependencies[i].LibraryRange.TypeConstraint &= ~LibraryDependencyTarget.Project; } } return(dependencies); }
private static void AddLibraryProperties(Library library, PackageSpec packageSpec, NuGetFramework targetFramework, string msbuildPath) { var projectStyle = packageSpec.RestoreMetadata?.ProjectStyle ?? ProjectStyle.Unknown; library[KnownLibraryProperties.PackageSpec] = packageSpec; library[KnownLibraryProperties.ProjectStyle] = projectStyle; if (packageSpec.RestoreMetadata?.Files != null) { // Record all files that would be in a nupkg library[KnownLibraryProperties.ProjectRestoreMetadataFiles] = packageSpec.RestoreMetadata.Files.ToList(); } // Avoid adding these properties for class libraries // and other projects which are not fully able to // participate in restore. if (packageSpec.RestoreMetadata == null || (projectStyle != ProjectStyle.Unknown && projectStyle != ProjectStyle.PackagesConfig)) { var frameworks = new List <NuGetFramework>( packageSpec.TargetFrameworks.Select(fw => fw.FrameworkName) .Where(fw => !fw.IsUnsupported)); // Record all frameworks in the project library[KnownLibraryProperties.ProjectFrameworks] = frameworks; var targetFrameworkInfo = packageSpec.GetTargetFramework(targetFramework); library[KnownLibraryProperties.TargetFrameworkInformation] = targetFrameworkInfo; // Add framework references var frameworkReferences = targetFrameworkInfo.Dependencies .Where(d => d.LibraryRange.TypeConstraint == LibraryDependencyTarget.Reference) .Select(d => d.Name) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); library[KnownLibraryProperties.FrameworkAssemblies] = frameworkReferences; } }
public Library GetLibrary(LibraryRange libraryRange, NuGetFramework targetFramework, string rootPath) { Library library = null; var name = libraryRange.Name; ExternalProjectReference externalReference = null; PackageSpec packageSpec = null; bool resolvedUsingDirectory = false; // Check the external references first if (_externalProjectsByName.TryGetValue(name, out externalReference)) { packageSpec = externalReference.PackageSpec; } else if (libraryRange.TypeConstraintAllows(LibraryDependencyTarget.Project)) { // Find the package spec resolver for this root path. var specResolver = GetPackageSpecResolver(rootPath); // Allow directory look ups unless this constrained to external resolvedUsingDirectory = specResolver.TryResolvePackageSpec(name, out packageSpec); } if (externalReference == null && packageSpec == null) { // unable to find any projects return(null); } // create a dictionary of dependencies to make sure that no duplicates exist var dependencies = new List <LibraryDependency>(); TargetFrameworkInformation targetFrameworkInfo = null; if (packageSpec != null) { // Add dependencies section dependencies.AddRange(packageSpec.Dependencies); // Add framework specific dependencies targetFrameworkInfo = packageSpec.GetTargetFramework(targetFramework); dependencies.AddRange(targetFrameworkInfo.Dependencies); // Remove all framework assemblies dependencies.RemoveAll(d => d.LibraryRange.TypeConstraint == LibraryDependencyTarget.Reference); // Disallow projects (resolved by directory) for non-xproj msbuild projects. // If there is no msbuild path then resolving by directory is allowed. // CSProj does not allow directory to directory look up. if (XProjUtility.IsMSBuildBasedProject(externalReference?.MSBuildProjectPath)) { foreach (var dependency in dependencies) { // Remove "project" from the allowed types for this dependency // This will require that projects referenced by an msbuild project // must be external projects. dependency.LibraryRange.TypeConstraint &= ~LibraryDependencyTarget.Project; } } } if (externalReference != null) { var childReferences = GetChildReferences(externalReference); var childReferenceNames = childReferences.Select(reference => reference.ProjectName).ToList(); // External references are created without pivoting on the TxM. Here we need to account for this // and filter out references except the nearest TxM. var filteredExternalDependencies = new HashSet <string>( childReferenceNames, StringComparer.OrdinalIgnoreCase); // Non-Xproj projects may only have one TxM, all external references should be // included if this is an msbuild based project. if (packageSpec != null && !XProjUtility.IsMSBuildBasedProject(externalReference.MSBuildProjectPath)) { // Create an exclude list of all references from the non-selected TxM // Start with all framework specific references var allFrameworkDependencies = GetProjectNames( packageSpec.TargetFrameworks.SelectMany(info => info.Dependencies)); var excludedDependencies = new HashSet <string>( allFrameworkDependencies, StringComparer.OrdinalIgnoreCase); // Then clear out excluded dependencies that are found in the good dependency list foreach (var dependency in GetProjectNames(dependencies)) { excludedDependencies.Remove(dependency); } // Remove excluded dependencies from the external list foreach (var excluded in excludedDependencies) { filteredExternalDependencies.Remove(excluded); } } // Set all dependencies from project.json to external if an external match was passed in // This is viral and keeps p2ps from looking into directories when we are going down // a path already resolved by msbuild. foreach (var dependency in dependencies.Where(d => IsProject(d) && filteredExternalDependencies.Contains(d.Name))) { dependency.LibraryRange.TypeConstraint = LibraryDependencyTarget.ExternalProject; } // Add dependencies passed in externally // These are usually msbuild references which have less metadata, they have // the lowest priority. // Note: Only add in dependencies that are in the filtered list to avoid getting the wrong TxM dependencies.AddRange(childReferences .Where(reference => filteredExternalDependencies.Contains(reference.ProjectName)) .Select(reference => new LibraryDependency { LibraryRange = new LibraryRange { Name = reference.ProjectName, VersionRange = VersionRange.Parse("1.0.0"), TypeConstraint = LibraryDependencyTarget.ExternalProject } })); } // Remove duplicate dependencies. A reference can exist both in csproj and project.json // dependencies is already ordered by importance here var uniqueDependencies = new List <LibraryDependency>(dependencies.Count); var projectNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var project in dependencies) { if (projectNames.Add(project.Name)) { uniqueDependencies.Add(project); } } library = new Library { LibraryRange = libraryRange, Identity = new LibraryIdentity { Name = externalReference?.ProjectName ?? packageSpec.Name, Version = packageSpec?.Version ?? NuGetVersion.Parse("1.0.0"), Type = LibraryType.Project, }, Path = packageSpec?.FilePath, Dependencies = uniqueDependencies, Resolved = true }; if (packageSpec != null) { library[KnownLibraryProperties.PackageSpec] = packageSpec; } string msbuildPath = null; if (externalReference == null) { // Build the path to the .xproj file // If it exists add it to the library properties for the lock file var projectDir = Path.GetDirectoryName(packageSpec.FilePath); var xprojPath = Path.Combine(projectDir, packageSpec.Name + ".xproj"); if (File.Exists(xprojPath)) { msbuildPath = xprojPath; } } else { msbuildPath = externalReference.MSBuildProjectPath; } if (msbuildPath != null) { library[KnownLibraryProperties.MSBuildProjectPath] = msbuildPath; } if (packageSpec != null) { // Record all frameworks in the project library[KnownLibraryProperties.ProjectFrameworks] = new List <NuGetFramework>( packageSpec.TargetFrameworks.Select(fw => fw.FrameworkName)); } if (targetFrameworkInfo != null) { library[KnownLibraryProperties.TargetFrameworkInformation] = targetFrameworkInfo; // Add framework references var frameworkReferences = targetFrameworkInfo.Dependencies .Where(d => d.LibraryRange.TypeConstraint == LibraryDependencyTarget.Reference) .Select(d => d.Name) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); library[KnownLibraryProperties.FrameworkAssemblies] = frameworkReferences; // Add a compile asset for msbuild to xproj projects if (targetFrameworkInfo.FrameworkName != null && msbuildPath?.EndsWith(".xproj", StringComparison.OrdinalIgnoreCase) == true) { var tfmFolder = targetFrameworkInfo.FrameworkName.GetShortFolderName(); // Projects under solution folders will have names such as src\\MyProject // For the purpose of finding the output assembly just take the last part of the name var projectName = packageSpec.Name.Split( new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries) .Last(); // Currently the assembly name cannot be changed for xproj, we can construct the path to where // the output should be. var asset = $"{tfmFolder}/{projectName}.dll"; library[KnownLibraryProperties.CompileAsset] = asset; library[KnownLibraryProperties.RuntimeAsset] = asset; } } return(library); }