forked from dotnet/sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProjectGraphUtilities.cs
More file actions
147 lines (114 loc) · 7.04 KB
/
Copy pathProjectGraphUtilities.cs
File metadata and controls
147 lines (114 loc) · 7.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.Versioning;
using Microsoft.Build.Execution;
using Microsoft.Build.Graph;
using Microsoft.DotNet.HotReload;
namespace Microsoft.DotNet.Watch;
internal static class ProjectGraphUtilities
{
extension(ProjectGraphNode projectNode)
{
public string GetDisplayName()
=> projectNode.ProjectInstance.GetDisplayName();
}
public static string GetDisplayName(this ProjectInstance project)
=> $"{Path.GetFileNameWithoutExtension(project.FullPath)} ({project.GetTargetFramework()})";
public static string GetTargetFramework(this ProjectInstance project)
=> project.GetPropertyValue(PropertyNames.TargetFramework);
public static IReadOnlyList<string> GetTargetFrameworks(this ProjectInstance project)
=> project.GetStringListPropertyValue(PropertyNames.TargetFrameworks);
public static Version? GetTargetFrameworkVersion(this ProjectGraphNode projectNode)
{
try
{
return new FrameworkName(projectNode.ProjectInstance.GetPropertyValue(PropertyNames.TargetFrameworkMoniker)).Version;
}
catch
{
return null;
}
}
public static IEnumerable<string> GetWebAssemblyCapabilities(this ProjectGraphNode projectNode)
=> projectNode.GetStringListPropertyValue(PropertyNames.WebAssemblyHotReloadCapabilities);
public static bool IsTargetFrameworkVersionOrNewer(this ProjectGraphNode projectNode, Version minVersion)
=> projectNode.GetTargetFrameworkVersion() is { } version && version >= minVersion;
public static bool IsNetCoreApp(string identifier)
=> string.Equals(identifier, ".NETCoreApp", StringComparison.OrdinalIgnoreCase);
public static bool IsNetCoreApp(this ProjectGraphNode projectNode)
=> IsNetCoreApp(projectNode.ProjectInstance.GetPropertyValue(PropertyNames.TargetFrameworkIdentifier));
public static bool IsNetCoreApp(this ProjectGraphNode projectNode, Version minVersion)
=> projectNode.IsNetCoreApp() && projectNode.IsTargetFrameworkVersionOrNewer(minVersion);
public static bool IsWebApp(this ProjectGraphNode projectNode)
=> projectNode.GetCapabilities().Any(static value => value is ProjectCapability.AspNetCore or ProjectCapability.WebAssembly);
public static string? GetOutputDirectory(this ProjectInstance project)
=> project.GetPropertyValue(PropertyNames.TargetPath) is { Length: >0 } path ? Path.GetDirectoryName(Path.Combine(project.Directory, path)) : null;
public static string GetAssemblyName(this ProjectInstance project)
=> project.GetPropertyValue(PropertyNames.TargetName);
public static string? GetIntermediateOutputDirectory(this ProjectInstance project)
=> project.GetPropertyValue(PropertyNames.IntermediateOutputPath) is { Length: >0 } path ? Path.Combine(project.Directory, path) : null;
public static IEnumerable<string> GetCapabilities(this ProjectGraphNode projectNode)
=> projectNode.ProjectInstance.GetItems(ItemNames.ProjectCapability).Select(item => item.EvaluatedInclude);
public static bool IsAutoRestartEnabled(this ProjectGraphNode projectNode)
=> projectNode.GetBooleanPropertyValue(PropertyNames.HotReloadAutoRestart);
public static bool AreDefaultItemsEnabled(this ProjectGraphNode projectNode)
=> projectNode.GetBooleanPropertyValue(PropertyNames.EnableDefaultItems);
public static IReadOnlyList<string> GetDefaultItemExcludes(this ProjectGraphNode projectNode)
=> projectNode.GetStringListPropertyValue(PropertyNames.DefaultItemExcludes);
public static IReadOnlyList<string> GetStringListPropertyValue(this ProjectGraphNode projectNode, string propertyName)
=> projectNode.ProjectInstance.GetStringListPropertyValue(propertyName);
public static IReadOnlyList<string> GetStringListPropertyValue(this ProjectInstance project, string propertyName)
=> project.GetPropertyValue(propertyName).Split(';', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
public static bool GetBooleanPropertyValue(this ProjectGraphNode projectNode, string propertyName, bool defaultValue = false)
=> GetBooleanPropertyValue(projectNode.ProjectInstance, propertyName, defaultValue);
public static bool GetBooleanPropertyValue(this ProjectInstance project, string propertyName, bool defaultValue = false)
=> project.GetPropertyValue(propertyName) is { Length: >0 } value ? bool.TryParse(value, out var result) && result : defaultValue;
public static bool GetBooleanMetadataValue(this ProjectItemInstance item, string metadataName, bool defaultValue = false)
=> item.GetMetadataValue(metadataName) is { Length: > 0 } value ? bool.TryParse(value, out var result) && result : defaultValue;
/// <summary>
/// Yields the project itself and all its ancestors, excluding outer build nodes.
/// </summary>
public static IEnumerable<ProjectGraphNode> GetAncestorsAndSelf(this ProjectGraphNode project)
=> GetAncestorsAndSelf([project]);
/// <summary>
/// Yields the given projects and all their ancestors, excluding outer build nodes.
/// </summary>
public static IEnumerable<ProjectGraphNode> GetAncestorsAndSelf(this IEnumerable<ProjectGraphNode> projects)
=> GetTransitiveProjects(projects, static project => project.ReferencingProjects);
/// <summary>
/// Yields the project itself and all transitively referenced projects, excluding outer build nodes.
/// </summary>
public static IEnumerable<ProjectGraphNode> GetDescendantsAndSelf(this ProjectGraphNode project)
=> GetDescendantsAndSelf([project]);
/// <summary>
/// Yields the given projects and all transitively referenced projects, excluding outer build nodes.
/// </summary>
public static IEnumerable<ProjectGraphNode> GetDescendantsAndSelf(this IEnumerable<ProjectGraphNode> projects)
=> GetTransitiveProjects(projects, static project => project.ProjectReferences);
private static IEnumerable<ProjectGraphNode> GetTransitiveProjects(IEnumerable<ProjectGraphNode> projects, Func<ProjectGraphNode, IEnumerable<ProjectGraphNode>> getEdges)
{
var visited = new HashSet<ProjectGraphNode>();
var queue = new Queue<ProjectGraphNode>();
foreach (var project in projects)
{
queue.Enqueue(project);
}
while (queue.Count > 0)
{
var project = queue.Dequeue();
if (visited.Add(project))
{
if (project.ProjectInstance.GetTargetFramework() != "")
{
yield return project;
}
foreach (var referencingProject in getEdges(project))
{
queue.Enqueue(referencingProject);
}
}
}
}
public static ProjectInstanceId GetId(this ProjectInstance project)
=> new(project.FullPath, project.GetTargetFramework());
}