예제 #1
0
        private static async Task <PackageSpec> GetPackageSpecForProjectJsonAsync(
            IDeferredProjectWorkspaceService deferredWorkspaceService,
            string projectPath,
            string projectJsonFilePath)
        {
            var projectName = Path.GetFileNameWithoutExtension(projectPath);
            var packageSpec = JsonPackageSpecReader.GetPackageSpec(projectName, projectJsonFilePath);

            var metadata = new ProjectRestoreMetadata();

            packageSpec.RestoreMetadata = metadata;

            metadata.ProjectStyle      = ProjectStyle.ProjectJson;
            metadata.ProjectPath       = projectPath;
            metadata.ProjectJsonPath   = packageSpec.FilePath;
            metadata.ProjectName       = packageSpec.Name;
            metadata.ProjectUniqueName = projectPath;

            foreach (var framework in packageSpec.TargetFrameworks.Select(e => e.FrameworkName))
            {
                metadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(framework));
            }

            await AddProjectReferencesAsync(deferredWorkspaceService, metadata, projectPath);

            return(packageSpec);
        }
예제 #2
0
        private static async Task <NuGetFramework> GetNuGetFramework(
            IDeferredProjectWorkspaceService deferredWorkspaceService,
            IMSBuildProjectDataService dataService,
            string projectPath)
        {
            var targetPlatformIdentifier = await deferredWorkspaceService.GetProjectPropertyAsync(dataService, TargetPlatformIdentifier);

            var targetPlatformVersion = await deferredWorkspaceService.GetProjectPropertyAsync(dataService, TargetPlatformVersion);

            var targetPlatformMinVersion = await deferredWorkspaceService.GetProjectPropertyAsync(dataService, TargetPlatformMinVersion);

            var targetFrameworkMoniker = await deferredWorkspaceService.GetProjectPropertyAsync(dataService, TargetFrameworkMoniker);

            var frameworkStrings = MSBuildProjectFrameworkUtility.GetProjectFrameworkStrings(
                projectFilePath: projectPath,
                targetFrameworks: null,
                targetFramework: null,
                targetFrameworkMoniker: targetFrameworkMoniker,
                targetPlatformIdentifier: targetPlatformIdentifier,
                targetPlatformVersion: targetPlatformVersion,
                targetPlatformMinVersion: targetPlatformMinVersion);

            var frameworkString = frameworkStrings.FirstOrDefault();

            if (!string.IsNullOrEmpty(frameworkString))
            {
                return(NuGetFramework.Parse(frameworkString));
            }

            return(NuGetFramework.UnsupportedFramework);
        }
예제 #3
0
        private static async Task <PackageSpec> GetPackageSpecForPackagesConfigAsync(IDeferredProjectWorkspaceService deferredWorkspaceService, string projectPath)
        {
            var projectName = Path.GetFileNameWithoutExtension(projectPath);

            var msbuildProjectDataService = await deferredWorkspaceService.GetMSBuildProjectDataService(projectPath);

            var nuGetFramework = await GetNuGetFramework(deferredWorkspaceService, msbuildProjectDataService, projectPath);

            var packageSpec = new PackageSpec(
                new List <TargetFrameworkInformation>
            {
                new TargetFrameworkInformation
                {
                    FrameworkName = nuGetFramework
                }
            });

            packageSpec.Name     = projectName;
            packageSpec.FilePath = projectPath;

            var metadata = new ProjectRestoreMetadata();

            packageSpec.RestoreMetadata = metadata;

            metadata.ProjectStyle      = ProjectStyle.PackagesConfig;
            metadata.ProjectPath       = projectPath;
            metadata.ProjectName       = projectName;
            metadata.ProjectUniqueName = projectPath;
            metadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(nuGetFramework));

            await AddProjectReferencesAsync(deferredWorkspaceService, metadata, projectPath);

            return(packageSpec);
        }
예제 #4
0
        private static async Task <List <NuGetFramework> > GetNuGetFrameworks(
            IDeferredProjectWorkspaceService deferredWorkspaceService,
            IMSBuildProjectDataService dataService,
            string projectPath)
        {
            var targetFrameworks = await deferredWorkspaceService.GetProjectPropertyAsync(dataService, TargetFrameworks);

            if (!string.IsNullOrEmpty(targetFrameworks))
            {
                return(targetFrameworks
                       .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                       .Select(NuGetFramework.Parse).ToList());
            }

            var targetFramework = await deferredWorkspaceService.GetProjectPropertyAsync(dataService, TargetFramework);

            if (!string.IsNullOrEmpty(targetFramework))
            {
                return(new List <NuGetFramework> {
                    NuGetFramework.Parse(targetFramework)
                });
            }

            // old packages.config style or legacy PackageRef
            return(new List <NuGetFramework> {
                await GetNuGetFramework(deferredWorkspaceService, dataService, projectPath)
            });
        }
예제 #5
0
        private async Task LoadSolutionFromMSBuildAsync(
            IDeferredProjectWorkspaceService deferredProjectWorkspaceService,
            CancellationToken cancellationToken)
        {
            AssertIsForeground();
            InitializeOutputPane();

            // Continue on the UI thread for these operations, since we are touching the VisualStudioWorkspace, etc.
            await PopulateWorkspaceFromDeferredProjectInfoAsync(deferredProjectWorkspaceService, cancellationToken).ConfigureAwait(true);
        }
        private async Task LoadSolutionFromMSBuildAsync(
            IDeferredProjectWorkspaceService deferredProjectWorkspaceService,
            CancellationToken cancellationToken)
        {
            AssertIsForeground();
            InitializeOutputPane();

            // Continue on the UI thread for these operations, since we are touching the VisualStudioWorkspace, etc.
            await PopulateWorkspaceFromDeferredProjectInfoAsync(deferredProjectWorkspaceService, cancellationToken).ConfigureAwait(true);
        }
예제 #7
0
        private static async Task <List <string> > GetRuntimeSupports(
            IDeferredProjectWorkspaceService deferredWorkspaceService,
            IMSBuildProjectDataService dataService)
        {
            var supports = (await GetProjectPropertyOrDefault(deferredWorkspaceService, dataService, RuntimeSupports))
                           .Split(';')
                           .Where(s => !string.IsNullOrEmpty(s))
                           .ToList();

            return(supports);
        }
예제 #8
0
        public SolutionRestoreJob(
            [Import(typeof(SVsServiceProvider))]
            IServiceProvider serviceProvider,
            IPackageRestoreManager packageRestoreManager,
            IVsSolutionManager solutionManager,
            ISourceRepositoryProvider sourceRepositoryProvider,
            IRestoreEventsPublisher restoreEventsPublisher,
#if !VS14
            IDeferredProjectWorkspaceService deferredWorkspaceService,
#endif
            ISettings settings)
        {
            if (serviceProvider == null)
            {
                throw new ArgumentNullException(nameof(serviceProvider));
            }

            if (packageRestoreManager == null)
            {
                throw new ArgumentNullException(nameof(packageRestoreManager));
            }

            if (solutionManager == null)
            {
                throw new ArgumentNullException(nameof(solutionManager));
            }

            if (sourceRepositoryProvider == null)
            {
                throw new ArgumentNullException(nameof(sourceRepositoryProvider));
            }

            if (restoreEventsPublisher == null)
            {
                throw new ArgumentNullException(nameof(restoreEventsPublisher));
            }

            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            _serviceProvider          = serviceProvider;
            _packageRestoreManager    = packageRestoreManager;
            _solutionManager          = solutionManager;
            _sourceRepositoryProvider = sourceRepositoryProvider;
            _restoreEventsPublisher   = restoreEventsPublisher;
            _settings = settings;
#if VS14
            _deferredWorkspaceService = null;
#else
            _deferredWorkspaceService = deferredWorkspaceService;
#endif
        }
예제 #9
0
        private async Task PopulateWorkspaceFromDeferredProjectInfoAsync(
            IDeferredProjectWorkspaceService deferredProjectWorkspaceService,
            CancellationToken cancellationToken)
        {
            // NOTE: We need to check cancellationToken after each await, in case the user has
            // already closed the solution.
            AssertIsForeground();

            var componentModel = _serviceProvider.GetService(typeof(SComponentModel)) as IComponentModel;
            var workspaceProjectContextFactory = componentModel.GetService <IWorkspaceProjectContextFactory>();

            var dte            = _serviceProvider.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
            var solutionConfig = (EnvDTE80.SolutionConfiguration2)dte.Solution.SolutionBuild.ActiveConfiguration;

            OutputToOutputWindow($"Getting project information - start");
            var start = DateTimeOffset.UtcNow;

            var projectInfos = SpecializedCollections.EmptyReadOnlyDictionary <string, DeferredProjectInformation>();

            // Note that `solutionConfig` may be null. For example: if the solution doesn't actually
            // contain any projects.
            if (solutionConfig != null)
            {
                // Capture the context so that we come back on the UI thread, and do the actual project creation there.
                projectInfos = await deferredProjectWorkspaceService.GetDeferredProjectInfoForConfigurationAsync(
                    $"{solutionConfig.Name}|{solutionConfig.PlatformName}",
                    cancellationToken).ConfigureAwait(true);
            }

            AssertIsForeground();
            cancellationToken.ThrowIfCancellationRequested();
            OutputToOutputWindow($"Getting project information - done (took {DateTimeOffset.UtcNow - start})");

            OutputToOutputWindow($"Creating projects - start");
            start = DateTimeOffset.UtcNow;
            var targetPathsToProjectPaths = BuildTargetPathMap(projectInfos);

            foreach (var projectFilename in projectInfos.Keys)
            {
                cancellationToken.ThrowIfCancellationRequested();
                GetOrCreateProjectFromArgumentsAndReferences(
                    workspaceProjectContextFactory,
                    projectFilename,
                    projectInfos,
                    targetPathsToProjectPaths);
            }
            OutputToOutputWindow($"Creating projects - done (took {DateTimeOffset.UtcNow - start})");

            OutputToOutputWindow($"Pushing to workspace - start");
            start = DateTimeOffset.UtcNow;
            FinishLoad();
            OutputToOutputWindow($"Pushing to workspace - done (took {DateTimeOffset.UtcNow - start})");
        }
예제 #10
0
        private static async Task <string> GetProjectPropertyOrDefault(
            IDeferredProjectWorkspaceService deferredWorkspaceService,
            IMSBuildProjectDataService dataService,
            string projectPropertyName,
            string defaultValue = "")
        {
            var propertyValue = await deferredWorkspaceService.GetProjectPropertyAsync(dataService, projectPropertyName);

            if (!string.IsNullOrEmpty(propertyValue))
            {
                return(propertyValue);
            }

            return(defaultValue);
        }
예제 #11
0
        private static async Task <List <string> > GetRuntimeIdentifiers(
            IDeferredProjectWorkspaceService deferredWorkspaceService,
            IMSBuildProjectDataService dataService)
        {
            var runtimeIdentifier = await GetProjectPropertyOrDefault(deferredWorkspaceService, dataService, RuntimeIdentifier);

            var runtimeIdentifiers = await GetProjectPropertyOrDefault(deferredWorkspaceService, dataService, RuntimeIdentifiers);

            var runtimes = (new[] { runtimeIdentifier, runtimeIdentifiers })
                           .SelectMany(s => s.Split(';'))
                           .Where(s => !string.IsNullOrEmpty(s))
                           .ToList();

            return(runtimes);
        }
예제 #12
0
        public WorkspaceProjectBuildProperties(
            string fullProjectPath,
            IDeferredProjectWorkspaceService workspaceService,
            IVsProjectThreadingService threadingService)
        {
            Assumes.Present(workspaceService);
            Assumes.Present(threadingService);

            _workspaceService = workspaceService;
            _threadingService = threadingService;
            _fullProjectPath  = fullProjectPath;

            _buildProjectDataService = new AsyncLazy <IMSBuildProjectDataService>(
                () => workspaceService.GetMSBuildProjectDataServiceAsync(_fullProjectPath),
                threadingService.JoinableTaskFactory);
        }
        public WorkspaceProjectServices(
            IVsProjectAdapter vsProjectAdapter,
            INuGetProjectServices projectServices)
        {
            Assumes.Present(vsProjectAdapter);
            Assumes.Present(projectServices);

            _vsProjectAdapter = vsProjectAdapter;
            _fullProjectPath  = vsProjectAdapter.FullProjectPath;

            _workspaceService = projectServices.GetGlobalService <IDeferredProjectWorkspaceService>();
            Assumes.Present(_workspaceService);

            _threadingService = projectServices.GetGlobalService <IVsProjectThreadingService>();
            Assumes.Present(_threadingService);

            _buildProjectDataService = new AsyncLazy <IMSBuildProjectDataService>(
                () => _workspaceService.GetMSBuildProjectDataServiceAsync(_fullProjectPath),
                _threadingService.JoinableTaskFactory);
        }
예제 #14
0
        public VsProjectAdapter(
            VsHierarchyItem vsHierarchyItem,
            ProjectNames projectNames,
            string fullProjectPath,
            Func <IVsHierarchy, EnvDTE.Project> loadDteProject,
            IProjectBuildProperties buildProperties,
            IVsProjectThreadingService threadingService,
            IDeferredProjectWorkspaceService workspaceService = null)
        {
            Assumes.Present(vsHierarchyItem);

            _vsHierarchyItem  = vsHierarchyItem;
            _dteProject       = new Lazy <EnvDTE.Project>(() => loadDteProject(_vsHierarchyItem.VsHierarchy));
            _workspaceService = workspaceService;
            _threadingService = threadingService;

            FullProjectPath = fullProjectPath;
            ProjectNames    = projectNames;
            BuildProperties = buildProperties;
        }
예제 #15
0
        public LegacyPackageReferenceProjectProvider(
            [Import(typeof(SVsServiceProvider))]
            IServiceProvider vsServiceProvider,
            IDeferredProjectWorkspaceService workspaceService,
            IVsProjectThreadingService threadingService)
        {
            Assumes.Present(vsServiceProvider);
            Assumes.Present(workspaceService);
            Assumes.Present(threadingService);

            _workspaceService = workspaceService;
            _threadingService = threadingService;

            _componentModel = new AsyncLazy <IComponentModel>(
                async() =>
            {
                await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();
                return(vsServiceProvider.GetService <SComponentModel, IComponentModel>());
            },
                _threadingService.JoinableTaskFactory);
        }
예제 #16
0
        private static async Task AddProjectReferencesAsync(
            IDeferredProjectWorkspaceService deferredWorkspaceService,
            ProjectRestoreMetadata metadata,
            string projectPath)
        {
            var references = await deferredWorkspaceService.GetProjectReferencesAsync(projectPath);

            foreach (var reference in references)
            {
                var restoreReference = new ProjectRestoreReference()
                {
                    ProjectPath       = reference,
                    ProjectUniqueName = reference
                };

                foreach (var frameworkInfo in metadata.TargetFrameworks)
                {
                    frameworkInfo.ProjectReferences.Add(restoreReference);
                }
            }
        }
        private async Task PopulateWorkspaceFromDeferredProjectInfoAsync(
            IDeferredProjectWorkspaceService deferredProjectWorkspaceService,
            CancellationToken cancellationToken)
        {
            // NOTE: We need to check cancellationToken after each await, in case the user has
            // already closed the solution.
            AssertIsForeground();

            var componentModel = _serviceProvider.GetService(typeof(SComponentModel)) as IComponentModel;
            var workspaceProjectContextFactory = componentModel.GetService<IWorkspaceProjectContextFactory>();

            var dte = _serviceProvider.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
            var solutionConfig = (EnvDTE80.SolutionConfiguration2)dte.Solution.SolutionBuild.ActiveConfiguration;

            OutputToOutputWindow($"Getting project information - start");
            var start = DateTimeOffset.UtcNow;

            var projectInfos = SpecializedCollections.EmptyReadOnlyDictionary<string, DeferredProjectInformation>();

            // Note that `solutionConfig` may be null. For example: if the solution doesn't actually
            // contain any projects.
            if (solutionConfig != null)
            {
                // Capture the context so that we come back on the UI thread, and do the actual project creation there.
                projectInfos = await deferredProjectWorkspaceService.GetDeferredProjectInfoForConfigurationAsync(
                    $"{solutionConfig.Name}|{solutionConfig.PlatformName}",
                    cancellationToken).ConfigureAwait(true);
            }

            AssertIsForeground();
            cancellationToken.ThrowIfCancellationRequested();
            OutputToOutputWindow($"Getting project information - done (took {DateTimeOffset.UtcNow - start})");

            OutputToOutputWindow($"Creating projects - start");
            start = DateTimeOffset.UtcNow;
            var targetPathsToProjectPaths = BuildTargetPathMap(projectInfos);
            foreach (var projectFilename in projectInfos.Keys)
            {
                cancellationToken.ThrowIfCancellationRequested();
                GetOrCreateProjectFromArgumentsAndReferences(
                    workspaceProjectContextFactory,
                    projectFilename,
                    projectInfos,
                    targetPathsToProjectPaths);
            }
            OutputToOutputWindow($"Creating projects - done (took {DateTimeOffset.UtcNow - start})");

            OutputToOutputWindow($"Pushing to workspace - start");
            start = DateTimeOffset.UtcNow;
            FinishLoad();
            OutputToOutputWindow($"Pushing to workspace - done (took {DateTimeOffset.UtcNow - start})");
        }
예제 #18
0
        private static async Task <PackageSpec> GetPackageSpecForPackageReferencesAsync(
            IDeferredProjectWorkspaceService deferredWorkspaceService,
            string projectPath)
        {
            var projectName      = Path.GetFileNameWithoutExtension(projectPath);
            var projectDirectory = Path.GetDirectoryName(projectPath);

            var msbuildProjectDataService = await deferredWorkspaceService.GetMSBuildProjectDataService(projectPath);

            var packageReferences = (await deferredWorkspaceService.GetProjectItemsAsync(msbuildProjectDataService, PackageReference)).ToList();

            if (packageReferences.Count == 0)
            {
                return(null);
            }

            var targetFrameworks = await GetNuGetFrameworks(deferredWorkspaceService, msbuildProjectDataService, projectPath);

            if (targetFrameworks.Count == 0)
            {
                return(null);
            }

            var outputPath = Path.GetFullPath(
                Path.Combine(
                    projectDirectory,
                    await GetProjectPropertyOrDefault(deferredWorkspaceService, msbuildProjectDataService, BaseIntermediateOutputPath)));

            var crossTargeting = targetFrameworks.Count > 1;

            var tfis = new List <TargetFrameworkInformation>();
            var projectsByFramework = new Dictionary <NuGetFramework, IEnumerable <ProjectRestoreReference> >();
            var runtimes            = new List <string>();
            var supports            = new List <string>();

            foreach (var targetFramework in targetFrameworks)
            {
                var tfi = new TargetFrameworkInformation
                {
                    FrameworkName = targetFramework
                };

                // re-evaluate msbuild project data service if there are multi-targets
                if (targetFrameworks.Count > 1)
                {
                    msbuildProjectDataService = await deferredWorkspaceService.GetMSBuildProjectDataService(
                        projectPath,
                        targetFramework.GetShortFolderName());

                    packageReferences = (await deferredWorkspaceService.GetProjectItemsAsync(msbuildProjectDataService, PackageReference)).ToList();
                }

                // Package target fallback per target framework
                var ptf = await deferredWorkspaceService.GetProjectPropertyAsync(msbuildProjectDataService, PackageTargetFallback);

                if (!string.IsNullOrEmpty(ptf))
                {
                    var fallBackList = ptf.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                                       .Select(NuGetFramework.Parse).ToList();

                    if (fallBackList.Count > 0)
                    {
                        tfi.FrameworkName = new FallbackFramework(tfi.FrameworkName, fallBackList);
                    }

                    tfi.Imports = fallBackList;
                }

                // package references per target framework
                tfi.Dependencies.AddRange(
                    packageReferences.Select(ToPackageLibraryDependency));

                // Project references per target framework
                var projectReferences = (await deferredWorkspaceService.GetProjectItemsAsync(msbuildProjectDataService, ProjectReference))
                                        .Select(item => ToProjectRestoreReference(item, projectDirectory));
                projectsByFramework.Add(tfi.FrameworkName, projectReferences);

                // Runtimes, Supports per target framework
                runtimes.AddRange(await GetRuntimeIdentifiers(deferredWorkspaceService, msbuildProjectDataService));
                supports.AddRange(await GetRuntimeSupports(deferredWorkspaceService, msbuildProjectDataService));

                tfis.Add(tfi);
            }

            var packageSpec = new PackageSpec(tfis)
            {
                Name            = projectName,
                FilePath        = projectPath,
                RestoreMetadata = new ProjectRestoreMetadata
                {
                    ProjectName       = projectName,
                    ProjectUniqueName = projectPath,
                    ProjectPath       = projectPath,
                    OutputPath        = outputPath,
                    ProjectStyle      = ProjectStyle.PackageReference,
                    TargetFrameworks  = (projectsByFramework.Select(
                                             kvp => new ProjectRestoreMetadataFrameworkInfo(kvp.Key)
                    {
                        ProjectReferences = kvp.Value?.ToList()
                    }
                                             )).ToList(),
                    OriginalTargetFrameworks = tfis
                                               .Select(tf => tf.FrameworkName.GetShortFolderName())
                                               .ToList(),
                    CrossTargeting = crossTargeting
                },
                RuntimeGraph = new RuntimeGraph(
                    runtimes.Distinct(StringComparer.Ordinal).Select(rid => new RuntimeDescription(rid)),
                    supports.Distinct(StringComparer.Ordinal).Select(s => new CompatibilityProfile(s)))
            };

            return(packageSpec);
        }
예제 #19
0
        public static async Task <DeferredProjectRestoreData> GetDeferredProjectsData(
            IDeferredProjectWorkspaceService deferredWorkspaceService,
            IEnumerable <string> deferredProjectsPath,
            CancellationToken token)
        {
            var packageReferencesDict = new Dictionary <PackageReference, List <string> >(new PackageReferenceComparer());
            var packageSpecs          = new List <PackageSpec>();

            foreach (var projectPath in deferredProjectsPath)
            {
                // packages.config
                string packagesConfigFilePath   = Path.Combine(Path.GetDirectoryName(projectPath), "packages.config");
                bool   packagesConfigFileExists = await deferredWorkspaceService.EntityExists(packagesConfigFilePath);

                if (packagesConfigFileExists)
                {
                    // read packages.config and get all package references.
                    var projectName = Path.GetFileNameWithoutExtension(projectPath);
                    using (var stream = new FileStream(packagesConfigFilePath, FileMode.Open, FileAccess.Read))
                    {
                        var reader            = new PackagesConfigReader(stream);
                        var packageReferences = reader.GetPackages();

                        foreach (var packageRef in packageReferences)
                        {
                            List <string> projectNames = null;
                            if (!packageReferencesDict.TryGetValue(packageRef, out projectNames))
                            {
                                projectNames = new List <string>();
                                packageReferencesDict.Add(packageRef, projectNames);
                            }

                            projectNames.Add(projectName);
                        }
                    }

                    // create package spec for packages.config based project
                    var packageSpec = await GetPackageSpecForPackagesConfigAsync(deferredWorkspaceService, projectPath);

                    if (packageSpec != null)
                    {
                        packageSpecs.Add(packageSpec);
                    }
                }
                else
                {
                    // project.json
                    string projectJsonFilePath   = Path.Combine(Path.GetDirectoryName(projectPath), "project.json");
                    bool   projectJsonFileExists = await deferredWorkspaceService.EntityExists(projectJsonFilePath);

                    if (projectJsonFileExists)
                    {
                        // create package spec for project.json based project
                        var packageSpec = await GetPackageSpecForProjectJsonAsync(deferredWorkspaceService, projectPath, projectJsonFilePath);

                        packageSpecs.Add(packageSpec);
                    }
                    else
                    {
                        // package references (CPS or Legacy CSProj)
                        var packageSpec = await GetPackageSpecForPackageReferencesAsync(deferredWorkspaceService, projectPath);

                        if (packageSpec != null)
                        {
                            packageSpecs.Add(packageSpec);
                        }
                    }
                }
            }

            return(new DeferredProjectRestoreData(packageReferencesDict, packageSpecs));
        }