private void PostAnalyzeBuild(Build build)
        {
            if (!build.Succeeded)
            {
                build.AddChild(new Error {
                    Text = "Build failed."
                });
            }
            else
            {
                build.AddChild(new Item {
                    Text = "Build succeeded."
                });
            }

            build.AddChild(new Property {
                Name = "Duration", Value = build.DurationText
            });

            doubleWritesAnalyzer.AppendDoubleWritesFolder(build);
            resolveAssemblyReferenceAnalyzer.AppendFinalReport(build);

            if (build.LogFilePath != null)
            {
                build.AddChildAtBeginning(new Item {
                    Text = build.LogFilePath
                });
            }

            var durations = taskDurations
                            .OrderByDescending(kvp => kvp.Value)
                            .Where(kvp => // no need to include MSBuild and CallTarget tasks as they are not "terminal leaf" tasks
                                   !string.Equals(kvp.Key, "MSBuild", StringComparison.OrdinalIgnoreCase) &&
                                   !string.Equals(kvp.Key, "CallTarget", StringComparison.OrdinalIgnoreCase))
                            .Take(10)
                            .ToArray();

            if (durations.Length > 0)
            {
                var top10Tasks = build.GetOrCreateNodeWithName <Folder>($"Top {durations.Count()} most expensive tasks");
                foreach (var kvp in durations)
                {
                    top10Tasks.AddChild(new Item {
                        Name = kvp.Key, Text = TextUtilities.DisplayDuration(kvp.Value)
                    });
                }
            }

            if (analyzerReports.Count > 0)
            {
                var analyzerReportSummary = build.GetOrCreateNodeWithName <Folder>($"Analyzer Summary");
                CscTaskAnalyzer.CreateMergedReport(analyzerReportSummary, analyzerReports.ToArray());
            }
        }
        public void BuildStarted(object sender, BuildStartedEventArgs args)
        {
            try
            {
                lock (syncLock)
                {
                    Build.StartTime = args.Timestamp;

                    Build.AddChild(new Property {
                        Name = "Process", Value = Process.GetCurrentProcess().MainModule.FileName
                    });

#if !NETCORE
                    Build.AddChild(new Property {
                        Name = "Command Line", Value = Environment.CommandLine
                    });
                    Build.AddChild(new Property {
                        Name = "Current Directory", Value = Environment.CurrentDirectory
                    });
#endif

                    var properties = Build.GetOrCreateNodeWithName <Folder>(Intern("Environment"));
                    AddProperties(properties, args.BuildEnvironment);
                }
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
        }
예제 #3
0
        private void PostAnalyzeBuild(Build build)
        {
            if (!build.Succeeded)
            {
                build.AddChild(new Error {
                    Text = "Build failed."
                });
            }
            else
            {
                build.AddChild(new Item {
                    Text = "Build succeeded."
                });
            }

            doubleWritesAnalyzer.AppendDoubleWritesFolder(build);
        }
예제 #4
0
        public static Build ReadBuild(string filePath)
        {
            var eventSource = new BinaryLogReplayEventSource();

            byte[] sourceArchive = null;

            eventSource.OnBlobRead += (kind, bytes) =>
            {
                if (kind == BinaryLogRecordKind.ProjectImportArchive)
                {
                    sourceArchive = bytes;
                }
            };

            StructuredLogger.SaveLogToDisk = false;
            StructuredLogger.CurrentBuild  = null;
            var structuredLogger = new StructuredLogger();

            structuredLogger.Parameters = "build.buildlog";
            structuredLogger.Initialize(eventSource);

            var sw = Stopwatch.StartNew();

            eventSource.Replay(filePath);
            var elapsed = sw.Elapsed;

            structuredLogger.Shutdown();

            var build = StructuredLogger.CurrentBuild;

            StructuredLogger.CurrentBuild = null;

            if (build == null)
            {
                build = new Build()
                {
                    Succeeded = false
                };
                build.AddChild(new Error()
                {
                    Text = "Error when opening the file: " + filePath
                });
            }

            var projectImportsZip = Path.ChangeExtension(filePath, ".ProjectImports.zip");

            if (sourceArchive == null && File.Exists(projectImportsZip))
            {
                sourceArchive = File.ReadAllBytes(projectImportsZip);
            }

            build.SourceFilesArchive = sourceArchive;
            // build.AddChildAtBeginning(new Message { Text = "Elapsed: " + elapsed.ToString() });

            return(build);
        }
        private void Analyze()
        {
            build.VisitAllChildren <Task>(t => AnalyzeTask(t));

            build.VisitAllChildren <Target>(t => AnalyzeTarget(t));
            if (!build.Succeeded)
            {
                build.AddChild(new Error {
                    Text = "Build failed."
                });
            }
            else
            {
                build.AddChild(new Item {
                    Text = "Build succeeded."
                });
            }

            build.VisitAllChildren <CopyTask>(c => AnalyzeFileCopies(c));
            AnalyzeDoubleWrites();
        }
예제 #6
0
        public static Build ReadFromXml(string xmlFilePath, Action <string> statusUpdate = null)
        {
            Build build = null;

            try
            {
                if (statusUpdate != null)
                {
                    statusUpdate("Loading " + xmlFilePath);
                }

                var doc  = XDocument.Load(xmlFilePath, LoadOptions.PreserveWhitespace);
                var root = doc.Root;

                if (statusUpdate != null)
                {
                    statusUpdate("Populating tree");
                }

                var reader = new XlinqLogReader();
                build = (Build)reader.ReadNode(root);
            }
            catch (Exception ex)
            {
                build = new Build()
                {
                    Succeeded = false
                };
                build.AddChild(new Error()
                {
                    Text = "Error when opening file: " + xmlFilePath
                });
                build.AddChild(new Error()
                {
                    Text = ex.ToString()
                });
            }

            return(build);
        }
예제 #7
0
        public void ProjectStarted(object sender, ProjectStartedEventArgs args)
        {
            try
            {
                lock (syncLock)
                {
                    Project  parentProject = null;
                    TreeNode parentNode    = null;

                    var parentContext = args?.ParentProjectBuildEventContext;
                    if (parentContext != null)
                    {
                        int parentProjectId = parentContext.ProjectContextId;
                        if (parentProjectId > 0)
                        {
                            parentProject = GetOrAddProject(parentProjectId);
                        }

                        int parentTaskId = parentContext.TaskId;
                        if (parentProject != null && parentTaskId > 0)
                        {
                            parentNode = parentProject.FindFirstDescendant <Task>(t => t.Id == parentTaskId);
                        }
                    }

                    var project = GetOrAddProject(args, parentProject);

                    // only parent the project if it's not already in the tree
                    if (project.Parent == null)
                    {
                        parentNode = parentNode ?? parentProject;

                        if (parentNode != null)
                        {
                            parentNode.AddChild(project);
                        }
                        else
                        {
                            // This is a "Root" project (no parent project).
                            Build.AddChild(project);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
        }
예제 #8
0
        private void PostAnalyzeBuild(Build build)
        {
            if (!build.Succeeded)
            {
                build.AddChild(new Error {
                    Text = "Build failed."
                });
            }
            else
            {
                build.AddChild(new Item {
                    Text = "Build succeeded."
                });
            }

            doubleWritesAnalyzer.AppendDoubleWritesFolder(build);

            if (build.LogFilePath != null)
            {
                build.AddChildAtBeginning(new Item {
                    Text = build.LogFilePath
                });
            }
        }
예제 #9
0
        private void HandleException(Exception ex)
        {
            ErrorReporting.ReportException(ex);

            try
            {
                lock (syncLock)
                {
                    Build.AddChild(new Error()
                    {
                        Text = ex.ToString()
                    });
                }
            }
            catch (Exception)
            {
            }
        }
예제 #10
0
        public void ProjectStarted(object sender, ProjectStartedEventArgs args)
        {
            try
            {
                lock (syncLock)
                {
                    Project parent = null;

                    int parentProjectId = args?.ParentProjectBuildEventContext.ProjectContextId ?? -1;
                    if (parentProjectId > 0)
                    {
                        parent = GetOrAddProject(parentProjectId);
                    }

                    var project = GetOrAddProject(args, parent);

                    // only parent the project if it's not already in the tree
                    if (project.Parent == null)
                    {
                        if (parent != null)
                        {
                            parent.AddChild(project);
                        }
                        else
                        {
                            // This is a "Root" project (no parent project).
                            Build.AddChild(project);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
        }
예제 #11
0
        public static Build ReadBuild(Stream stream, byte[] projectImportsArchive = null)
        {
            var eventSource = new BinaryLogReplayEventSource();

            Build build = null;

            eventSource.OnBlobRead += (kind, bytes) =>
            {
                if (kind == BinaryLogRecordKind.ProjectImportArchive)
                {
                    projectImportsArchive = bytes;
                }
            };
            eventSource.OnException += ex =>
            {
                if (build != null)
                {
                    build.AddChild(new Error()
                    {
                        Text = "Error when reading the file: " + ex.ToString()
                    });
                }
            };

            StructuredLogger.SaveLogToDisk = false;
            StructuredLogger.CurrentBuild  = null;
            var structuredLogger = new StructuredLogger();

            structuredLogger.Parameters = "build.buildlog";
            structuredLogger.Initialize(eventSource);

            build = structuredLogger.Construction.Build;

            var sw = Stopwatch.StartNew();

            eventSource.Replay(stream);
            var elapsed = sw.Elapsed;

            structuredLogger.Shutdown();

            build = StructuredLogger.CurrentBuild;
            StructuredLogger.CurrentBuild = null;

            if (build == null)
            {
                build = new Build()
                {
                    Succeeded = false
                };
                build.AddChild(new Error()
                {
                    Text = "Error when opening the log file."
                });
            }

            if (build.SourceFilesArchive == null && projectImportsArchive != null)
            {
                build.SourceFilesArchive = projectImportsArchive;
            }

            // build.AddChildAtBeginning(new Message { Text = "Elapsed: " + elapsed.ToString() });

            return(build);
        }
        public Build Read(Stream stream)
        {
            Build build = new Build();

            this.stringTable = build.StringTable;

            var stack = new Stack <object>(1024);

            stack.Push(build);

            XmlNodeType previous = XmlNodeType.None;

            try
            {
                var xmlReaderSettings = new XmlReaderSettings()
                {
                    IgnoreWhitespace = true,
                };

                using (reader = XmlReader.Create(stream, xmlReaderSettings))
                {
                    reader.MoveToContent();

                    ReadAttributes();
                    PopulateAttributes(build); // read the attributes on the root Build element that we created manually

                    while (reader.Read())
                    {
                        var nodeType = reader.NodeType;
                        switch (reader.NodeType)
                        {
                        case XmlNodeType.Element:
                            var node = ReadNode();

                            var parent = (TreeNode)stack.Peek();
                            parent.AddChild(node);

                            if (!reader.IsEmptyElement)
                            {
                                stack.Push(node);
                            }

                            break;

                        case XmlNodeType.EndElement:
                        {
                            // if the element content is an empty string
                            if (previous == XmlNodeType.Element)
                            {
                                var valueNode = stack.Peek();
                                SetElementValue(valueNode, "");
                            }

                            stack.Pop();
                            break;
                        }

                        case XmlNodeType.Text:
                        {
                            var    valueNode = stack.Peek();
                            string value     = reader.Value;
                            SetElementValue(valueNode, stringTable.Intern(value));

                            break;
                        }

                        case XmlNodeType.Whitespace:
                        {
                            var valueNode     = stack.Peek();
                            var nameValueNode = valueNode as NameValueNode;
                            if (nameValueNode != null)
                            {
                                nameValueNode.Value = GetCurrentValue();
                            }
                            else
                            {
                                var message = valueNode as Message;
                                if (message != null)
                                {
                                    message.Text = GetCurrentValue();
                                }
                            }

                            break;
                        }

                        case XmlNodeType.None:
                        case XmlNodeType.Attribute:
                        case XmlNodeType.CDATA:
                        case XmlNodeType.EntityReference:
                        case XmlNodeType.Entity:
                        case XmlNodeType.ProcessingInstruction:
                        case XmlNodeType.Comment:
                        case XmlNodeType.Document:
                        case XmlNodeType.DocumentType:
                        case XmlNodeType.DocumentFragment:
                        case XmlNodeType.Notation:
                        case XmlNodeType.SignificantWhitespace:
                        case XmlNodeType.EndEntity:
                        case XmlNodeType.XmlDeclaration:
                        default:
                            break;
                        }

                        previous = nodeType;
                    }
                }
            }
            catch (Exception ex)
            {
                build = new Build()
                {
                    Succeeded = false
                };
                build.AddChild(new Error()
                {
                    Text = "Error when opening XML log file."
                });
                build.AddChild(new Error()
                {
                    Text = ex.ToString()
                });
            }

            return(build);
        }
예제 #13
0
        public static Build ReadBuild(Stream stream, Progress progress, byte[] projectImportsArchive = null)
        {
            var eventSource = new BinLogReader();

            Build build = null;
            IEnumerable <string> strings = null;

            eventSource.OnBlobRead += (kind, bytes) =>
            {
                if (kind == BinaryLogRecordKind.ProjectImportArchive)
                {
                    projectImportsArchive = bytes;
                }
            };
            eventSource.OnException += ex =>
            {
                if (build != null)
                {
                    build.AddChild(new Error()
                    {
                        Text = "Error when reading the file: " + ex.ToString()
                    });
                }
            };
            eventSource.OnStringDictionaryComplete += s =>
            {
                strings = s;
            };

            StructuredLogger.SaveLogToDisk = false;
            StructuredLogger.CurrentBuild  = null;
            var structuredLogger = new StructuredLogger();

            structuredLogger.Parameters = "build.buildlog";
            structuredLogger.Initialize(eventSource);

            build = structuredLogger.Construction.Build;

            eventSource.OnFileFormatVersionRead += fileFormatVersion =>
            {
                build.FileFormatVersion = fileFormatVersion;

                // strings are deduplicated starting with version 10
                if (fileFormatVersion >= 10)
                {
                    build.StringTable.NormalizeLineEndings   = false;
                    build.StringTable.HasDeduplicatedStrings = true;
                    if (ReuseBinlogStrings)
                    {
                        build.StringTable.DisableDeduplication = true;
                    }
                }
            };

            var sw = Stopwatch.StartNew();

            eventSource.Replay(stream, progress);

            var elapsed = sw.Elapsed;

            if (strings != null)
            {
                if (ReuseBinlogStrings)
                {
                    // since strings are already deduplicated in the file, no need to do it again
                    build.StringTable.SetStrings(strings);
                }
                else
                {
                    // intern all strings in one fell swoop here instead of interning multiple times
                    // one by one when processing task parameters
                    build.StringTable.Intern(strings);
                }
            }

            structuredLogger.Shutdown();

            build = StructuredLogger.CurrentBuild;
            StructuredLogger.CurrentBuild = null;

            if (build == null)
            {
                build = new Build()
                {
                    Succeeded = false
                };
                build.AddChild(new Error()
                {
                    Text = "Error when opening the log file."
                });
            }

            if (build.SourceFilesArchive == null && projectImportsArchive != null)
            {
                build.SourceFilesArchive = projectImportsArchive;
            }

            // strings = build.StringTable.Instances.OrderBy(s => s).ToArray();

            // Serialization.WriteStringsToFile(@"C:\temp\1.txt", strings.ToArray());

            return(build);
        }
예제 #14
0
        public static Build ReadBuild(Stream stream, byte[] projectImportsArchive = null)
        {
            var eventSource = new BinLogReader();

            Build build = null;

            eventSource.OnBlobRead += (kind, bytes) =>
            {
                if (kind == BinaryLogRecordKind.ProjectImportArchive)
                {
                    projectImportsArchive = bytes;
                }
            };
            eventSource.OnException += ex =>
            {
                if (build != null)
                {
                    build.AddChild(new Error()
                    {
                        Text = "Error when reading the file: " + ex.ToString()
                    });
                }
            };

            StructuredLogger.SaveLogToDisk = false;
            StructuredLogger.CurrentBuild  = null;
            var structuredLogger = new StructuredLogger();

            structuredLogger.Parameters = "build.buildlog";
            structuredLogger.Initialize(eventSource);

            eventSource.OnFileFormatVersionRead += fileFormatVersion =>
            {
                if (fileFormatVersion >= 10)
                {
                    // since strings are already deduplicated in the file, no need to do it again
                    // TODO: but search will not work if the string table is empty
                    // structuredLogger.Construction.StringTable.DisableDeduplication = true;
                }
            };

            build = structuredLogger.Construction.Build;

            var sw = Stopwatch.StartNew();

            eventSource.Replay(stream);
            var elapsed = sw.Elapsed;

            structuredLogger.Shutdown();

            build = StructuredLogger.CurrentBuild;
            StructuredLogger.CurrentBuild = null;

            if (build == null)
            {
                build = new Build()
                {
                    Succeeded = false
                };
                build.AddChild(new Error()
                {
                    Text = "Error when opening the log file."
                });
            }

            if (build.SourceFilesArchive == null && projectImportsArchive != null)
            {
                build.SourceFilesArchive = projectImportsArchive;
            }

            // build.AddChildAtBeginning(new Message { Text = "Elapsed: " + elapsed.ToString() });

            return(build);
        }