/// <summary>
        /// Executes the logic for this workflow activity
        /// </summary>
        protected override void InternalExecute()
        {
            this.BuildDetail = this.ActivityContext.GetExtension <IBuildDetail>();
            string generatedFile = "Metrics.xml";

            if (this.GeneratedFileName != null && !string.IsNullOrEmpty(this.GeneratedFileName.Get(this.ActivityContext)))
            {
                generatedFile = Path.Combine(this.BuildDetail.DropLocation, this.GeneratedFileName.Get(this.ActivityContext));
            }

            if (!this.RunCodeMetrics(generatedFile))
            {
                return;
            }

            IActivityTracking     currentTracking = this.ActivityContext.GetExtension <IBuildLoggingExtension>().GetActivityTracking(this.ActivityContext);
            IBuildInformationNode rootNode        = AddTextNode("Processing metrics", currentTracking.Node);

            string fileName = Path.GetFileName(generatedFile);
            string pathToFileInDropFolder = Path.Combine(this.BuildDetail.DropLocation, fileName);

            AddLinkNode(fileName, new Uri(pathToFileInDropFolder), rootNode);

            CodeMetricsReport result = CodeMetricsReport.LoadFromFile(generatedFile);

            if (result == null)
            {
                LogBuildMessage("Could not load metric result file ");
                return;
            }

            foreach (var target in result.Targets)
            {
                var targetNode = AddTextNode("Target: " + target.Name, rootNode);
                foreach (var module in target.Modules)
                {
                    var moduleNode = AddTextNode("Module: " + module.Name, targetNode);
                    this.ProcessMetrics(module.Name, module.Metrics, moduleNode);
                    foreach (var ns in module.Namespaces)
                    {
                        var namespaceNode = AddTextNode("Namespace: " + ns.Name, moduleNode);
                        this.ProcessMetrics(ns.Name, ns.Metrics, namespaceNode);
                        foreach (var type in ns.Types)
                        {
                            var typeNode = AddTextNode("Type: " + type.Name, namespaceNode);
                            this.ProcessMetrics(type.Name, type.Metrics, typeNode);
                            foreach (var member in type.Members)
                            {
                                var memberNode = AddTextNode("Member: " + member.Name, typeNode);
                                this.ProcessMetrics(member.Name, member.Metrics, memberNode);
                            }
                        }
                    }
                }
            }
        }
        public CodeMetricsReport Build(IEnumerable <ModuleMetric> metrics)
        {
            CodeMetricsReport codeMetricsReport = new CodeMetricsReport();

            codeMetricsReport.Version = 11;
            CodeMetricsReport codeMetricsReport1 = codeMetricsReport;

            codeMetricsReport1.Add(MetricsReportBuilder.GetTargetsResult(metrics));
            return(codeMetricsReport1);
        }
示例#3
0
        private static void BuildReportFrom(IEnumerable <ModuleMetric> metrics, string reportFile)
        {
            CodeMetricsReport codeMetricsReport = (new MetricsReportBuilder()).Build(metrics);

            using (Stream stream = File.Open(reportFile, FileMode.OpenOrCreate, FileAccess.Write))
            {
                stream.SetLength((long)0);
                codeMetricsReport.WriteTo(stream);
                stream.Flush();
            }
            File.Create(RoslynMetricsExe.GetSuccessFileName(reportFile));
        }
示例#4
0
        /// <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);
        }