// Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.DotNet.ProjectModel.Compilation; using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.ProjectModel.Resolution; using NuGet.Frameworks; namespace Microsoft.DotNet.ProjectModel { public class ProjectContext { public GlobalSettings GlobalSettings { get; } public ProjectDescription RootProject { get; } public NuGetFramework TargetFramework { get; } public string RuntimeIdentifier { get; } public Project ProjectFile => RootProject.Project; public LockFile LockFile { get; } public string RootDirectory => GlobalSettings?.DirectoryPath; public string ProjectDirectory => ProjectFile.ProjectDirectory; public string PackagesDirectory { get; } public LibraryManager LibraryManager { get; } internal ProjectContext( GlobalSettings globalSettings, ProjectDescription rootProject, NuGetFramework targetFramework, string runtimeIdentifier, string packagesDirectory, LibraryManager libraryManager, LockFile lockfile) { GlobalSettings = globalSettings; RootProject = rootProject; TargetFramework = targetFramework; RuntimeIdentifier = runtimeIdentifier; PackagesDirectory = packagesDirectory; LibraryManager = libraryManager; LockFile = lockfile; } public LibraryExporter CreateExporter(string configuration, string buildBasePath = null) { return new LibraryExporter(RootProject, LibraryManager, configuration, RuntimeIdentifier, buildBasePath, RootDirectory); } /// /// Creates a project context for the project located at , /// specifically in the context of the framework specified in /// public static ProjectContext Create(string projectPath, NuGetFramework framework) { return Create(projectPath, framework, Enumerable.Empty()); } /// /// Creates a project context for the project located at , /// specifically in the context of the framework specified in /// and the candidate runtime identifiers specified in /// public static ProjectContext Create(string projectPath, NuGetFramework framework, IEnumerable runtimeIdentifiers) { if (projectPath.EndsWith(Project.FileName)) { projectPath = Path.GetDirectoryName(projectPath); } return new ProjectContextBuilder() .WithProjectDirectory(projectPath) .WithTargetFramework(framework) .WithRuntimeIdentifiers(runtimeIdentifiers) .Build(); } public static ProjectContextBuilder CreateBuilder(string projectPath, NuGetFramework framework) { if (projectPath.EndsWith(Project.FileName)) { projectPath = Path.GetDirectoryName(projectPath); } return new ProjectContextBuilder() .WithProjectDirectory(projectPath) .WithTargetFramework(framework); } /// /// Creates a project context for each framework located in the project at /// public static IEnumerable CreateContextForEachFramework(string projectPath, ProjectReaderSettings settings = null, IEnumerable runtimeIdentifiers = null) { if (!projectPath.EndsWith(Project.FileName)) { projectPath = Path.Combine(projectPath, Project.FileName); } var project = ProjectReader.GetProject(projectPath, settings); foreach (var framework in project.GetTargetFrameworks()) { yield return new ProjectContextBuilder() .WithProject(project) .WithTargetFramework(framework.FrameworkName) .WithReaderSettings(settings) .WithRuntimeIdentifiers(runtimeIdentifiers ?? Enumerable.Empty()) .Build(); } } /// /// Creates a project context for each target located in the project at /// public static IEnumerable CreateContextForEachTarget(string projectPath) { if (!projectPath.EndsWith(Project.FileName)) { projectPath = Path.Combine(projectPath, Project.FileName); } var project = ProjectReader.GetProject(projectPath); return new ProjectContextBuilder() .WithProject(project) .BuildAllTargets(); } /// /// Creates a project context based on existing context but using runtime target /// /// /// /// public ProjectContext CreateRuntimeContext(IEnumerable runtimeIdentifiers) { var context = Create(ProjectFile.ProjectFilePath, TargetFramework, runtimeIdentifiers); if (context.RuntimeIdentifier == null) { var rids = string.Join(", ", runtimeIdentifiers); throw new InvalidOperationException($"Can not find runtime target for framework '{TargetFramework}' and RID's '{rids}'. " + "Possible causes:" + Environment.NewLine + "1. Project is not restored or restore failed - run `dotnet restore`" + Environment.NewLine + "2. Project is not targeting `runable` framework (`netstandardapp*` or `net*`)" ); } return context; } public OutputPaths GetOutputPaths(string configuration, string buidBasePath = null, string outputPath = null) { return OutputPathsCalculator.GetOutputPaths(ProjectFile, TargetFramework, RuntimeIdentifier, configuration, RootDirectory, buidBasePath, outputPath); } } }