/// <summary> /// Get NuGet AutoComplete APIs for the specified package sources. /// </summary> /// <param name="packageSources"> /// The package sources. /// </param> /// <param name="cancellationToken"> /// An optional <see cref="CancellationToken"/> that can be used to cancel the operation. /// </param> /// <returns> /// A task that resolves to a list of <see cref="AutoCompleteResource"/>s. /// </returns> public static async Task <List <AutoCompleteResource> > GetAutoCompleteResources(IEnumerable <PackageSource> packageSources, CancellationToken cancellationToken = default(CancellationToken)) { if (packageSources == null) { throw new ArgumentNullException(nameof(packageSources)); } List <AutoCompleteResource> autoCompleteResources = new List <AutoCompleteResource>(); var providers = new List <Lazy <INuGetResourceProvider> >(); // Add v3 API support providers.AddRange(Repository.Provider.GetCoreV3()); // Add v2 API support providers.AddRange(Repository.Provider.GetCoreV2()); foreach (PackageSource packageSource in packageSources) { SourceRepository sourceRepository = new SourceRepository(packageSource, providers); AutoCompleteResource autoCompleteResource = await sourceRepository.GetResourceAsync <AutoCompleteResource>(cancellationToken); if (autoCompleteResource != null) { autoCompleteResources.Add(autoCompleteResource); } } return(autoCompleteResources); }
/// <summary> /// Get NuGet AutoComplete APIs for the specified package sources. /// </summary> /// <param name="packageSources"> /// The package sources. /// </param> /// <param name="cancellationToken"> /// An optional <see cref="CancellationToken"/> that can be used to cancel the operation. /// </param> /// <returns> /// A task that resolves to a list of <see cref="AutoCompleteResource"/>s. /// </returns> public static async Task <List <AutoCompleteResource> > GetAutoCompleteResources(IEnumerable <PackageSource> packageSources, CancellationToken cancellationToken = default(CancellationToken)) { if (packageSources == null) { throw new ArgumentNullException(nameof(packageSources)); } List <AutoCompleteResource> autoCompleteResources = new List <AutoCompleteResource>(); List <SourceRepository> sourceRepositories = packageSources.CreateResourceRepositories(); foreach (SourceRepository sourceRepository in sourceRepositories) { AutoCompleteResource autoCompleteResource = await sourceRepository.GetResourceAsync <AutoCompleteResource>(cancellationToken); if (autoCompleteResource != null) { autoCompleteResources.Add(autoCompleteResource); } } return(autoCompleteResources); }
/// <summary> /// Determine the NuGet package sources configured for the current project and create clients for them. /// </summary> /// <param name="cancellationToken"> /// An optional <see cref="CancellationToken"/> that can be used to cancel the operation. /// </param> /// <returns> /// <c>true</c>, if the package sources were loaded; otherwise, <c>false</c>. /// </returns> public virtual async Task <bool> ConfigurePackageSources(CancellationToken cancellationToken = default(CancellationToken)) { try { _configuredPackageSources.Clear(); _autoCompleteResources.Clear(); bool includeLocalSources = Workspace.Configuration.NuGet.IncludeLocalSources; HashSet <string> ignoredPackageSources = Workspace.Configuration.NuGet.IgnorePackageSources; foreach (PackageSource packageSource in NuGetHelper.GetWorkspacePackageSources(ProjectFile.Directory.FullName)) { // Exclude package sources explicitly ignored by name. string packageSourceName = packageSource.Name ?? "<unknown>"; if (ignoredPackageSources.Contains(packageSourceName)) { Log.Verbose("Ignoring package source named {PackageSourceName} (the language server has been explicitly configured to ignore it).", packageSourceName); continue; } // Exclude package sources explicitly ignored by URI. Uri packageSourceUri = packageSource.TrySourceAsUri ?? new Uri("unknown:/", UriKind.Absolute); if (ignoredPackageSources.Contains(packageSourceUri.AbsoluteUri)) { Log.Verbose("Ignoring package source with URI {PackageSourceURI} (the language server has been explicitly configured to ignore it).", packageSourceUri.AbsoluteUri); continue; } // Exclude unsupported package-source types. if (!packageSource.IsHttp) { if (packageSourceUri.Scheme == Uri.UriSchemeFile) { if (!includeLocalSources) { Log.Verbose("Ignoring local package source {PackageSourceName} ({PackageSourcePath}) (the language server has not been configured to use local package sources).", packageSourceName, packageSourceUri.AbsolutePath ); continue; } } else { Log.Verbose("Ignoring local package source {PackageSourceName} ({PackageSourceUri}) (the language server only supports local and HTTP-based package sources).", packageSourceName, packageSourceUri.AbsolutePath ); continue; } } _configuredPackageSources.Add(packageSource); } Log.Information("{PackageSourceCount} package sources configured for project {ProjectFile}.", _configuredPackageSources.Count, VSCodeDocumentUri.GetFileSystemPath(DocumentUri) ); foreach (PackageSource packageSource in _configuredPackageSources) { if (packageSource.IsMachineWide) { Log.Information(" Globally-configured package source {PackageSourceName} (v{PackageSourceProtocolVersion}) => {PackageSourceUri}", packageSource.Name, packageSource.ProtocolVersion, packageSource.SourceUri ); } else { Log.Information(" Locally-configured package source {PackageSourceName} (v{PackageSourceProtocolVersion}) => {PackageSourceUri}", packageSource.Name, packageSource.ProtocolVersion, packageSource.SourceUri ); } } List <SourceRepository> sourceRepositories = _configuredPackageSources.CreateResourceRepositories(); foreach (SourceRepository sourceRepository in sourceRepositories) { ServiceIndexResourceV3 serviceIndex = await sourceRepository.GetResourceAsync <ServiceIndexResourceV3>(cancellationToken); if (serviceIndex == null) { Log.Warning(" Ignoring configured package source {PackageSourceName} ({PackageSourceUri}) because the v3 service index cannot be found for this package source.", sourceRepository.PackageSource.Name ?? "<unknown>", sourceRepository.PackageSource.TrySourceAsUri?.AbsoluteUri ?? "unknown:/" ); continue; } IReadOnlyList <ServiceIndexEntry> autoCompleteServices = serviceIndex.GetServiceEntries(ServiceTypes.SearchAutocompleteService); if (autoCompleteServices.Count == 0) { Log.Warning(" Ignoring configured package source {PackageSourceName} ({PackageSourceUri}) because it does not appear to support a compatible version of the NuGet auto-complete API.", sourceRepository.PackageSource.Name ?? "<unknown>", sourceRepository.PackageSource.TrySourceAsUri?.AbsoluteUri ?? "unknown:/" ); continue; } AutoCompleteResource autoCompleteResource = await sourceRepository.GetResourceAsync <AutoCompleteResource>(cancellationToken); if (autoCompleteResource == null) { // Should not happen. Log.Error("Failed to retrieve {ServiceName} service instance for configured package source {PackageSourceName} ({PackageSourceUri}).", "AutoComplete", sourceRepository.PackageSource.Name ?? "<unknown>", sourceRepository.PackageSource.TrySourceAsUri?.AbsoluteUri ?? "unknown:/" ); continue; } _autoCompleteResources.Add(autoCompleteResource); } return(true); } catch (Exception packageSourceLoadError) { Log.Error(packageSourceLoadError, "Error configuring NuGet package sources for MSBuild project '{ProjectFileName}'.", ProjectFile.FullName); return(false); } }