public void Populate(SearchResult result) { if (result == null) { return; } if (result.MatchedByType && result.WordsInFields.Count == 0) { Highlights.Add(new HighlightedText { Text = OriginalType }); Highlights.Add(" " + TextUtilities.ShortenValue(result.Node.ToString(), "...")); AddDuration(result); return; } Highlights.Add(OriginalType); foreach (var wordsInField in result.WordsInFields.GroupBy(t => t.field, t => t.match)) { Highlights.Add(" "); var fieldText = wordsInField.Key; //NameValueNode is speial case: have to show name=value when seached only in one (name or value) var named = SearchResult.Node as NameValueNode; if (named != null && wordsInField.Key.Equals(named.Value)) { Highlights.Add(named.Name + " = "); } fieldText = TextUtilities.ShortenValue(fieldText, "..."); var highlightSpans = TextUtilities.GetHighlightedSpansInText(fieldText, wordsInField); int index = 0; foreach (var span in highlightSpans) { if (span.Start > index) { Highlights.Add(fieldText.Substring(index, span.Start - index)); } Highlights.Add(new HighlightedText { Text = fieldText.Substring(span.Start, span.Length) }); index = span.End; } if (index < fieldText.Length) { Highlights.Add(fieldText.Substring(index, fieldText.Length - index)); } //NameValueNode is speial case: have to show name=value when seached only in one (name or value) if (named != null && wordsInField.Key.Equals(named.Name)) { Highlights.Add(" = " + TextUtilities.ShortenValue(named.Value, "...")); } } AddDuration(result); }
/// <summary> /// Try to update the project data given a project started event. This is useful if the project /// was created (e.g. as a parent) before we saw the started event. /// <remarks>Does nothing if the data has already been set or the new data is null.</remarks> /// </summary> /// <param name="args">The <see cref="ProjectStartedEventArgs"/> instance containing the event data.</param> public void UpdateProject(Project project, ProjectStartedEventArgs args) { if (project.Name == null && args != null) { project.StartTime = args.Timestamp; project.Name = Intern(Path.GetFileName(args.ProjectFile)); project.ProjectFile = Intern(args.ProjectFile); project.EntryTargets = string.IsNullOrWhiteSpace(args.TargetNames) ? ImmutableArray <string> .Empty : stringTable.InternList(TextUtilities.SplitSemicolonDelimitedList(args.TargetNames)); project.TargetsText = args.TargetNames; var evaluationId = BuildEventContext.InvalidEvaluationId; if (args.BuildEventContext.EvaluationId > BuildEventContext.InvalidEvaluationId) { evaluationId = args.BuildEventContext.EvaluationId; } else if (args.ParentProjectBuildEventContext != null && args.ParentProjectBuildEventContext.EvaluationId > BuildEventContext.InvalidEvaluationId) { evaluationId = args.ParentProjectBuildEventContext.EvaluationId; } project.EvaluationId = evaluationId; if (evaluationId != BuildEventContext.InvalidEvaluationId) { project.EvaluationText = Intern("id:" + evaluationId); } project.GlobalProperties = stringTable.InternStringDictionary(args.GlobalProperties) ?? ImmutableDictionary <string, string> .Empty; if (args.GlobalProperties != null) { AddGlobalProperties(project); } if (!string.IsNullOrEmpty(args.TargetNames)) { AddEntryTargets(project); } if (args.Properties != null) { var properties = project.GetOrCreateNodeWithName <Folder>(Strings.Properties); AddProperties( properties, args .Properties .Cast <DictionaryEntry>() .OrderBy(d => d.Key) .Select(d => new KeyValuePair <string, string>( Intern(Convert.ToString(d.Key)), Intern(Convert.ToString(d.Value)))), project); } if (args.Items != null) { RetrieveProjectInstance(project, args); var items = project.GetOrCreateNodeWithName <Folder>("Items"); foreach (DictionaryEntry kvp in args.Items.OfType <DictionaryEntry>().OrderBy(i => i.Key)) { var itemName = Intern(Convert.ToString(kvp.Key)); var itemGroup = items.GetOrCreateNodeWithName <Folder>(itemName); var item = new Item(); var taskItem = kvp.Value as ITaskItem; if (taskItem != null) { item.Text = Intern(taskItem.ItemSpec); foreach (DictionaryEntry metadataName in taskItem.CloneCustomMetadata()) { item.AddChild(new Metadata { Name = Intern(Convert.ToString(metadataName.Key)), Value = Intern(Convert.ToString(metadataName.Value)) }); } itemGroup.AddChild(item); } } } } }
public void Populate(SearchResult result) { if (result == null) { return; } var node = result.Node; if (result.WordsInFields.Count == 0) { if (result.MatchedByType) { Highlights.Add(new HighlightedText { Text = OriginalType }); } Highlights.Add((Highlights.Count > 0 ? " " : "") + TextUtilities.ShortenValue(GetNodeText(node), "...")); AddDuration(result); return; } if (OriginalType != Strings.Folder) { Highlights.Add(OriginalType); } // NameValueNode is special case: have to show name=value when searched only in one (name or value) var nameValueNode = node as NameValueNode; var namedNode = node as NamedNode; bool nameFound = false; bool valueFound = false; bool namedNodeNameFound = false; foreach (var fieldText in result.WordsInFields) { if (nameValueNode != null) { if (!nameFound && fieldText.field.Equals(nameValueNode.Name)) { nameFound = true; } if (!valueFound && fieldText.field.Equals(nameValueNode.Value)) { valueFound = true; } } else if (namedNode != null && !namedNodeNameFound) { if (fieldText.field.Equals(namedNode.Name)) { namedNodeNameFound = true; } } } if (namedNode != null && !namedNodeNameFound) { Highlights.Add((Highlights.Count > 0 ? " " : "") + namedNode.Name); if (GetNodeDifferentiator(node) is object differentiator) { Highlights.Add(differentiator); } } foreach (var wordsInField in result.WordsInFields.GroupBy(t => t.field, t => t.match)) { var fieldText = wordsInField.Key; if (fieldText == OriginalType) { // OriginalType already added above continue; } if (Highlights.Count > 0) { Highlights.Add(" "); } if (nameValueNode != null && fieldText.Equals(nameValueNode.Value) && !nameFound) { Highlights.Add(nameValueNode.Name + " = "); } fieldText = TextUtilities.ShortenValue(fieldText, "..."); var highlightSpans = TextUtilities.GetHighlightedSpansInText(fieldText, wordsInField); int index = 0; foreach (var span in highlightSpans) { if (span.Start > index) { Highlights.Add(fieldText.Substring(index, span.Start - index)); } Highlights.Add(new HighlightedText { Text = fieldText.Substring(span.Start, span.Length) }); index = span.End; } if (index < fieldText.Length) { Highlights.Add(fieldText.Substring(index, fieldText.Length - index)); } if (nameValueNode != null && wordsInField.Key.Equals(nameValueNode.Name)) { if (!valueFound) { Highlights.Add(" = " + TextUtilities.ShortenValue(nameValueNode.Value, "...")); } else { Highlights.Add(" = "); } } if (namedNode != null && namedNode.Name == wordsInField.Key) { if (GetNodeDifferentiator(node) is object differentiator) { Highlights.Add(differentiator); } } } AddDuration(result); }
public override string ToString() { var sb = new StringBuilder(); sb.Append($"Project Name={Name} File={ProjectFile}"); if (EntryTargets != null && EntryTargets.Any()) { sb.Append($" Targets=[{string.Join(", ", EntryTargets)}]"); } if (GlobalProperties != null) { sb.Append($" GlobalProperties=[{string.Join(", ", GlobalProperties.Select(kvp => $"{kvp.Key}={TextUtilities.ShortenValue(kvp.Value, "...", maxChars: 150)}"))}]"); } return(sb.ToString()); }
public static void HandleThereWasAConflict(Parameter parameter, string message, StringCache stringTable) { var numberOfLeadingSpaces = TextUtilities.GetNumberOfLeadingSpaces(message); TreeNode node = parameter; switch (numberOfLeadingSpaces) { case 0: parameter.AddChild(new Item() { Text = stringTable.Intern(message) }); break; case 4: node = parameter.LastChild as TreeNode ?? node; Add(node, message, 4); break; case 6: { if (parameter.LastChild is TreeNode item) { node = item; if (item.LastChild is TreeNode item2) { node = item2; } } Add(node, message, 6); } break; case 8: { if (parameter.LastChild is TreeNode item) { node = item; if (item.LastChild is TreeNode item2) { node = item2; if (item2.LastChild is TreeNode item3) { node = item3; } } } Add(node, message, 8); } break; default: Add(node, message, 0); break; } void Add(TreeNode parent, string text, int spaces) { text = text.Substring(spaces); parent.AddChild(new Item { Text = stringTable.Intern(text) }); } }
/// <summary> /// Handles a generic BuildMessage event and assigns it to the appropriate logging node. /// </summary> /// <param name="args">The <see cref="BuildMessageEventArgs"/> instance containing the event data.</param> public void AddMessage(LazyFormattedBuildEventArgs args, string message) { message = Intern(message); TreeNode node = null; var messageNode = new Message { Text = message, Timestamp = args.Timestamp }; BaseNode nodeToAdd = messageNode; var buildEventContext = args.BuildEventContext; if (buildEventContext?.TaskId > 0) { node = GetTask(args); if (node is Task task) { if (task.Name == "ResolveAssemblyReference") { Folder inputs = task.FindChild <Folder>(Strings.Inputs); Folder results = task.FindChild <Folder>(Strings.Results); node = results ?? inputs; if (message.StartsWith(" ", StringComparison.Ordinal)) { message = message.Substring(4); var parameter = node?.FindLastChild <Parameter>(); if (parameter != null) { bool thereWasAConflict = Strings.IsThereWasAConflictPrefix(parameter.ToString()); //parameter.ToString().StartsWith(Strings.ThereWasAConflictPrefix); if (thereWasAConflict) { HandleThereWasAConflict(parameter, message, stringTable); return; } if (!string.IsNullOrWhiteSpace(message)) { node = parameter; if (message.StartsWith(" ", StringComparison.Ordinal)) { message = message.Substring(4); var lastItem = parameter.FindLastChild <Item>(); // only indent if it's not a "For SearchPath..." message - that one needs to be directly under parameter // also don't indent if it's under AssemblyFoldersEx in Results if (lastItem != null && !Strings.ForSearchPathPrefix.IsMatch(message) && !parameter.Name.StartsWith("AssemblyFoldersEx", StringComparison.Ordinal)) { node = lastItem; } } if (!string.IsNullOrEmpty(message)) { var equals = message.IndexOf('='); if (equals != -1) { var kvp = TextUtilities.ParseNameValue(message); node.AddChild(new Metadata { Name = Intern(kvp.Key.TrimEnd(space)), Value = Intern(kvp.Value.TrimStart(space)) }); } else { node.AddChild(new Item() { Text = Intern(message) }); } } } return; } } else { if (results == null) { bool isResult = Strings.UnifiedPrimaryReferencePrefix.IsMatch(message) || Strings.PrimaryReferencePrefix.IsMatch(message) || Strings.DependencyPrefix.IsMatch(message) || Strings.UnifiedDependencyPrefix.IsMatch(message) || Strings.AssemblyFoldersExLocation.IsMatch(message) || Strings.IsThereWasAConflictPrefix(message); if (isResult) { results = task.GetOrCreateNodeWithName <Folder>(Strings.Results); node = results; } else { if (inputs == null) { inputs = task.GetOrCreateNodeWithName <Folder>(Strings.Inputs); } node = inputs; } } else { node = results; } node.GetOrCreateNodeWithName <Parameter>(Intern(message.TrimEnd(':'))); return; } } else if (string.Equals(task.Name, "MSBuild", StringComparison.OrdinalIgnoreCase)) { var additionalPropertiesMatch = Strings.AdditionalPropertiesPrefix.Match(message); if (message.StartsWith(Strings.GlobalPropertiesPrefix, StringComparison.Ordinal) || additionalPropertiesMatch.Success || Strings.OverridingGlobalPropertiesPrefix.IsMatch(message) || message.StartsWith(Strings.RemovingPropertiesPrefix, StringComparison.Ordinal) || Strings.RemovingProjectProperties.IsMatch(message)) { if (additionalPropertiesMatch.Success) { node = node.GetOrCreateNodeWithName <Folder>(Strings.AdditionalProperties); } node.GetOrCreateNodeWithName <Folder>(message); return; } node = node.FindLastChild <Folder>() ?? node; if (message.Length > 2 && message[0] == ' ' && message[1] == ' ') { if (node is Folder f && f.Name == Strings.AdditionalProperties) { node = f.FindLastChild <Folder>() ?? node; } message = message.Substring(2); } var kvp = TextUtilities.ParseNameValue(message); if (kvp.Value == "") { nodeToAdd = new Item { Text = Intern(kvp.Key) }; } else { nodeToAdd = new Property { Name = Intern(kvp.Key), Value = Intern(kvp.Value) }; } } else if (string.Equals(task.Name, "RestoreTask")) { // just throw these away to save space // https://github.com/NuGet/Home/issues/10383 if (message.StartsWith(Strings.RestoreTask_CheckingCompatibilityFor, StringComparison.Ordinal)) { return; } else if (message.StartsWith(" GET", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("GET"); } else if (message.StartsWith(" CACHE", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("CACHE"); } else if (message.StartsWith(" OK", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("OK"); } else if (message.StartsWith(" NotFound", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("NotFound"); } else if (message.StartsWith("PackageSignatureVerificationLog:", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("PackageSignatureVerificationLog"); } else if (message.StartsWith("Writing assets file to disk", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("Assets file"); } else if (message.StartsWith("Writing cache file to disk", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("Cache file"); } else if (message.StartsWith("Persisting dg to", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("dg file"); } else if (message.StartsWith("Generating MSBuild file", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("MSBuild file"); } else if (message.StartsWith("Lock not required", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("Lock not required"); } else if (message.StartsWith("Installing", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("Installing"); } else if (message.StartsWith("Restoring packages for", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("Restoring packages for"); } else if (message.StartsWith("Reading project file", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("Reading project file"); } else if (message.StartsWith("Scanning packages for", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("Scanning packages for"); } else if (message.StartsWith("Merging in runtimes", StringComparison.Ordinal)) { node = node.GetOrCreateNodeWithName <Folder>("Merging in runtimes"); } else if ( message.StartsWith(Strings.RestoreTask_CheckingCompatibilityFor, StringComparison.Ordinal) || message.StartsWith(Strings.RestoreTask_CheckingCompatibilityOfPackages, StringComparison.Ordinal) || message.StartsWith(Strings.RestoreTask_AcquiringLockForTheInstallation, StringComparison.Ordinal) || message.StartsWith(Strings.RestoreTask_AcquiredLockForTheInstallation, StringComparison.Ordinal) || message.StartsWith(Strings.RestoreTask_CompletedInstallationOf, StringComparison.Ordinal) || message.StartsWith(Strings.RestoreTask_ResolvingConflictsFor, StringComparison.Ordinal) || message.StartsWith(Strings.RestoreTask_AllPackagesAndProjectsAreCompatible, StringComparison.Ordinal) || message.StartsWith(Strings.RestoreTask_Committing, StringComparison.Ordinal) ) { return; } } } } else if (buildEventContext?.TargetId > 0) { node = GetTarget(args); if (Strings.TaskSkippedFalseCondition.Match(message).Success) { messageNode.IsLowRelevance = true; } } else if (buildEventContext?.ProjectContextId > 0) { var project = construction.GetOrAddProject(buildEventContext.ProjectContextId); node = project; if (Strings.IsTargetSkipped(message)) { var targetName = Intern(TextUtilities.ParseQuotedSubstring(message)); if (targetName != null) { var skippedTarget = project.GetOrAddTargetByName(targetName, args.Timestamp); skippedTarget.StartTime = args.Timestamp; skippedTarget.EndTime = args.Timestamp; node = skippedTarget; messageNode.IsLowRelevance = true; } } } else if (buildEventContext.EvaluationId != -1) { node = construction.EvaluationFolder; var evaluationId = buildEventContext.EvaluationId; var evaluation = construction.Build.FindEvaluation(evaluationId); if (evaluation != null) { node = evaluation; } if (Strings.PropertyReassignmentRegex.IsMatch(message)) { TimedNode properties; if (evaluation != null) { properties = evaluation.PropertyReassignmentFolder; } else { properties = node.GetOrCreateNodeWithName <TimedNode>(Strings.PropertyReassignmentFolder, addAtBeginning: true); } var propertyName = Strings.GetPropertyName(message); node = properties.GetOrCreateNodeWithName <Folder>(propertyName); } if (node != null && node.FindChild <Message>(message) != null) { // avoid duplicate messages return; } } if (node == null) { node = construction.Build; if (Strings.IsEvaluationMessage(message)) { if (!evaluationMessagesAlreadySeen.Add(message)) { return; } node = construction.EvaluationFolder; } else if (Strings.PropertyReassignmentRegex.IsMatch(message)) { if (!evaluationMessagesAlreadySeen.Add(message)) { return; } var properties = construction.EvaluationFolder.GetOrCreateNodeWithName <Folder>(Strings.PropertyReassignmentFolder); node = properties.GetOrCreateNodeWithName <Folder>(Strings.GetPropertyName(message)); } else if (Strings.IsTargetDoesNotExistAndWillBeSkipped(message)) { var folder = construction.EvaluationFolder; node = folder; messageNode.IsLowRelevance = true; } else if (buildEventContext != null && (buildEventContext.NodeId == 0 && buildEventContext.ProjectContextId == 0 && buildEventContext.ProjectInstanceId == 0 && buildEventContext.TargetId == 0 && buildEventContext.TaskId == 0)) { // must be Detailed Build Summary // https://github.com/Microsoft/msbuild/blob/master/src/XMakeBuildEngine/BackEnd/Components/Scheduler/Scheduler.cs#L509 DetailedSummary.AppendLine(message); return; } } node.AddChild(nodeToAdd); }
/// <summary> /// Handles a generic BuildMessage event and assigns it to the appropriate logging node. /// </summary> /// <param name="args">The <see cref="BuildMessageEventArgs"/> instance containing the event data.</param> public void AddMessage(LazyFormattedBuildEventArgs args, string message) { message = stringTable.Intern(message); TreeNode node = null; var messageNode = new Message { Text = message, Timestamp = args.Timestamp }; object nodeToAdd = messageNode; if (args.BuildEventContext?.TaskId > 0) { node = construction .GetOrAddProject(args.BuildEventContext.ProjectContextId) .GetTargetById(args.BuildEventContext.TargetId) .GetTaskById(args.BuildEventContext.TaskId); var task = node as Task; if (task != null) { if (task.Name == "ResolveAssemblyReference") { Folder inputs = task.GetOrCreateNodeWithName <Folder>("Inputs"); Folder results = task.FindChild <Folder>("Results"); node = results ?? inputs; if (message.StartsWith(" ")) { message = message.Substring(4); var parameter = node.FindLastChild <Parameter>(); if (parameter != null) { bool thereWasAConflict = parameter.ToString().StartsWith(Strings.ThereWasAConflictPrefix); if (thereWasAConflict) { HandleThereWasAConflict(parameter, message, stringTable); return; } if (!string.IsNullOrWhiteSpace(message)) { node = parameter; if (message.StartsWith(" ")) { message = message.Substring(4); var lastItem = parameter.FindLastChild <Item>(); // only indent if it's not a "For SearchPath..." message - that one needs to be directly under parameter // also don't indent if it's under AssemblyFoldersEx in Results if (lastItem != null && !message.StartsWith(Strings.ForSearchPathPrefix) && !parameter.Name.StartsWith("AssemblyFoldersEx")) { node = lastItem; } } if (!string.IsNullOrEmpty(message)) { var equals = message.IndexOf('='); if (equals != -1) { var kvp = TextUtilities.ParseNameValue(message); node.AddChild(new Metadata { Name = stringTable.Intern(kvp.Key.TrimEnd(space)), Value = stringTable.Intern(kvp.Value.TrimStart(space)) }); } else { node.AddChild(new Item() { Text = stringTable.Intern(message) }); } } } return; } } else { if (results == null) { bool isResult = message.StartsWith(Strings.UnifiedPrimaryReferencePrefix) || message.StartsWith(Strings.PrimaryReferencePrefix) || message.StartsWith(Strings.DependencyPrefix) || message.StartsWith(Strings.UnifiedDependencyPrefix) || message.StartsWith(Strings.AssemblyFoldersExLocation) || message.StartsWith(Strings.ThereWasAConflictPrefix); if (isResult) { results = task.GetOrCreateNodeWithName <Folder>("Results"); node = results; } else { node = inputs; } } else { node = results; } node.GetOrCreateNodeWithName <Parameter>(stringTable.Intern(message.TrimEnd(':'))); return; } } else if (task.Name == "MSBuild") { if (message.StartsWith(Strings.GlobalPropertiesPrefix) || message.StartsWith(Strings.AdditionalPropertiesPrefix) || message.StartsWith(Strings.OverridingGlobalPropertiesPrefix) || message.StartsWith(Strings.RemovingPropertiesPrefix)) { node.GetOrCreateNodeWithName <Folder>(message); return; } node = node.FindLastChild <Folder>(); if (message[0] == ' ' && message[1] == ' ') { message = message.Substring(2); } var kvp = TextUtilities.ParseNameValue(message); if (kvp.Value == "") { nodeToAdd = new Item { Text = stringTable.Intern(kvp.Key) }; } else { nodeToAdd = new Property { Name = stringTable.Intern(kvp.Key), Value = stringTable.Intern(kvp.Value) }; } } } } else if (args.BuildEventContext?.TargetId > 0) { node = construction .GetOrAddProject(args.BuildEventContext.ProjectContextId) .GetTargetById(args.BuildEventContext.TargetId); if (Strings.IsTaskSkipped(message)) { messageNode.IsLowRelevance = true; } } else if (args.BuildEventContext?.ProjectContextId > 0) { var project = construction.GetOrAddProject(args.BuildEventContext.ProjectContextId); node = project; if (Strings.IsTargetSkipped(message)) { var targetName = stringTable.Intern(TextUtilities.ParseQuotedSubstring(message)); if (targetName != null) { node = project.GetOrAddTargetByName(targetName); messageNode.IsLowRelevance = true; } } } else if (Reflector.GetEvaluationId(args.BuildEventContext) is int evaluationId && evaluationId != -1) { var evaluation = construction.EvaluationFolder; var project = evaluation.FindChild <Project>(p => p.Id == evaluationId); node = project; if (node != null && node.FindChild <Message>(message) != null) { // avoid duplicate messages return; } } if (node == null) { node = construction.Build; if (Strings.IsEvaluationMessage(message)) { if (!evaluationMessagesAlreadySeen.Add(message)) { return; } node = construction.EvaluationFolder; } else if (Strings.IsTargetDoesNotExistAndWillBeSkipped(message)) { var folder = construction.EvaluationFolder; node = folder; messageNode.IsLowRelevance = true; } else if (args.BuildEventContext != null && (args.BuildEventContext.NodeId == 0 && args.BuildEventContext.ProjectContextId == 0 && args.BuildEventContext.ProjectInstanceId == 0 && args.BuildEventContext.TargetId == 0 && args.BuildEventContext.TaskId == 0)) { // must be Detailed Build Summary // https://github.com/Microsoft/msbuild/blob/master/src/XMakeBuildEngine/BackEnd/Components/Scheduler/Scheduler.cs#L509 DetailedSummary.AppendLine(message); return; } } node.AddChild(nodeToAdd); }