Introducing Project QA: Part 3 (With great power)

This is part 3 of a 3 part series overviewing the Project QA Drupal module:

Unfamiliar with Project QA? You can check out the project page on

As I developed this module I became more and more excited about what these tools I kept finding could do if I were to integrate them. In discussing ideas with colleagues there was a central theme that kept coming up and was said best by Peter Parker:

With great power comes great responsibility.

My goal in creating this module was to make some of the programming process a bit more transparent as well as quantifiable. With a few missteps in creating sample reports to demo to people I quickly realized how easy it would be to 1) use this as a litmus test and 2) deduce inaccurate meaning potentially leading to 3) unfortunate decisions and consequences.

To be more specific; I became aware of how this should not be used to determine someone’s employability or value. That is not to say that it can’t help educate a decision, but rather just that this tool should not be the judge and jury. Its intended purpose and most complimentary role is to help teams gain a higher level picture and historical understanding over their own or inherited projects. This understanding with undoubtedly raise questions and draw attention to certain aspects of a project, prompting further investigation. I find this to be both appropriate and healthy.

Let’s take a quick example. Suppose you are comparing two developers on a project to see how they are performing. You find that both are checking in code regularly, commenting appropriately, and even producing roughly the same amount of code. However you see a major difference in code complexity. One developer’s code is maintaining fairly consistent complexity levels (easy to maintain) while the other’s code is rising steadily in complexity. Your initial concern could be that the code is not being structured properly or will be far too difficult to make changes to at a later date.

But what if there is something else going on? What if you forgot to consider the breakdown in roles between the two developers; one was responsible for writing simple helper functions while the other was implementing some pretty hairy business logic being handed to them via complex requirements? What actually may be happening here is not an indictment of each developer’s skill but rather the manifestation of a requirements gathering phase that didn’t expose some contradictory functionalities. The report itself is still proving to be very valuable, but as with anything involving interpretation it is essential to tread cautiously.

Another topic has come up in discussion as well. One of the great ideas shared with me was to use this tool as a gatekeeper of sorts to validate thresholds before allowing pushes to production. This can offer a great deal of stability to a project. It can also have two opposite side effects; a false sense of security and a roadblock preventing essential code from being deployed. In either case, nothing can replace a solid code review process. This tool definitely has a role but it should be in helping a code reviewer look in to various aspects of a project and glean insight, not replacing the code reviewer all together.


Introducing Project QA: Part 2 (Writing a submodule)

This is part 2 of a 3 part series overviewing the Project QA Drupal module:

Unfamiliar with Project QA? You can check out the project page on

Let’s walk through building a submodule for Project QA, shall we? There’s three main steps to implementing your own extension to projectqa:

  1. Create a fresh module
  2. Create entities to store your data
  3. Implement hook_eval_gitcommit

Set up your module

Creating a new module is outside the scope of this post. If you are new to module development or need a refresher, head over to for all the resources.

I am curious what modules people are working on, though. if you start one I’d love to hear about it. It may be something valuable to a wide enough audience to consider including in the main module.

Create entities to store your data

This part of projectqa is intentionally left wide open. You are expected to develop the entities to store your data. This also means you have complete control over the structure and accessing abilities of that data. I highly recommend leveraging the Entity API module. It will make your life easier as well as the lives of anyone building off of your work. Additionally it’s already a dependency for projectqa so you’ll have access to it on any system that you’re building your projectqa submodule for.

Consider how you want to leverage your data but also try to keep it as normalized as possible. For PHPLOC I decided to store in two tables; one table for the extracted data and one table for the delta data that was calculated. Putting it all in one table would’ve made a far too large table as well as too much information if I’m only interested in the delta. A bit more description on this will be in the next step.

Implement hook_eval_gitcommit

hook_eval_gitcommit($repo_path, $git_commit)

This hook gets fired by the main projectqa module on each git commit in the history of a repo. You don’t need to worry about walking the repo history, that is taking care of for you. You also don’t need to execute any git commands as the repo is already checked out to the proper location for you.


$repo_path: The system path where the repo is located.

$git_commit: The git commit to process.

The most important piece of information is the repo path that gets passed to you. This tells you were on the filesystem to look in order to start your processing of the code. Be sure not to alter any of the files as that would pollute the code to be processed for both your module and any other module accessing that git commit after your code is executed.

The git commit hash that is passed to you is more of an optional piece of information. You don’t need to do anything with it unless it is valuable to whatever data processing algorithm you are utilizing. The git commit hash is already being saved to the projectqa_gitcommit table for you.

In the case of the projectqa_phploc submodule I was interested in calculating the deltas between commits and storing them so reporting could be easier and more performant. In order to accomplish this, I made this call from within my hook implementation:

This way I can now access the correct records in my own table for the previous commit (remember, do not alter the file system or execute git commands) and generate the diff against my current commit and save to the database along with my current values. For better organization and scaleability I keep all delta values in a separate table (entity).

If you end up developing a submodule for projectqa be sure to stay in contact and keep an eye out for updates. I already have plans for a few more hooks to implement that may help a number of developers. I will also be implementing some functionality to help validate, reprocess, and catch up data if needed.

Introducing Project QA

This is part 1 of a 3 part series overviewing the Project QA Drupal module:

Ever wish there was a better way to keep an eye on a project you’re working on? After being inspired by this presentation at Drupalcon Portland I decided to create a Drupal module to help automate the code evaluation process: Project QA.

Don’t want to read? Skip ahead, there’s a video introduction and demo!


At its heart, Project QA is a Drupal module that scans git repos and offers hooks for processing them. By itself, Project QA does not evaluate your code at all.

When you tell Project QA to scan a repo, it checks the repo out locally (or updates it if it already has a copy from a previous run), and then begins stepping backwards through the git history one commit at a time. A record of the commit is saved, including the commit hash, the timestamp of the commit, and the author of the commit. After each commit is checked out a hook is fired to allow submodules to act on the repo in its current state. After all commits have been processed, Project QA evaluates the existing tags in the repo and matches them up with the imported commits.

It is pretty generic except for one major condition: every action or piece of data is always linked back to a specific git commit. The code being evaluated doesn’t need to be Drupal code, or even PHP code; as long as it exists in a git repo you can access.


The real fun begins when you consider submodules. With this initial release I’ve included one submodule based on the PHPLOC tool. PHPLOC “is a tool for quickly measuring the size and analyzing the structure of a PHP project.” One of its great strengths is measuring cyclomatic complexity alongside a host of stats about the number of files, methods, lines of code, comments, etc.

The PHPLOC submodule uses the Project QA hook to run on every commit in a repository’s history. All data is saved into custom entities, as well as delta information from between git commits for faster and easier reporting. All of this information is exposed to views so writing custom reports is easy.

Some report ideas include:

  • Who is introducing the most complexity (for good or bad)?
  • Is code being checked in regularly during a project?
  • How does a particular module stack up against others?
  • Are your developers commenting their code enough?
  • Were there any major changes or spikes in the history of the code, indicating things such as a bad merge, extra modules or files, or maybe an onslaught of sloppy or duplicate code?


I have plans for implementing submodules to run other PHP tools like the copy-paste detector, mess detector, and perhaps even code sniffer. Beyond that I’d love to see JavaScript evaluations taking place in submodules as well. I’ve also wanted to make this as easy as possible for writing your own reports but know that including some default common reports to get you started is beneficial as well. In that vein, if you have suggestions let me know!

You can check out the project page on