Skip to content
Nuthan Munaiah edited this page Dec 5, 2016 · 2 revisions

Extending reaper

In this article, the process of extending reaper to add support for the analysis of repositories in a currently unsupported programming language is described. We will use JavaScript as the programming language to add support for.

Dimensions

reaper measures eight attributes about each repository. These attributes are architecture, community, continuous integration, documentation, history, issues, license, and unit testing. Five of these eight attributes (architecture, continuous integration, documentation, license, and unit testing) depend on the source code. However, only three of the five attributes (architecture, documentation, and unit testing) depend on the programming language used in the development of the source code. However, the documentation attribute uses cloc which already supports a wide variety of programming languages. Therefore, only the architecture and unit testing attributes must be modify to accommodate additional programming languages.

In the subsections that follow, the process of modifying the implementation of architecture and unit testing in reaper is described. Please note that the implementation of every attribute in reaper primarily contains one file, main.py, located within the attributes\<name> directory where <name> is the name of the attribute. The main.py follows a template shown below:

def run(project_id, repo_path, cursor, **options):
  # Implementation goes here.

Architecture

The architecture attribute is currently implemented using Pygments, however, given the dynamic nature of JavaScript the Pygments-based approach will not work. An alternative to using Pygmentswould be to use an external call graph generation utility to generate an undirected graph of relationships between files in the project. Although call graph construction for JavaScript programs is an active area of research (see [1]), there are a few tools such as javascript-call-graph, callgraph, UglifyJS, and Google Closure Compiler that may be used to generate a call graph.

With an appropriate call graph generation utility identified, modify the file attributes/architecture/main.py as shown below:

def run(project_id, repo_path, cursor, **options):
  result = 0
  cursor.execute(
    'SELECT language FROM projects WHERE id = {}'.format(project_id)
  )
  record = cursor.fetchone()
  language = record[0].lower() if record[0] else record[0]

  graph = networkx.Graph()
  if language.lower() != 'javascript':
    # JavaScript: Use external utility
    build_js_graph(repo_path, graph)
  else:
    # Default: Use Pygments
    ...
    lexer = lexers.get_lexer_by_name(language)
    build_graph(file_paths, graph, lexer)

  result = get_connectedness(graph)
  return result >= options['threshold'], result

def build_js_graph(repo_path, graph):
  # TODO: Invoke external utility to generate JavaScript call graph

Unit Testing

The unit testing attribute already supports a skeletal implementation specific to JavaScript. In the currently implementation, the unit testing attribute only supports the detection of the Mocha JavaScript testing framework. Support for additional testing frameworks may be adding by modifying the file attributes/unit_test/discovered/javascript.py. For example, to extend the unit testing attribute to support QUnit JavaScript testing framework, define a new function, __qunit__, and add its reference to the self.frameworks list. A sample implementation is shown below:

class JavaScriptTestDiscoverer(TestDiscoverer):
  def __init__(self):
    self.language = 'Javascript'
    self.languages = ['Javascript']
    self.extensions = ['*.js']
    self.frameworks = [
        self.__mocha__,
        self.__qunit__
    ]

  ...

  def __qunit__(self, path, sloc):
    pattern = 'QUnit.test\(.*\)'
    return self.measure(path, sloc, pattern)

References

[1] Asger Feldthaus, Max Schäfer, Manu Sridharan, Julian Dolby, and Frank Tip. 2013. Efficient construction of approximate call graphs for JavaScript IDE services. In Proceedings of the 2013 International Conference on Software Engineering (ICSE '13). IEEE Press, Piscataway, NJ, USA, 752-761.* for more information.

Clone this wiki locally