├── .gitignore ├── .gitmodules ├── AUTHORS.txt ├── LICENSE.txt ├── README.md ├── contributing.md ├── doc └── images │ ├── BuildLoggingOpenLogFileMenu.png │ ├── BuildLoggingWindow.png │ ├── BuildTabProperties.png │ ├── MSBuildBinaryLogFileBuildTab.png │ ├── MSBuildLogFile.png │ ├── TargetSummaryTab.png │ └── TaskSummaryTab.png ├── gen-mpack.sh └── src ├── Common.Build.props ├── Microsoft.VisualStudio.ProjectSystem.LogModel ├── Microsoft.VisualStudio.ProjectSystem.LogModel.csproj └── Properties │ └── AssemblyInfo.cs ├── Microsoft.VisualStudio.ProjectSystem.Tools ├── Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor │ ├── BinaryLogDocumentData.cs │ └── BinaryLogViewModels.cs ├── Microsoft.VisualStudio.ProjectSystem.Tools.csproj ├── Microsoft.VisualStudio.Shell.Interop │ └── __VSERRORCATEGORY.cs ├── Microsoft.VisualStudio.Shell.TableManager │ ├── ITableDataSink.cs │ ├── ITableDataSource.cs │ ├── ITableEntry.cs │ └── StandardTableKeyNames.cs └── Properties │ └── AssemblyInfo.cs ├── MonoDevelop.ProjectSystem.Tools.sln └── MonoDevelop.ProjectSystem.Tools ├── MonoDevelop.ProjectSystem.Tools.Gui ├── BinaryLogBuildTreeView.cs ├── BinaryLogDocumentControllerExtension.cs ├── BinaryLogEvaluationSummaryView.cs ├── BinaryLogSummaryViewBase.cs ├── BinaryLogTargetSummaryView.cs ├── BinaryLogTaskSummaryView.cs ├── BuildLoggingPad.cs ├── BuildLoggingWidget.UI.cs └── BuildLoggingWidget.cs ├── MonoDevelop.ProjectSystem.Tools.csproj ├── MonoDevelop.ProjectSystem.Tools ├── BinaryLogProcessor.cs ├── BuildLoggingCommands.cs ├── BuildLoggingProjectExtension.cs ├── BuildLoggingSolutionExtension.cs ├── BuildSession.cs ├── BuildType.cs ├── MSBuildBinLogProgressMonitor.cs ├── MSBuildProcessArguments.cs ├── MSBuildProcessProgressMonitor.cs ├── MSBuildProcessServiceMonitor.cs ├── MSBuildTarget.cs ├── MSBuildTargetEventArgs.cs ├── MSBuildTargetMonitor.cs ├── MSBuildTargetProgressMonitor.cs ├── MSBuildTargetStatus.cs ├── MSBuildTargetStatusExtensions.cs ├── ProjectExtensions.cs ├── ProjectSystemService.cs ├── SolutionExtensions.cs └── TargetEvaluationResultExtensions.cs ├── MonoDevelop.References.props └── Properties ├── AddinInfo.cs ├── AssemblyInfo.cs └── MonoDevelop.ProjectSystem.Tools.addin.xml /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | *.userprefs 4 | *.DS_Store 5 | packages 6 | .vs/ 7 | *.csproj.user -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/project-system-tools"] 2 | path = external/project-system-tools 3 | url = git://github.com/mrward/project-system-tools.git 4 | -------------------------------------------------------------------------------- /AUTHORS.txt: -------------------------------------------------------------------------------- 1 | Matt Ward -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Project System Tools for MonoDevelop and Visual Studio for Mac 2 | 3 | Inspired by [Project System Tools for Visual Studio on Windows](https://github.com/dotnet/project-system-tools). 4 | 5 | ## Build Logging Window 6 | 7 | To open the Build Logging Window 8 | 9 | - Select View - Pads - Build Logging 10 | 11 | Click the green arrow button to enable the logging of the MSBuild targets for builds and design-time builds. 12 | 13 | ![Build Logging Window](doc/images/BuildLoggingWindow.png) 14 | 15 | To stop the logging click the red square stop button. 16 | 17 | To filter the targets either use the combo box to restrict the targets to builds or design time builds, or use the search, on the right hand side of the window, to filter the targets displayed. 18 | 19 | To open the log output for an MSBuild target 20 | 21 | - Double click the row. 22 | - Right click the row and select Open Log File 23 | 24 | ![Open Log File context menu](doc/images/BuildLoggingOpenLogFileMenu.png) 25 | 26 | ![MSBuild Log File](doc/images/MSBuildLogFile.png) 27 | 28 | To open a binary log into the binary log viewer: 29 | 30 | - Right click the row and Open Binary Log File 31 | 32 | Note that not all MSBuild targets currently support generating a binary log. 33 | 34 | ![MSBuild Binary Log File - Build tab](doc/images/MSBuildBinaryLogFileBuildTab.png) 35 | 36 | Three tabs are available when a binlog file is opened. 37 | 38 | - Build 39 | - Tree view of the binary log targets and tasks 40 | - Properties for a target or task are shown in the Properties window. 41 | - Target Summary 42 | - Target name 43 | - Source filename 44 | - Number of calls 45 | - Time taken 46 | - Percentage of total time taken 47 | - Task Summary 48 | - Task name 49 | - Source filename 50 | - Number of calls 51 | - Time taken 52 | - Percentage of total time taken 53 | 54 | ![MSBuild Binary Log File - Target Summary tab](doc/images/TargetSummaryTab.png) 55 | 56 | ![MSBuild Binary Log File - Task Summary tab](doc/images/TaskSummaryTab.png) 57 | 58 | Selecting a tree node in the Build tab will show properties for the node in the Properties window. 59 | 60 | ![MSBuild Binary Log File - Build tab - Properties window](doc/images/BuildTabProperties.png) 61 | 62 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for taking the time to contribute to this project. 4 | 5 | # License 6 | 7 | The MonoDevelop Project Systems Tools addin is MIT licensed. By contributing to the project you agree to license your contributions by the same license. -------------------------------------------------------------------------------- /doc/images/BuildLoggingOpenLogFileMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrward/monodevelop-project-system-tools/f04ab451fb34fbc644e98ac5cebc208ed4f5a12c/doc/images/BuildLoggingOpenLogFileMenu.png -------------------------------------------------------------------------------- /doc/images/BuildLoggingWindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrward/monodevelop-project-system-tools/f04ab451fb34fbc644e98ac5cebc208ed4f5a12c/doc/images/BuildLoggingWindow.png -------------------------------------------------------------------------------- /doc/images/BuildTabProperties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrward/monodevelop-project-system-tools/f04ab451fb34fbc644e98ac5cebc208ed4f5a12c/doc/images/BuildTabProperties.png -------------------------------------------------------------------------------- /doc/images/MSBuildBinaryLogFileBuildTab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrward/monodevelop-project-system-tools/f04ab451fb34fbc644e98ac5cebc208ed4f5a12c/doc/images/MSBuildBinaryLogFileBuildTab.png -------------------------------------------------------------------------------- /doc/images/MSBuildLogFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrward/monodevelop-project-system-tools/f04ab451fb34fbc644e98ac5cebc208ed4f5a12c/doc/images/MSBuildLogFile.png -------------------------------------------------------------------------------- /doc/images/TargetSummaryTab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrward/monodevelop-project-system-tools/f04ab451fb34fbc644e98ac5cebc208ed4f5a12c/doc/images/TargetSummaryTab.png -------------------------------------------------------------------------------- /doc/images/TaskSummaryTab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrward/monodevelop-project-system-tools/f04ab451fb34fbc644e98ac5cebc208ed4f5a12c/doc/images/TaskSummaryTab.png -------------------------------------------------------------------------------- /gen-mpack.sh: -------------------------------------------------------------------------------- 1 | "/Applications/Visual Studio.app/Contents/MacOS/vstool" setup pack $PWD/bin/MonoDevelop.ProjectSystem.Tools.dll -d:$PWD -------------------------------------------------------------------------------- /src/Common.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | \Applications\Visual Studio %28Preview%29.app\Contents\MonoBundle 5 | 6 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.LogModel/Microsoft.VisualStudio.ProjectSystem.LogModel.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | false 6 | false 7 | 8 | 9 | bin\Debug 10 | DEBUG; 11 | 12 | 13 | bin\Release 14 | 15 | 16 | 17 | $(MDBinDir)\Microsoft.Build.dll 18 | False 19 | 20 | 21 | $(MDBinDir)\Microsoft.Build.Framework.dll 22 | False 23 | 24 | 25 | $(MDBinDir)\Microsoft.Build.Utilities.Core.dll 26 | False 27 | 28 | 29 | False 30 | $(MDBinDir)\System.Collections.Immutable.dll 31 | 32 | 33 | 34 | 35 | Microsoft.VisualStudio.ProjectSystem.LogModel\Build.cs 36 | 37 | 38 | Microsoft.VisualStudio.ProjectSystem.LogModel\Diagnostic.cs 39 | 40 | 41 | Microsoft.VisualStudio.ProjectSystem.LogModel\EvaluatedLocation.cs 42 | 43 | 44 | Microsoft.VisualStudio.ProjectSystem.LogModel\EvaluatedPass.cs 45 | 46 | 47 | Microsoft.VisualStudio.ProjectSystem.LogModel\EvaluatedProfile.cs 48 | 49 | 50 | Microsoft.VisualStudio.ProjectSystem.LogModel\EvaluatedProject.cs 51 | 52 | 53 | Microsoft.VisualStudio.ProjectSystem.LogModel\Evaluation.cs 54 | 55 | 56 | Microsoft.VisualStudio.ProjectSystem.LogModel\Item.cs 57 | 58 | 59 | Microsoft.VisualStudio.ProjectSystem.LogModel\ItemAction.cs 60 | 61 | 62 | Microsoft.VisualStudio.ProjectSystem.LogModel\ItemGroup.cs 63 | 64 | 65 | Microsoft.VisualStudio.ProjectSystem.LogModel\Log.cs 66 | 67 | 68 | Microsoft.VisualStudio.ProjectSystem.LogModel\Message.cs 69 | 70 | 71 | Microsoft.VisualStudio.ProjectSystem.LogModel\Node.cs 72 | 73 | 74 | Microsoft.VisualStudio.ProjectSystem.LogModel\Project.cs 75 | 76 | 77 | Microsoft.VisualStudio.ProjectSystem.LogModel\PropertySet.cs 78 | 79 | 80 | Microsoft.VisualStudio.ProjectSystem.LogModel\Result.cs 81 | 82 | 83 | Microsoft.VisualStudio.ProjectSystem.LogModel\Target.cs 84 | 85 | 86 | Microsoft.VisualStudio.ProjectSystem.LogModel\Task.cs 87 | 88 | 89 | Microsoft.VisualStudio.ProjectSystem.LogModel\Time.cs 90 | 91 | 92 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\BaseInfo.cs 93 | 94 | 95 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\BuildInfo.cs 96 | 97 | 98 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\DiagnosticInfo.cs 99 | 100 | 101 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\EvaluatedLocationInfo.cs 102 | 103 | 104 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\EvaluatedPassInfo.cs 105 | 106 | 107 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\EvaluatedProfileInfo.cs 108 | 109 | 110 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\EvaluatedProjectInfo.cs 111 | 112 | 113 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\EvaluationInfo.cs 114 | 115 | 116 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\ItemActionInfo.cs 117 | 118 | 119 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\ItemGroupInfo.cs 120 | 121 | 122 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\ItemInfo.cs 123 | 124 | 125 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\MessageInfo.cs 126 | 127 | 128 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\ModelBuilder.cs 129 | 130 | 131 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\ProjectInfo.cs 132 | 133 | 134 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\PropertySetInfo.cs 135 | 136 | 137 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\TargetInfo.cs 138 | 139 | 140 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\TaskInfo.cs 141 | 142 | 143 | Microsoft.VisualStudio.ProjectSystem.LogModel.Builder\TimeInfo.cs 144 | 145 | 146 | Resources.Designer.cs 147 | True 148 | True 149 | Resources.resx 150 | 151 | 152 | 153 | 154 | Resources.resx 155 | ResXFileCodeGenerator 156 | Resources.Designer.cs 157 | 158 | 159 | 160 | 161 | xlf\Resources.cs.xlf 162 | 163 | 164 | xlf\Resources.de.xlf 165 | 166 | 167 | xlf\Resources.es.xlf 168 | 169 | 170 | xlf\Resources.fr.xlf 171 | 172 | 173 | xlf\Resources.it.xlf 174 | 175 | 176 | xlf\Resources.ja.xlf 177 | 178 | 179 | xlf\Resources.ko.xlf 180 | 181 | 182 | xlf\Resources.pl.xlf 183 | 184 | 185 | xlf\Resources.pt-BR.xlf 186 | 187 | 188 | xlf\Resources.ru.xlf 189 | 190 | 191 | xlf\Resources.tr.xlf 192 | 193 | 194 | xlf\Resources.zh-Hans.xlf 195 | 196 | 197 | xlf\Resources.zh-Hant.xlf 198 | 199 | 200 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.LogModel/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AssemblyInfo.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | using System.Reflection; 27 | using System.Runtime.CompilerServices; 28 | 29 | // Information about this assembly is defined by the following attributes. 30 | // Change them to the values specific to your project. 31 | 32 | [assembly: AssemblyTitle ("Microsoft.VisualStudio.ProjectSystem.LogModel")] 33 | [assembly: AssemblyDescription ("")] 34 | [assembly: AssemblyConfiguration ("")] 35 | [assembly: AssemblyCompany ("Microsoft")] 36 | [assembly: AssemblyProduct ("")] 37 | [assembly: AssemblyCopyright ("Microsoft Corporation")] 38 | [assembly: AssemblyTrademark ("")] 39 | [assembly: AssemblyCulture ("")] 40 | 41 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 42 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 43 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 44 | 45 | [assembly: AssemblyVersion ("0.13")] 46 | 47 | // The following attributes are used to specify the signing key for the assembly, 48 | // if desired. See the Mono documentation for more information about signing. 49 | 50 | //[assembly: AssemblyDelaySign(false)] 51 | //[assembly: AssemblyKeyFile("")] 52 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.Tools/Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor/BinaryLogDocumentData.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | // 4 | // Based on: 5 | // https://github.com/dotnet/project-system-tools/blob/master/src/ProjectSystemTools/BinaryLogEditor/BinaryLogDocumentData.cs 6 | 7 | using System; 8 | using System.Collections.Immutable; 9 | using Microsoft.Build.Logging; 10 | using Microsoft.VisualStudio.ProjectSystem.LogModel; 11 | using Microsoft.VisualStudio.ProjectSystem.LogModel.Builder; 12 | 13 | namespace Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor 14 | { 15 | internal class BinaryLogDocumentData 16 | { 17 | public Log Log { get; private set; } 18 | 19 | public event EventHandler Loaded; 20 | 21 | public void Load (string fileName) 22 | { 23 | try { 24 | var replayEventSource = new BinaryLogReplayEventSource (); 25 | var builder = new ModelBuilder (replayEventSource); 26 | replayEventSource.Replay (fileName); 27 | Log = builder.Finish (); 28 | } catch (Exception ex) { 29 | if (ex is AggregateException aggregateException) { 30 | Log = new Log (null, ImmutableList.Empty, aggregateException.InnerExceptions.ToImmutableList ()); 31 | } else { 32 | Log = new Log (null, ImmutableList.Empty, new[] { ex }.ToImmutableList ()); 33 | } 34 | } 35 | 36 | Loaded?.Invoke (this, new EventArgs ()); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.Tools/Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor/BinaryLogViewModels.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | // 4 | // Based on: 5 | // https://github.com/dotnet/project-system-tools/blob/e5c00e55fe7f0d5cf0cdd249475c570b2a633d19/src/ProjectSystemTools/BinaryLogEditor/BinaryLogEditorPane.cs 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Collections.ObjectModel; 10 | using System.Linq; 11 | using Microsoft.VisualStudio.ProjectSystem.LogModel; 12 | using Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel; 13 | 14 | namespace Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor 15 | { 16 | internal class BinaryLogViewModels 17 | { 18 | public BinaryLogViewModels (BinaryLogDocumentData binaryLogDocument) 19 | { 20 | BuildTreeViewItems = new ObservableCollection (); 21 | TargetListViewItems = new ObservableCollection (); 22 | TaskListViewItems = new ObservableCollection (); 23 | EvaluationListViewItems = new ObservableCollection (); 24 | 25 | BinaryLogDocument = binaryLogDocument; 26 | } 27 | 28 | public ObservableCollection BuildTreeViewItems { get; } 29 | public ObservableCollection EvaluationListViewItems { get; } 30 | public ObservableCollection TargetListViewItems { get; } 31 | public ObservableCollection TaskListViewItems { get; } 32 | public BinaryLogDocumentData BinaryLogDocument { get; } 33 | 34 | public void Build () 35 | { 36 | if (BinaryLogDocument.Log.Exceptions.Any ()) { 37 | BuildTreeViewItems.Add (new ListViewModel ("Exceptions", BinaryLogDocument.Log.Exceptions, ex => new ExceptionViewModel (ex))); 38 | } 39 | 40 | //if (documentData.Log.Evaluations.Any ()) { 41 | // evaluationTreeViewItems.Add (new ListViewModel ($"Evaluations ({documentData.Log.Evaluations.SelectMany (e => e.EvaluatedProjects).Aggregate (TimeSpan.Zero, (t, p) => t + (p.EndTime - p.StartTime)):mm':'ss'.'ffff})", documentData.Log.Evaluations, e => e.EvaluatedProjects.Count == 1 42 | // ? (BaseViewModel)new EvaluatedProjectViewModel (e) 43 | // : new EvaluationViewModel (e))); 44 | //} 45 | 46 | if (BinaryLogDocument.Log.Build?.Projects != null) { 47 | BuildTreeViewItems.Add (new BuildViewModel (BinaryLogDocument.Log.Build)); 48 | 49 | var allTargets = CollectTargets (BinaryLogDocument.Log.Build.Projects); 50 | var groupedTargets = allTargets.GroupBy (target => Tuple.Create (target.Name, target.SourceFilePath)); 51 | var totalTime = BinaryLogDocument.Log.Build.EndTime - BinaryLogDocument.Log.Build.StartTime; 52 | foreach (var groupedTarget in groupedTargets) { 53 | var time = groupedTarget.Aggregate (TimeSpan.Zero, (current, target) => current + (target.EndTime - target.StartTime)); 54 | TargetListViewItems.Add (new TargetListViewModel ( 55 | groupedTarget.Key.Item1, 56 | groupedTarget.Key.Item2, 57 | groupedTarget.Count (), 58 | time, 59 | time.Ticks / (double)totalTime.Ticks)); 60 | } 61 | 62 | var allTasks = CollectTasks (BinaryLogDocument.Log.Build.Projects); 63 | var groupedTasks = allTasks.GroupBy (task => Tuple.Create (task.Name, task.SourceFilePath)); 64 | foreach (var groupedTask in groupedTasks) { 65 | var time = groupedTask.Aggregate (TimeSpan.Zero, (current, task) => current + (task.EndTime - task.StartTime)); 66 | TaskListViewItems.Add (new TaskListViewModel ( 67 | groupedTask.Key.Item1, 68 | groupedTask.Key.Item2, 69 | groupedTask.Count (), 70 | time, 71 | time.Ticks / (double)totalTime.Ticks)); 72 | } 73 | 74 | var allEvaluations = CollectEvaluations ( 75 | BinaryLogDocument.Log.Evaluations 76 | .SelectMany (e => e.EvaluatedProjects) 77 | .Select (p => p.EvaluationProfile) 78 | .Where (p => p != null) 79 | .SelectMany (p => p.Passes) 80 | .SelectMany (p => p.Locations)).ToList (); 81 | var totalEvaluationTime = allEvaluations.Aggregate (TimeSpan.Zero, (current, e) => current + e.Time.ExclusiveTime); 82 | var groupedEvaluations = 83 | allEvaluations.GroupBy (e => Tuple.Create (e.ElementName, e.Kind, e.File, e.Line)); 84 | foreach (var groupedEvaluation in groupedEvaluations) { 85 | var time = groupedEvaluation.Aggregate (TimeSpan.Zero, (current, e) => current + e.Time.ExclusiveTime); 86 | EvaluationListViewItems.Add (new EvaluationListViewModel ( 87 | groupedEvaluation.Key.Item1, 88 | groupedEvaluation.First ().ElementDescription, 89 | groupedEvaluation.Key.Item2.ToString (), 90 | groupedEvaluation.Key.Item3, 91 | groupedEvaluation.Key.Item4, 92 | groupedEvaluation.Count (), 93 | time, 94 | time.Ticks / (double)totalEvaluationTime.Ticks)); 95 | } 96 | } 97 | } 98 | 99 | static IEnumerable CollectTargets (IEnumerable projects) 100 | { 101 | var allTargets = new List (); 102 | foreach (var targets in projects.Select (p => CollectTargets (p))) { 103 | allTargets.AddRange (targets); 104 | } 105 | return allTargets; 106 | } 107 | 108 | static IEnumerable CollectTargets (Project project) 109 | { 110 | return project.Targets.Union ( 111 | project.Targets.SelectMany (t => t.Tasks) 112 | .SelectMany (t => t.ChildProjects) 113 | .SelectMany (CollectTargets)); 114 | } 115 | 116 | static IEnumerable CollectTasks (IEnumerable projects) 117 | { 118 | var allTasks = new List (); 119 | foreach (var tasks in projects.Select (p => CollectTasks (p))) { 120 | allTasks.AddRange (tasks); 121 | } 122 | return allTasks; 123 | } 124 | 125 | static IEnumerable CollectTasks (Project project) 126 | { 127 | return project.Targets.SelectMany (target => target.Tasks) 128 | .Union ( 129 | project.Targets.SelectMany (t => t.Tasks) 130 | .SelectMany (t => t.ChildProjects) 131 | .SelectMany (CollectTasks)); 132 | } 133 | 134 | static IEnumerable CollectEvaluations (IEnumerable locations) 135 | { 136 | if (!locations.Any ()) 137 | return locations; 138 | 139 | return locations.Union (CollectEvaluations (locations.SelectMany (l => l.Children))); 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.Tools/Microsoft.VisualStudio.ProjectSystem.Tools.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | false 6 | false 7 | 8 | 9 | bin\Debug 10 | 11 | 12 | bin\Release 13 | 14 | 15 | 16 | $(MDBinDir)\Microsoft.Build.dll 17 | False 18 | 19 | 20 | $(MDBinDir)\Microsoft.Build.Framework.dll 21 | False 22 | 23 | 24 | $(MDBinDir)\Microsoft.Build.Utilities.Core.dll 25 | False 26 | 27 | 28 | False 29 | $(MDBinDir)\System.Collections.Immutable.dll 30 | 31 | 32 | 33 | 34 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\BaseViewModel.cs 35 | 36 | 37 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\BuildViewModel.cs 38 | 39 | 40 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\DictionaryBasedPropertyDescriptor.cs 41 | 42 | 43 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\EvaluatedLocationViewModel.cs 44 | 45 | 46 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\EvaluatedPassViewModel.cs 47 | 48 | 49 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\EvaluatedProjectViewModel.cs 50 | 51 | 52 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\EvaluationListViewModel.cs 53 | 54 | 55 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\EvaluationViewModel.cs 56 | 57 | 58 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\ExceptionViewModel.cs 59 | 60 | 61 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\ItemViewModel.cs 62 | 63 | 64 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\IViewModelWithProperties.cs 65 | 66 | 67 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\ListViewModel.cs 68 | 69 | 70 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\NodeViewModel.cs 71 | 72 | 73 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\ProjectViewModel.cs 74 | 75 | 76 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\PropertyViewModel.cs 77 | 78 | 79 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\RootViewModel.cs 80 | 81 | 82 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\SelectedObjectWrapper.cs 83 | 84 | 85 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\TargetListViewModel.cs 86 | 87 | 88 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\TargetViewModel.cs 89 | 90 | 91 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\TaskListViewModel.cs 92 | 93 | 94 | Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel\TaskViewModel.cs 95 | 96 | 97 | Microsoft.VisualStudio.ProjectSystem.Tools.TableControl\TableKeyNames.cs 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.Tools/Microsoft.VisualStudio.Shell.Interop/__VSERRORCATEGORY.cs: -------------------------------------------------------------------------------- 1 | // 2 | // __VSERRORCATEGORY.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | namespace Microsoft.VisualStudio.Shell.Interop 28 | { 29 | enum __VSERRORCATEGORY 30 | { 31 | EC_ERROR = 0, 32 | EC_WARNING = 1, 33 | EC_MESSAGE = 2 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.Tools/Microsoft.VisualStudio.Shell.TableManager/ITableDataSink.cs: -------------------------------------------------------------------------------- 1 | // 2 | // ITableDataSink.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System.Collections.Generic; 28 | 29 | namespace Microsoft.VisualStudio.Shell.TableManager 30 | { 31 | interface ITableDataSink 32 | { 33 | void AddEntries (IReadOnlyList newEntries, bool removeAllEntries = false); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.Tools/Microsoft.VisualStudio.Shell.TableManager/ITableDataSource.cs: -------------------------------------------------------------------------------- 1 | // 2 | // ITableDataSource.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | 29 | namespace Microsoft.VisualStudio.Shell.TableManager 30 | { 31 | interface ITableDataSource 32 | { 33 | string SourceTypeIdentifier { get; } 34 | 35 | string Identifier { get; } 36 | 37 | string DisplayName { get; } 38 | 39 | IDisposable Subscribe (ITableDataSink sink); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.Tools/Microsoft.VisualStudio.Shell.TableManager/ITableEntry.cs: -------------------------------------------------------------------------------- 1 | // 2 | // ITableEntry.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | namespace Microsoft.VisualStudio.Shell.TableManager 28 | { 29 | interface ITableEntry 30 | { 31 | object Identity { get; } 32 | 33 | bool TryGetValue (string keyName, out object content); 34 | bool TrySetValue (string keyName, object content); 35 | bool CanSetValue (string keyName); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.Tools/Microsoft.VisualStudio.Shell.TableManager/StandardTableKeyNames.cs: -------------------------------------------------------------------------------- 1 | // 2 | // StandardTableKeyNames.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | namespace Microsoft.VisualStudio.Shell.TableManager 28 | { 29 | static class StandardTableKeyNames 30 | { 31 | public const string ErrorSeverity = "errorseverity"; 32 | public const string Text = "text"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.ProjectSystem.Tools/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AssemblyInfo.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | using System.Reflection; 27 | using System.Runtime.CompilerServices; 28 | 29 | // Information about this assembly is defined by the following attributes. 30 | // Change them to the values specific to your project. 31 | 32 | [assembly: AssemblyTitle ("Microsoft.VisualStudio.ProjectSystem.Tools")] 33 | [assembly: AssemblyDescription ("")] 34 | [assembly: AssemblyConfiguration ("")] 35 | [assembly: AssemblyCompany ("Microsoft")] 36 | [assembly: AssemblyProduct ("")] 37 | [assembly: AssemblyCopyright ("Microsoft Corporation")] 38 | [assembly: AssemblyTrademark ("")] 39 | [assembly: AssemblyCulture ("")] 40 | 41 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 42 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 43 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 44 | 45 | [assembly: AssemblyVersion ("0.13")] 46 | 47 | // The following attributes are used to specify the signing key for the assembly, 48 | // if desired. See the Mono documentation for more information about signing. 49 | 50 | //[assembly: AssemblyDelaySign(false)] 51 | //[assembly: AssemblyKeyFile("")] 52 | [assembly: InternalsVisibleTo ("MonoDevelop.ProjectSystem.Tools")] 53 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.ProjectSystem.Tools", "MonoDevelop.ProjectSystem.Tools\MonoDevelop.ProjectSystem.Tools.csproj", "{992972DC-DE0E-42BF-BB00-86B4512723BD}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.VisualStudio.ProjectSystem.LogModel", "Microsoft.VisualStudio.ProjectSystem.LogModel\Microsoft.VisualStudio.ProjectSystem.LogModel.csproj", "{03755881-A132-4CC3-9EC4-CD33192C4428}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.VisualStudio.ProjectSystem.Tools", "Microsoft.VisualStudio.ProjectSystem.Tools\Microsoft.VisualStudio.ProjectSystem.Tools.csproj", "{0E542C28-B9D6-4E2F-9C72-48063AB67007}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {992972DC-DE0E-42BF-BB00-86B4512723BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {992972DC-DE0E-42BF-BB00-86B4512723BD}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {992972DC-DE0E-42BF-BB00-86B4512723BD}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {992972DC-DE0E-42BF-BB00-86B4512723BD}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {03755881-A132-4CC3-9EC4-CD33192C4428}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {03755881-A132-4CC3-9EC4-CD33192C4428}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {03755881-A132-4CC3-9EC4-CD33192C4428}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {03755881-A132-4CC3-9EC4-CD33192C4428}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {0E542C28-B9D6-4E2F-9C72-48063AB67007}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {0E542C28-B9D6-4E2F-9C72-48063AB67007}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {0E542C28-B9D6-4E2F-9C72-48063AB67007}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {0E542C28-B9D6-4E2F-9C72-48063AB67007}.Release|Any CPU.Build.0 = Release|Any CPU 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools.Gui/BinaryLogBuildTreeView.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryLogBuildTreeView.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Collections.ObjectModel; 30 | using Microsoft.VisualStudio.ProjectSystem.LogModel; 31 | using Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel; 32 | using MonoDevelop.DesignerSupport; 33 | using MonoDevelop.Ide; 34 | using MonoDevelop.Ide.Gui; 35 | using Xwt; 36 | using Xwt.Drawing; 37 | 38 | namespace MonoDevelop.ProjectSystem.Tools.Gui 39 | { 40 | class BinaryLogBuildTreeView : Widget, IPropertyPadProvider 41 | { 42 | ObservableCollection rootViewModels; 43 | TreeView treeView; 44 | TreeStore treeStore; 45 | DataField textDataField = new DataField (); 46 | DataField imageDataField = new DataField (); 47 | DataField viewModelDataField = new DataField (); 48 | BaseViewModel selectedViewModel; 49 | 50 | public BinaryLogBuildTreeView (ObservableCollection rootViewModels) 51 | { 52 | this.rootViewModels = rootViewModels; 53 | 54 | Build (); 55 | AddTreeViewItems (); 56 | 57 | treeView.SelectionChanged += TreeViewSelectionChanged; 58 | } 59 | 60 | void Build () 61 | { 62 | treeView = new TreeView (); 63 | treeView.HeadersVisible = false; 64 | 65 | treeStore = new TreeStore (textDataField, imageDataField, viewModelDataField); 66 | treeView.DataSource = treeStore; 67 | 68 | var column = new ListViewColumn ("Node"); 69 | column.Views.Add (new ImageCellView (imageDataField)); 70 | 71 | var cellView = new TextCellView (); 72 | cellView.MarkupField = textDataField; 73 | column.Views.Add (cellView); 74 | treeView.Columns.Add (column); 75 | 76 | Content = treeView; 77 | } 78 | 79 | void AddTreeViewItems () 80 | { 81 | foreach (BaseViewModel viewModel in rootViewModels) { 82 | TreeNavigator navigator = treeStore.AddNode (); 83 | SetTreeNodeValues (navigator, viewModel); 84 | AddChildTreeNodes (navigator, viewModel); 85 | } 86 | } 87 | 88 | void AddChildTreeNodes (TreeNavigator navigator, BaseViewModel viewModel) 89 | { 90 | foreach (BaseViewModel childViewModel in viewModel.Children) { 91 | TreeNavigator childNavigator = navigator.AddChild (); 92 | SetTreeNodeValues (childNavigator, childViewModel); 93 | AddChildTreeNodes (childNavigator, childViewModel); 94 | 95 | navigator.MoveToParent (); 96 | } 97 | } 98 | 99 | void SetTreeNodeValues (TreeNavigator navigator, BaseViewModel viewModel) 100 | { 101 | if (viewModel is NodeViewModel nodeViewModel) { 102 | navigator.SetValue (textDataField, GetTreeNodeText (nodeViewModel)); 103 | navigator.SetValue (imageDataField, GetTreeNodeImage (nodeViewModel)); 104 | } else { 105 | navigator.SetValue (textDataField, viewModel.Text); 106 | } 107 | 108 | navigator.SetValue (viewModelDataField, viewModel); 109 | } 110 | 111 | static string GetTreeNodeText (NodeViewModel nodeViewModel) 112 | { 113 | string markup = nodeViewModel.Text; 114 | 115 | switch (nodeViewModel.Result) { 116 | case Result.Failed: 117 | case Result.Succeeded: 118 | if (nodeViewModel.IsPrimary) { 119 | markup = "" + markup + ""; 120 | } 121 | return markup + " (" + nodeViewModel.Elapsed + ")"; 122 | 123 | case Result.Skipped: 124 | return "" + markup + ""; 125 | 126 | default: 127 | return markup; 128 | } 129 | } 130 | 131 | static Image GetTreeNodeImage (NodeViewModel nodeViewModel) 132 | { 133 | switch (nodeViewModel.Result) { 134 | case Result.Failed: 135 | return ImageService.GetIcon (Stock.Error, IconSize.Small); 136 | case Result.Succeeded: 137 | return ImageService.GetIcon ("md-done", IconSize.Small); 138 | 139 | default: 140 | return null; 141 | } 142 | } 143 | 144 | protected override void Dispose (bool disposing) 145 | { 146 | if (disposing) { 147 | treeView.SelectionChanged -= TreeViewSelectionChanged; 148 | } 149 | base.Dispose (disposing); 150 | } 151 | 152 | void TreeViewSelectionChanged (object sender, EventArgs e) 153 | { 154 | selectedViewModel = GetBaseViewModel (treeView.SelectedRow); 155 | } 156 | 157 | BaseViewModel GetBaseViewModel (TreePosition position) 158 | { 159 | if (position == null) 160 | return null; 161 | 162 | TreeNavigator navigator = treeStore.GetNavigatorAt (position); 163 | if (navigator == null) 164 | return null; 165 | 166 | return navigator.GetValue (viewModelDataField); 167 | } 168 | 169 | public object GetActiveComponent () 170 | { 171 | return selectedViewModel?.Properties; 172 | } 173 | 174 | public object GetProvider () 175 | { 176 | return GetActiveComponent (); 177 | } 178 | 179 | public void OnEndEditing (object obj) 180 | { 181 | } 182 | 183 | public void OnChanged (object obj) 184 | { 185 | } 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools.Gui/BinaryLogDocumentControllerExtension.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryLogDocumentControllerExtension.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.IO; 29 | using System.Threading.Tasks; 30 | using Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor; 31 | using MonoDevelop.Components; 32 | using MonoDevelop.Core; 33 | using MonoDevelop.DesignerSupport; 34 | using MonoDevelop.Ide.Gui.Documents; 35 | 36 | namespace MonoDevelop.ProjectSystem.Tools.Gui 37 | { 38 | class BinaryLogDocumentControllerExtension : DocumentControllerExtension, IPropertyPadProvider 39 | { 40 | DocumentView mainView; 41 | BinaryLogBuildTreeView buildTreeView; 42 | DocumentViewContent buildTreeDocumentView; 43 | BinaryLogTargetSummaryView targetSummaryView; 44 | BinaryLogTaskSummaryView taskSummaryView; 45 | //BinaryLogEvaluationSummaryView evaluationSummaryView; 46 | BinaryLogDocumentData binaryLogDocument; 47 | BinaryLogViewModels viewModels; 48 | FilePath originalFileName; 49 | 50 | public override Task SupportsController (DocumentController controller) 51 | { 52 | bool supported = false; 53 | if (controller is FileDocumentController fileController && 54 | fileController.FilePath.IsNotNull) { 55 | supported = fileController.FilePath.HasExtension (".binlog"); 56 | } 57 | 58 | return Task.FromResult (supported); 59 | } 60 | 61 | public override Task Initialize (Properties status) 62 | { 63 | var fileController = Controller as FileDocumentController; 64 | if (fileController != null) { 65 | return Initialize (fileController, status); 66 | } 67 | 68 | return base.Initialize (status); 69 | } 70 | 71 | async Task Initialize (FileDocumentController fileController, Properties status) 72 | { 73 | await base.Initialize (status); 74 | 75 | Controller.DocumentTitleChanged += OnDocumentTitleChanged; 76 | 77 | originalFileName = fileController.FilePath; 78 | 79 | binaryLogDocument = new BinaryLogDocumentData (); 80 | viewModels = new BinaryLogViewModels (binaryLogDocument); 81 | await Task.Run (() => { 82 | binaryLogDocument.Load (fileController.FilePath); 83 | viewModels.Build (); 84 | }); 85 | } 86 | 87 | public override void Dispose () 88 | { 89 | base.Dispose (); 90 | 91 | if (Controller != null) { 92 | Controller.DocumentTitleChanged -= OnDocumentTitleChanged; 93 | } 94 | 95 | mainView = null; 96 | } 97 | 98 | void OnDocumentTitleChanged (object sender, EventArgs e) 99 | { 100 | if (Controller is FileDocumentController fileController) { 101 | // Workaround the BuildOutputView setting the document title to be the full filepath. 102 | fileController.DocumentTitle = fileController.FilePath.FileName; 103 | } 104 | } 105 | 106 | protected override async Task OnInitializeView () 107 | { 108 | mainView = await base.OnInitializeView (); 109 | 110 | buildTreeView = new BinaryLogBuildTreeView (viewModels.BuildTreeViewItems); 111 | buildTreeDocumentView = AttachView (buildTreeView, GettextCatalog.GetString ("Build")); 112 | 113 | targetSummaryView = new BinaryLogTargetSummaryView (viewModels.TargetListViewItems); 114 | AttachView (targetSummaryView, GettextCatalog.GetString ("Target Summary")); 115 | 116 | taskSummaryView = new BinaryLogTaskSummaryView (viewModels.TaskListViewItems); 117 | AttachView (taskSummaryView, GettextCatalog.GetString ("Task Summary")); 118 | 119 | // Not seen any evaluations so not adding this view since it will always be empty. 120 | //evaluationSummaryView = new BinaryLogEvaluationSummaryView (viewModels.EvaluationListViewItems); 121 | //AttachView (evaluationSummaryView, GettextCatalog.GetString ("Evaluation Summary")); 122 | 123 | return mainView; 124 | } 125 | 126 | DocumentViewContent AttachView (Xwt.Widget childView, string title) 127 | { 128 | var content = new DocumentViewContent (() => new XwtControl (childView)) { 129 | Title = title 130 | }; 131 | mainView.AttachedViews.Add (content); 132 | 133 | return content; 134 | } 135 | 136 | /// 137 | /// Workaround SaveAs dialog being shown twice by the default BuildOutputViewContent. 138 | /// 139 | public override Task OnSave () 140 | { 141 | if (Controller is FileDocumentController fileController) { 142 | FilePath fileName = fileController.FilePath; 143 | if (originalFileName.IsNotNull) { 144 | File.Copy (originalFileName, fileName, true); 145 | originalFileName = fileName; 146 | return Task.CompletedTask; 147 | } 148 | } 149 | return base.OnSave (); 150 | } 151 | 152 | object IPropertyPadProvider.GetActiveComponent () 153 | { 154 | if (!IsBuildTreeViewActive ()) 155 | return null; 156 | 157 | return buildTreeView.GetActiveComponent (); 158 | } 159 | 160 | object IPropertyPadProvider.GetProvider () 161 | { 162 | if (!IsBuildTreeViewActive ()) 163 | return null; 164 | 165 | return buildTreeView.GetProvider (); 166 | } 167 | 168 | bool IsBuildTreeViewActive () 169 | { 170 | return mainView.ActiveViewInHierarchy == buildTreeDocumentView; 171 | } 172 | 173 | void IPropertyPadProvider.OnEndEditing (object obj) 174 | { 175 | } 176 | 177 | void IPropertyPadProvider.OnChanged (object obj) 178 | { 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools.Gui/BinaryLogEvaluationSummaryView.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryLogEvaluationSummaryView.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | 26 | using System.Collections.ObjectModel; 27 | using Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel; 28 | using MonoDevelop.Core; 29 | using Xwt; 30 | 31 | namespace MonoDevelop.ProjectSystem.Tools.Gui 32 | { 33 | class BinaryLogEvaluationSummaryView : BinaryLogSummaryViewBase 34 | { 35 | readonly ObservableCollection evaluationListViewItems; 36 | 37 | DataField nameDataField = new DataField (); 38 | DataField sourceFileNameDataField = new DataField (); 39 | DataField lineDataField = new DataField (); 40 | DataField lineSortField = new DataField (); 41 | DataField callsDataField = new DataField (); 42 | DataField callsSortField = new DataField (); 43 | DataField timeDataField = new DataField (); 44 | // Cannot sort on TimeSpan. Unsupported data type. 45 | DataField timeSortField = new DataField (); 46 | DataField percentageDataField = new DataField (); 47 | DataField percentageSortField = new DataField (); 48 | 49 | public BinaryLogEvaluationSummaryView (ObservableCollection evaluationListViewItems) 50 | { 51 | this.evaluationListViewItems = evaluationListViewItems; 52 | 53 | Build ( 54 | nameDataField, 55 | sourceFileNameDataField, 56 | lineDataField, 57 | lineSortField, 58 | callsDataField, 59 | callsSortField, 60 | timeDataField, 61 | timeSortField, 62 | percentageDataField, 63 | percentageSortField); 64 | 65 | AddListViewColumns (); 66 | AddListViewItems (); 67 | } 68 | 69 | void AddListViewColumns () 70 | { 71 | AddTextColumn (nameDataField, GettextCatalog.GetString ("Name")); 72 | AddTextColumn (sourceFileNameDataField, GettextCatalog.GetString ("File")); 73 | AddTextColumn (lineDataField, GettextCatalog.GetString ("Line"), lineSortField); 74 | AddTextColumn (callsDataField, GettextCatalog.GetString ("Calls"), callsSortField); 75 | AddTextColumn (timeDataField, GettextCatalog.GetString ("Time"), timeSortField); 76 | AddTextColumn (percentageDataField, GettextCatalog.GetString ("Percentage"), percentageSortField); 77 | } 78 | 79 | void AddListViewItems () 80 | { 81 | foreach (EvaluationListViewModel viewModel in evaluationListViewItems) { 82 | int row = listStore.AddRow (); 83 | 84 | listStore.SetValue (row, nameDataField, viewModel.Name); 85 | listStore.SetValue (row, sourceFileNameDataField, viewModel.SourceFilePath); 86 | listStore.SetValue (row, callsDataField, viewModel.Number.ToString ()); 87 | listStore.SetValue (row, callsSortField, viewModel.Number); 88 | 89 | listStore.SetValue (row, lineDataField, viewModel.Line.ToString ()); 90 | listStore.SetValue (row, lineSortField, viewModel.Line); 91 | 92 | SetTimeValue (row, viewModel.Time, timeDataField, timeSortField); 93 | SetPercentageValue (row, viewModel.Percentage, percentageDataField, percentageSortField); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools.Gui/BinaryLogSummaryViewBase.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryLogSummaryViewBase.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using Xwt; 29 | 30 | namespace MonoDevelop.ProjectSystem.Tools.Gui 31 | { 32 | abstract class BinaryLogSummaryViewBase : Widget 33 | { 34 | protected ListView listView; 35 | protected ListStore listStore; 36 | 37 | protected void Build (params IDataField[] fields) 38 | { 39 | listView = new ListView (); 40 | listView.BorderVisible = false; 41 | listView.HeadersVisible = true; 42 | 43 | listStore = new ListStore (fields); 44 | listView.DataSource = listStore; 45 | 46 | Content = listView; 47 | } 48 | 49 | protected void AddTextColumn (DataField dataField, string columnTitle, IDataField sortDataField = null) 50 | { 51 | var column = new ListViewColumn (); 52 | column.Title = columnTitle; 53 | column.SortDataField = sortDataField ?? dataField; 54 | 55 | var textViewCell = new TextCellView (); 56 | textViewCell.TextField = dataField; 57 | column.Views.Add (textViewCell); 58 | column.CanResize = true; 59 | listView.Columns.Add (column); 60 | } 61 | 62 | protected void SetTimeValue (int row, TimeSpan time, DataField dataField, DataField sortField) 63 | { 64 | listStore.SetValue (row, dataField, time.ToString (@"hh\:mm\:ss\:ffff")); 65 | listStore.SetValue (row, sortField, time.Ticks); 66 | } 67 | 68 | protected void SetPercentageValue (int row, double percentage, DataField dataField, DataField sortField) 69 | { 70 | listStore.SetValue (row, dataField, percentage.ToString ("P2")); 71 | listStore.SetValue (row, sortField, percentage); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools.Gui/BinaryLogTargetSummaryView.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryLogTargetSummaryView.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System.Collections.ObjectModel; 28 | using AppKit; 29 | using Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel; 30 | using MonoDevelop.Core; 31 | using Xwt; 32 | 33 | namespace MonoDevelop.ProjectSystem.Tools.Gui 34 | { 35 | class BinaryLogTargetSummaryView : BinaryLogSummaryViewBase 36 | { 37 | readonly ObservableCollection targetListViewItems; 38 | 39 | DataField targetNameDataField = new DataField (); 40 | DataField sourceFileNameDataField = new DataField (); 41 | DataField callsDataField = new DataField (); 42 | DataField callsSortField = new DataField (); 43 | DataField timeDataField = new DataField (); 44 | // Cannot sort on TimeSpan. Unsupported data type. 45 | DataField timeSortField = new DataField (); 46 | DataField percentageDataField = new DataField (); 47 | DataField percentageSortField = new DataField (); 48 | 49 | const int TargetNameColumnIndex = 0; 50 | const int SourceFileNameColumnIndex = 1; 51 | const int CallsColumnIndex = 2; 52 | const int TimeColumnIndex = 3; 53 | const int PercentageColumnIndex = 4; 54 | 55 | public BinaryLogTargetSummaryView (ObservableCollection targetListViewItems) 56 | { 57 | this.targetListViewItems = targetListViewItems; 58 | 59 | Build ( 60 | targetNameDataField, 61 | sourceFileNameDataField, 62 | callsDataField, 63 | callsSortField, 64 | timeDataField, 65 | timeSortField, 66 | percentageDataField, 67 | percentageSortField); 68 | 69 | AddListViewColumns (); 70 | AddListViewItems (); 71 | } 72 | 73 | void AddListViewColumns () 74 | { 75 | AddTextColumn (targetNameDataField, GettextCatalog.GetString ("Target Name")); 76 | AddTextColumn (sourceFileNameDataField, GettextCatalog.GetString ("Source")); 77 | AddTextColumn (callsDataField, GettextCatalog.GetString ("Calls"), callsSortField); 78 | AddTextColumn (timeDataField, GettextCatalog.GetString ("Time"), timeSortField); 79 | AddTextColumn (percentageDataField, GettextCatalog.GetString ("Percentage"), percentageSortField); 80 | 81 | SetInitialListViewColumnWidths (); 82 | } 83 | 84 | void AddListViewItems () 85 | { 86 | foreach (TargetListViewModel viewModel in targetListViewItems) { 87 | int row = listStore.AddRow (); 88 | 89 | listStore.SetValue (row, targetNameDataField, viewModel.Name); 90 | listStore.SetValue (row, sourceFileNameDataField, viewModel.SourceFilePath); 91 | listStore.SetValue (row, callsDataField, viewModel.Number.ToString ()); 92 | listStore.SetValue (row, callsSortField, viewModel.Number); 93 | 94 | SetTimeValue (row, viewModel.Time, timeDataField, timeSortField); 95 | SetPercentageValue (row, viewModel.Percentage, percentageDataField, percentageSortField); 96 | } 97 | } 98 | 99 | void SetInitialListViewColumnWidths () 100 | { 101 | var view = listView.Surface.NativeWidget as NSView; 102 | if (view is NSScrollView scroll) { 103 | view = scroll.DocumentView as NSView; 104 | } 105 | 106 | var tableView = view as NSTableView; 107 | if (tableView != null) { 108 | var columns = tableView.TableColumns (); 109 | 110 | columns[TargetNameColumnIndex].Width = 250; 111 | columns[SourceFileNameColumnIndex].Width = 250; 112 | columns[CallsColumnIndex].Width = 50; 113 | columns[TimeColumnIndex].Width = 100; 114 | columns[PercentageColumnIndex].Width = 80; 115 | 116 | tableView.Identifier = "MonoDevelop.BuildLogging.BuildLogTargetSummaryView.ListView"; 117 | tableView.AutosaveName = tableView.Identifier; 118 | tableView.AutosaveTableColumns = true; 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools.Gui/BinaryLogTaskSummaryView.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryLogTaskSummaryView.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System.Collections.ObjectModel; 28 | using AppKit; 29 | using Microsoft.VisualStudio.ProjectSystem.Tools.BinaryLogEditor.ViewModel; 30 | using MonoDevelop.Core; 31 | using Xwt; 32 | 33 | namespace MonoDevelop.ProjectSystem.Tools.Gui 34 | { 35 | class BinaryLogTaskSummaryView : BinaryLogSummaryViewBase 36 | { 37 | readonly ObservableCollection taskListViewItems; 38 | 39 | DataField taskNameDataField = new DataField (); 40 | DataField sourceFileNameDataField = new DataField (); 41 | DataField callsDataField = new DataField (); 42 | DataField callsSortField = new DataField (); 43 | DataField timeDataField = new DataField (); 44 | // Cannot sort on TimeSpan. Unsupported data type. 45 | DataField timeSortField = new DataField (); 46 | DataField percentageDataField = new DataField (); 47 | DataField percentageSortField = new DataField (); 48 | 49 | const int TargetNameColumnIndex = 0; 50 | const int SourceFileNameColumnIndex = 1; 51 | const int CallsColumnIndex = 2; 52 | const int TimeColumnIndex = 3; 53 | const int PercentageColumnIndex = 4; 54 | 55 | public BinaryLogTaskSummaryView (ObservableCollection taskListViewItems) 56 | { 57 | this.taskListViewItems = taskListViewItems; 58 | 59 | Build ( 60 | taskNameDataField, 61 | sourceFileNameDataField, 62 | callsDataField, 63 | callsSortField, 64 | timeDataField, 65 | timeSortField, 66 | percentageDataField, 67 | percentageSortField); 68 | 69 | AddListViewColumns (); 70 | AddListViewItems (); 71 | } 72 | 73 | void AddListViewColumns () 74 | { 75 | AddTextColumn (taskNameDataField, GettextCatalog.GetString ("Task Name")); 76 | AddTextColumn (sourceFileNameDataField, GettextCatalog.GetString ("Source")); 77 | AddTextColumn (callsDataField, GettextCatalog.GetString ("Calls"), callsSortField); 78 | AddTextColumn (timeDataField, GettextCatalog.GetString ("Time"), timeSortField); 79 | AddTextColumn (percentageDataField, GettextCatalog.GetString ("Percentage"), percentageSortField); 80 | 81 | SetInitialListViewColumnWidths (); 82 | } 83 | 84 | void AddListViewItems () 85 | { 86 | foreach (TaskListViewModel viewModel in taskListViewItems) { 87 | int row = listStore.AddRow (); 88 | 89 | listStore.SetValue (row, taskNameDataField, viewModel.Name); 90 | listStore.SetValue (row, sourceFileNameDataField, viewModel.SourceFilePath); 91 | listStore.SetValue (row, callsDataField, viewModel.Number.ToString ()); 92 | listStore.SetValue (row, callsSortField, viewModel.Number); 93 | 94 | SetTimeValue (row, viewModel.Time, timeDataField, timeSortField); 95 | SetPercentageValue (row, viewModel.Percentage, percentageDataField, percentageSortField); 96 | } 97 | } 98 | 99 | void SetInitialListViewColumnWidths () 100 | { 101 | var view = listView.Surface.NativeWidget as NSView; 102 | if (view is NSScrollView scroll) { 103 | view = scroll.DocumentView as NSView; 104 | } 105 | 106 | var tableView = view as NSTableView; 107 | if (tableView != null) { 108 | var columns = tableView.TableColumns (); 109 | 110 | columns[TargetNameColumnIndex].Width = 250; 111 | columns[SourceFileNameColumnIndex].Width = 250; 112 | columns[CallsColumnIndex].Width = 50; 113 | columns[TimeColumnIndex].Width = 100; 114 | columns[PercentageColumnIndex].Width = 80; 115 | 116 | tableView.Identifier = "MonoDevelop.BuildLogging.BuildLogTaskSummaryView.ListView"; 117 | tableView.AutosaveName = tableView.Identifier; 118 | tableView.AutosaveTableColumns = true; 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools.Gui/BuildLoggingPad.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BuildLoggingPad.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Linq; 29 | using MonoDevelop.Components; 30 | using MonoDevelop.Components.Declarative; 31 | using MonoDevelop.Components.Docking; 32 | using MonoDevelop.Core; 33 | using MonoDevelop.Ide.Gui; 34 | 35 | namespace MonoDevelop.ProjectSystem.Tools.Gui 36 | { 37 | public class BuildLoggingPad : PadContent 38 | { 39 | BuildLoggingWidget widget; 40 | XwtControl control; 41 | ToolbarButtonItem startButton; 42 | ToolbarButtonItem stopButton; 43 | ToolbarButtonItem clearButton; 44 | ToolbarPopUpButtonItem buildTypeFilterComboBox; 45 | ContextMenu buildTypeFilterMenu; 46 | ToolbarSearchItem searchEntry; 47 | TimeSpan searchDelayTimeSpan = TimeSpan.FromMilliseconds (250); 48 | IDisposable searchTimer; 49 | 50 | BuildType[] buildTypes = new BuildType [] { 51 | BuildType.All, 52 | BuildType.Build, 53 | BuildType.DesignTimeBuild 54 | }; 55 | 56 | public override Control Control { 57 | get { 58 | if (control == null) { 59 | widget = new BuildLoggingWidget (); 60 | control = new XwtControl (widget); 61 | } 62 | // Returning control does not work. 63 | return control.GetNativeWidget (); 64 | } 65 | } 66 | 67 | public override void Dispose () 68 | { 69 | ProjectSystemService.MSBuildTargetStarted -= MSBuildTargetStarted; 70 | ProjectSystemService.MSBuildTargetFinished -= MSBuildTargetFinished; 71 | 72 | startButton.Clicked -= OnStartButtonClicked; 73 | stopButton.Clicked -= OnStopButtonClicked; 74 | clearButton.Clicked -= OnClearButtonClicked; 75 | searchEntry.TextChanged -= SearchEntryChanged; 76 | 77 | foreach (ContextMenuItem menuItem in buildTypeFilterMenu.Items) { 78 | menuItem.Clicked -= BuildTypeFilterComboBoxChanged; 79 | } 80 | 81 | DisposeExistingTimer (); 82 | 83 | widget.Dispose (); 84 | 85 | base.Dispose (); 86 | } 87 | 88 | protected override void Initialize (IPadWindow window) 89 | { 90 | var toolbar = new Toolbar (); 91 | 92 | startButton = new ToolbarButtonItem (toolbar.Properties, nameof (startButton)); 93 | startButton.Icon = Ide.Gui.Stock.RunProgramIcon; 94 | startButton.Clicked += OnStartButtonClicked; 95 | startButton.Tooltip = GettextCatalog.GetString ("Enable build logging"); 96 | toolbar.AddItem (startButton); 97 | 98 | stopButton = new ToolbarButtonItem (toolbar.Properties, nameof (stopButton)); 99 | stopButton.Icon = Ide.Gui.Stock.Stop; 100 | stopButton.Clicked += OnStopButtonClicked; 101 | stopButton.Tooltip = GettextCatalog.GetString ("Stop build logging"); 102 | // Cannot disable the button before the underlying NSView is created. 103 | //stopButton.Enabled = false; 104 | toolbar.AddItem (stopButton); 105 | 106 | clearButton = new ToolbarButtonItem (toolbar.Properties, nameof (clearButton)); 107 | clearButton.Icon = Ide.Gui.Stock.Clear; 108 | clearButton.Clicked += OnClearButtonClicked; 109 | clearButton.Tooltip = GettextCatalog.GetString ("Clear"); 110 | toolbar.AddItem (clearButton); 111 | 112 | buildTypeFilterComboBox = new ToolbarPopUpButtonItem (toolbar.Properties, nameof (buildTypeFilterComboBox)); 113 | buildTypeFilterComboBox.Menu = CreateBuildTypeFilterMenu (); 114 | toolbar.AddItem (buildTypeFilterComboBox); 115 | 116 | searchEntry = new ToolbarSearchItem (toolbar.Properties, nameof (searchEntry)); 117 | searchEntry.Position = ToolbarItemPosition.Trailing; 118 | searchEntry.Label = GettextCatalog.GetString ("Search"); 119 | searchEntry.TextChanged += SearchEntryChanged; 120 | toolbar.AddItem (searchEntry); 121 | 122 | window.SetToolbar (toolbar, DockPositionType.Top); 123 | 124 | // Workaround being unable to set the button's Enabled state before the underlying 125 | // NSView is created. It is created after SetToolbar is called. 126 | stopButton.Enabled = false; 127 | 128 | ProjectSystemService.MSBuildTargetStarted += MSBuildTargetStarted; 129 | ProjectSystemService.MSBuildTargetFinished += MSBuildTargetFinished; 130 | } 131 | 132 | ContextMenu CreateBuildTypeFilterMenu () 133 | { 134 | string[] buildTypeItems = buildTypes 135 | .Select (buildType => GetDisplayText (buildType)) 136 | .ToArray (); 137 | 138 | buildTypeFilterMenu = new ContextMenu (); 139 | 140 | foreach (BuildType buildType in buildTypes) { 141 | var menuItem = new ContextMenuItem (); 142 | menuItem.Label = GetDisplayText (buildType); 143 | menuItem.Context = buildType; 144 | menuItem.Clicked += BuildTypeFilterComboBoxChanged; 145 | 146 | buildTypeFilterMenu.Items.Add (menuItem); 147 | } 148 | 149 | return buildTypeFilterMenu; 150 | } 151 | 152 | void OnStartButtonClicked (object sender, EventArgs e) 153 | { 154 | ProjectSystemService.IsEnabled = true; 155 | startButton.Enabled = false; 156 | stopButton.Enabled = true; 157 | } 158 | 159 | void OnStopButtonClicked (object sender, EventArgs e) 160 | { 161 | ProjectSystemService.IsEnabled = false; 162 | startButton.Enabled = true; 163 | stopButton.Enabled = false; 164 | } 165 | 166 | void OnClearButtonClicked (object sender, EventArgs e) 167 | { 168 | widget.ClearItems (); 169 | } 170 | 171 | void MSBuildTargetStarted (object sender, MSBuildTargetEventArgs e) 172 | { 173 | Runtime.AssertMainThread (); 174 | 175 | widget.AddMSBuildTarget (e.BuildTarget); 176 | } 177 | 178 | void MSBuildTargetFinished (object sender, MSBuildTargetEventArgs e) 179 | { 180 | Runtime.AssertMainThread (); 181 | 182 | widget.UpdateMSBuildTarget (e.BuildTarget); 183 | } 184 | 185 | static string GetDisplayText (BuildType buildType) 186 | { 187 | switch (buildType) { 188 | case BuildType.All: 189 | return GettextCatalog.GetString ("All"); 190 | case BuildType.Build: 191 | return GettextCatalog.GetString ("Builds"); 192 | case BuildType.DesignTimeBuild: 193 | return GettextCatalog.GetString ("Design-time Builds"); 194 | default: 195 | return buildType.ToString (); 196 | } 197 | } 198 | 199 | void BuildTypeFilterComboBoxChanged (object sender, ContextMenuItemClickedEventArgs e) 200 | { 201 | widget.BuildType = (BuildType)e.Context; 202 | } 203 | 204 | void SearchEntryChanged (object sender, EventArgs e) 205 | { 206 | DisposeExistingTimer (); 207 | searchTimer = Xwt.Application.TimeoutInvoke (searchDelayTimeSpan, Search); 208 | } 209 | 210 | bool Search () 211 | { 212 | widget.SearchFilter = searchEntry.Text; 213 | return false; 214 | } 215 | 216 | void DisposeExistingTimer () 217 | { 218 | if (searchTimer != null) { 219 | searchTimer.Dispose (); 220 | } 221 | } 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools.Gui/BuildLoggingWidget.UI.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BuildLoggingWidget.UI.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using AppKit; 28 | using MonoDevelop.Core; 29 | using Xwt; 30 | 31 | namespace MonoDevelop.ProjectSystem.Tools.Gui 32 | { 33 | partial class BuildLoggingWidget : Widget 34 | { 35 | ListView listView; 36 | ListStore listStore; 37 | DataField projectDataField = new DataField (); 38 | DataField dimensionsDataField = new DataField (); 39 | DataField targetsDataField = new DataField (); 40 | DataField typeDataField = new DataField (); 41 | DataField startDataField = new DataField (); 42 | DataField elapsedDataField = new DataField (); 43 | DataField statusDataField = new DataField (); 44 | DataField msbuildTargetDataField = new DataField (); 45 | 46 | const int ProjectColumnIndex = 0; 47 | const int DimensionsColumnIndex = 1; 48 | const int TargetsColumnIndex = 2; 49 | const int TypeColumnIndex = 3; 50 | const int StartColumnIndex = 4; 51 | const int ElapsedColumnIndex = 5; 52 | const int StatusColumnIndex = 6; 53 | 54 | void Build () 55 | { 56 | listView = new ListView (); 57 | listView.BorderVisible = false; 58 | listView.HeadersVisible = true; 59 | listStore = new ListStore ( 60 | projectDataField, 61 | dimensionsDataField, 62 | targetsDataField, 63 | typeDataField, 64 | startDataField, 65 | elapsedDataField, 66 | statusDataField, 67 | msbuildTargetDataField); 68 | listView.DataSource = listStore; 69 | 70 | AddTextColumn (projectDataField, GettextCatalog.GetString ("Project")); 71 | AddTextColumn (dimensionsDataField, GettextCatalog.GetString ("Dimensions")); 72 | AddTextColumn (targetsDataField, GettextCatalog.GetString ("Targets")); 73 | AddTextColumn (typeDataField, GettextCatalog.GetString ("Type")); 74 | AddTextColumn (startDataField, GettextCatalog.GetString ("Start")); 75 | AddTextColumn (elapsedDataField, GettextCatalog.GetString ("Elapsed")); 76 | AddTextColumn (statusDataField, GettextCatalog.GetString ("Status")); 77 | 78 | SetInitialListViewColumnWidths (); 79 | 80 | Content = listView; 81 | } 82 | 83 | void AddTextColumn (DataField dataField, string columnTitle) 84 | { 85 | var column = new ListViewColumn (); 86 | column.Title = columnTitle; 87 | var textViewCell = new TextCellView (); 88 | textViewCell.TextField = dataField; 89 | column.Views.Add (textViewCell); 90 | column.CanResize = true; 91 | listView.Columns.Add (column); 92 | } 93 | 94 | void SetInitialListViewColumnWidths () 95 | { 96 | var view = listView.Surface.NativeWidget as NSView; 97 | if (view is NSScrollView scroll) { 98 | view = scroll.DocumentView as NSView; 99 | } 100 | 101 | var tableView = view as NSTableView; 102 | if (tableView != null) { 103 | var columns = tableView.TableColumns (); 104 | 105 | columns[ProjectColumnIndex].Width = 250; 106 | columns[DimensionsColumnIndex].Width = 150; 107 | columns[TargetsColumnIndex].Width = 450; 108 | columns[TypeColumnIndex].Width = 100; 109 | columns[StartColumnIndex].Width = 150; 110 | columns[ElapsedColumnIndex].Width = 60; 111 | columns[StatusColumnIndex].Width = 70; 112 | 113 | tableView.Identifier = "MonoDevelop.BuildLogging.BuildingLoggingWindow.ListView"; 114 | tableView.AutosaveName = tableView.Identifier; 115 | tableView.AutosaveTableColumns = true; 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools.Gui/BuildLoggingWidget.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BuildLoggingWidget.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.IO; 30 | using AppKit; 31 | using CoreGraphics; 32 | using MonoDevelop.Components; 33 | using MonoDevelop.Components.Commands; 34 | using MonoDevelop.Core; 35 | using MonoDevelop.Ide; 36 | using MonoDevelop.Projects; 37 | using Xwt; 38 | 39 | namespace MonoDevelop.ProjectSystem.Tools.Gui 40 | { 41 | partial class BuildLoggingWidget 42 | { 43 | BuildType buildType = BuildType.All; 44 | string searchFilter = string.Empty; 45 | List msbuildTargets = new List (); 46 | 47 | public BuildLoggingWidget () 48 | { 49 | Build (); 50 | 51 | listView.RowActivated += ListViewRowActivated; 52 | listView.ButtonPressed += ListViewButtonPressed; 53 | } 54 | 55 | public void ClearItems () 56 | { 57 | DeleteMSBuildOutputFiles (); 58 | 59 | msbuildTargets.Clear (); 60 | listStore.Clear (); 61 | } 62 | 63 | public void AddMSBuildTarget (MSBuildTarget target) 64 | { 65 | msbuildTargets.Add (target); 66 | 67 | if (IsAllowedByFilter (target)) { 68 | AddMSBuildTargetToListView (target); 69 | } 70 | } 71 | 72 | bool IsAllowedByFilter (MSBuildTarget target) 73 | { 74 | if (buildType != BuildType.All && 75 | buildType != target.BuildType) { 76 | return false; 77 | } 78 | 79 | return IsAllowedBySearchFilter (target); 80 | } 81 | 82 | void AddMSBuildTargetToListView (MSBuildTarget target) 83 | { 84 | int row = listStore.AddRow (); 85 | 86 | listStore.SetValues ( 87 | row, 88 | 89 | projectDataField, 90 | target.ProjectFileName.FileName, 91 | 92 | dimensionsDataField, 93 | target.Dimensions, 94 | 95 | elapsedDataField, 96 | GetDisplayText (target.Duration), 97 | 98 | targetsDataField, 99 | target.Targets, 100 | 101 | typeDataField, 102 | target.BuildType.ToString (), 103 | 104 | startDataField, 105 | GetDisplayText (target.StartTime), 106 | 107 | statusDataField, 108 | target.Status.GetDisplayText (), 109 | 110 | msbuildTargetDataField, 111 | target); 112 | } 113 | 114 | static string GetDisplayText (TimeSpan? duration) 115 | { 116 | if (!duration.HasValue) { 117 | return string.Empty; 118 | } 119 | 120 | return duration.Value.TotalSeconds.ToString ("N3"); 121 | } 122 | 123 | static string GetDisplayText (DateTime time) 124 | { 125 | return time.ToString ("s"); 126 | } 127 | 128 | public void UpdateMSBuildTarget (MSBuildTarget target) 129 | { 130 | for (int row = listStore.RowCount - 1; row >= 0; --row) { 131 | MSBuildTarget currentTarget = listStore.GetValue (row, msbuildTargetDataField); 132 | if (target == currentTarget) { 133 | listStore.SetValues ( 134 | row, 135 | 136 | elapsedDataField, 137 | GetDisplayText (target.Duration), 138 | 139 | statusDataField, 140 | target.Status.GetDisplayText ()); 141 | 142 | return; 143 | } 144 | } 145 | } 146 | 147 | protected override void Dispose (bool disposing) 148 | { 149 | if (disposing) { 150 | listView.RowActivated -= ListViewRowActivated; 151 | listView.ButtonPressed -= ListViewButtonPressed; 152 | 153 | DeleteMSBuildOutputFiles (); 154 | } 155 | base.Dispose (disposing); 156 | } 157 | 158 | void DeleteMSBuildOutputFiles () 159 | { 160 | MSBuildTarget target = null; 161 | 162 | for (int row = 0; row < listStore.RowCount; ++row) { 163 | try { 164 | target = listStore.GetValue (row, msbuildTargetDataField); 165 | 166 | if (target.LogFileName.IsNotNull) { 167 | File.Delete (target.LogFileName); 168 | } 169 | 170 | if (target.BinLogFileName.IsNotNull) { 171 | File.Delete (target.BinLogFileName); 172 | } 173 | } catch (Exception ex) { 174 | LoggingService.LogError ( 175 | string.Format ("Unable to remove msbuild output file {0}", target), 176 | ex); 177 | } 178 | } 179 | } 180 | 181 | void ListViewRowActivated (object sender, ListViewRowEventArgs e) 182 | { 183 | OpenLogFileForRow (e.RowIndex); 184 | } 185 | 186 | void OpenLogFileForRow (int row, bool binLog = false) 187 | { 188 | MSBuildTarget target = GetMSBuildTargetForRow (row); 189 | 190 | FilePath fileNameToOpen = binLog ? target.BinLogFileName : target.LogFileName; 191 | 192 | if (fileNameToOpen.IsNotNull && File.Exists (fileNameToOpen)) { 193 | IdeApp.Workbench.OpenDocument (fileNameToOpen, (Project)null) 194 | .Ignore (); 195 | } 196 | } 197 | 198 | MSBuildTarget GetMSBuildTargetForSelectedRow () 199 | { 200 | return GetMSBuildTargetForRow (listView.SelectedRow); 201 | } 202 | 203 | MSBuildTarget GetMSBuildTargetForRow (int row) 204 | { 205 | if (row < 0) { 206 | return null; 207 | } 208 | 209 | return listStore.GetValue (row, msbuildTargetDataField); 210 | } 211 | 212 | void ListViewButtonPressed (object sender, ButtonEventArgs e) 213 | { 214 | if (!e.IsContextMenuTrigger) { 215 | return; 216 | } 217 | 218 | var commands = IdeApp.CommandService.CreateCommandEntrySet ("/MonoDevelop/BuildLoggingPad/ContextMenu"); 219 | var view = listView.Surface.NativeWidget as NSView; 220 | var menu = IdeApp.CommandService.CreateNSMenu (commands, this); 221 | ShowContextMenu (view, (int)e.X, (int)e.Y, menu); 222 | } 223 | 224 | /// 225 | /// Take from main/src/core/MonoDevelop.Ide/MonoDevelop.Components/ContextMenuExtensionsMac.cs 226 | /// 227 | static void ShowContextMenu (NSView parent, int x, int y, NSMenu menu, bool selectFirstItem = false, bool convertToViewCoordinates = true) 228 | { 229 | if (parent == null) 230 | throw new ArgumentNullException ("parent"); 231 | if (menu == null) 232 | throw new ArgumentNullException ("menu"); 233 | 234 | var pt = convertToViewCoordinates ? parent.ConvertPointToView (new CGPoint (x, y), null) : new CGPoint (x, y); 235 | if (selectFirstItem) { 236 | menu.PopUpMenu (menu.ItemAt (0), pt, parent); 237 | } else { 238 | var tmp_event = NSEvent.MouseEvent (NSEventType.LeftMouseDown, 239 | pt, 240 | 0, 0, 241 | parent.Window.WindowNumber, 242 | null, 0, 0, 0); 243 | 244 | // the following lines are here to dianose & fix VSTS 1026106 - we were getting 245 | // a SigSegv from here and it is likely caused by NSEvent being null, however 246 | // it's worth leaving Debug checks in just to be on the safe side 247 | if (tmp_event == null) { 248 | // since this is often called outside of a try/catch loop, we'll just 249 | // log an error and not throw the exception 250 | LoggingService.LogInternalError (new ArgumentNullException (nameof (tmp_event))); 251 | return; 252 | } 253 | 254 | System.Diagnostics.Debug.Assert (parent != null, "Parent was modified (set to null) during execution."); 255 | System.Diagnostics.Debug.Assert (menu != null, "Menu was modified (set to null) during execution."); 256 | 257 | NSMenu.PopUpContextMenu (menu, tmp_event, parent); 258 | } 259 | } 260 | 261 | [CommandUpdateHandler (BuildLoggingCommands.OpenLogFile)] 262 | void OnUpdateOpenLogFile (CommandInfo info) 263 | { 264 | info.Enabled = MSBuildLogFileExists (); 265 | } 266 | 267 | [CommandHandler (BuildLoggingCommands.OpenLogFile)] 268 | void OpenLogFile () 269 | { 270 | if (IsMSBuildTargetSelected ()) { 271 | OpenLogFileForRow (listView.SelectedRow); 272 | } 273 | } 274 | 275 | [CommandUpdateHandler (BuildLoggingCommands.OpenBinLogFile)] 276 | void OnUpdateOpenBinLogFile (CommandInfo info) 277 | { 278 | info.Enabled = MSBuildBinLogFileExists (); 279 | } 280 | 281 | [CommandHandler (BuildLoggingCommands.OpenBinLogFile)] 282 | void OpenBinLogFile () 283 | { 284 | if (IsMSBuildTargetSelected ()) { 285 | OpenLogFileForRow (listView.SelectedRow, binLog: true); 286 | } 287 | } 288 | 289 | bool MSBuildLogFileExists () 290 | { 291 | MSBuildTarget target = GetMSBuildTargetForSelectedRow (); 292 | 293 | return target != null && 294 | target.LogFileName.IsNotNull && 295 | File.Exists (target.LogFileName); 296 | } 297 | 298 | bool MSBuildBinLogFileExists () 299 | { 300 | MSBuildTarget target = GetMSBuildTargetForSelectedRow (); 301 | 302 | if (target == null) { 303 | return false; 304 | } 305 | 306 | target.CopyBinLogFile (); 307 | 308 | return target.BinLogFileName.IsNotNull && 309 | File.Exists (target.BinLogFileName); 310 | } 311 | 312 | bool IsMSBuildTargetSelected () 313 | { 314 | return listView.SelectedRow >= 0; 315 | } 316 | 317 | public BuildType BuildType { 318 | get { return buildType; } 319 | set { 320 | buildType = value; 321 | ApplyFilter (); 322 | } 323 | } 324 | 325 | public string SearchFilter { 326 | get { return searchFilter; } 327 | set { 328 | searchFilter = value; 329 | ApplyFilter (); 330 | } 331 | } 332 | 333 | void ApplyFilter () 334 | { 335 | listStore.Clear (); 336 | 337 | foreach (MSBuildTarget target in msbuildTargets) { 338 | if (IsAllowedByFilter (target)) { 339 | AddMSBuildTargetToListView (target); 340 | } 341 | } 342 | } 343 | 344 | bool IsAllowedBySearchFilter (MSBuildTarget target) 345 | { 346 | if (string.IsNullOrEmpty (searchFilter)) { 347 | return true; 348 | } 349 | 350 | return 351 | IsSearchFilterMatch (target.BuildType.ToString ()) || 352 | IsSearchFilterMatch (target.Dimensions) || 353 | IsSearchFilterMatch (target.ProjectFileName.FileName) || 354 | IsSearchFilterMatch (target.ProjectName) || 355 | IsSearchFilterMatch (target.Status.GetDisplayText ()) || 356 | IsSearchFilterMatch (target.Targets) || 357 | IsSearchFilterMatch (GetDisplayText (target.Duration)) || 358 | IsSearchFilterMatch (GetDisplayText (target.StartTime)); 359 | } 360 | 361 | bool IsSearchFilterMatch (string text) 362 | { 363 | if (string.IsNullOrEmpty (text)) { 364 | return false; 365 | } 366 | 367 | return text.IndexOf (searchFilter, StringComparison.OrdinalIgnoreCase) >= 0; 368 | } 369 | } 370 | } 371 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | net7.0 6 | false 7 | false 8 | ..\..\bin 9 | 10 | 11 | 12 | $(MDBinDir)\Microsoft.Build.dll 13 | False 14 | 15 | 16 | $(MDBinDir)\Microsoft.Build.Framework.dll 17 | False 18 | 19 | 20 | $(MDBinDir)\Microsoft.Build.Utilities.Core.dll 21 | False 22 | 23 | 24 | 25 | 26 | BuildLoggingWidget.cs 27 | 28 | 29 | 30 | 31 | MonoDevelop.ProjectSystem.Tools.addin.xml 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/BinaryLogProcessor.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryLogProcessor.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Collections; 29 | using System.Collections.Generic; 30 | using Microsoft.Build.Framework; 31 | using Microsoft.Build.Logging; 32 | using MonoDevelop.Core; 33 | 34 | namespace MonoDevelop.ProjectSystem.Tools 35 | { 36 | class BinaryLogProcessor : IDisposable 37 | { 38 | readonly FilePath binLogFileName; 39 | readonly BinaryLogReplayEventSource replayEventSource = new BinaryLogReplayEventSource (); 40 | readonly HashSet projectFileNames = new HashSet (); 41 | 42 | public BinaryLogProcessor (FilePath binLogFileName) 43 | { 44 | this.binLogFileName = binLogFileName; 45 | 46 | replayEventSource.ProjectStarted += ProjectStarted; 47 | } 48 | 49 | public IEnumerable ProjectFileNames { 50 | get { return projectFileNames; } 51 | } 52 | 53 | public void Dispose () 54 | { 55 | replayEventSource.ProjectStarted -= ProjectStarted; 56 | } 57 | 58 | public void Process () 59 | { 60 | replayEventSource.Replay (binLogFileName); 61 | } 62 | 63 | void ProjectStarted (object sender, ProjectStartedEventArgs e) 64 | { 65 | if (!string.IsNullOrEmpty (e.ProjectFile)) { 66 | projectFileNames.Add (e.ProjectFile); 67 | } 68 | 69 | if (e.Properties == null) { 70 | return; 71 | } 72 | 73 | foreach (DictionaryEntry entry in e.Properties) { 74 | var key = entry.Key as string; 75 | if (key == "MSBuildProjectFullPath") { 76 | var fileName = new FilePath ((string)entry.Value); 77 | projectFileNames.Add (fileName); 78 | } 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/BuildLoggingCommands.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BuildLoggingCommands.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | namespace MonoDevelop.ProjectSystem.Tools 28 | { 29 | enum BuildLoggingCommands 30 | { 31 | OpenLogFile, 32 | OpenBinLogFile 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/BuildLoggingProjectExtension.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BuildLoggingProjectExtension.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | using System; 27 | using System.Threading.Tasks; 28 | using MonoDevelop.Core; 29 | using MonoDevelop.Projects; 30 | 31 | namespace MonoDevelop.ProjectSystem.Tools 32 | { 33 | class BuildLoggingProjectExtension : ProjectExtension 34 | { 35 | protected override Task OnRunTarget ( 36 | ProgressMonitor monitor, 37 | string target, 38 | ConfigurationSelector configuration, 39 | TargetEvaluationContext context) 40 | { 41 | if (ProjectSystemService.IsEnabled) { 42 | return OnMonitorRunTarget (monitor, target, configuration, context); 43 | } 44 | return base.OnRunTarget (monitor, target, configuration, context); 45 | } 46 | 47 | async Task OnMonitorRunTarget ( 48 | ProgressMonitor monitor, 49 | string target, 50 | ConfigurationSelector configuration, 51 | TargetEvaluationContext context) 52 | { 53 | using (var buildMonitor = new MSBuildTargetMonitor (Project, target, configuration, context)) { 54 | try { 55 | ProgressMonitor modifiedMonitor = buildMonitor.GetProgressMonitor (monitor); 56 | TargetEvaluationResult result = await base.OnRunTarget (modifiedMonitor, target, configuration, context); 57 | buildMonitor.OnResult (result); 58 | return result; 59 | } catch (Exception ex) { 60 | buildMonitor.OnException (ex); 61 | throw; 62 | } 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/BuildLoggingSolutionExtension.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BuildLoggingSolutionExtension.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System.Threading.Tasks; 28 | using MonoDevelop.Core; 29 | using MonoDevelop.Core.ProgressMonitoring; 30 | using MonoDevelop.Projects; 31 | 32 | namespace MonoDevelop.ProjectSystem.Tools 33 | { 34 | class BuildLoggingSolutionExtension : SolutionExtension 35 | { 36 | protected override Task OnBeginBuildOperation ( 37 | ProgressMonitor monitor, 38 | ConfigurationSelector configuration, 39 | OperationContext operationContext) 40 | { 41 | if (ProjectSystemService.IsEnabled) { 42 | monitor = AddMSBuildBinLogProgressMonitor (monitor); 43 | } 44 | return base.OnBeginBuildOperation (monitor, configuration, operationContext); 45 | } 46 | 47 | ProgressMonitor AddMSBuildBinLogProgressMonitor (ProgressMonitor monitor) 48 | { 49 | var aggregatedMonitor = monitor as AggregatedProgressMonitor; 50 | if (aggregatedMonitor == null) { 51 | aggregatedMonitor = new AggregatedProgressMonitor (monitor); 52 | } 53 | 54 | // Enable monitor for WriteLog only. This avoids errors due to a task being started before 55 | // the OnBeginBuildOperation was called which the bin log progress monitor is not aware of. 56 | var binLogMonitor = new MSBuildBinLogProgressMonitor (); 57 | aggregatedMonitor.AddFollowerMonitor (binLogMonitor, binLogMonitor.Actions); 58 | 59 | return aggregatedMonitor; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/BuildSession.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BuildSession.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.IO; 30 | using System.Linq; 31 | using System.Threading.Tasks; 32 | using MonoDevelop.Core; 33 | using MonoDevelop.Projects; 34 | 35 | namespace MonoDevelop.ProjectSystem.Tools 36 | { 37 | sealed class BuildSession 38 | { 39 | public BuildSession (BuildSessionStartedEvent buildSessionStarted) 40 | { 41 | Id = buildSessionStarted.SessionId; 42 | BinLogFileName = buildSessionStarted.LogFile; 43 | IsRunning = true; 44 | ProjectFileNames = new List (); 45 | } 46 | 47 | public int Id { get; set; } 48 | public FilePath BinLogFileName { get; set; } 49 | 50 | public bool IsRunning { get; set; } 51 | 52 | /// 53 | /// Populated at the end of the solution build session after the binlog is processed. 54 | /// 55 | public List ProjectFileNames { get; private set; } 56 | 57 | public Task ProcessBuildSessionAsync () 58 | { 59 | if (!BackupBinLogFile ()) { 60 | return Task.CompletedTask;; 61 | } 62 | 63 | if (Runtime.IsMainThread) { 64 | return Task.Run (() => ProcessBuildSessionAsync ()); 65 | } 66 | 67 | try { 68 | using (var processor = new BinaryLogProcessor (BinLogFileName)) { 69 | processor.Process (); 70 | ProjectFileNames = processor.ProjectFileNames.ToList (); 71 | } 72 | } catch (Exception ex) { 73 | LoggingService.LogError (string.Format ("Unable to process binlog '{0}'", BinLogFileName), ex); 74 | } 75 | 76 | return Task.CompletedTask; 77 | } 78 | 79 | /// 80 | /// Need to make a copy of the binlog since the built-in binlog viewer will delete the file. 81 | /// 82 | bool BackupBinLogFile () 83 | { 84 | try { 85 | FilePath newBinLogFileName = BinLogFileName.ChangeName (BinLogFileName.FileNameWithoutExtension + "-copy"); 86 | File.Copy (BinLogFileName, newBinLogFileName); 87 | BinLogFileName = newBinLogFileName; 88 | 89 | return true; 90 | } catch (Exception ex) { 91 | LoggingService.LogError (string.Format ("Unable to copy binlog file '{0}'", BinLogFileName), ex); 92 | } 93 | 94 | return false; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/BuildType.cs: -------------------------------------------------------------------------------- 1 | // 2 | // BuildType.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | namespace MonoDevelop.ProjectSystem.Tools 28 | { 29 | enum BuildType 30 | { 31 | None = 0, 32 | All = 1, 33 | Build, 34 | DesignTimeBuild 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/MSBuildBinLogProgressMonitor.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MSBuildBinLogProgressMonitor.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using MonoDevelop.Core; 28 | using MonoDevelop.Core.ProgressMonitoring; 29 | using MonoDevelop.Projects; 30 | 31 | namespace MonoDevelop.ProjectSystem.Tools 32 | { 33 | class MSBuildBinLogProgressMonitor : ProgressMonitor 34 | { 35 | public MonitorAction Actions { 36 | get { return MonitorAction.WriteLog; } 37 | } 38 | 39 | protected override void OnWriteLogObject (object logObject) 40 | { 41 | var buildSessionStarted = logObject as BuildSessionStartedEvent; 42 | var buildSessionFinished = logObject as BuildSessionFinishedEvent; 43 | if (buildSessionStarted != null) { 44 | ProjectSystemService.OnBuildSessionStarted (buildSessionStarted); 45 | } else if (buildSessionFinished != null) { 46 | ProjectSystemService.OnBuildSessionFinished (buildSessionFinished); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/MSBuildProcessArguments.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MSBuildProcessArguments.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Text; 29 | using MonoDevelop.Core; 30 | using MonoDevelop.Core.PooledObjects; 31 | using MonoDevelop.Projects.MSBuild; 32 | 33 | namespace MonoDevelop.ProjectSystem.Tools 34 | { 35 | class MSBuildProcessArguments 36 | { 37 | string arguments; 38 | 39 | public MSBuildProcessArguments (string arguments) 40 | { 41 | this.arguments = arguments ?? string.Empty; 42 | Parse (); 43 | } 44 | 45 | public override string ToString () 46 | { 47 | return arguments; 48 | } 49 | 50 | public string Targets { get; internal set; } 51 | public BuildType BuildType { get; internal set; } 52 | 53 | void Parse () 54 | { 55 | const string targetArgument = "--target:"; 56 | 57 | var targetsBuilder = PooledStringBuilder.GetInstance (); 58 | 59 | string[] parts = arguments.Split (' '); 60 | foreach (string part in parts) { 61 | if (part.StartsWith (targetArgument)) { 62 | AppendTargets (targetsBuilder, part.Substring (targetArgument.Length + 1)); 63 | } else if (part.StartsWith ("/t") || part.StartsWith ("-t")) { 64 | AppendTargets (targetsBuilder, part.Substring (3)); 65 | } 66 | } 67 | 68 | Targets = targetsBuilder.ToStringAndFree (); 69 | BuildType = MSBuildTarget.GetBuildType (Targets); 70 | } 71 | 72 | static void AppendTargets (StringBuilder targetsBuilder, string targets) 73 | { 74 | if (targetsBuilder.Length > 0) { 75 | targetsBuilder.Append (';'); 76 | } 77 | 78 | targetsBuilder.Append (targets); 79 | } 80 | 81 | /// 82 | /// Adding a verbosity parameter to the end overrides any existing verbosity parameters. 83 | /// 84 | public static string AddVerbosity (string arguments, MSBuildVerbosity verbosity) 85 | { 86 | return arguments + GetVerbosityArgument (verbosity); 87 | } 88 | 89 | static string GetVerbosityArgument (MSBuildVerbosity verbosity) 90 | { 91 | switch (verbosity) { 92 | case MSBuildVerbosity.Detailed: 93 | return " /v:d"; 94 | case MSBuildVerbosity.Diagnostic: 95 | return " /v:diag"; 96 | case MSBuildVerbosity.Minimal: 97 | return " /v:m"; 98 | case MSBuildVerbosity.Quiet: 99 | return " /v:q"; 100 | default: // Normal 101 | return " /v:n"; 102 | } 103 | } 104 | 105 | public static string AddBinLogFileName (string arguments, FilePath binLogFileName) 106 | { 107 | return arguments + GetQuotedBinLogArgument (binLogFileName); 108 | } 109 | 110 | static string GetQuotedBinLogArgument (FilePath binLogFileName) 111 | { 112 | return " /bl:\"" + binLogFileName + "\""; 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/MSBuildProcessProgressMonitor.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MSBuildProcessProgressMonitor.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System.IO; 28 | using MonoDevelop.Core; 29 | using MonoDevelop.Core.Execution; 30 | 31 | namespace MonoDevelop.ProjectSystem.Tools 32 | { 33 | class MSBuildProcessProgressMonitor : MSBuildTargetProgressMonitor 34 | { 35 | public MSBuildProcessProgressMonitor ( 36 | TextWriter outWriter, 37 | TextWriter errorWriter, 38 | FilePath logFileName) 39 | : base (logFileName) 40 | { 41 | // Setting Log and ErrorLog will chain these writers to the 42 | // ProgressMonitor's Log and ErrorLog writers. 43 | Log = outWriter; 44 | ErrorLog = errorWriter; 45 | } 46 | 47 | public ProcessWrapper Process { get; set; } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/MSBuildProcessServiceMonitor.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MSBuildProcessServiceMonitor.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.IO; 30 | using System.Threading; 31 | using MonoDevelop.Core; 32 | using MonoDevelop.Core.Execution; 33 | using MonoDevelop.Ide; 34 | using MonoDevelop.Projects.MSBuild; 35 | 36 | namespace MonoDevelop.ProjectSystem.Tools 37 | { 38 | class MSBuildProcessServiceMonitor : IDisposable 39 | { 40 | readonly MSBuildProcessService.StartTrackedProcessCallback originalHandler; 41 | readonly Dictionary buildTargets = new Dictionary (); 42 | 43 | static int sessionId; 44 | 45 | public MSBuildProcessServiceMonitor () 46 | { 47 | originalHandler = MSBuildProcessService.StartTrackedProcessHandler; 48 | MSBuildProcessService.StartTrackedProcessHandler = StartProcess; 49 | } 50 | 51 | public void Dispose () 52 | { 53 | MSBuildProcessService.StartTrackedProcessHandler = originalHandler; 54 | } 55 | 56 | ProcessWrapper StartProcess (ProcessStartArgs args) 57 | { 58 | int currentSessionId = Interlocked.Increment (ref sessionId); 59 | 60 | var msbuildProcessArguments = new MSBuildProcessArguments (args.Arguments); 61 | 62 | var buildTarget = new MSBuildTarget { 63 | ProjectName = GettextCatalog.GetString ("Solution"), 64 | ProjectFileName = GettextCatalog.GetString ("Solution"), 65 | Targets = msbuildProcessArguments.Targets, 66 | BuildType = msbuildProcessArguments.BuildType, 67 | Dimensions = GetDimensions (msbuildProcessArguments.Targets) 68 | }; 69 | 70 | buildTarget.Start (); 71 | 72 | args.Arguments = MSBuildProcessArguments.AddVerbosity (args.Arguments, Runtime.Preferences.MSBuildVerbosity.Value); 73 | args.Arguments = MSBuildProcessArguments.AddBinLogFileName (args.Arguments, buildTarget.BinLogFileName); 74 | 75 | lock (buildTargets) { 76 | buildTargets [currentSessionId] = buildTarget; 77 | } 78 | 79 | ProjectSystemService.OnTargetStarted (buildTarget); 80 | 81 | var monitor = new MSBuildProcessProgressMonitor (args.OutWriter, args.ErrorWriter, buildTarget.LogFileName); 82 | 83 | ProcessWrapper process = Runtime.ProcessService.StartProcess ( 84 | args.Command, 85 | args.Arguments, 86 | args.WorkingDirectory, 87 | monitor.Log, 88 | monitor.ErrorLog, 89 | args.Exited); 90 | 91 | monitor.Process = process; 92 | 93 | process.Task.ContinueWith (_ => { 94 | OnMSBuildProcessExited (currentSessionId, monitor); 95 | }); 96 | 97 | return process; 98 | } 99 | 100 | string GetDimensions (string targets) 101 | { 102 | if (StringComparer.OrdinalIgnoreCase.Equals ("GenerateRestoreGraphFile", targets)) { 103 | return IdeApp.ProjectOperations.CurrentSelectedSolution.GetDimensions (); 104 | } 105 | 106 | return string.Empty; 107 | } 108 | 109 | void OnMSBuildProcessExited (int currentSessionId, MSBuildProcessProgressMonitor monitor) 110 | { 111 | MSBuildTarget buildTarget = null; 112 | 113 | using (monitor) { 114 | lock (buildTargets) { 115 | if (buildTargets.TryGetValue (currentSessionId, out buildTarget)) { 116 | buildTargets.Remove (currentSessionId); 117 | } else { 118 | return; 119 | } 120 | } 121 | 122 | if (monitor.Process.Task.IsFaulted) { 123 | buildTarget.OnException (monitor.Process.Task.Exception); 124 | } else if (monitor.Process.Task.IsCanceled) { 125 | buildTarget.OnResult (MSBuildTargetStatus.Failed); 126 | } else if (monitor.Process.ProcessAsyncOperation.ExitCode == 0) { 127 | buildTarget.OnResult (MSBuildTargetStatus.Finished); 128 | } else { 129 | buildTarget.OnResult (MSBuildTargetStatus.Failed); 130 | } 131 | } 132 | 133 | ProjectSystemService.OnTargetFinished (buildTarget); 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/MSBuildTarget.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MSBuildTarget.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Diagnostics; 30 | using System.IO; 31 | using MonoDevelop.Core; 32 | using MonoDevelop.Projects; 33 | 34 | namespace MonoDevelop.ProjectSystem.Tools 35 | { 36 | class MSBuildTarget 37 | { 38 | Stopwatch stopwatch; 39 | bool copiedBinLogFile; 40 | 41 | public string Targets { get; set; } 42 | public string ProjectName { get; set; } 43 | public FilePath ProjectFileName { get; set; } 44 | public BuildType BuildType { get; set; } 45 | public string Dimensions { get; set; } 46 | 47 | public DateTime StartTime { get; set; } 48 | public TimeSpan? Duration { get; set; } 49 | 50 | public MSBuildTargetStatus Status { get; set; } 51 | 52 | public FilePath LogFileName { get; private set; } 53 | 54 | public FilePath BuildSessionBinLogFileName { get; set; } 55 | public FilePath BinLogFileName { get; private set; } 56 | public List BuildSessions { get; set; } 57 | 58 | public static BuildType GetBuildType (string target) 59 | { 60 | if (string.IsNullOrEmpty (target)) { 61 | return BuildType.None; 62 | } 63 | 64 | if (target == ProjectService.BuildTarget || 65 | target == ProjectService.CleanTarget || 66 | target == "Pack") { 67 | return BuildType.Build; 68 | } 69 | 70 | return BuildType.DesignTimeBuild; 71 | } 72 | 73 | public void Start () 74 | { 75 | StartTime = DateTime.UtcNow; 76 | stopwatch = Stopwatch.StartNew (); 77 | 78 | GenerateLogFileName (); 79 | } 80 | 81 | public void GenerateLogFileName () 82 | { 83 | string fileNameWithoutFileExtension = Path.Combine (Path.GetTempPath (), GetLogFileNamePrefix ()); 84 | 85 | LogFileName = fileNameWithoutFileExtension + ".msbuild.log"; 86 | BinLogFileName = fileNameWithoutFileExtension + ".binlog"; 87 | } 88 | 89 | /// 90 | /// Get a unique log file name. Based on: 91 | /// https://github.com/dotnet/project-system-tools/blob/7eb2f653890c159f750781de56bc7d261e7f4255/src/ProjectSystemTools/BuildLogging/Model/LoggerBase.cs#L22 92 | /// 93 | string GetLogFileNamePrefix () 94 | { 95 | string fileName = string.Format ( 96 | "{0}_{1}{2}_{3}", 97 | ProjectName, 98 | GetDimensionLogFileNamePart (), 99 | BuildType, 100 | StartTime.ToString ("o") 101 | ); 102 | return fileName.Replace (':', '_'); 103 | } 104 | 105 | string GetDimensionLogFileNamePart () 106 | { 107 | if (string.IsNullOrEmpty (Dimensions)) { 108 | return string.Empty; 109 | } 110 | 111 | return Dimensions.Replace ('|', '_') + "_"; 112 | } 113 | 114 | public void CopyBinLogFile () 115 | { 116 | if (copiedBinLogFile) { 117 | return; 118 | } 119 | 120 | UpdateBuildSessionBinLogFileName (); 121 | 122 | if (BuildSessionBinLogFileName.IsNull) { 123 | return; 124 | } 125 | 126 | try { 127 | if (File.Exists (BinLogFileName)) { 128 | copiedBinLogFile = true; 129 | return; 130 | } 131 | 132 | File.Copy (BuildSessionBinLogFileName, BinLogFileName); 133 | } catch (Exception ex) { 134 | LoggingService.LogError ( 135 | string.Format ("Unable to copy bin log file {0}", BuildSessionBinLogFileName), 136 | ex); 137 | } 138 | 139 | copiedBinLogFile = true; 140 | } 141 | 142 | void UpdateBuildSessionBinLogFileName () 143 | { 144 | if (BuildSessions == null) { 145 | return; 146 | } 147 | 148 | foreach (BuildSession buildSession in BuildSessions) { 149 | if (buildSession.ProjectFileNames.Contains (ProjectFileName)) { 150 | BuildSessionBinLogFileName = buildSession.BinLogFileName; 151 | } 152 | } 153 | } 154 | 155 | public void OnResult (TargetEvaluationResult result) 156 | { 157 | OnResult (result.GetMSBuildTargetStatus ()); 158 | } 159 | 160 | public void OnResult (MSBuildTargetStatus status) 161 | { 162 | stopwatch.Stop (); 163 | Status = status; 164 | Duration = stopwatch.Elapsed; 165 | } 166 | 167 | public void OnException (Exception ex) 168 | { 169 | OnResult (MSBuildTargetStatus.Exception); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/MSBuildTargetEventArgs.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MSBuildTargetEventArgs.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | using System; 27 | namespace MonoDevelop.ProjectSystem.Tools 28 | { 29 | class MSBuildTargetEventArgs : EventArgs 30 | { 31 | public MSBuildTargetEventArgs (MSBuildTarget buildTarget) 32 | { 33 | BuildTarget = buildTarget; 34 | 35 | } 36 | public MSBuildTarget BuildTarget { get; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/MSBuildTargetMonitor.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MSBuildTargetMonitor.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using MonoDevelop.Core; 29 | using MonoDevelop.Core.ProgressMonitoring; 30 | using MonoDevelop.Projects; 31 | 32 | namespace MonoDevelop.ProjectSystem.Tools 33 | { 34 | class MSBuildTargetMonitor : IDisposable 35 | { 36 | MSBuildTarget buildTarget; 37 | MSBuildTargetProgressMonitor progressMonitor; 38 | TargetEvaluationContext context; 39 | 40 | public MSBuildTargetMonitor ( 41 | Project project, 42 | string target, 43 | ConfigurationSelector configuration, 44 | TargetEvaluationContext context) 45 | { 46 | // Ensure log verbosity is set for non-build targets. 47 | this.context = context; 48 | context.LogVerbosity = Runtime.Preferences.MSBuildVerbosity.Value; 49 | 50 | buildTarget = new MSBuildTarget { 51 | ProjectName = project.Name, 52 | ProjectFileName = project.FileName, 53 | Targets = target ?? string.Empty, 54 | BuildType = MSBuildTarget.GetBuildType (target), 55 | Dimensions = project.GetDimensions (configuration) 56 | }; 57 | 58 | buildTarget.Start (); 59 | 60 | ProjectSystemService.OnTargetStarted (buildTarget); 61 | } 62 | 63 | public ProgressMonitor GetProgressMonitor (ProgressMonitor monitor) 64 | { 65 | var aggregatedMonitor = monitor as AggregatedProgressMonitor; 66 | if (aggregatedMonitor == null) { 67 | aggregatedMonitor = new AggregatedProgressMonitor (monitor); 68 | } 69 | 70 | // Generate a bin log file. 71 | context.BinLogFilePath = buildTarget.BinLogFileName; 72 | 73 | // Ensure that a binlog is generated by using a LongOperations. 74 | // ShortOperations run in a temporary build session and share a single 75 | // binlog which is not supported by project system tools. Using 76 | // LongOperations ensures a binlog is created for each msbuild target. 77 | context.BuilderQueue = BuilderQueue.LongOperations; 78 | 79 | progressMonitor = new MSBuildTargetProgressMonitor (buildTarget.LogFileName); 80 | aggregatedMonitor.AddFollowerMonitor (progressMonitor, progressMonitor.Actions); 81 | 82 | return aggregatedMonitor; 83 | } 84 | 85 | public void Dispose () 86 | { 87 | progressMonitor?.Dispose (); 88 | } 89 | 90 | public void OnResult (TargetEvaluationResult result) 91 | { 92 | buildTarget.OnResult (result); 93 | ProjectSystemService.OnTargetFinished (buildTarget); 94 | } 95 | 96 | public void OnException (Exception ex) 97 | { 98 | buildTarget.OnException (ex); 99 | ProjectSystemService.OnTargetFinished (buildTarget); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/MSBuildTargetProgressMonitor.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MSBuildTargetProgressMonitor.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System.IO; 28 | using System.Text; 29 | using MonoDevelop.Core; 30 | using MonoDevelop.Core.PooledObjects; 31 | using MonoDevelop.Core.ProgressMonitoring; 32 | 33 | namespace MonoDevelop.ProjectSystem.Tools 34 | { 35 | class MSBuildTargetProgressMonitor : ProgressMonitor 36 | { 37 | PooledStringBuilder logBuilder = PooledStringBuilder.GetInstance (); 38 | readonly FilePath logFileName; 39 | bool disposed; 40 | 41 | public MSBuildTargetProgressMonitor (FilePath logFileName) 42 | { 43 | this.logFileName = logFileName; 44 | } 45 | 46 | public MonitorAction Actions { 47 | get { return MonitorAction.WriteLog | MonitorAction.Dispose; } 48 | } 49 | 50 | protected override void OnWriteLog (string message) 51 | { 52 | lock (logBuilder) { 53 | logBuilder.Append (message); 54 | } 55 | } 56 | 57 | protected override void OnWriteErrorLog (string message) 58 | { 59 | lock (logBuilder) { 60 | logBuilder.Append (message); 61 | } 62 | } 63 | 64 | protected override void OnDispose (bool disposing) 65 | { 66 | base.OnDispose (disposing); 67 | 68 | if (disposing && !disposed) { 69 | lock (logBuilder) { 70 | disposed = true; 71 | SaveLogOutputToFile (); 72 | } 73 | } 74 | } 75 | 76 | void SaveLogOutputToFile () 77 | { 78 | string text = logBuilder.ToStringAndFree (); 79 | File.WriteAllText (logFileName, text); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/MSBuildTargetStatus.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MSBuildTargetStatus.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | namespace MonoDevelop.ProjectSystem.Tools 28 | { 29 | enum MSBuildTargetStatus 30 | { 31 | Running, 32 | Finished, 33 | Failed, 34 | Exception 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/MSBuildTargetStatusExtensions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MSBuildTargetStatusExtensions.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using MonoDevelop.Core; 28 | 29 | namespace MonoDevelop.ProjectSystem.Tools 30 | { 31 | static class MSBuildTargetStatusExtensions 32 | { 33 | public static string GetDisplayText (this MSBuildTargetStatus status) 34 | { 35 | switch (status) { 36 | case MSBuildTargetStatus.Running: 37 | return GettextCatalog.GetString ("Running"); 38 | case MSBuildTargetStatus.Finished: 39 | return GettextCatalog.GetString ("Finished"); 40 | case MSBuildTargetStatus.Failed: 41 | return GettextCatalog.GetString ("Failed"); 42 | case MSBuildTargetStatus.Exception: 43 | return GettextCatalog.GetString ("Exception"); 44 | default: 45 | LoggingService.LogError ("Unknown MSBuildTargetStatus {0}", status); 46 | return status.ToString (); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/ProjectExtensions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // ProjectExtensions.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using MonoDevelop.Projects; 28 | 29 | namespace MonoDevelop.ProjectSystem.Tools 30 | { 31 | static class ProjectExtensions 32 | { 33 | public static string GetDimensions (this Project project, ConfigurationSelector selector) 34 | { 35 | if (selector == null) { 36 | return string.Empty; 37 | } 38 | 39 | ItemConfiguration configuration = selector.GetConfiguration (project); 40 | return configuration?.ToString () ?? string.Empty; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/ProjectSystemService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // ProjectSystemToolsService.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Linq; 30 | using MonoDevelop.Core; 31 | using MonoDevelop.Ide; 32 | using MonoDevelop.Projects; 33 | 34 | namespace MonoDevelop.ProjectSystem.Tools 35 | { 36 | static class ProjectSystemService 37 | { 38 | static bool enabled; 39 | static bool initializedMSBuildTaskLogging; 40 | static readonly Dictionary runningBuildSessions = 41 | new Dictionary (); 42 | static MSBuildProcessServiceMonitor msbuildProcessServiceMonitor; 43 | 44 | public static bool IsEnabled { 45 | get { return enabled; } 46 | set { 47 | enabled = value; 48 | 49 | if (enabled) { 50 | msbuildProcessServiceMonitor = new MSBuildProcessServiceMonitor (); 51 | } else { 52 | msbuildProcessServiceMonitor.Dispose (); 53 | } 54 | 55 | if (enabled && !initializedMSBuildTaskLogging) { 56 | InitializeMSBuildTaskLogging (); 57 | initializedMSBuildTaskLogging = true; 58 | } 59 | } 60 | } 61 | 62 | static void InitializeMSBuildTaskLogging () 63 | { 64 | try { 65 | // This is needed to ensure task inputs are logged. The remote msbuild host 66 | // does not set the BuildParameters.LogTaskInputs to true itself and setting 67 | // the MSBUILDLOGTASKINPUTS environment variable is a workaround. 68 | Environment.SetEnvironmentVariable ("MSBUILDLOGTASKINPUTS", "1"); 69 | 70 | // Ensure remote msbuild hosts are recreated so the MSBUILDLOGTASKINPUTS 71 | // environment variable is inherited by the new host processes. 72 | foreach (Project project in IdeApp.Workspace.GetAllProjects ()) { 73 | project.ShutdownProjectBuilder (); 74 | } 75 | } catch (Exception ex) { 76 | LoggingService.LogError ("Failed to shutdown project builders after enabling MSBuild task input logging", ex); 77 | } 78 | } 79 | 80 | public static event EventHandler MSBuildTargetStarted; 81 | public static event EventHandler MSBuildTargetFinished; 82 | 83 | internal static void OnTargetStarted (MSBuildTarget target) 84 | { 85 | Runtime.RunInMainThread (() => { 86 | MSBuildTargetStarted?.Invoke (null, new MSBuildTargetEventArgs (target)); 87 | }).Ignore (); 88 | } 89 | 90 | internal static void OnTargetFinished (MSBuildTarget target) 91 | { 92 | target.BuildSessions = GetBuildSessions (); 93 | 94 | Runtime.RunInMainThread (() => { 95 | MSBuildTargetFinished?.Invoke (null, new MSBuildTargetEventArgs (target)); 96 | }).Ignore (); 97 | } 98 | 99 | internal static void OnBuildSessionStarted (BuildSessionStartedEvent buildSessionStarted) 100 | { 101 | lock (runningBuildSessions) { 102 | var buildSession = new BuildSession (buildSessionStarted); 103 | runningBuildSessions [buildSession.Id] = buildSession; 104 | } 105 | } 106 | 107 | internal static void OnBuildSessionFinished (BuildSessionFinishedEvent buildSessionFinished) 108 | { 109 | lock (runningBuildSessions) { 110 | if (runningBuildSessions.TryGetValue (buildSessionFinished.SessionId, out BuildSession buildSession)) { 111 | runningBuildSessions.Remove (buildSessionFinished.SessionId); 112 | 113 | buildSession.IsRunning = false; 114 | buildSession.ProcessBuildSessionAsync () 115 | .Ignore (); 116 | } 117 | } 118 | } 119 | 120 | static List GetBuildSessions () 121 | { 122 | lock (runningBuildSessions) { 123 | return runningBuildSessions.Values.ToList (); 124 | } 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/SolutionExtensions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // SolutionExtensions.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using MonoDevelop.Ide; 28 | using MonoDevelop.Projects; 29 | 30 | namespace MonoDevelop.ProjectSystem.Tools 31 | { 32 | static class SolutionExtensions 33 | { 34 | public static string GetDimensions (this Solution solution) 35 | { 36 | return solution.GetDimensions (IdeApp.Workspace.ActiveConfiguration ?? ConfigurationSelector.Default); 37 | } 38 | 39 | public static string GetDimensions (this Solution solution, ConfigurationSelector selector) 40 | { 41 | if (solution == null || selector == null) { 42 | return string.Empty; 43 | } 44 | 45 | ItemConfiguration configuration = selector.GetConfiguration (solution); 46 | return configuration?.ToString () ?? string.Empty; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.ProjectSystem.Tools/TargetEvaluationResultExtensions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // TargetEvaluationResultExtensions.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using MonoDevelop.Projects; 28 | 29 | namespace MonoDevelop.ProjectSystem.Tools 30 | { 31 | static class TargetEvaluationResultExtensions 32 | { 33 | public static MSBuildTargetStatus GetMSBuildTargetStatus (this TargetEvaluationResult result) 34 | { 35 | if ((result.BuildResult == null) || 36 | result.BuildResult.HasErrors || 37 | result.BuildResult.Failed) { 38 | return MSBuildTargetStatus.Failed; 39 | } 40 | 41 | return MSBuildTargetStatus.Finished; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/MonoDevelop.References.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | $(MDBinDir)\Microsoft.macOS.dll 8 | False 9 | 10 | 11 | False 12 | $(MDBinDir)\Mono.Addins.dll 13 | 14 | 15 | False 16 | $(MDBinDir)\MonoDevelop.Core.dll 17 | 18 | 19 | False 20 | $(MDBinDir)\AddIns\MonoDevelop.DesignerSupport\MonoDevelop.DesignerSupport.dll 21 | 22 | 23 | False 24 | $(MDBinDir)\MonoDevelop.Ide.dll 25 | 26 | 27 | False 28 | $(MDBinDir)\Newtonsoft.Json.dll 29 | 30 | 31 | False 32 | $(MDBinDir)\System.Collections.Immutable.dll 33 | 34 | 35 | False 36 | $(MDBinDir)\Xwt.dll 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/Properties/AddinInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AddinInfo.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | using Mono.Addins; 27 | 28 | [assembly: Addin ( 29 | "ProjectSystemTools", 30 | Namespace = "MonoDevelop", 31 | Version = "0.13", 32 | Category = "IDE extensions")] 33 | 34 | [assembly: AddinName ("Project System Tools")] 35 | [assembly: AddinDescription ("Tools for working the project system")] 36 | 37 | [assembly: AddinDependency ("Core", "17.5")] 38 | [assembly: AddinDependency ("Ide", "17.5")] 39 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AssemblyInfo.cs 3 | // 4 | // Author: 5 | // Matt Ward 6 | // 7 | // Copyright (c) 2019 Microsoft Corporation 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | using System.Reflection; 27 | using System.Runtime.CompilerServices; 28 | using System.Runtime.Versioning; 29 | 30 | // Information about this assembly is defined by the following attributes. 31 | // Change them to the values specific to your project. 32 | 33 | [assembly: AssemblyTitle ("MonoDevelop.ProjectSystem.Tools")] 34 | [assembly: AssemblyDescription ("")] 35 | [assembly: AssemblyConfiguration ("")] 36 | [assembly: AssemblyCompany ("Microsoft")] 37 | [assembly: AssemblyProduct ("")] 38 | [assembly: AssemblyCopyright ("Microsoft Corporation")] 39 | [assembly: AssemblyTrademark ("")] 40 | [assembly: AssemblyCulture ("")] 41 | 42 | // Need to fix CA1416 build warning. 43 | // This call site is reachable on all platforms. 'NSLayoutConstraint.Active' is only supported on: 'ios' 10.0 and later, 44 | // 'maccatalyst' 10.0 and later, 'macOS/OSX' 10.14 and later, 'tvos' 10.0 and later. (CA1416)) 45 | // https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1416 46 | [assembly: SupportedOSPlatform ("macos10.14")] 47 | 48 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 49 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 50 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 51 | 52 | [assembly: AssemblyVersion ("0.13")] 53 | 54 | // The following attributes are used to specify the signing key for the assembly, 55 | // if desired. See the Mono documentation for more information about signing. 56 | 57 | //[assembly: AssemblyDelaySign(false)] 58 | //[assembly: AssemblyKeyFile("")] 59 | -------------------------------------------------------------------------------- /src/MonoDevelop.ProjectSystem.Tools/Properties/MonoDevelop.ProjectSystem.Tools.addin.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 34 | 35 | 36 | 37 | Build Logging pad context menu. 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 50 | 51 | --------------------------------------------------------------------------------