Skip to content

Commit 8a4cdec

Browse files
committed
Target graph search improvements
1 parent f8189ec commit 8a4cdec

File tree

2 files changed

+115
-31
lines changed

2 files changed

+115
-31
lines changed

src/StructuredLogViewer/Controls/BuildControl.xaml.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,6 +2413,8 @@ private bool Invoke(BaseNode treeNode)
24132413
}
24142414

24152415
break;
2416+
case Target target when target.Parent is Folder:
2417+
return SearchForTarget(target.Name);
24162418
case Target target:
24172419
return DisplayTarget(target.SourceFilePath, target.Name);
24182420
case Task task:
@@ -2520,6 +2522,21 @@ private bool SearchForProject(string name)
25202522
return true;
25212523
}
25222524

2525+
private bool SearchForTarget(string name)
2526+
{
2527+
string text = searchLogControl.SearchText;
2528+
var matcher = new NodeQueryMatcher(text);
2529+
string project = "";
2530+
if (matcher.ProjectMatchers.Count == 1)
2531+
{
2532+
project = matcher.ProjectMatchers[0].Query;
2533+
}
2534+
2535+
text = $"$target \"{name}\" project({project})";
2536+
searchLogControl.SearchText = text;
2537+
return true;
2538+
}
2539+
25232540
private bool DisplayEmbeddedFile(Item item)
25242541
{
25252542
string path = item.Text;

src/StructuredLogger/Analyzers/TargetGraph.cs

Lines changed: 98 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ private TargetGraph TryGetTargetGraph(ProjectEvaluation evaluation)
3434

3535
public TargetGraph GetTargetGraph(ProjectEvaluation evaluation)
3636
{
37+
if (evaluation == null)
38+
{
39+
return null;
40+
}
41+
3742
if (TryGetTargetGraph(evaluation) is TargetGraph graph)
3843
{
3944
return graph;
@@ -59,23 +64,49 @@ bool ISearchExtension.TryGetResults(NodeQueryMatcher matcher, IList<SearchResult
5964
return false;
6065
}
6166

62-
if (resultCollector.Count != 1 || resultCollector[0].Node is not Target target)
67+
string targetName = null;
68+
ProjectEvaluation evaluation = null;
69+
TargetGraph graph = null;
70+
71+
if (resultCollector.Count == 0)
6372
{
64-
return false;
65-
}
73+
var projectMatcher = matcher.ProjectMatchers.FirstOrDefault();
74+
if (projectMatcher == null)
75+
{
76+
return false;
77+
}
6678

67-
if (target.Project == null || target.Project.GetEvaluation(this.Build) is not ProjectEvaluation evaluation)
79+
var allEvaluations = Build.EvaluationFolder?.Children.OfType<ProjectEvaluation>();
80+
var matchingProjects = allEvaluations
81+
.Where(e => projectMatcher.IsMatch(e.Name) is { } match && match != SearchResult.EmptyQueryMatch)
82+
.ToArray();
83+
if (matchingProjects.Select(e => e.SourceFilePath).Distinct(StringComparer.OrdinalIgnoreCase).Count() != 1)
84+
{
85+
return false;
86+
}
87+
88+
evaluation = matchingProjects.LastOrDefault();
89+
graph = GetTargetGraph(evaluation);
90+
targetName = graph.GetTarget(matcher.Terms[0].Word).Name;
91+
}
92+
else if (resultCollector.Count == 1 && resultCollector[0].Node is Target target)
6893
{
69-
return false;
94+
if (target.Project == null)
95+
{
96+
return false;
97+
}
98+
99+
evaluation = target.Project.GetEvaluation(Build);
100+
graph = GetTargetGraph(evaluation);
101+
targetName = target.Name;
70102
}
71103

72-
var graph = GetTargetGraph(evaluation);
73-
if (graph == null)
104+
if (targetName == null || evaluation == null || graph == null)
74105
{
75106
return false;
76107
}
77108

78-
var node = graph.GetTarget(target.Name);
109+
var node = graph.GetTarget(targetName);
79110
if (node == null)
80111
{
81112
return false;
@@ -85,32 +116,58 @@ bool ISearchExtension.TryGetResults(NodeQueryMatcher matcher, IList<SearchResult
85116
var depends = graph.AllTargets.Where(t => t.DependsOnTargets.Contains(node)).ToArray();
86117
var after = graph.AllTargets.Where(t => t.AfterTargets.Contains(node)).ToArray();
87118

88-
if (before.Length == 0 && depends.Length == 0 && after.Length == 0)
119+
if (before.Length == 0 &&
120+
depends.Length == 0 &&
121+
after.Length == 0 &&
122+
node.BeforeTargets.Count == 0 &&
123+
node.DependsOnTargets.Count == 0 &&
124+
node.AfterTargets.Count == 0)
89125
{
90126
return false;
91127
}
92128

93-
var graphFolder = new Folder { Name = "Target Graph" };
129+
var graphFolder = new Folder { Name = "Target Graph", IsExpanded = true };
94130

95131
if (before.Length > 0)
96132
{
97-
var beforeFolder = new Folder { Name = "BeforeTargets" };
98-
Add(beforeFolder, before);
99-
graphFolder.AddChild(beforeFolder);
133+
var folder = new Folder { Name = $"BeforeTargets" };
134+
Add(folder, before);
135+
graphFolder.AddChild(folder);
100136
}
101137

102-
if (depends.Length > 0)
138+
if (after.Length > 0)
103139
{
104-
var dependsFolder = new Folder { Name = $"Targets that depend on {target.Name}" };
105-
Add(dependsFolder, depends);
106-
graphFolder.AddChild(dependsFolder);
140+
var folder = new Folder { Name = $"AfterTargets" };
141+
Add(folder, after);
142+
graphFolder.AddChild(folder);
107143
}
108144

109-
if (after.Length > 0)
145+
if (node.DependsOnTargets.Count > 0)
146+
{
147+
var folder = new Folder { Name = "DependsOnTargets" };
148+
Add(folder, node.DependsOnTargets);
149+
graphFolder.AddChild(folder);
150+
}
151+
152+
if (node.BeforeTargets.Count > 0)
153+
{
154+
var folder = new Folder { Name = $"Targets that run before {targetName}" };
155+
Add(folder, node.BeforeTargets);
156+
graphFolder.AddChild(folder);
157+
}
158+
159+
if (node.AfterTargets.Count > 0)
110160
{
111-
var afterFolder = new Folder { Name = "AfterTargets" };
112-
Add(afterFolder, after);
113-
graphFolder.AddChild(afterFolder);
161+
var folder = new Folder { Name = $"Targets that run after {targetName}" };
162+
Add(folder, node.AfterTargets);
163+
graphFolder.AddChild(folder);
164+
}
165+
166+
if (depends.Length > 0)
167+
{
168+
var folder = new Folder { Name = $"Targets that depend on {targetName}" };
169+
Add(folder, depends);
170+
graphFolder.AddChild(folder);
114171
}
115172

116173
resultCollector.Add(new SearchResult(graphFolder));
@@ -196,36 +253,42 @@ public static TargetGraph ParseXml(string text, Dictionary<string, string> props
196253
var afterTargets = Expand(afterTargetsText, props);
197254
var dependsOnTargets = Expand(dependsOnTargetsText, props);
198255

199-
var node = result.GetTarget(name);
256+
var node = result.GetOrCreateTarget(name);
200257

201258
foreach (var before in beforeTargets)
202259
{
203-
var dest = result.GetTarget(before);
260+
var dest = result.GetOrCreateTarget(before);
204261
dest.BeforeTargets.Insert(0, node);
205262
}
206263

207264
foreach (var after in afterTargets)
208265
{
209-
var dest = result.GetTarget(after);
266+
var dest = result.GetOrCreateTarget(after);
210267
dest.AfterTargets.Insert(0, node);
211268
}
212269

213270
foreach (var dep in dependsOnTargets)
214271
{
215-
var dest = result.GetTarget(dep);
272+
var dest = result.GetOrCreateTarget(dep);
216273
node.DependsOnTargets.Add(dest);
217274
}
218275
}
219276

220277
return result;
221278
}
222279

223-
public TargetNode GetTarget(string text)
280+
public TargetNode GetTarget(string name)
224281
{
225-
if (!targetNodes.TryGetValue(text, out var node))
282+
targetNodes.TryGetValue(name, out var result);
283+
return result;
284+
}
285+
286+
public TargetNode GetOrCreateTarget(string name)
287+
{
288+
if (!targetNodes.TryGetValue(name, out var node))
226289
{
227-
node = new TargetNode { Name = text };
228-
targetNodes.Add(text, node);
290+
node = new TargetNode { Name = name };
291+
targetNodes.Add(name, node);
229292
}
230293

231294
return node;
@@ -246,7 +309,11 @@ private static string[] Expand(string expression, Dictionary<string, string> pro
246309
}
247310
}
248311

249-
return expression.Split([';'], StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray();
312+
return
313+
expression.Split([';'], StringSplitOptions.RemoveEmptyEntries)
314+
.Select(s => s.Trim('\r', '\n', ' ', '\t'))
315+
.Where(s => !string.IsNullOrWhiteSpace(s))
316+
.ToArray();
250317
}
251318

252319
private static string GetAttribute(XElement element, string attributeName)
@@ -261,7 +328,7 @@ private static string GetAttribute(XElement element, string attributeName)
261328
var visited = new HashSet<TargetNode>();
262329
var stack = new Stack<(string targetName, string relationship)>();
263330

264-
VisitTargets(entryTargets.Select(GetTarget), stack, visited, target =>
331+
VisitTargets(entryTargets.Select(GetOrCreateTarget), stack, visited, target =>
265332
{
266333
if (string.Equals(target.Name, targetToFind, StringComparison.OrdinalIgnoreCase))
267334
{

0 commit comments

Comments
 (0)