Ejemplo n.º 1
0
def analyze(args, logger):
    '''Analyze the files as specified in *args*. Logging is done through the
    given *logger*.
    The *args* object should have the following attributes:

        * ``path``: the file to analyze.
        * ``exclude`` and ``ignore``: the patterns specifying which files to
            exclude and which directories to ignore.
        * ``no_assert``: if ``True``, ``assert`` statements will not be counted
            towards increasing the cyclomatic complexity.
        * ``absolute``, ``modules`` and ``average``: the threshold for the
            complexity.
    '''
    config = Config(
        exclude=args.exclude,
        ignore=args.ignore,
        order=SCORE,
        no_assert=args.no_assert,
        show_closures=False,
        min='A',
        max='F',
    )
    h = CCHarvester(args.path, config)
    results = h._to_dicts()
    return find_infractions(args, logger, results), results
Ejemplo n.º 2
0
    def analyze(paths,
                min='A',
                max='F',
                exclude=None,
                ignore=None,
                order='SCORE',
                no_assert=False,
                include_ipynb=False,
                ipynb_cells=False):

        config = Config(
            min=min.upper(),
            max=max.upper(),
            exclude=exclude,
            ignore=ignore,
            show_complexity=False,
            average=False,
            total_average=False,
            order=getattr(cc_mod, order.upper(), getattr(cc_mod, 'SCORE')),
            no_assert=no_assert,
            show_closures=False,
            include_ipynb=include_ipynb,
            ipynb_cells=ipynb_cells,
        )

        harvester = CCHarvester(paths, config)

        return harvester._to_dicts()
 def analyze_complexity(self, args):
     
     def av(mod_cc, len):
         return mod_cc / len if len != 0 else 0
     
     config = Config(
         exclude=args.exclude,
         ignore=args.ignore,
         order=SCORE,
         no_assert=args.no_assert,
         multi=args.multi,
         show_closures=False,
         min='A',
         max='F')
     total_cc = 0.
     total_blocks = 0
     module_averages = []
     
     try:
         h = CCHarvester([args.path], config)
         m = MIHarvester([args.path], config)
         cc_results = h._to_dicts()
         mi_results = []
         for filename, mi_data in m.results:
             if mi_data:
                 # continue
                 mi_results.append((mi_data['mi'], mi_data['rank']))
         for module, blocks in cc_results.items():
             module_cc = 0.
             if len(blocks) != 0:
                 for block in blocks:
                     if block != "error":
                         module_cc += block['complexity']
                         r = cc_rank(block['complexity'])
             module_averages.append((module, av(module_cc, len(blocks))))
             total_cc += module_cc
             total_blocks += len(blocks)
         return module_averages, mi_results
     except Exception as e:
         print (exc_info()[0], e)
         return None, None
Ejemplo n.º 4
0
    def start(self, paths):

        self.paths = paths
        cc_harvester = CCHarvester(paths, self.config)
        self.cc_output = cc_harvester._to_dicts()
Ejemplo n.º 5
0
def analyse(paths):

    #Setup the Configuration for each Harvester 
    config = Config(
        exclude=[],
        ignore=[],
        order=SCORE,
        no_assert= False,
        show_closures=False,
        min='A',
        max='F',
    )

    config2 = Config(
        exclude=[],
        ignore=[],
        by_function= False
    )

    config3 = Config(
        min= 'A',
        max= 'C',
        exclude=[],
        ignore=[],
        multi=True,
        show=True,
    )

    config4 = Config(
        exclude=[],
        ignore=[],
        summary=False,
        json=True,
    )
    


    """
    ----------------------
    Cyclomatic Complexity 
    ---------------------
    Cyclomatic Complexity corresponds to the number of decisions a block of code contains plus 1. 
    This number (also called McCabe number) is equal to the number of linearly independent paths through the code. 
    This number can be used as a guide when testing conditional logic in blocks.Radon analyzes the AST tree 
    of a Python program to compute Cyclomatic Complexity. Statements have the following effects on Cyclomatic Complexity:
    """
    
    h = CCHarvester(paths, config)
    ccResults = h._to_dicts()
    # print(ccResults)
    numOfFunctions = 0
    complexity = 0

    # for result in ccResults.values():
    #     numOfFunctions += 1
    #     complexity += result['complexity'] if isinstance(result, dict) else 0

    for path in paths:
        for i in ccResults.get(path, []):
            numOfFunctions += 1
            complexity += i["complexity"] if isinstance(i, dict) else 0

    cc = complexity/numOfFunctions if numOfFunctions != 0 else 0

    """
    -------------------
    Halstead's Metrics
    ------------------
    Halstead’s goal was to identify measurable properties of software, and the relations between them. 
    These numbers are statically computed from the source code: Effort, Bugs, Length, Difficulty, Time, Vocabulary , Volume
    """
    i = HCHarvester(paths, config2)
    hcResults = i._to_dicts()
  
    halsteadEffort = 0
    halsteadBugs = 0
    halsteadLength = 0 
    halsteadDifficulty = 0
    halsteadTime = 0
    halsteadVocabulary = 0 
    halsteadVolume = 0
    numberOfFiles = 0

    for result in hcResults.values():
        if 'total' in result:
            halsteadEffort += result["total"][9]
            halsteadBugs  += result["total"][11]
            halsteadLength  += result["total"][5]
            halsteadDifficulty += result["total"][8]
            halsteadTime += result["total"][10]
            halsteadVocabulary += result["total"][4]
            halsteadVolume += result["total"][7]
        numberOfFiles += 1

    avgHalsteadEffort = halsteadEffort/numberOfFiles
    avgHalsteadBugs = halsteadBugs/numberOfFiles
    avgHalsteadLength = halsteadLength /numberOfFiles
    avgHalsteadDifficulty = halsteadDifficulty/numberOfFiles
    avgHalsteadTime = halsteadTime/numberOfFiles
    avgHalsteadVocabulary = halsteadVocabulary/numberOfFiles
    avgHalsteadVolume = halsteadVolume/numberOfFiles

    
    """
    ---------------------------------------
    MI Harvester for Maintainability index
    --------------------------------------
    Maintainability Index is a software metric which measures how maintainable (easy to support and change)
    the source code is. The maintainability index is calculated as a factored formula consisting of SLOC (Source Lines Of Code),
    Cyclomatic Complexity and Halstead volume. It is used in several automated software metric tools, including the Microsoft 
    Visual Studio 2010 development environment, which uses a shifted scale (0 to 100) derivative.
    """
    j = MIHarvester(paths, config3)
    miResults = dict(j.filtered_results)

    miVal = 0 
    numOfFiles = 0
    for result in miResults.values():
        if 'mi' in result:
            miVal += result["mi"] 
        numOfFiles += 1

    mi = miVal/numOfFiles
    


    """
    ------------
    Raw Metrics
    -----------
    The following are the definitions employed by Radon:
     - LOC: The total number of lines of code. It does not necessarily correspond to the number of lines in the file.
     - LLOC: The number of logical lines of code. Every logical line of code contains exactly one statement.
     - SLOC: The number of source lines of code - not necessarily corresponding to the LLOC. [sloc]
     - Comments: The number of comment lines. Multi-line strings are not counted as comment since, to the Python interpreter, they are just strings.
     - Multi: The number of lines which represent multi-line strings.  [multi] 
     - Blanks: The number of blank lines (or whitespace-only ones).  [blank]
    """
    k = RawHarvester(paths, config4)
    rawResults = (dict(k.results))

    comments = 0
    lloc = 0
    loc = 0
    for result in rawResults.values():
        if 'comments' in result:
            comments += result['comments']
        if 'lloc' in result:
            lloc += result['lloc']
        if 'loc' in result:
            loc += result['loc']


    data = {
        "numberOfFiles" : len(paths),
        "numberOfLines" : loc,
        "numberOfLogicalLines" : lloc, 
        "numberOfComments" : comments, 
        "cyclomaticComplexity" : cc, 
        "maintainabilityIndex" : mi,
        "halsteadEffort" : avgHalsteadEffort,
        "halsteadBugs" : avgHalsteadBugs,
        "halsteadLength" :avgHalsteadLength,
        "halsteadDifficulty" : avgHalsteadDifficulty,
        "halsteadTime" : avgHalsteadTime, 
        "halsteadVocabulary" : avgHalsteadVocabulary, 
        "halsteadVolume" : avgHalsteadVolume
    }

    return data
Ejemplo n.º 6
0
def run_radon_analysis(file_path, radon_config):
    harvester = CCHarvester([file_path], radon_config)
    return harvester._to_dicts()
Ejemplo n.º 7
0
def run_radon_analysis(file_path, radon_config):
    harvester = CCHarvester([file_path], radon_config)
    return harvester._to_dicts()