public async Task NuGetv3LocalRepository_FindPackagesById_UsesProvidedIdCase() { // Arrange using (var workingDir = TestDirectory.Create()) { var id = "Foo"; var target = new NuGetv3LocalRepository(workingDir); await SimpleTestPackageUtility.CreateFolderFeedV3( workingDir, PackageSaveMode.Defaultv3, new SimpleTestPackageContext("foo", "1.0.0")); // Act var packages = target.FindPackagesById(id); // Assert Assert.Equal(1, packages.Count()); Assert.Equal(id, packages.ElementAt(0).Id); Assert.Equal("1.0.0", packages.ElementAt(0).Version.ToNormalizedString()); } }
private void WriteLockFile(string projectLockFilePath, HashSet <Library> graphItems, NuGetv3LocalRepository repository) { var excludes = new[] { ".nuspec", ".nupkg", ".sha512" }; var lockFile = new LockFile(); lockFile.Islocked = false; foreach (var item in graphItems.OrderBy(x => x.Name)) { var package = repository.FindPackagesById(item.Name).FirstOrDefault(p => p.Version == item.Version); if (package != null) { NuspecReader nuspecReader = null; using (var stream = File.OpenRead(package.ManifestPath)) { nuspecReader = new NuspecReader(stream); } var library = new LockFileLibrary(); library.Name = item.Name; library.Version = item.Version; library.FrameworkReferenceGroups = nuspecReader.GetFrameworkReferenceGroups().ToList(); library.ReferenceGroups = nuspecReader.GetReferenceGroups().ToList(); library.DependencyGroups = nuspecReader.GetDependencyGroups().ToList(); library.Files = Directory.EnumerateFiles(package.ExpandedPath, "*.*", SearchOption.AllDirectories) .Where(path => !excludes.Contains(Path.GetExtension(path))) .Select(path => path.Substring(package.ExpandedPath.Length).TrimStart(Path.DirectorySeparatorChar).Replace(Path.DirectorySeparatorChar, '/')) .ToList(); lockFile.Libraries.Add(library); } } var lockFileFormat = new LockFileFormat(); lockFileFormat.Write(projectLockFilePath, lockFile); }
private Task <RestoreTargetGraph[]> WalkRuntimeDependencies(LibraryRange projectRange, RestoreTargetGraph graph, RuntimeGraph projectRuntimeGraph, RemoteDependencyWalker walker, RemoteWalkContext context, NuGetv3LocalRepository localRepository) { // Load runtime specs _log.LogVerbose("Scanning packages for runtime.json files..."); var runtimeGraph = projectRuntimeGraph; graph.Graph.ForEach(node => { var match = node?.Item?.Data?.Match; if (match == null) { return; } // Locate the package in the local repository var package = localRepository.FindPackagesById(match.Library.Name).FirstOrDefault(p => p.Version == match.Library.Version); if (package != null) { var nextGraph = LoadRuntimeGraph(package); if (nextGraph != null) { _log.LogVerbose($"Merging in runtimes defined in {match.Library}"); runtimeGraph = RuntimeGraph.Merge(runtimeGraph, nextGraph); } } }); var resultGraphs = new List <Task <RestoreTargetGraph> >(); foreach (var runtimeName in projectRuntimeGraph.Runtimes.Keys) { _log.LogInformation($"Restoring packages for {graph.Framework} on {runtimeName}"); resultGraphs.Add(WalkDependencies(projectRange, graph.Framework, runtimeName, runtimeGraph, walker, context)); } return(Task.WhenAll(resultGraphs)); }
private LocalPackageInfo FindCandidate(string name, VersionRange versionRange) { var packages = _repository.FindPackagesById(name); return(packages.FindBestMatch(versionRange, info => info?.Version)); }
private LockFile CreateLockFile(PackageSpec project, List <RestoreTargetGraph> targetGraphs, NuGetv3LocalRepository repository) { var lockFile = new LockFile(); using (var sha512 = SHA512.Create()) { foreach (var item in targetGraphs.SelectMany(g => g.Flattened).Distinct().OrderBy(x => x.Data.Match.Library)) { var library = item.Data.Match.Library; var packageInfo = repository.FindPackagesById(library.Name) .FirstOrDefault(p => p.Version == library.Version); if (packageInfo == null) { continue; } var lockFileLib = CreateLockFileLibrary( packageInfo, sha512, correctedPackageName: library.Name); lockFile.Libraries.Add(lockFileLib); } } // Use empty string as the key of dependencies shared by all frameworks lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( string.Empty, project.Dependencies.Select(x => x.LibraryRange.ToString()))); foreach (var frameworkInfo in project.TargetFrameworks) { lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( frameworkInfo.FrameworkName.ToString(), frameworkInfo.Dependencies.Select(x => x.LibraryRange.ToString()))); } // Add the targets foreach (var targetGraph in targetGraphs) { var target = new LockFileTarget(); target.TargetFramework = targetGraph.Framework; target.RuntimeIdentifier = targetGraph.RuntimeIdentifier; foreach (var library in targetGraph.Flattened.Select(g => g.Key).OrderBy(x => x)) { var packageInfo = repository.FindPackagesById(library.Name) .FirstOrDefault(p => p.Version == library.Version); if (packageInfo == null) { continue; } var targetLibrary = CreateLockFileTargetLibrary( packageInfo, targetGraph, new DefaultPackagePathResolver(repository.RepositoryRoot), correctedPackageName: library.Name); target.Libraries.Add(targetLibrary); } lockFile.Targets.Add(target); } return(lockFile); }
public LockFile CreateLockFile( LockFile previousLockFile, PackageSpec project, IEnumerable <RestoreTargetGraph> targetGraphs, NuGetv3LocalRepository repository, RemoteWalkContext context, IEnumerable <ToolRestoreResult> toolRestoreResults) { var lockFile = new LockFile(); lockFile.Version = _lockFileVersion; var resolver = new VersionFolderPathResolver(repository.RepositoryRoot); var previousLibraries = previousLockFile?.Libraries.ToDictionary(l => Tuple.Create <string, NuGetVersion>(l.Name, l.Version)); // Use empty string as the key of dependencies shared by all frameworks lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( string.Empty, project.Dependencies .Select(group => group.LibraryRange.ToLockFileDependencyGroupString()) .OrderBy(group => group, StringComparer.Ordinal))); foreach (var frameworkInfo in project.TargetFrameworks .OrderBy(framework => framework.FrameworkName.ToString(), StringComparer.Ordinal)) { lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( frameworkInfo.FrameworkName.ToString(), frameworkInfo.Dependencies .Select(x => x.LibraryRange.ToLockFileDependencyGroupString()) .OrderBy(dependency => dependency, StringComparer.Ordinal))); } // Record all libraries used foreach (var item in targetGraphs.SelectMany(g => g.Flattened).Distinct() .OrderBy(x => x.Data.Match.Library)) { var library = item.Data.Match.Library; if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase)) { // Do not include the project itself as a library. continue; } if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject) { // Project LocalMatch localMatch = (LocalMatch)item.Data.Match; var projectLib = new LockFileLibrary() { Name = library.Name, Version = library.Version, Type = LibraryType.Project, }; // Set the relative path if a path exists // For projects without project.json this will be empty if (!string.IsNullOrEmpty(localMatch.LocalLibrary.Path)) { projectLib.Path = PathUtility.GetRelativePath( project.FilePath, localMatch.LocalLibrary.Path, '/'); } // The msbuild project path if it exists object msbuildPath; if (localMatch.LocalLibrary.Items.TryGetValue(KnownLibraryProperties.MSBuildProjectPath, out msbuildPath)) { var msbuildRelativePath = PathUtility.GetRelativePath( project.FilePath, (string)msbuildPath, '/'); projectLib.MSBuildProject = msbuildRelativePath; } lockFile.Libraries.Add(projectLib); } else if (library.Type == LibraryType.Package) { // Packages var packageInfo = repository.FindPackagesById(library.Name) .FirstOrDefault(p => p.Version == library.Version); if (packageInfo == null) { continue; } var sha512 = File.ReadAllText(resolver.GetHashPath(packageInfo.Id, packageInfo.Version)); LockFileLibrary previousLibrary = null; previousLibraries?.TryGetValue(Tuple.Create(library.Name, library.Version), out previousLibrary); var lockFileLib = previousLibrary; // If we have the same library in the lock file already, use that. if (previousLibrary == null || previousLibrary.Sha512 != sha512) { var path = resolver.GetPackageDirectory(packageInfo.Id, packageInfo.Version); path = PathUtility.GetPathWithForwardSlashes(path); lockFileLib = CreateLockFileLibrary( packageInfo, sha512, path, correctedPackageName: library.Name); } else if (Path.DirectorySeparatorChar != LockFile.DirectorySeparatorChar) { // Fix slashes for content model patterns lockFileLib.Files = lockFileLib.Files .Select(p => p.Replace(Path.DirectorySeparatorChar, LockFile.DirectorySeparatorChar)) .ToList(); } lockFile.Libraries.Add(lockFileLib); var packageIdentity = new PackageIdentity(lockFileLib.Name, lockFileLib.Version); context.PackageFileCache.TryAdd(packageIdentity, lockFileLib.Files); } } var libraries = lockFile.Libraries.ToDictionary(lib => Tuple.Create(lib.Name, lib.Version)); var warnForImports = project.TargetFrameworks.Any(framework => framework.Warn); var librariesWithWarnings = new HashSet <LibraryIdentity>(); // Add the targets foreach (var targetGraph in targetGraphs .OrderBy(graph => graph.Framework.ToString(), StringComparer.Ordinal) .ThenBy(graph => graph.RuntimeIdentifier, StringComparer.Ordinal)) { var target = new LockFileTarget(); target.TargetFramework = targetGraph.Framework; target.RuntimeIdentifier = targetGraph.RuntimeIdentifier; var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, project, targetGraph); var fallbackFramework = target.TargetFramework as FallbackFramework; var warnForImportsOnGraph = warnForImports && fallbackFramework != null; foreach (var graphItem in targetGraph.Flattened.OrderBy(x => x.Key)) { var library = graphItem.Key; if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject) { if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase)) { // Do not include the project itself as a library. continue; } var localMatch = (LocalMatch)graphItem.Data.Match; // Target framework information is optional and may not exist for csproj projects // that do not have a project.json file. string projectFramework = null; object frameworkInfoObject; if (localMatch.LocalLibrary.Items.TryGetValue( KnownLibraryProperties.TargetFrameworkInformation, out frameworkInfoObject)) { // Retrieve the resolved framework name, if this is null it means that the // project is incompatible. This is marked as Unsupported. var targetFrameworkInformation = (TargetFrameworkInformation)frameworkInfoObject; projectFramework = targetFrameworkInformation.FrameworkName?.DotNetFrameworkName ?? NuGetFramework.UnsupportedFramework.DotNetFrameworkName; } // Create the target entry var lib = new LockFileTargetLibrary() { Name = library.Name, Version = library.Version, Type = LibraryType.Project, Framework = projectFramework, // Find all dependencies which would be in the nuspec // Include dependencies with no constraints, or package/project/external // Exclude suppressed dependencies, the top level project is not written // as a target so the node depth does not matter. Dependencies = graphItem.Data.Dependencies .Where( d => (d.LibraryRange.TypeConstraintAllowsAnyOf( LibraryDependencyTarget.PackageProjectExternal)) && d.SuppressParent != LibraryIncludeFlags.All) .Select(d => GetDependencyVersionRange(d)) .ToList() }; object compileAssetObject; if (localMatch.LocalLibrary.Items.TryGetValue( KnownLibraryProperties.CompileAsset, out compileAssetObject)) { var item = new LockFileItem((string)compileAssetObject); lib.CompileTimeAssemblies.Add(item); lib.RuntimeAssemblies.Add(item); } // Add frameworkAssemblies for projects object frameworkAssembliesObject; if (localMatch.LocalLibrary.Items.TryGetValue( KnownLibraryProperties.FrameworkAssemblies, out frameworkAssembliesObject)) { lib.FrameworkAssemblies.AddRange((List <string>)frameworkAssembliesObject); } target.Libraries.Add(lib); continue; } else if (library.Type == LibraryType.Package) { var packageInfo = repository.FindPackagesById(library.Name) .FirstOrDefault(p => p.Version == library.Version); if (packageInfo == null) { continue; } // include flags LibraryIncludeFlags includeFlags; if (!flattenedFlags.TryGetValue(library.Name, out includeFlags)) { includeFlags = ~LibraryIncludeFlags.ContentFiles; } var targetLibrary = LockFileUtils.CreateLockFileTargetLibrary( libraries[Tuple.Create(library.Name, library.Version)], packageInfo, targetGraph, resolver, correctedPackageName: library.Name, dependencyType: includeFlags, targetFrameworkOverride: null, dependencies: graphItem.Data.Dependencies); target.Libraries.Add(targetLibrary); // Log warnings if the target library used the fallback framework if (warnForImportsOnGraph && !librariesWithWarnings.Contains(library)) { var nonFallbackFramework = new NuGetFramework(fallbackFramework); var targetLibraryWithoutFallback = LockFileUtils.CreateLockFileTargetLibrary( libraries[Tuple.Create(library.Name, library.Version)], packageInfo, targetGraph, resolver, correctedPackageName: library.Name, targetFrameworkOverride: nonFallbackFramework, dependencyType: includeFlags, dependencies: graphItem.Data.Dependencies); if (!targetLibrary.Equals(targetLibraryWithoutFallback)) { var libraryName = $"{library.Name} {library.Version}"; _logger.LogWarning(string.Format(CultureInfo.CurrentCulture, Strings.Log_ImportsFallbackWarning, libraryName, String.Join(", ", fallbackFramework.Fallback), nonFallbackFramework)); // only log the warning once per library librariesWithWarnings.Add(library); } } } } lockFile.Targets.Add(target); } PopulateProjectFileToolGroups(project, lockFile); PopulateTools(toolRestoreResults, lockFile); return(lockFile); }
private void WriteTargetsAndProps(PackageSpec project, List <RestoreTargetGraph> targetGraphs, NuGetv3LocalRepository repository) { // Get the runtime-independent graphs var tfmGraphs = targetGraphs.Where(g => string.IsNullOrEmpty(g.RuntimeIdentifier)).ToList(); if (tfmGraphs.Count > 1) { var name = $"{project.Name}.nuget.targets"; var path = Path.Combine(project.BaseDirectory, name); _log.LogInformation($"Generating MSBuild file {name}"); GenerateMSBuildErrorFile(path); return; } var graph = tfmGraphs[0]; var pathResolver = new DefaultPackagePathResolver(repository.RepositoryRoot); var targets = new List <string>(); var props = new List <string>(); foreach (var library in graph.Flattened.Distinct().OrderBy(g => g.Data.Match.Library)) { var package = repository.FindPackagesById(library.Key.Name).FirstOrDefault(p => p.Version == library.Key.Version); if (package != null) { var criteria = graph.Conventions.Criteria.ForFramework(graph.Framework); var contentItemCollection = new ContentItemCollection(); using (var nupkgStream = File.OpenRead(package.ZipPath)) { var reader = new PackageReader(nupkgStream); contentItemCollection.Load(reader.GetFiles()); } // Find MSBuild thingies var buildItems = contentItemCollection.FindBestItemGroup(criteria, graph.Conventions.Patterns.MSBuildFiles); if (buildItems != null) { // We need to additionally filter to items that are named "{packageId}.targets" and "{packageId}.props" // Filter by file name here and we'll filter by extension when we add things to the lists. var items = buildItems.Items .Where(item => Path.GetFileNameWithoutExtension(item.Path).Equals(package.Id, StringComparison.OrdinalIgnoreCase)) .ToList(); targets.AddRange(items .Select(c => c.Path) .Where(path => Path.GetExtension(path).Equals(".targets", StringComparison.OrdinalIgnoreCase)) .Select(path => Path.Combine(pathResolver.GetPackageDirectory(package.Id, package.Version), path.Replace('/', Path.DirectorySeparatorChar)))); props.AddRange(items .Select(c => c.Path) .Where(path => Path.GetExtension(path).Equals(".props", StringComparison.OrdinalIgnoreCase)) .Select(path => Path.Combine(pathResolver.GetPackageDirectory(package.Id, package.Version), path.Replace('/', Path.DirectorySeparatorChar)))); } } } // Generate the files as needed var targetsName = $"{project.Name}.nuget.targets"; var propsName = $"{project.Name}.nuget.props"; var targetsPath = Path.Combine(project.BaseDirectory, targetsName); var propsPath = Path.Combine(project.BaseDirectory, propsName); if (targets.Any()) { _log.LogInformation($"Generating MSBuild file {targetsName}"); GenerateImportsFile(repository, targetsPath, targets); } else if (File.Exists(targetsPath)) { File.Delete(targetsPath); } if (props.Any()) { _log.LogInformation($"Generating MSBuild file {propsName}"); GenerateImportsFile(repository, propsPath, props); } else if (File.Exists(propsPath)) { File.Delete(propsPath); } }