/// <summary> /// Executes the logic for this workflow activity /// </summary> protected override void InternalExecute() { this.logCodeMetrics = this.LogCodeMetrics.Get(this.ActivityContext); this.BuildDetail = this.ActivityContext.GetExtension <IBuildDetail>(); string generatedFile = "Metrics.xml"; string outputLocation = this.BuildDetail.DropLocation; if (string.IsNullOrEmpty(outputLocation)) { outputLocation = this.BinariesDirectory.Get(this.ActivityContext); } if (this.GeneratedFileName != null && !string.IsNullOrEmpty(this.GeneratedFileName.Get(this.ActivityContext))) { generatedFile = Path.Combine(outputLocation, this.GeneratedFileName.Get(this.ActivityContext)); } if (!this.RunCodeMetrics(generatedFile)) { return; } IActivityTracking currentTracking = this.ActivityContext.GetExtension <IBuildLoggingExtension>().GetActivityTracking(this.ActivityContext); if (!this.AnalyzeMetricsResult.Get(this.ActivityContext)) { BaseCodeActivity.AddTextNode("Skipped code metrics analysis (not set to run)", currentTracking.Node); return; } IBuildInformationNode rootNode = AddTextNode("Analyzing code metrics results", currentTracking.Node); string fileName = Path.GetFileName(generatedFile); string pathToFileInDropFolder = Path.Combine(outputLocation, fileName); BaseCodeActivity.AddLinkNode(fileName, new Uri(pathToFileInDropFolder), rootNode); CodeMetricsReport result = CodeMetricsReport.LoadFromFile(generatedFile); if (result == null) { this.LogBuildMessage("Could not load metric result file "); return; } // Get thresholds for each level. var memberMetricThresholds = new MethodMetricsThresholds(this); var typeMetricThresholds = new TypeMetricsThresholds(this, memberMetricThresholds); // var namespaceMetricThresholds = new NameSpaceMetricsThresholds(this); //Uncomment in this if you want to perform metric checks on namespaces // var assemblyMetricThresholds = new AssemblyMetricsThresholds(this); // Uncomment in this if you want to perform metric checks on assemblies int noOfTypeViolations = 0; int noOfMethodViolations = 0; foreach (var target in result.Targets) { var targetNode = this.logCodeMetrics ? AddTextNode("Target: " + target.Name, rootNode) : null; foreach (var module in target.Modules) { var moduleNode = this.logCodeMetrics ? AddTextNode("Module: " + module.Name, targetNode) : null; foreach (var ns in module.Namespaces) { var namespaceNode = this.logCodeMetrics ? AddTextNode("Namespace: " + ns.Name, moduleNode) : null; foreach (var type in ns.Types) { var typeNode = this.logCodeMetrics ? AddTextNode("Type: " + type.Name, namespaceNode) : null; var typeInformation = new MemberInformation(null, type, ns, module); noOfTypeViolations += this.ProcessMetrics(typeNode, typeInformation.TheClass.Metrics, typeMetricThresholds, typeInformation.FullyQualifiedName, typeInformation.TheClass.Name); noOfMethodViolations += (from member in type.Members let memberNode = this.logCodeMetrics ? AddTextNode("Member: " + member.Name + " " + member.MetricsInformation, typeNode) : null let memberInformation = new MemberInformation(member, type, ns, module) select this.ProcessMetrics(memberNode, memberInformation.TheMember.Metrics, memberMetricThresholds, memberInformation.FullyQualifiedName, memberInformation.TheMember.Name)).Sum(); } } } } var numberMessageTypes = string.Format("Number of Code Metric warnings/errors on types: {0}", noOfTypeViolations); var numberMessageMethods = string.Format("Number of Code Metric warnings/errors on methods: {0}", noOfMethodViolations); BaseCodeActivity.AddTextNode(numberMessageTypes, rootNode); BaseCodeActivity.AddTextNode(numberMessageMethods, rootNode); }
/// <summary> /// Executes the logic for this workflow activity /// </summary> protected override void InternalExecute() { this.logCodeMetrics = this.LogCodeMetrics.Get(this.ActivityContext); this.BuildDetail = this.ActivityContext.GetExtension<IBuildDetail>(); string generatedFile = "Metrics.xml"; string outputLocation = this.BuildDetail.DropLocation; if (string.IsNullOrEmpty(outputLocation)) { outputLocation = this.BinariesDirectory.Get(this.ActivityContext); } if (this.GeneratedFileName != null && !string.IsNullOrEmpty(this.GeneratedFileName.Get(this.ActivityContext))) { generatedFile = Path.Combine(outputLocation, this.GeneratedFileName.Get(this.ActivityContext)); } if (!this.RunCodeMetrics(generatedFile)) { return; } IActivityTracking currentTracking = this.ActivityContext.GetExtension<IBuildLoggingExtension>().GetActivityTracking(this.ActivityContext); if (!this.AnalyzeMetricsResult.Get(this.ActivityContext)) { BaseCodeActivity.AddTextNode("Skipped code metrics analysis (not set to run)", currentTracking.Node); return; } IBuildInformationNode rootNode = AddTextNode("Analyzing code metrics results", currentTracking.Node); string fileName = Path.GetFileName(generatedFile); string pathToFileInDropFolder = Path.Combine(outputLocation, fileName); BaseCodeActivity.AddLinkNode(fileName, new Uri(pathToFileInDropFolder), rootNode); CodeMetricsReport result = CodeMetricsReport.LoadFromFile(generatedFile); if (result == null) { this.LogBuildMessage("Could not load metric result file "); return; } // Get thresholds for each level. var memberMetricThresholds = new MethodMetricsThresholds(this); var typeMetricThresholds = new TypeMetricsThresholds(this, memberMetricThresholds); // var namespaceMetricThresholds = new NameSpaceMetricsThresholds(this); //Uncomment in this if you want to perform metric checks on namespaces // var assemblyMetricThresholds = new AssemblyMetricsThresholds(this); // Uncomment in this if you want to perform metric checks on assemblies int noOfTypeViolations = 0; int noOfMethodViolations = 0; foreach (var target in result.Targets) { var targetNode = this.logCodeMetrics ? AddTextNode("Target: " + target.Name, rootNode) : null; foreach (var module in target.Modules) { var moduleNode = this.logCodeMetrics ? AddTextNode("Module: " + module.Name, targetNode) : null; foreach (var ns in module.Namespaces) { var namespaceNode = this.logCodeMetrics ? AddTextNode("Namespace: " + ns.Name, moduleNode) : null; foreach (var type in ns.Types) { var typeNode = this.logCodeMetrics ? AddTextNode("Type: " + type.Name, namespaceNode) : null; var typeInformation = new MemberInformation(null, type, ns, module); noOfTypeViolations += this.ProcessMetrics(typeNode, typeInformation.TheClass.Metrics, typeMetricThresholds, typeInformation.FullyQualifiedName, typeInformation.TheClass.Name); noOfMethodViolations += (from member in type.Members let memberNode = this.logCodeMetrics ? AddTextNode("Member: " + member.Name + " " + member.MetricsInformation, typeNode) : null let memberInformation = new MemberInformation(member, type, ns, module) select this.ProcessMetrics(memberNode, memberInformation.TheMember.Metrics, memberMetricThresholds, memberInformation.FullyQualifiedName, memberInformation.TheMember.Name)).Sum(); } } } } var numberMessageTypes = string.Format("Number of Code Metric warnings/errors on types: {0}", noOfTypeViolations); var numberMessageMethods = string.Format("Number of Code Metric warnings/errors on methods: {0}", noOfMethodViolations); BaseCodeActivity.AddTextNode(numberMessageTypes, rootNode); BaseCodeActivity.AddTextNode(numberMessageMethods, rootNode); }