internal static string GetToolCacheFilePath(RestoreRequest request, LockFile lockFile) { if (request.ProjectStyle == ProjectStyle.DotnetCliTool && lockFile != null) { var toolName = ToolRestoreUtility.GetToolIdOrNullFromSpec(request.Project); var lockFileLibrary = ToolRestoreUtility.GetToolTargetLibrary(lockFile, toolName); if (lockFileLibrary != null) { var version = lockFileLibrary.Version; var toolPathResolver = new ToolPathResolver(request.PackagesDirectory); return(GetToolCacheFilePath(toolPathResolver.GetToolDirectoryPath( toolName, version, lockFile.Targets.First().TargetFramework), toolName)); } } return(null); }
public RestoreCommand(RestoreRequest request) { _request = request ?? throw new ArgumentNullException(nameof(request)); // Validate the lock file version requested if (_request.LockFileVersion < 1 || _request.LockFileVersion > LockFileFormat.Version) { Debug.Fail($"Lock file version {_request.LockFileVersion} is not supported."); throw new ArgumentOutOfRangeException(nameof(_request.LockFileVersion)); } var collectorLoggerHideWarningsAndErrors = request.Project.RestoreSettings.HideWarningsAndErrors || request.HideWarningsAndErrors; var collectorLogger = new RestoreCollectorLogger(_request.Log, collectorLoggerHideWarningsAndErrors); collectorLogger.ApplyRestoreInputs(_request.Project); _logger = collectorLogger; }
/// <summary> /// This method verifies that the assets files, props/targets files and all the packages written out in the assets file are present on disk /// When the project has opted into packages lock file, it also verified that the lock file is present on disk. /// This does not account if the files were manually modified since the last restore /// </summary> internal static bool VerifyRestoreOutput(RestoreRequest request) { if (!File.Exists(request.ExistingLockFile?.Path)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_AssetsFileNotOnDisk, request.Project.Name)); return(false); } if (request.ProjectStyle == ProjectStyle.PackageReference || request.ProjectStyle == ProjectStyle.Standalone) { var targetsFilePath = BuildAssetsUtils.GetMSBuildFilePath(request.Project, request, "targets"); if (!File.Exists(targetsFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_TargetsFileNotOnDisk, request.Project.Name, targetsFilePath)); return(false); } var propsFilePath = BuildAssetsUtils.GetMSBuildFilePath(request.Project, request, "props"); if (!File.Exists(propsFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_PropsFileNotOnDisk, request.Project.Name, propsFilePath)); return(false); } if (PackagesLockFileUtilities.IsNuGetLockFileEnabled(request.Project)) { var packageLockFilePath = PackagesLockFileUtilities.GetNuGetLockFilePath(request.Project); if (!File.Exists(packageLockFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_LockFileNotOnDisk, request.Project.Name, packageLockFilePath)); return(false); } } } if (!VerifyPackagesOnDisk(request)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_MissingPackagesOnDisk, request.Project.Name)); return(false); } return(true); }
/// <summary> /// This method verifies that the assets files, props/targets files and all the packages written out in the assets file are present on disk /// When the project has opted into packages lock file, it also verified that the lock file is present on disk. /// This does not account if the files were manually modified since the last restore /// </summary> internal static bool VerifyRestoreOutput(RestoreRequest request, CacheFile cacheFile) { if (!string.IsNullOrWhiteSpace(request.LockFilePath) && !File.Exists(request.LockFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_AssetsFileNotOnDisk, request.Project.Name)); return(false); } if (request.ProjectStyle == ProjectStyle.PackageReference || request.ProjectStyle == ProjectStyle.Standalone) { var targetsFilePath = BuildAssetsUtils.GetMSBuildFilePath(request.Project, BuildAssetsUtils.TargetsExtension); if (!File.Exists(targetsFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_TargetsFileNotOnDisk, request.Project.Name, targetsFilePath)); return(false); } var propsFilePath = BuildAssetsUtils.GetMSBuildFilePath(request.Project, BuildAssetsUtils.PropsExtension); if (!File.Exists(propsFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_PropsFileNotOnDisk, request.Project.Name, propsFilePath)); return(false); } if (PackagesLockFileUtilities.IsNuGetLockFileEnabled(request.Project)) { var packageLockFilePath = PackagesLockFileUtilities.GetNuGetLockFilePath(request.Project); if (!File.Exists(packageLockFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_LockFileNotOnDisk, request.Project.Name, packageLockFilePath)); return(false); } } } if (cacheFile.HasAnyMissingPackageFiles) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_MissingPackagesOnDisk, request.Project.Name)); return(false); } return(true); }
public OriginalCaseGlobalPackageFolder(RestoreRequest request, Guid parentId) { if (request == null) { throw new ArgumentNullException(nameof(request)); } _request = request; _localRepositories = new List <NuGetv3LocalRepository>(); _localRepositories.Add(request.DependencyProviders.GlobalPackages); _localRepositories.AddRange(request.DependencyProviders.FallbackPackageFolders); _pathResolver = new VersionFolderPathResolver( _request.PackagesDirectory, _request.IsLowercasePackagesDirectory); _toolPathResolver = new ToolPathResolver( _request.PackagesDirectory, _request.IsLowercasePackagesDirectory); }
public ProjectRestoreRequest( RestoreRequest request, PackageSpec packageSpec, LockFile existingLockFile, RestoreCollectorLogger log) { CacheContext = request.CacheContext; Log = log; PackagesDirectory = request.PackagesDirectory; ExistingLockFile = existingLockFile; MaxDegreeOfConcurrency = request.MaxDegreeOfConcurrency; Project = packageSpec; PackageExtractionContext = new PackageExtractionContext( request.PackageSaveMode, request.XmlDocFileSaveMode, request.ClientPolicyContext, log) { SignedPackageVerifier = request.SignedPackageVerifier }; }
internal static string GetToolCacheFilePath(RestoreRequest request, LockFile lockFile) { if (request.ProjectStyle != ProjectStyle.DotnetCliTool) { var toolName = ToolRestoreUtility.GetToolIdOrNullFromSpec(request.Project); var lockFileLibrary = ToolRestoreUtility.GetToolTargetLibrary(lockFile, toolName); if (lockFileLibrary != null) { var version = lockFileLibrary.Version; var toolPathResolver = new ToolPathResolver(request.PackagesDirectory); var projFileName = Path.GetFileName(request.Project.RestoreMetadata.ProjectPath); return(PathUtility.GetDirectoryName(toolPathResolver.GetLockFilePath( toolName, version, lockFile.Targets.First().TargetFramework)) + $"{projFileName}.nuget.cache"); } } return(null); }
private RestoreSummaryRequest Create( string inputPath, RestoreArgs restoreContext) { var file = new FileInfo(inputPath); // Get settings relative to the input file var settings = restoreContext.GetSettings(file.DirectoryName); var sources = restoreContext.GetEffectiveSources(settings, null); var FallbackPackageFolders = restoreContext.GetEffectiveFallbackPackageFolders(settings); var globalPath = restoreContext.GetEffectiveGlobalPackagesFolder(file.DirectoryName, settings); var sharedCache = _providerCache.GetOrCreate( globalPath, FallbackPackageFolders, sources, restoreContext.CacheContext, restoreContext.Log); var project = JsonPackageSpecReader.GetPackageSpec(file.Directory.Name, file.FullName); var request = new RestoreRequest( project, sharedCache, restoreContext.CacheContext, restoreContext.Log) { ParentId = restoreContext.ParentId }; restoreContext.ApplyStandardProperties(request); var summaryRequest = new RestoreSummaryRequest(request, inputPath, SettingsUtility.GetConfigFilePaths(settings), sources); return(summaryRequest); }
private RestoreSummaryRequest Create( string projectNameToRestore, ExternalProjectReference project, HashSet <ExternalProjectReference> projectReferenceClosure, RestoreArgs restoreArgs, DependencyGraphSpec projectDgSpec, SettingsLoadingContext settingsLoadingContext) { var projectPackageSpec = projectDgSpec.GetProjectSpec(projectNameToRestore); //fallback paths, global packages path and sources need to all be passed in the dg spec var fallbackPaths = projectPackageSpec.RestoreMetadata.FallbackFolders; var globalPath = GetPackagesPath(restoreArgs, projectPackageSpec); var settings = Settings.LoadImmutableSettingsGivenConfigPaths(projectPackageSpec.RestoreMetadata.ConfigFilePaths, settingsLoadingContext); var sources = restoreArgs.GetEffectiveSources(settings, projectPackageSpec.RestoreMetadata.Sources); var clientPolicyContext = ClientPolicyContext.GetClientPolicy(settings, restoreArgs.Log); var sharedCache = _providerCache.GetOrCreate( globalPath, fallbackPaths.AsList(), sources, restoreArgs.CacheContext, restoreArgs.Log); var rootPath = Path.GetDirectoryName(project.PackageSpec.FilePath); // Create request var request = new RestoreRequest( project.PackageSpec, sharedCache, restoreArgs.CacheContext, clientPolicyContext, restoreArgs.Log) { // Set properties from the restore metadata ProjectStyle = project.PackageSpec.RestoreMetadata.ProjectStyle, // Project.json is special cased to put assets file and generated .props and targets in the project folder RestoreOutputPath = project.PackageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson ? rootPath : project.PackageSpec.RestoreMetadata.OutputPath, DependencyGraphSpec = projectDgSpec, MSBuildProjectExtensionsPath = projectPackageSpec.RestoreMetadata.OutputPath }; var restoreLegacyPackagesDirectory = project.PackageSpec?.RestoreMetadata?.LegacyPackagesDirectory ?? DefaultRestoreLegacyPackagesDirectory; request.IsLowercasePackagesDirectory = !restoreLegacyPackagesDirectory; // Standard properties restoreArgs.ApplyStandardProperties(request); // Add project references request.ExternalProjects = projectReferenceClosure.ToList(); // The lock file is loaded later since this is an expensive operation var summaryRequest = new RestoreSummaryRequest( request, project.MSBuildProjectPath, settings.GetConfigFilePaths(), sources); return(summaryRequest); }
public OriginalCaseGlobalPackageFolder(RestoreRequest request) : this(request, Guid.Empty) { }
public static List <MSBuildOutputFile> GetMSBuildOutputFiles(PackageSpec project, LockFile assetsFile, IEnumerable <RestoreTargetGraph> targetGraphs, IReadOnlyList <NuGetv3LocalRepository> repositories, RestoreRequest request, string assetsFilePath, bool restoreSuccess, ILogger log) { // Generate file names var targetsPath = GetMSBuildFilePath(project, request, "targets"); var propsPath = GetMSBuildFilePath(project, request, "props"); // Targets files contain a macro for the repository root. If only the user package folder was used // allow a replacement. If fallback folders were used the macro cannot be applied. // Do not use macros for fallback folders. Use only the first repository which is the user folder. var repositoryRoot = repositories.First().RepositoryRoot; // Invalid msbuild projects should write out an msbuild error target if (!targetGraphs.Any()) { return(GenerateMultiTargetFailureFiles( targetsPath, propsPath, request.ProjectStyle)); } // Add additional conditionals for multi targeting var multiTargetingFromMetadata = (request.Project.RestoreMetadata?.CrossTargeting == true); var isMultiTargeting = multiTargetingFromMetadata || request.Project.TargetFrameworks.Count > 1; // ItemGroups for each file. var props = new List <MSBuildRestoreItemGroup>(); var targets = new List <MSBuildRestoreItemGroup>(); // MultiTargeting imports are shared between TFMs, to avoid // duplicate import warnings only add each once. var multiTargetingImportsAdded = new HashSet <string>(StringComparer.OrdinalIgnoreCase); // Skip runtime graphs, msbuild targets may not come from RID specific packages. var ridlessTargets = assetsFile.Targets .Where(e => string.IsNullOrEmpty(e.RuntimeIdentifier)); var packagesWithTools = new HashSet <string>(assetsFile.Libraries.Where(i => i.HasTools).Select(i => i.Name), StringComparer.OrdinalIgnoreCase); foreach (var ridlessTarget in ridlessTargets) { // There could be multiple string matches from the MSBuild project. var frameworkConditions = GetMatchingFrameworkStrings(project, ridlessTarget.TargetFramework) .Select(match => string.Format(CultureInfo.InvariantCulture, TargetFrameworkCondition, match)) .ToArray(); // Find matching target in the original target graphs. var targetGraph = targetGraphs.FirstOrDefault(e => string.IsNullOrEmpty(e.RuntimeIdentifier) && ridlessTarget.TargetFramework == e.Framework); // Sort by dependency order, child package assets should appear higher in the // msbuild targets and props files so that parents can depend on them. var sortedGraph = TopologicalSortUtility.SortPackagesByDependencyOrder(ConvertToPackageDependencyInfo(targetGraph.Flattened)); // Filter out to packages only, exclude projects. var packageType = new HashSet <string>( targetGraph.Flattened.Where(e => e.Key.Type == LibraryType.Package) .Select(e => e.Key.Name), StringComparer.OrdinalIgnoreCase); // Package -> PackageInfo // PackageInfo is kept lazy to avoid hitting the disk for packages // with no relevant assets. var sortedPackages = sortedGraph.Where(e => packageType.Contains(e.Id)) .Select(sortedPkg => new KeyValuePair <LockFileTargetLibrary, Lazy <LocalPackageSourceInfo> >( key: ridlessTarget.Libraries.FirstOrDefault(assetsPkg => sortedPkg.Version == assetsPkg.Version && sortedPkg.Id.Equals(assetsPkg.Name, StringComparison.OrdinalIgnoreCase)), value: new Lazy <LocalPackageSourceInfo>(() => NuGetv3LocalRepositoryUtility.GetPackage( repositories, sortedPkg.Id, sortedPkg.Version)))) .Where(e => e.Key != null) .ToArray(); // build/ {packageId}.targets var buildTargetsGroup = new MSBuildRestoreItemGroup(); buildTargetsGroup.RootName = MSBuildRestoreItemGroup.ImportGroup; buildTargetsGroup.Position = 2; buildTargetsGroup.Items.AddRange(sortedPackages.SelectMany(pkg => pkg.Key.Build.WithExtension(TargetsExtension) .Where(e => pkg.Value.Exists()) .Select(e => pkg.Value.GetAbsolutePath(e))) .Select(path => GetPathWithMacros(path, repositoryRoot)) .Select(GenerateImport)); targets.AddRange(GenerateGroupsWithConditions(buildTargetsGroup, isMultiTargeting, frameworkConditions)); // props/ {packageId}.props var buildPropsGroup = new MSBuildRestoreItemGroup(); buildPropsGroup.RootName = MSBuildRestoreItemGroup.ImportGroup; buildPropsGroup.Position = 2; buildPropsGroup.Items.AddRange(sortedPackages.SelectMany(pkg => pkg.Key.Build.WithExtension(PropsExtension) .Where(e => pkg.Value.Exists()) .Select(e => pkg.Value.GetAbsolutePath(e))) .Select(path => GetPathWithMacros(path, repositoryRoot)) .Select(GenerateImport)); props.AddRange(GenerateGroupsWithConditions(buildPropsGroup, isMultiTargeting, frameworkConditions)); // Create an empty PropertyGroup for package properties var packagePathsPropertyGroup = MSBuildRestoreItemGroup.Create("PropertyGroup", Enumerable.Empty <XElement>(), 1000, isMultiTargeting ? frameworkConditions : Enumerable.Empty <string>()); var projectGraph = targetGraph.Graphs.FirstOrDefault(); // Packages with GeneratePathProperty=true var packageIdsToCreatePropertiesFor = new HashSet <string>(projectGraph.Item.Data.Dependencies.Where(i => i.GeneratePathProperty).Select(i => i.Name), StringComparer.OrdinalIgnoreCase); var localPackages = sortedPackages.Select(e => e.Value); // Find the packages with matching IDs in the list of sorted packages, filtering out ones that there was no match for or that don't exist var packagePathProperties = localPackages .Where(pkg => pkg?.Value?.Package != null && (packagesWithTools.Contains(pkg.Value.Package.Id) || packageIdsToCreatePropertiesFor.Contains(pkg.Value.Package.Id)) && pkg.Exists()) .Select(pkg => pkg.Value.Package) // Get the property .Select(GeneratePackagePathProperty); packagePathsPropertyGroup.Items.AddRange(packagePathProperties); // Don't bother adding the PropertyGroup if there were no properties added if (packagePathsPropertyGroup.Items.Any()) { props.Add(packagePathsPropertyGroup); } if (isMultiTargeting) { // buildMultiTargeting/ {packageId}.targets var buildCrossTargetsGroup = new MSBuildRestoreItemGroup(); buildCrossTargetsGroup.RootName = MSBuildRestoreItemGroup.ImportGroup; buildCrossTargetsGroup.Position = 0; buildCrossTargetsGroup.Items.AddRange(sortedPackages.SelectMany(pkg => pkg.Key.BuildMultiTargeting.WithExtension(TargetsExtension) .Where(e => pkg.Value.Exists()) .Select(e => pkg.Value.GetAbsolutePath(e))) .Where(path => multiTargetingImportsAdded.Add(path)) .Select(path => GetPathWithMacros(path, repositoryRoot)) .Select(GenerateImport)); targets.AddRange(GenerateGroupsWithConditions(buildCrossTargetsGroup, isMultiTargeting, CrossTargetingCondition)); // buildMultiTargeting/ {packageId}.props var buildCrossPropsGroup = new MSBuildRestoreItemGroup(); buildCrossPropsGroup.RootName = MSBuildRestoreItemGroup.ImportGroup; buildCrossPropsGroup.Position = 0; buildCrossPropsGroup.Items.AddRange(sortedPackages.SelectMany(pkg => pkg.Key.BuildMultiTargeting.WithExtension(PropsExtension) .Where(e => pkg.Value.Exists()) .Select(e => pkg.Value.GetAbsolutePath(e))) .Where(path => multiTargetingImportsAdded.Add(path)) .Select(path => GetPathWithMacros(path, repositoryRoot)) .Select(GenerateImport)); props.AddRange(GenerateGroupsWithConditions(buildCrossPropsGroup, isMultiTargeting, CrossTargetingCondition)); } // Write out contentFiles only for XPlat PackageReference projects. if (request.ProjectStyle != ProjectStyle.ProjectJson && request.Project.RestoreMetadata?.SkipContentFileWrite != true) { // Create a group for every package, with the nearest from each of allLanguages props.AddRange(sortedPackages.Select(pkg => pkg.Key.ContentFiles .Where(e => pkg.Value.Exists()) .OrderBy(e => e.Path, StringComparer.Ordinal) .Select(e => Tuple.Create( item1: pkg.Key, item2: e, item3: GetPathWithMacros(pkg.Value.GetAbsolutePath(e), repositoryRoot)))) .SelectMany(e => GetLanguageGroups(e)) .SelectMany(group => GenerateGroupsWithConditions(group, isMultiTargeting, frameworkConditions))); } } // Add exclude all condition to all groups foreach (var group in props.Concat(targets)) { group.Conditions.Add(ExcludeAllCondition); } // Create XML, these may be null if the file should be deleted/not written out. var propsXML = GenerateMSBuildFile(props, request.ProjectStyle); var targetsXML = GenerateMSBuildFile(targets, request.ProjectStyle); // Return all files to write out or delete. var files = new List <MSBuildOutputFile> { new MSBuildOutputFile(propsPath, propsXML), new MSBuildOutputFile(targetsPath, targetsXML) }; var packageFolders = repositories.Select(e => e.RepositoryRoot); AddNuGetPropertiesToFirstImport(files, packageFolders, repositoryRoot, request.ProjectStyle, assetsFilePath, restoreSuccess); return(files); }
/// <summary> /// This method verifies that the assets files, props/targets files and all the packages written out in the assets file are present on disk /// When the project has opted into packages lock file, it also verified that the lock file is present on disk. /// This does not account if the files were manually modified since the last restore /// </summary> internal static bool VerifyRestoreOutput(RestoreRequest request, CacheFile cacheFile) { if (!string.IsNullOrWhiteSpace(request.LockFilePath) && !File.Exists(request.LockFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_AssetsFileNotOnDisk, request.Project.Name)); return(false); } if (request.ProjectStyle == ProjectStyle.PackageReference || request.ProjectStyle == ProjectStyle.Standalone) { var targetsFilePath = BuildAssetsUtils.GetMSBuildFilePath(request.Project, BuildAssetsUtils.TargetsExtension); if (!File.Exists(targetsFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_TargetsFileNotOnDisk, request.Project.Name, targetsFilePath)); return(false); } var propsFilePath = BuildAssetsUtils.GetMSBuildFilePath(request.Project, BuildAssetsUtils.PropsExtension); if (!File.Exists(propsFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_PropsFileNotOnDisk, request.Project.Name, propsFilePath)); return(false); } if (PackagesLockFileUtilities.IsNuGetLockFileEnabled(request.Project)) { var packageLockFilePath = PackagesLockFileUtilities.GetNuGetLockFilePath(request.Project); if (!File.Exists(packageLockFilePath)) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_LockFileNotOnDisk, request.Project.Name, packageLockFilePath)); return(false); } } } if (cacheFile.HasAnyMissingPackageFiles) { request.Log.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_MissingPackagesOnDisk, request.Project.Name)); return(false); } if (request.UpdatePackageLastAccessTime) { foreach (var package in cacheFile.ExpectedPackageFilePaths) { if (!package.StartsWith(request.PackagesDirectory, StringComparison.OrdinalIgnoreCase)) { continue; } var packageDirectory = Path.GetDirectoryName(package); var metadataFile = Path.Combine(packageDirectory, PackagingCoreConstants.NupkgMetadataFileExtension); try { request.DependencyProviders.PackageFileCache.UpdateLastAccessTime(metadataFile); } catch (Exception ex) { request.Log.Log(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1802, string.Format(CultureInfo.InvariantCulture, Strings.Error_CouldNotUpdateMetadataLastAccessTime, metadataFile, ex.Message))); } } } return(true); }
public async Task <RestoreResult> ExecuteAsync(RestoreRequest request) { if (request.Project.TargetFrameworks.Count == 0) { _log.LogError("The project does not specify any target frameworks!"); return(new RestoreResult(success: false, restoreGraphs: Enumerable.Empty <RestoreTargetGraph>())); } var projectLockFilePath = string.IsNullOrEmpty(request.LockFilePath) ? Path.Combine(request.Project.BaseDirectory, LockFileFormat.LockFileName) : request.LockFilePath; _log.LogInformation($"Restoring packages for '{request.Project.FilePath}'"); _log.LogWarning("TODO: Read and use lock file"); // Load repositories var projectResolver = new PackageSpecResolver(request.Project.BaseDirectory); var nugetRepository = Repository.Factory.GetCoreV3(request.PackagesDirectory); var context = new RemoteWalkContext(); context.ProjectLibraryProviders.Add( new LocalDependencyProvider( new PackageSpecReferenceDependencyProvider(projectResolver))); if (request.ExternalProjects != null) { context.ProjectLibraryProviders.Add( new LocalDependencyProvider( new ExternalProjectReferenceDependencyProvider(request.ExternalProjects))); } context.LocalLibraryProviders.Add( new SourceRepositoryDependencyProvider(nugetRepository, _log)); foreach (var provider in request.Sources.Select(s => CreateProviderFromSource(s, request.NoCache))) { context.RemoteLibraryProviders.Add(provider); } var remoteWalker = new RemoteDependencyWalker(context); var projectRange = new LibraryRange() { Name = request.Project.Name, VersionRange = new VersionRange(request.Project.Version), TypeConstraint = LibraryTypes.Project }; // Resolve dependency graphs var frameworks = request.Project.TargetFrameworks.Select(f => f.FrameworkName).ToList(); var graphs = new List <RestoreTargetGraph>(); foreach (var framework in frameworks) { graphs.Add(await WalkDependencies(projectRange, framework, remoteWalker, context)); } if (graphs.Any(g => g.InConflict)) { _log.LogError("Failed to resolve conflicts"); return(new RestoreResult(success: false, restoreGraphs: graphs)); } // Install the runtime-agnostic packages var allInstalledPackages = new HashSet <LibraryIdentity>(); var localRepository = new NuGetv3LocalRepository(request.PackagesDirectory, checkPackageIdCase: false); await InstallPackages(graphs, request.PackagesDirectory, allInstalledPackages, request.MaxDegreeOfConcurrency); // Resolve runtime dependencies var runtimeGraphs = new List <RestoreTargetGraph>(); if (request.Project.RuntimeGraph.Runtimes.Count > 0) { foreach (var graph in graphs) { var runtimeSpecificGraphs = await WalkRuntimeDependencies(projectRange, graph, request.Project.RuntimeGraph, remoteWalker, context, localRepository); runtimeGraphs.AddRange(runtimeSpecificGraphs); } graphs.AddRange(runtimeGraphs); if (runtimeGraphs.Any(g => g.InConflict)) { _log.LogError("Failed to resolve conflicts"); return(new RestoreResult(success: false, restoreGraphs: graphs)); } // Install runtime-specific packages await InstallPackages(runtimeGraphs, request.PackagesDirectory, allInstalledPackages, request.MaxDegreeOfConcurrency); } else { _log.LogVerbose("Skipping runtime dependency walk, no runtimes defined in project.json"); } // Build the lock file var repository = new NuGetv3LocalRepository(request.PackagesDirectory, checkPackageIdCase: false); var lockFile = CreateLockFile(request.Project, graphs, repository); var lockFileFormat = new LockFileFormat(); lockFileFormat.Write(projectLockFilePath, lockFile); return(new RestoreResult(true, graphs, lockFile)); }
/// <summary> /// If the dependencyGraphSpec is not set, we cannot no-op on this project restore. /// No-Op restore is not supported for CLI Tools at this point /// </summary> internal static bool IsNoOpSupported(RestoreRequest request) { return(request.DependencyGraphSpec != null && request.ProjectStyle != ProjectStyle.DotnetCliTool); }
public async Task<RestoreResult> ExecuteAsync(RestoreRequest request) { if (request.Project.TargetFrameworks.Count == 0) { _log.LogError("The project does not specify any target frameworks!"); return new RestoreResult(success: false, restoreGraphs: Enumerable.Empty<RestoreTargetGraph>()); } var projectLockFilePath = string.IsNullOrEmpty(request.LockFilePath) ? Path.Combine(request.Project.BaseDirectory, LockFileFormat.LockFileName) : request.LockFilePath; _log.LogInformation($"Restoring packages for '{request.Project.FilePath}'"); _log.LogWarning("TODO: Read and use lock file"); // Load repositories var projectResolver = new PackageSpecResolver(request.Project); var nugetRepository = Repository.Factory.GetCoreV3(request.PackagesDirectory); var context = new RemoteWalkContext(); ExternalProjectReference exterenalProjectReference = null; if (request.ExternalProjects.Any()) { exterenalProjectReference = new ExternalProjectReference( request.Project.Name, request.Project.FilePath, request.ExternalProjects.Select(p => p.Name)); } context.ProjectLibraryProviders.Add( new LocalDependencyProvider( new PackageSpecReferenceDependencyProvider(projectResolver, exterenalProjectReference))); if (request.ExternalProjects != null) { context.ProjectLibraryProviders.Add( new LocalDependencyProvider( new ExternalProjectReferenceDependencyProvider(request.ExternalProjects))); } context.LocalLibraryProviders.Add( new SourceRepositoryDependencyProvider(nugetRepository, _log)); foreach (var provider in request.Sources.Select(s => CreateProviderFromSource(s, request.NoCache))) { context.RemoteLibraryProviders.Add(provider); } var remoteWalker = new RemoteDependencyWalker(context); var projectRange = new LibraryRange() { Name = request.Project.Name, VersionRange = new VersionRange(request.Project.Version), TypeConstraint = LibraryTypes.Project }; // Resolve dependency graphs var frameworks = request.Project.TargetFrameworks.Select(f => f.FrameworkName).ToList(); var graphs = new List<RestoreTargetGraph>(); var frameworkTasks = new List<Task<RestoreTargetGraph>>(); foreach (var framework in frameworks) { frameworkTasks.Add(WalkDependencies(projectRange, framework, remoteWalker, context)); } graphs.AddRange(await Task.WhenAll(frameworkTasks)); if (graphs.Any(g => g.InConflict)) { _log.LogError("Failed to resolve conflicts"); return new RestoreResult(success: false, restoreGraphs: graphs); } // Install the runtime-agnostic packages var allInstalledPackages = new HashSet<LibraryIdentity>(); var localRepository = new NuGetv3LocalRepository(request.PackagesDirectory, checkPackageIdCase: false); await InstallPackages(graphs, request.PackagesDirectory, allInstalledPackages, request.MaxDegreeOfConcurrency); // Resolve runtime dependencies var runtimeGraphs = new List<RestoreTargetGraph>(); if (request.Project.RuntimeGraph.Runtimes.Count > 0) { var runtimeTasks = new List<Task<RestoreTargetGraph[]>>(); foreach (var graph in graphs) { runtimeTasks.Add(WalkRuntimeDependencies(projectRange, graph, request.Project.RuntimeGraph, remoteWalker, context, localRepository)); } foreach (var runtimeSpecificGraphs in await Task.WhenAll(runtimeTasks)) { runtimeGraphs.AddRange(runtimeSpecificGraphs); } graphs.AddRange(runtimeGraphs); if (runtimeGraphs.Any(g => g.InConflict)) { _log.LogError("Failed to resolve conflicts"); return new RestoreResult(success: false, restoreGraphs: graphs); } // Install runtime-specific packages await InstallPackages(runtimeGraphs, request.PackagesDirectory, allInstalledPackages, request.MaxDegreeOfConcurrency); } else { _log.LogVerbose("Skipping runtime dependency walk, no runtimes defined in project.json"); } // Build the lock file var repository = new NuGetv3LocalRepository(request.PackagesDirectory, checkPackageIdCase: false); var lockFile = CreateLockFile(request.Project, graphs, repository); var lockFileFormat = new LockFileFormat(); lockFileFormat.Write(projectLockFilePath, lockFile); // Generate Targets/Props files WriteTargetsAndProps(request.Project, graphs, repository); return new RestoreResult(true, graphs, lockFile); }
/// <summary> /// If the dependencyGraphSpec is not set, we cannot no-op on this project restore. /// </summary> internal static bool IsNoOpSupported(RestoreRequest request) { return(request.DependencyGraphSpec != null); }
/// <summary> /// Evaluate the location of the cache file path, based on ProjectStyle. /// </summary> internal static string GetCacheFilePath(RestoreRequest request) { return(GetCacheFilePath(request, lockFile: null)); }
public int Main(string[] args) { #if DEBUG if (args.Contains("--debug")) { args = args.Skip(1).ToArray(); System.Diagnostics.Debugger.Launch(); } #endif // Set up logging _log = new CommandOutputLogger(); var app = new CommandLineApplication(); app.Name = "nuget3"; app.FullName = ".NET Package Manager"; app.HelpOption("-h|--help"); app.VersionOption("--version", GetType().GetTypeInfo().Assembly.GetName().Version.ToString()); app.Command("restore", restore => { restore.Description = "Restores packages for a project and writes a lock file"; var sources = restore.Option("-s|--source <source>", "Specifies a NuGet package source to use during the restore", CommandOptionType.MultipleValue); var packagesDirectory = restore.Option("--packages <packagesDirectory>", "Directory to install packages in", CommandOptionType.SingleValue); var parallel = restore.Option("-p|--parallel <noneOrNumberOfParallelTasks>", $"The number of concurrent tasks to use when restoring. Defaults to {RestoreRequest.DefaultDegreeOfConcurrency}; pass 'none' to run without concurrency.", CommandOptionType.SingleValue); var projectFile = restore.Argument("[project file]", "The path to the project to restore for, either a project.json or the directory containing it. Defaults to the current directory"); restore.OnExecute(async () => { // Figure out the project directory IEnumerable<string> externalProjects = null; PackageSpec project; var projectPath = Path.GetFullPath(projectFile.Value ?? "."); if (string.Equals(PackageSpec.PackageSpecFileName, Path.GetFileName(projectPath), StringComparison.OrdinalIgnoreCase)) { _log.LogVerbose($"Reading project file {projectFile.Value}"); projectPath = Path.GetDirectoryName(projectPath); project = JsonPackageSpecReader.GetPackageSpec(File.ReadAllText(projectFile.Value), Path.GetFileName(projectPath), projectFile.Value); } else if (MsBuildUtility.IsMsBuildBasedProject(projectPath)) { #if DNXCORE50 throw new NotSupportedException(); #else externalProjects = MsBuildUtility.GetProjectReferences(projectPath); projectPath = Path.GetDirectoryName(Path.GetFullPath(projectPath)); var packageSpecFile = Path.Combine(projectPath, PackageSpec.PackageSpecFileName); project = JsonPackageSpecReader.GetPackageSpec(File.ReadAllText(packageSpecFile), Path.GetFileName(projectPath), projectFile.Value); _log.LogVerbose($"Reading project file {projectFile.Value}"); #endif } else { var file = Path.Combine(projectPath, PackageSpec.PackageSpecFileName); _log.LogVerbose($"Reading project file {file}"); project = JsonPackageSpecReader.GetPackageSpec(File.ReadAllText(file), Path.GetFileName(projectPath), file); } _log.LogVerbose($"Loaded project {project.Name} from {project.FilePath}"); // Resolve the root directory var rootDirectory = PackageSpecResolver.ResolveRootDirectory(projectPath); _log.LogVerbose($"Found project root directory: {rootDirectory}"); // Resolve the packages directory var packagesDir = packagesDirectory.HasValue() ? packagesDirectory.Value() : Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), ".nuget", "packages"); _log.LogVerbose($"Using packages directory: {packagesDir}"); var packageSources = sources.Values.Select(s => new PackageSource(s)); if (!packageSources.Any()) { var settings = Settings.LoadDefaultSettings(projectPath, configFileName: null, machineWideSettings: null); var packageSourceProvider = new PackageSourceProvider(settings); packageSources = packageSourceProvider.LoadPackageSources(); } var request = new RestoreRequest( project, packageSources, packagesDir); if (externalProjects != null) { foreach (var externalReference in externalProjects) { request.ExternalProjects.Add( new ExternalProjectReference( externalReference, Path.Combine(Path.GetDirectoryName(externalReference), PackageSpec.PackageSpecFileName), projectReferences: Enumerable.Empty<string>())); } } // Run the restore if (parallel.HasValue()) { int parallelDegree; if (string.Equals(parallel.Value(), "none", StringComparison.OrdinalIgnoreCase)) { request.MaxDegreeOfConcurrency = 1; } else if (int.TryParse(parallel.Value(), out parallelDegree)) { request.MaxDegreeOfConcurrency = parallelDegree; } } if (request.MaxDegreeOfConcurrency <= 1) { _log.LogInformation("Running non-parallel restore"); } else { _log.LogInformation($"Running restore with {request.MaxDegreeOfConcurrency} concurrent jobs"); } var command = new RestoreCommand(_log); var sw = Stopwatch.StartNew(); var result = await command.ExecuteAsync(request); sw.Stop(); _log.LogInformation($"Restore completed in {sw.ElapsedMilliseconds:0.00}ms!"); return 0; }); }); app.Command("diag", diag => { diag.Description = "Diagnostic commands for debugging package dependency graphs"; diag.Command("lockfile", lockfile => { lockfile.Description = "Dumps data from the project lock file"; var project = lockfile.Option("--project <project>", "Path containing the project lockfile, or the patht to the lockfile itself", CommandOptionType.SingleValue); var target = lockfile.Option("--target <target>", "View information about a specific project target", CommandOptionType.SingleValue); var library = lockfile.Argument("<library>", "Optionally, get detailed information about a specific library"); lockfile.OnExecute(() => { var diagnostics = new DiagnosticCommands(_log); var projectFile = project.HasValue() ? project.Value() : Path.GetFullPath("."); return diagnostics.Lockfile(projectFile, target.Value(), library.Value); }); }); diag.OnExecute(() => { diag.ShowHelp(); return 0; }); }); app.OnExecute(() => { app.ShowHelp(); return 0; }); return app.Execute(args); }