예제 #1
0
        private PackageRestoreUnconfiguredInput MergeRestoreInputs(IReadOnlyCollection <PackageRestoreConfiguredInput> inputs)
        {
            // If there are no updates, we have no active configurations
            ProjectRestoreInfo?restoreInfo = null;

            if (inputs.Count != 0)
            {
                // We need to combine the snapshots from each implicitly active configuration (ie per TFM),
                // resolving any conflicts, which we'll report to the user.
                string               msbuildProjectExtensionsPath = ResolveMSBuildProjectExtensionsPathConflicts(inputs);
                string               originalTargetFrameworks     = ResolveOriginalTargetFrameworksConflicts(inputs);
                string               projectAssetsFilePath        = ResolveProjectAssetsFilePathConflicts(inputs);
                IVsReferenceItems    toolReferences   = ResolveToolReferenceConflicts(inputs);
                IVsTargetFrameworks2 targetFrameworks = GetAllTargetFrameworks(inputs);

                restoreInfo = new ProjectRestoreInfo(
                    msbuildProjectExtensionsPath,
                    projectAssetsFilePath,
                    originalTargetFrameworks,
                    targetFrameworks,
                    toolReferences);
            }

            return(new PackageRestoreUnconfiguredInput(restoreInfo, inputs));
        }
예제 #2
0
        public static byte[] CalculateHash(ProjectRestoreInfo restoreInfo)
        {
            Requires.NotNull(restoreInfo, nameof(restoreInfo));

            using var hasher = new IncrementalHasher();

            AppendProperty(hasher, nameof(restoreInfo.ProjectAssetsFilePath), restoreInfo.ProjectAssetsFilePath);
            AppendProperty(hasher, nameof(restoreInfo.MSBuildProjectExtensionsPath), restoreInfo.MSBuildProjectExtensionsPath);
            AppendProperty(hasher, nameof(restoreInfo.OriginalTargetFrameworks), restoreInfo.OriginalTargetFrameworks);

            foreach (IVsTargetFrameworkInfo3 framework in restoreInfo.TargetFrameworks)
            {
                AppendProperty(hasher, nameof(framework.TargetFrameworkMoniker), framework.TargetFrameworkMoniker);
                AppendFrameworkProperties(hasher, framework);
                AppendReferences(hasher, framework.ProjectReferences);
                AppendReferences(hasher, framework.PackageReferences);
                AppendReferences(hasher, framework.FrameworkReferences);
                AppendReferences(hasher, framework.PackageDownloads);
                AppendReferences(hasher, framework.CentralPackageVersions);
            }

            AppendReferences(hasher, restoreInfo.ToolReferences);

            return(hasher.GetHashAndReset());
        }
        private async Task <bool> RestoreCoreAsync(ProjectRestoreInfo restoreInfo)
        {
            // Restore service always does work regardless of whether the value we pass
            // them to actually contains changes, only nominate if there are any.
            byte[] hash = RestoreHasher.CalculateHash(restoreInfo);

            if (_latestHash != null && Enumerable.SequenceEqual(hash, _latestHash))
            {
                return(true);
            }

            _latestHash = hash;

            JoinableTask <bool> joinableTask = JoinableFactory.RunAsync(() =>
            {
                return(NominateForRestoreAsync(restoreInfo, _projectAsynchronousTasksService.UnloadCancellationToken));
            });

            _projectAsynchronousTasksService.RegisterAsyncTask(joinableTask,
                                                               ProjectCriticalOperation.Build | ProjectCriticalOperation.Unload | ProjectCriticalOperation.Rename,
                                                               registerFaultHandler: true);

            // Prevent overlap until Restore completes
            return(await joinableTask);
        }
        public static IReadOnlyCollection <PackageRestoreConfiguredInput>?Create(ProjectRestoreInfo restoreInfo)
        {
            ProjectConfiguration projectConfiguration = ProjectConfigurationFactory.Create("Debug|x64");
            IComparable          projectVersion       = (IComparable)0;

            return(new PackageRestoreConfiguredInput[1] {
                new PackageRestoreConfiguredInput(projectConfiguration, restoreInfo, projectVersion)
            });
        }
예제 #5
0
 private void HintProjectDependentFile(ProjectRestoreInfo restoreInfo)
 {
     if (restoreInfo.ProjectAssetsFilePath.Length != 0)
     {
         // Hint to CPS that the assets file "might" have changed and therefore
         // reevaluate if it has. It already listens to file-changed events for it,
         // but can miss them during periods where the buffer is overflowed when
         // there are lots of changes.
         _projectDependentFileChangeNotificationService.OnAfterDependentFilesChanged(
             fileFullPaths: new[] { restoreInfo.ProjectAssetsFilePath },
             project: ContainingProject);
     }
 }
            private RestoreData CreateRestoreData(ProjectRestoreInfo restoreInfo)
            {
                // Restore service gives us a guarantee that the assets file
                // will contain *at least* the changes that we pushed to it.

                if (restoreInfo.ProjectAssetsFilePath.Length == 0)
                {
                    return(new RestoreData(string.Empty, DateTime.MinValue, succeeded: false));
                }

                return(new RestoreData(
                           restoreInfo.ProjectAssetsFilePath,
                           GetLastWriteTimeUtc(restoreInfo.ProjectAssetsFilePath)));
            }
        private async Task <bool> NominateForRestoreAsync(ProjectRestoreInfo restoreInfo, CancellationToken cancellationToken)
        {
            RestoreLogger.BeginNominateRestore(_logger, _project.FullPath, restoreInfo);

            try
            {
                return(await _solutionRestoreService.NominateProjectAsync(_project.FullPath, restoreInfo, cancellationToken));
            }
            finally
            {
                CodeMarkers.Instance.CodeMarker(CodeMarkerTimerId.PerfPackageRestoreEnd);

                RestoreLogger.EndNominateRestore(_logger, _project.FullPath);
            }
        }
        private RestoreData CreateRestoreData(ProjectRestoreInfo restoreInfo, bool succeeded)
        {
            string projectAssetsFilePath = restoreInfo.ProjectAssetsFilePath;

            // Restore service gives us a guarantee that the assets file
            // will contain *at least* the changes that we pushed to it.

            if (projectAssetsFilePath.Length == 0)
            {
                return(new RestoreData(string.Empty, DateTime.MinValue, succeeded: false));
            }

            DateTime lastWriteTime = _fileSystem.GetLastFileWriteTimeOrMinValueUtc(projectAssetsFilePath);

            return(new RestoreData(
                       projectAssetsFilePath,
                       lastWriteTime,
                       succeeded: succeeded && lastWriteTime != DateTime.MinValue));
        }
        private Task HintProjectDependentFileAsync(ProjectRestoreInfo restoreInfo)
        {
            // Hint to CPS that the assets file "might" have changed and therefore
            // reevaluate if it has. It already listens to file-changed events for it,
            // but can miss them during periods where the buffer is overflowed when
            // there are lots of changes.
            if (restoreInfo.ProjectAssetsFilePath.Length > 0)
            {
                return(_projectAccessor.EnterWriteLockAsync((collection, token) =>
                {
                    var hint = new ProjectChangeFileSystemEntityHint(ContainingProject !,
                                                                     ProjectChangeFileSystemEntityHint.UpdateProjectDependentFile,
                                                                     new[] { restoreInfo.ProjectAssetsFilePath });

                    return _projectChangeHintSubmissionService.Value.HintAsync(hint);
                }));
            }

            return(Task.CompletedTask);
        }
            private async Task RestoreAsync(ProjectRestoreInfo restoreInfo)
            {
                // Restore service always does work regardless of whether the value we pass them to actually
                // contains changes, only nominate if there are any.
                if (RestoreComparer.RestoreInfos.Equals(_latestValue, restoreInfo))
                {
                    return;
                }

                _latestValue = restoreInfo;

                JoinableTask joinableTask = JoinableFactory.RunAsync(() =>
                {
                    return(NominateForRestoreAsync(restoreInfo, _projectAsynchronousTasksService.UnloadCancellationToken));
                });

                _projectAsynchronousTasksService.RegisterAsyncTask(joinableTask,
                                                                   ProjectCriticalOperation.Build | ProjectCriticalOperation.Unload | ProjectCriticalOperation.Rename,
                                                                   registerFaultHandler: true);

                // Prevent overlap until Restore completes
                await joinableTask;
            }
예제 #11
0
 public PackageRestoreConfiguredInput(ProjectConfiguration projectConfiguration, ProjectRestoreInfo restoreInfo, IComparable configuredProjectVersion)
 {
     ProjectConfiguration     = projectConfiguration;
     RestoreInfo              = restoreInfo;
     ConfiguredProjectVersion = configuredProjectVersion;
 }