Browse Source

Added new metric, ratio of comment lines to code lines

holyraspi 4 years ago
parent
commit
eb01e802d4
3 changed files with 89 additions and 0 deletions
  1. 15 0
      metrixpp/ext/std/code/ratio.ini
  2. 50 0
      metrixpp/ext/std/code/ratio.py
  3. 24 0
      metrixpp/mpp/api.py

+ 15 - 0
metrixpp/ext/std/code/ratio.ini

@@ -0,0 +1,15 @@
+;
+;    Metrix++, Copyright 2009-2019, Metrix++ Project
+;    Link: https://github.com/metrixplusplus/metrixplusplus
+;    
+;    This file is a part of Metrix++ Tool.
+;    
+
+[Plugin]
+version: 1.0
+package: std.code
+module:  ratio
+class:   Plugin
+depends: std.code.lines
+actions: collect
+enabled: True

+ 50 - 0
metrixpp/ext/std/code/ratio.py

@@ -0,0 +1,50 @@
+#
+#    Metrix++, Copyright 2009-2019, Metrix++ Project
+#    Link: https://github.com/metrixplusplus/metrixplusplus
+#    
+#    This file is a part of Metrix++ Tool.
+#    
+
+import mpp.api
+
+class Plugin(mpp.api.Plugin,
+             mpp.api.IConfigurable,
+             mpp.api.Child,
+             mpp.api.MetricPluginMixin):
+    
+    def declare_configuration(self, parser):
+        self.parser = parser
+        parser.add_option("--std.code.ratio.commentcode", "--scrcc", action="store_true", default=False,
+                         help="Enables collection of comment ratio metric (per region detalization) - "
+                         "ratio of non-empty lines of comments to non-empty lines of code"
+                         " It uses std.code.lines.code, std.code.lines.comments"
+                         " metrics to calculate the ratio."
+                         " [default: %default]")
+
+    def configure(self, options):
+        self.is_active_ratiocommentcode = options.__dict__['std.code.ratio.commentcode']
+        if self.is_active_ratiocommentcode == True:
+            required_opts = ['std.code.lines.comments', 'std.code.lines.code']
+            for each in required_opts:
+                if options.__dict__[each] == False:
+                    self.parser.error('option --std.code.ratio.commentcode: requires --{0} option'.
+                                      format(each)) 
+    
+    def initialize(self):
+        self.declare_metric(self.is_active_ratiocommentcode,
+                            self.Field('commentcode', float),
+                            {
+                             'std.code.lines':(None, self.RatioCalculatorCounter)
+                            },
+                            # set none, because this plugin is not interested in parsing the code
+                            marker_type_mask=mpp.api.Marker.T.NONE)
+        
+        super(Plugin, self).initialize(fields=self.get_fields())
+
+        if self.is_active() == True:
+            self.subscribe_by_parents_name('std.code.lines')
+
+    class RatioCalculatorCounter(mpp.api.MetricPluginMixin.RatioCalculator):
+        ratio_dividend = ('std.code.lines', 'comments')
+        ratio_divisor = ('std.code.lines', 'code')
+

+ 24 - 0
metrixpp/mpp/api.py

@@ -1167,6 +1167,30 @@ class MetricPluginMixin(Parent):
                     break
             return self.result
 
+    class RatioCalculator(PlainCounter):
+        
+        def __init__(self, *args, **kwargs):
+            super(MetricPluginMixin.RatioCalculator, self).__init__(*args, **kwargs)
+            self.result = self.region.get_data(self.namespace, self.field)
+            if self.result == None:
+                self.result = 0.0
+        
+        def get_result(self):
+            sourced_dividend = self.region.get_data(self.ratio_dividend[0], self.ratio_dividend[1])
+            sourced_divisor = self.region.get_data(self.ratio_divisor[0], self.ratio_divisor[1])
+            if ((sourced_dividend != None) 
+                and
+                (sourced_dividend != 0)
+                and
+                (sourced_divisor != None)
+                and
+                (sourced_divisor != 0)):
+                    self.result = sourced_dividend / sourced_divisor
+            else:
+              self.result = 0.0
+
+            return self.result
+
     def declare_metric(self, is_active, field,
                        pattern_to_search_or_map_of_patterns,
                        marker_type_mask=Marker.T.ANY,