public async Task <bool> NominateProjectAsync(string projectUniqueName, CancellationToken token)
        {
            Assumes.NotNullOrEmpty(projectUniqueName);

            if (!_projectSystemCache.TryGetProjectNames(projectUniqueName, out ProjectNames projectNames))
            {
                IVsSolution2 vsSolution2 = await _vsSolution2.GetValueAsync(token);

                projectNames = await ProjectNames.FromIVsSolution2(projectUniqueName, vsSolution2, token);
            }
            var dgSpec      = new DependencyGraphSpec();
            var packageSpec = new PackageSpec()
            {
                Name = projectUniqueName
            };

            dgSpec.AddProject(packageSpec);
            dgSpec.AddRestore(packageSpec.Name);
            _projectSystemCache.AddProjectRestoreInfo(projectNames, dgSpec, new List <IAssetsLogMessage>());

            // returned task completes when scheduled restore operation completes.
            var restoreTask = _restoreWorker.ScheduleRestoreAsync(
                SolutionRestoreRequest.OnUpdate(),
                token);

            return(await restoreTask);
        }
 private async ValueTask<IPackageMetadataProvider> GetPackageMetadataProviderAsync(
     IReadOnlyCollection<PackageSourceContextInfo> packageSources,
     CancellationToken cancellationToken)
 {
     IReadOnlyCollection<SourceRepository> sourceRepositories = await _sharedServiceState.GetRepositoriesAsync(packageSources, cancellationToken);
     SourceRepository localRepo = await _packagesFolderLocalRepositoryLazy.GetValueAsync(cancellationToken);
     IEnumerable<SourceRepository> globalRepo = await _globalPackageFolderRepositoriesLazy.GetValueAsync(cancellationToken);
     return new MultiSourcePackageMetadataProvider(sourceRepositories, localRepo, globalRepo, new VisualStudioActivityLogger());
 }
        private async Task <ProjectNames> GetProjectNamesAsync(string projectUniqueName, CancellationToken cancellationToken)
        {
            await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            cancellationToken.ThrowIfCancellationRequested();

            IVsSolution2 sln = await _vsSolution2.GetValueAsync(cancellationToken);

            ErrorHandler.ThrowOnFailure(sln.GetProjectOfUniqueName(projectUniqueName, out IVsHierarchy project));
            ErrorHandler.ThrowOnFailure(sln.GetGuidOfProject(project, out Guid guid));
            ErrorHandler.ThrowOnFailure(sln.GetUniqueNameOfProject(project, out string uniqueName));

            string shortName = Path.GetFileNameWithoutExtension(projectUniqueName);

            // Note this does not match what is generated by VsProjectAdapterProvider from the DTE project, but we haven't got any bug reports yet.
            // https://github.com/NuGet/Home/issues/9690
            string customUniqueName = uniqueName;

            var projectNames = new ProjectNames(
                fullName: projectUniqueName,
                uniqueName: uniqueName,
                shortName: shortName,
                customUniqueName: customUniqueName,
                projectId: guid.ToString());

            return(projectNames);
        }
Пример #4
0
        public async ValueTask <IReadOnlyCollection <PackageSearchMetadataContextInfo> > GetAllPackagesAsync(
            IReadOnlyCollection <IProjectContextInfo> projectContextInfos,
            IReadOnlyCollection <PackageSourceContextInfo> packageSources,
            IReadOnlyCollection <string> targetFrameworks,
            SearchFilter searchFilter,
            ItemFilter itemFilter,
            bool isSolution,
            CancellationToken cancellationToken)
        {
            Assumes.NotNullOrEmpty(projectContextInfos);
            Assumes.NotNullOrEmpty(packageSources);
            Assumes.NotNull(searchFilter);

            bool recommendPackages = false;
            IReadOnlyCollection <SourceRepository> sourceRepositories = await _sharedServiceState.GetRepositoriesAsync(packageSources, cancellationToken);

            (IPackageFeed? mainFeed, IPackageFeed? recommenderFeed)packageFeeds = await CreatePackageFeedAsync(
                projectContextInfos,
                targetFrameworks,
                itemFilter,
                isSolution,
                recommendPackages,
                sourceRepositories,
                cancellationToken);

            Assumes.NotNull(packageFeeds.mainFeed);

            SourceRepository packagesFolderSourceRepository = await _packagesFolderLocalRepositoryLazy.GetValueAsync(cancellationToken);

            IEnumerable <SourceRepository> globalPackageFolderRepositories = await GetAllPackageFoldersAsync(projectContextInfos, cancellationToken);

            var metadataProvider = new MultiSourcePackageMetadataProvider(
                sourceRepositories,
                packagesFolderSourceRepository,
                globalPackageFolderRepositories,
                new VisualStudioActivityLogger());

            var searchObject = new SearchObject(packageFeeds.mainFeed, packageFeeds.recommenderFeed, metadataProvider, packageSources, PackageSearchMetadataMemoryCache);

            return(await searchObject.GetAllPackagesAsync(searchFilter, cancellationToken));
        }
Пример #5
0
        public async Task <bool> IsFeatureEnabledAsync(NuGetFeatureFlagConstants featureFlag)
        {
            GetEnvironmentVariablesForFeature(featureFlag, out bool isFeatureForcedEnabled, out bool isFeatureForcedDisabled);
            // Perform the check from the feature flag service only once.
            // There are events sent for targetted notification changes, but we don't listen to those at this point.
            if (!_featureFlagCache.TryGetValue(featureFlag.Name, out bool featureEnabled))
            {
                var featureFlagService = await _ivsFeatureFlags.GetValueAsync();

                await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                featureEnabled = featureFlagService.IsFeatureEnabled(featureFlag.Name, defaultValue: featureFlag.DefaultState);
                _featureFlagCache.Add(featureFlag.Name, featureEnabled);
            }
            return(!isFeatureForcedDisabled && (isFeatureForcedEnabled || featureEnabled));
        }
Пример #6
0
        public bool TryCreateContext(string projectUniqueName, out IVsPathContext outputPathContext)
        {
            if (projectUniqueName == null)
            {
                throw new ArgumentNullException(nameof(projectUniqueName));
            }

            // invoke async operation from within synchronous method
            outputPathContext = NuGetUIThreadHelper.JoinableTaskFactory.Run(
                async() =>
            {
                var dte    = await _dte.GetValueAsync();
                var lookup = await GetPathToDTEProjectLookupAsync(dte);

                if (!lookup.TryGetValue(projectUniqueName, out var dteProject))
                {
                    return(null);
                }

                return(await CreatePathContextAsync(dteProject, projectUniqueName, CancellationToken.None));
            });

            return(outputPathContext != null);
        }
Пример #7
0
        /// <summary>
        /// This is where the nominate calls for the IVs1 and IVS3 APIs combine. The reason for this method is to avoid duplication and potential issues
        /// The issue with this method is that it has some weird custom logging to ensure backward compatibility. It's on the implementer to ensure these calls are correct.
        /// <param name="projectUniqueName">projectUniqueName</param>
        /// <param name="projectRestoreInfo">projectRestoreInfo. Can be null</param>
        /// <param name="projectRestoreInfo2">proectRestoreInfo2. Can be null</param>
        /// <param name="token"></param>
        /// <remarks>Exactly one of projectRestoreInfos has to null.</remarks>
        /// <returns>The task that scheduled restore</returns>
        private async Task <bool> NominateProjectAsync(string projectUniqueName, IVsProjectRestoreInfo projectRestoreInfo, IVsProjectRestoreInfo2 projectRestoreInfo2, CancellationToken token)
        {
            if (string.IsNullOrEmpty(projectUniqueName))
            {
                throw new ArgumentException(Resources.Argument_Cannot_Be_Null_Or_Empty, nameof(projectUniqueName));
            }

            if (projectRestoreInfo == null && projectRestoreInfo2 == null)
            {
                throw new ArgumentNullException(nameof(projectRestoreInfo));
            }

            if (projectRestoreInfo != null && projectRestoreInfo2 != null)
            {
                throw new ArgumentException($"Internal error: Both {nameof(projectRestoreInfo)} and {nameof(projectRestoreInfo2)} cannot have values. Please file an issue at NuGet/Home if you see this exception.");
            }

            if (projectRestoreInfo != null)
            {
                if (projectRestoreInfo.TargetFrameworks == null)
                {
                    throw new InvalidOperationException("TargetFrameworks cannot be null.");
                }
            }
            else
            {
                if (projectRestoreInfo2.TargetFrameworks == null)
                {
                    throw new InvalidOperationException("TargetFrameworks cannot be null.");
                }
            }

            try
            {
                _logger.LogInformation(
                    $"The nominate API is called for '{projectUniqueName}'.");

                if (!_projectSystemCache.TryGetProjectNames(projectUniqueName, out ProjectNames projectNames))
                {
                    IVsSolution2 vsSolution2 = await _vsSolution2.GetValueAsync(token);

                    projectNames = await ProjectNames.FromIVsSolution2(projectUniqueName, vsSolution2, token);
                }

                DependencyGraphSpec dgSpec;
                IReadOnlyList <IAssetsLogMessage> nominationErrors = null;
                try
                {
                    dgSpec = ToDependencyGraphSpec(projectNames, projectRestoreInfo, projectRestoreInfo2);
                }
                catch (Exception e)
                {
                    var restoreLogMessage = RestoreLogMessage.CreateError(NuGetLogCode.NU1105, string.Format(Resources.NU1105, projectNames.ShortName, e.Message));
                    restoreLogMessage.LibraryId = projectUniqueName;

                    nominationErrors = new List <IAssetsLogMessage>()
                    {
                        AssetsLogMessage.Create(restoreLogMessage)
                    };

                    var    projectDirectory        = Path.GetDirectoryName(projectUniqueName);
                    string projectIntermediatePath = projectRestoreInfo == null
                        ? projectRestoreInfo2.BaseIntermediatePath
                        : projectRestoreInfo.BaseIntermediatePath;
                    var dgSpecOutputPath = GetProjectOutputPath(projectDirectory, projectIntermediatePath);
                    dgSpec = CreateMinimalDependencyGraphSpec(projectUniqueName, dgSpecOutputPath);
                }

                _projectSystemCache.AddProjectRestoreInfo(projectNames, dgSpec, nominationErrors);

                // returned task completes when scheduled restore operation completes.
                var restoreTask = _restoreWorker.ScheduleRestoreAsync(
                    SolutionRestoreRequest.OnUpdate(),
                    token);

                return(await restoreTask);
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (Exception e)
            {
                _logger.LogError(e.ToString());
                TelemetryUtility.EmitException(nameof(VsSolutionRestoreService), nameof(NominateProjectAsync), e);
                return(false);
            }
        }