There are plenty of resources in the Drupal community for learning how to build a module. This article is not about building a custom module. My goal is to provide a guide for auditing and reviewing a Drupal module. In doing so, I'm aiming to help you achieve your goal to understand, document, clean up, and hopefully improve a Drupal module.
Prerequisites before auditing and reviewing a module
One expert tip is to experiment with the `drush generate` command, which provides starter code for every possible feature and aspect in a module. The help text from the `drush generate` command serves as a table of contents of sorts for what is contained in a Drupal module.
It’s essential to understand the typical uses of a Drupal module so that you can conceptually categorize what the code is doing. For example, if you see a form alter hook, you should assume that the module is enhancing or tweaking another core or contributed module's form.
Generally, Drupal modules will:
- Extend core and other modules.
- Enhance a contributed or custom theme.
- Create new functionality.
- Integrate with external systems.
It is also important to note that a Drupal module should have a well-defined purpose with clear objectives. A good Drupal module developer leverages the Drupal community's best practices, making it easy for other developers to understand and improve the code.
Steps to audit and review a module
Step 1: Play with it
Before ever looking under the hood of a module, you should take it for a drive - install it and see if you can get it to work as expected. You can use SimplyTest.me to install and try a module in a 24-hour Drupal sandbox environment. You might need to view the module's README file or project page, focusing on figuring out what the module is doing.
Step 2: Read the documentation.
Every module has some documentation, and even the most poorly documented module has an *.info.yml file with a description. Most modules have a README file that can capture key concepts and features. All contributed modules have a project page that may also link to documentation on Drupal.org. You want to understand the creators' intentions, the code's history, and any gotchas (a.k.a. known issues or limitations).
Step 3: Scan the code
Step 4: Research the APIs and hooks
Drupal core provides so many features, hooks, and integrations even an experienced developer can't remember every possible API or hook. You may need to look up a hook or API on Drupal.org. If there is @todo or @see link in the code's comments, it is worth investigating the task or references a little further. As you do your research, you will need to document your findings.
Step 5: Document your findings
Here is an excellent time to remind yourself to take notes while auditing a module. In many cases, notes can be added directly to the module's README. Don't hesitate to add comments directly to the code base, and you can remove the irrelevant comments before creating a pull request.
Generally, when faced with any challenging Drupal task, I create a document to scribble down everything I am thinking and seeing in a module. Gradually, my document has notes, references, and even steps to test the module. Ultimately, my notes are moved into the module's README file, comments, or may become a starting point for writing new or additional tests.
Step 6: Confirm expectations using tests
It’s absolutely necessary to have tests associated with a module. Tests ensure the module works as expected, provides stability, and acts as a secondary form of documentation.
Tests can be challenging to write. I’ve had times when I spent more time writing a test than writing the working code, and even felt overwhelmed trying to write automated tests for some code. When I feel that automated tests are too challenging, I’ll write a manual test script plan in the module's README. This challenge leads to my best rule and guidance for tests:
"Tests confirm expectations."
A Drupal module should always communicate its expectations. A module's README file and project page define the expectations, the code implements these expectations, and tests confirm them. Having manual tests written out is better than no tests. At some point, you or someone else, will convert the manual tests into automated tests.
Step 7: Clean up the code
A Drupal module should always follow Drupal's code standards. Linting tools like PHP CodeSniffer and PHPStan can check your code for style, mistakes, and deprecated code. Following coding standards make your code more accessible for other people to understand. When reviewing a module, see if it follows Drupal's code standards.
Conversely, I have found that sometimes strictly following a coding standard can make code harder to read. Drupal's coding standards are constantly evolving. For example, there is an ongoing debate about what character length to wrap arrays. My advice is to write clean code based on the coding standards and read the book on writing Clean Code.
Cleaning up a module and applying code standards make it easier to start improving the code.
Step 8: Improve the code
So far, we have explored how to play, scan, research, document, test, and clean up a module to understand how a Drupal module works so that you can help improve it. This article's prerequisite is knowing how to build a Drupal build; therefore, you should be comfortable writing code. I just want to nudge you to think about the bigger picture when improving a Drupal module.
Drupal is open source; someone will review your code if you contribute your improvements or fixes back to the community. If you're working on a custom module, someone on your team should review your code.
Before diving in and improving a module, step back and think about the next person reviewing it and maybe even using it. As you can see, I like boiling down complex processes into simple statements. The Google Engineering Team has shared its entire code review process, and the below quote captures the essential thing to think about when improving code.
"In general, reviewers should favor approving a CL once it is in a state where it definitely improves the overall code health of the system being worked on, even if the CL isn’t perfect."
In other words, when writing code, make sure it improves the system's overall health. Everything I have talked about, including writing documentation, tests, and clean code, works toward having a healthy Drupal module be part of Drupal's larger ecosystem of modules.
Our collective goal is to improve the overall health of Drupal's ecosystem and our organization's Drupal implementation. You should never hesitate to refactor a module.That said, Refactoring is a topic for another day. If you want to get a head start on that subject, "Martin Fowler's book Refactoring: Improving the Design of Existing Code is the canonical reference." -- https://en.wikipedia.org/wiki/Code_refactoring
Wrapping this up
I recently looked back at my 10+ years of coding custom and contributing Drupal modules. As I review some of my older Drupal 8 modules and review other team members' modules and code, it is challenging to audit, review, and help improve existing code.
The eight steps I have defined may not be the exact steps you would take to review a Drupal module, but auditing, reviewing, and improving a module is a process that you’ll have to attend to at some point. The question I leave you with is, "What is your process and steps for auditing, reviewing, and improving a Drupal?"
- Using Code Generators in Drupal 8
Ivan Zugec talks about all the code generation options available to Drupal.
- A Quick Guide for Code Reviews
Andrew Berry writes about reviewing APIs, security, documentation, tests, and standards related to Drupal 7 modules, but many of his suggestions and tips are applicable to Drupal 8
- Your Code Review Checklist: 14 Things to Include
Tash Postolovski shares a comprehensive checklist for common code review steps.