public IEnumerable <ProjectDependency> ResolveProjectDependencies(ProjectContext projectContext, HashSet <string> preResolvedProjects = null) { preResolvedProjects = preResolvedProjects ?? new HashSet <string>(); var projectExports = projectContext.CreateExporter("_").GetDependencies(); var possibleProjectDependencies = FindPossibleProjectDependencies(projectContext.ProjectFile.ProjectFilePath); var projectDependencies = new List <ProjectDependency>(); foreach (var projectExport in projectExports) { var projectExportName = projectExport.Library.Identity.Name; ProjectDependency projectDependency; if (!possibleProjectDependencies.TryGetValue(projectExportName, out projectDependency)) { if (projectExport.Library.Identity.Type.Equals(LibraryType.Project) && !preResolvedProjects.Contains(projectExportName)) { MigrationErrorCodes .MIGRATE1014($"Unresolved project dependency ({projectExportName})").Throw(); } else { continue; } } projectDependencies.Add(projectDependency); } return(projectDependencies); }
private ProjectId AddProject(ProjectContext project) { // Create the framework specific project and add it to the workspace var projectInfo = ProjectInfo.Create( ProjectId.CreateNewId(), VersionStamp.Create(), project.ProjectFile.Name + "+" + project.TargetFramework, project.ProjectFile.Name, LanguageNames.CSharp, project.ProjectFile.ProjectFilePath); OnProjectAdded(projectInfo); // TODO: ctor argument? var configuration = "Debug"; var compilationOptions = project.GetLanguageSpecificCompilerOptions(project.TargetFramework, configuration); var compilationSettings = ToCompilationSettings(compilationOptions, project.TargetFramework, project.ProjectFile.ProjectDirectory); OnParseOptionsChanged(projectInfo.Id, new CSharpParseOptions(compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines)); OnCompilationOptionsChanged(projectInfo.Id, compilationSettings.CompilationOptions); foreach (var file in project.ProjectFile.Files.SourceFiles) { AddSourceFile(projectInfo, file); } var exporter = project.CreateExporter(configuration); foreach (var dependency in exporter.GetDependencies()) { var projectDependency = dependency.Library as ProjectDescription; if (projectDependency != null) { var projectDependencyContext = ProjectContext.Create(projectDependency.Project.ProjectFilePath, projectDependency.Framework); var id = AddProject(projectDependencyContext); OnProjectReferenceAdded(projectInfo.Id, new ProjectReference(id)); } else { foreach (var asset in dependency.CompilationAssemblies) { OnMetadataReferenceAdded(projectInfo.Id, GetMetadataReference(asset.ResolvedPath)); } } foreach (var file in dependency.SourceReferences) { AddSourceFile(projectInfo, file); } } return projectInfo.Id; }
private static bool Compile(ProjectContext context, string configuration, string outputOptionValue, string intermediateOutputValue, bool buildProjectReferences, bool noHost) { // Set up Output Paths string outputPath = GetOutputPath(context, configuration, outputOptionValue); string intermediateOutputPath = GetIntermediateOutputPath(context, configuration, intermediateOutputValue, outputOptionValue); Directory.CreateDirectory(outputPath); Directory.CreateDirectory(intermediateOutputPath); // Create the library exporter var exporter = context.CreateExporter(configuration); // Gather exports for the project var dependencies = exporter.GetDependencies().ToList(); if (buildProjectReferences) { var projects = new Dictionary <string, ProjectDescription>(); // Build project references foreach (var dependency in dependencies) { var projectDependency = dependency.Library as ProjectDescription; if (projectDependency != null && projectDependency.Project.Files.SourceFiles.Any()) { projects[projectDependency.Identity.Name] = projectDependency; } } foreach (var projectDependency in Sort(projects)) { // Skip compiling project dependencies since we've already figured out the build order var compileResult = Command.Create("dotnet-compile", $"--framework {projectDependency.Framework} " + $"--configuration {configuration} " + $"--output \"{outputPath}\" " + $"--temp-output \"{intermediateOutputPath}\" " + "--no-project-dependencies " + (noHost ? "--no-host " : string.Empty) + $"\"{projectDependency.Project.ProjectDirectory}\"") .ForwardStdOut() .ForwardStdErr() .Execute(); if (compileResult.ExitCode != 0) { return(false); } } projects.Clear(); } return(CompileProject(context, configuration, outputPath, intermediateOutputPath, dependencies, noHost)); }
public static ProjectContextSnapshot Create(ProjectContext context, string configuration, IEnumerable <string> currentSearchPaths) { var snapshot = new ProjectContextSnapshot(); var allDependencyDiagnostics = new List <DiagnosticMessage>(); allDependencyDiagnostics.AddRange(context.LibraryManager.GetAllDiagnostics()); allDependencyDiagnostics.AddRange(DependencyTypeChangeFinder.Diagnose(context, currentSearchPaths)); var diagnosticsLookup = allDependencyDiagnostics.ToLookup(d => d.Source); var allExports = context.CreateExporter(configuration) .GetAllExports() .ToDictionary(export => export.Library.Identity.Name); var allSourceFiles = new List <string>(context.ProjectFile.Files.SourceFiles); var allFileReferences = new List <string>(); var allProjectReferences = new List <ProjectReferenceDescription>(); var allDependencies = new Dictionary <string, DependencyDescription>(); // All exports are returned. When the same library name have a ReferenceAssembly type export and a Package type export // both will be listed as dependencies. Prefix "fx/" will be added to ReferenceAssembly type dependency. foreach (var export in allExports.Values) { allSourceFiles.AddRange(export.SourceReferences.Select(f => f.ResolvedPath)); var diagnostics = diagnosticsLookup[export.Library].ToList(); var description = DependencyDescription.Create(export.Library, diagnostics, allExports); allDependencies[description.Name] = description; var projectDescription = export.Library as ProjectDescription; if (projectDescription != null) { if (projectDescription.Identity.Name != context.ProjectFile.Name) { allProjectReferences.Add(ProjectReferenceDescription.Create(projectDescription)); } } else { allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath)); } } snapshot.RootDependency = context.ProjectFile.Name; snapshot.TargetFramework = context.TargetFramework; snapshot.SourceFiles = allSourceFiles.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); snapshot.CompilerOptions = context.GetLanguageSpecificCompilerOptions(context.TargetFramework, configuration); snapshot.ProjectReferences = allProjectReferences.OrderBy(reference => reference.Name).ToList(); snapshot.FileReferences = allFileReferences.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); snapshot.DependencyDiagnostics = allDependencyDiagnostics; snapshot.Dependencies = allDependencies; return(snapshot); }
public static ProjectContextSnapshot Create(ProjectContext context, string configuration, IEnumerable<string> currentSearchPaths) { var snapshot = new ProjectContextSnapshot(); var allDependencyDiagnostics = new List<DiagnosticMessage>(); allDependencyDiagnostics.AddRange(context.LibraryManager.GetAllDiagnostics()); allDependencyDiagnostics.AddRange(DependencyTypeChangeFinder.Diagnose(context, currentSearchPaths)); var diagnosticsLookup = allDependencyDiagnostics.ToLookup(d => d.Source); var allExports = context.CreateExporter(configuration) .GetAllExports() .ToDictionary(export => export.Library.Identity.Name); var allSourceFiles = new List<string>(context.ProjectFile.Files.SourceFiles); var allFileReferences = new List<string>(); var allProjectReferences = new List<ProjectReferenceDescription>(); var allDependencies = new Dictionary<string, DependencyDescription>(); // All exports are returned. When the same library name have a ReferenceAssembly type export and a Package type export // both will be listed as dependencies. Prefix "fx/" will be added to ReferenceAssembly type dependency. foreach (var export in allExports.Values) { allSourceFiles.AddRange(export.SourceReferences.Select(f => f.ResolvedPath)); var diagnostics = diagnosticsLookup[export.Library].ToList(); var description = DependencyDescription.Create(export.Library, diagnostics, allExports); allDependencies[description.Name] = description; var projectDescription = export.Library as ProjectDescription; if (projectDescription != null) { if (projectDescription.Identity.Name != context.ProjectFile.Name) { allProjectReferences.Add(ProjectReferenceDescription.Create(projectDescription)); } } else { allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath)); } } snapshot.RootDependency = context.ProjectFile.Name; snapshot.TargetFramework = context.TargetFramework; snapshot.SourceFiles = allSourceFiles.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); snapshot.CompilerOptions = context.GetLanguageSpecificCompilerOptions(context.TargetFramework, configuration); snapshot.ProjectReferences = allProjectReferences.OrderBy(reference => reference.Name).ToList(); snapshot.FileReferences = allFileReferences.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); snapshot.DependencyDiagnostics = allDependencyDiagnostics; snapshot.Dependencies = allDependencies; return snapshot; }
public static AssemblyLoadContext CreateLoadContext( [NotNull] this ProjectContext context, [NotNull] string runtimeIdentifier, [NotNull] string configuration, [CanBeNull] string outputPath = null) { var exporter = context.CreateExporter(configuration); var assemblies = new Dictionary <AssemblyName, string>(AssemblyNameComparer.OrdinalIgnoreCase); var dllImports = new Dictionary <string, string>(); var fallbacks = DependencyContext.Default.RuntimeGraph.FirstOrDefault(f => f.Runtime.Equals(runtimeIdentifier)); if (fallbacks == null) { throw new InvalidOperationException($"Failed to load runtime fallback graph for: {runtimeIdentifier}"); } foreach (var export in exporter.GetAllExports()) { var group = SelectGroup(export.RuntimeAssemblyGroups, fallbacks); // TODO: Handle resource assemblies if (group != null) { foreach (var asset in group.Assets) { // REVIEW: Should we use the following? // AssemblyLoadContext.GetAssemblyName(asset.ResolvedPath); var assemblyName = new AssemblyName(asset.Name); assemblies[assemblyName] = asset.ResolvedPath; } } group = SelectGroup(export.NativeLibraryGroups, fallbacks); if (group != null) { foreach (var asset in group.Assets) { dllImports[asset.Name] = asset.ResolvedPath; } } } return(new DesignTimeProjectLoadContext( assemblies, dllImports, // Add the project's output directory path to ensure project-to-project references get located new[] { context.GetOutputPaths(configuration, outputPath: outputPath).CompilationOutputPath })); }
public IEnumerable <TemplatePackage> GetInstalledTemplates() { if (_templatesProjectContext.LockFile == null) { RestoreTemplatePackages(); ReloadTemplatesProject(); } var templatePackages = _templatesProjectContext.LockFile.PackageLibraries; var exporter = _templatesProjectContext.CreateExporter("Debug"); var packages = exporter.GetAllExports().Select(e => e.Library).OfType <PackageDescription>(); foreach (var package in packages) { var manifestFile = package.Library.Files.SingleOrDefault(f => f == "templates\\templates.json"); // TODO: Handle other packages turning up in lock file due to template packages having dependencies if (manifestFile != null) { var templatePackage = new TemplatePackage { Id = package.Identity.Name, Version = package.Identity.Version.ToString() }; var manifestFilePath = Path.Combine(package.Path, manifestFile).Replace('\\', Path.DirectorySeparatorChar); var manifest = JObject.Parse(File.ReadAllText(manifestFilePath)); var projectTemplates = manifest["projectTemplates"].Children <JProperty>(); var templates = projectTemplates.Select(c => new Template { Name = c.Value["title"].ToString(), Package = templatePackage, Files = package.Library.Files .Where(f => f.StartsWith("templates\\" + c.Name + "\\")) .Select(f => new TemplateFile { SourcePath = Path.Combine(package.Path, f).Replace('\\', Path.DirectorySeparatorChar), DestPath = f.Substring(("templates\\" + c.Name + "\\files\\").Length) }) .ToList(), Path = c.Name }); templatePackage.Templates = templates.ToList(); yield return(templatePackage); } } }
public ProjectInfo(ProjectContext context, string configuration, IEnumerable <string> currentSearchPaths) { var allExports = context.CreateExporter(configuration).GetAllExports().ToList(); var allDiagnostics = context.LibraryManager.GetAllDiagnostics(); Context = context; Configuration = configuration; var allSourceFiles = new List <string>(context.ProjectFile.Files.SourceFiles); var allFileReferences = new List <string>(); foreach (var export in allExports) { allSourceFiles.AddRange(export.SourceReferences); allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath)); } SourceFiles = allSourceFiles.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); CompilationAssembiles = allFileReferences.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); var allProjectReferences = new List <ProjectReferenceDescription>(); var allDependencyDiagnostics = new List <DiagnosticMessage>(); allDependencyDiagnostics.AddRange(context.LibraryManager.GetAllDiagnostics()); allDependencyDiagnostics.AddRange(DependencyTypeChangeFinder.Diagnose(Context, currentSearchPaths)); var diagnosticsLookup = allDependencyDiagnostics.ToLookup(d => d.Source); Dependencies = new Dictionary <string, DependencyDescription>(); foreach (var library in context.LibraryManager.GetLibraries()) { var diagnostics = diagnosticsLookup[library].ToList(); var description = DependencyDescription.Create(library, diagnostics); Dependencies[description.Name] = description; if (library is ProjectDescription && library.Identity.Name != context.ProjectFile.Name) { allProjectReferences.Add(ProjectReferenceDescription.Create((ProjectDescription)library)); } } DependencyDiagnostics = allDependencyDiagnostics; ProjectReferences = allProjectReferences.OrderBy(reference => reference.Name).ToList(); }
public static ProjectContextSnapshot Create(ProjectContext context, string configuration, IEnumerable<string> currentSearchPaths) { var snapshot = new ProjectContextSnapshot(); var allDependencyDiagnostics = new List<DiagnosticMessage>(); allDependencyDiagnostics.AddRange(context.LibraryManager.GetAllDiagnostics()); allDependencyDiagnostics.AddRange(DependencyTypeChangeFinder.Diagnose(context, currentSearchPaths)); var diagnosticsLookup = allDependencyDiagnostics.ToLookup(d => d.Source); var allSourceFiles = new List<string>(context.ProjectFile.Files.SourceFiles); var allFileReferences = new List<string>(); var allProjectReferences = new List<ProjectReferenceDescription>(); var allDependencies = new Dictionary<string, DependencyDescription>(); foreach (var export in context.CreateExporter(configuration).GetDependencies()) { allSourceFiles.AddRange(export.SourceReferences); allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath)); var library = export.Library; var diagnostics = diagnosticsLookup[library].ToList(); var description = DependencyDescription.Create(library, diagnostics); allDependencies[description.Name] = description; var projectDescription = library as ProjectDescription; if (projectDescription != null) { allProjectReferences.Add(ProjectReferenceDescription.Create(projectDescription)); } } snapshot.RootDependency = context.ProjectFile.Name; snapshot.TargetFramework = context.TargetFramework; snapshot.SourceFiles = allSourceFiles.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); snapshot.CompilerOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration); snapshot.ProjectReferences = allProjectReferences.OrderBy(reference => reference.Name).ToList(); snapshot.FileReferences = allFileReferences.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); snapshot.DependencyDiagnostics = allDependencyDiagnostics; snapshot.Dependencies = allDependencies; return snapshot; }