Whether you are working as a solo developer or within a large software team, the quest for producing high-quality code remains paramount. Static code analysis stands as a valuable ally in this endeavor, offering an efficient means to scan, improve, and track the quality of your codebase.
What is static code analysis?
The term static analysis refers to the process of analyzing the source code of a program without executing it. Static analysis tools are generally easy to use yet powerful, capable of spotting errors and enhancing code organization and readability. This set of tools identifies issues and explains why they are problematic, often suggesting ways to fix them.
Another important concept is Static Application Security Testing (SAST), which also analyzes the source code of an application without executing it. However, the primary focus is to evaluate the code for security vulnerabilities. The goal is to find weaknesses in the code that could lead to security breaches or vulnerabilities when the application runs. These terms can get mixed, making it hard to draw the line and classify a tool as a static code analyzer or SAST. For the sake of this article, we will refer to the term static code analysis because it is more general, but we will also consider security issues.
With a proper configuration, you can have a tool automatically analyze your code during the development lifecycle, making sure the following types of issues get fixed as early as possible: unused variables, unreachable code, logic errors, insecure configuration, commented code, code that is too complex, buffer overflows, resource leaks, SQL injection flaws, to name a few.
It must be stated, however, that passing a static code analysis will not guarantee that your code is bug-free or that its behavior matches its specifications. The analyzer doesn’t know what your code is supposed to do. It can identify logic and syntax errors related to the programming language but cannot detect mistakes in functionality or the program's intended behavior or performance. Therefore, static code analysis should be combined with other analyses, such as unit testing.
What are the best static code analysis tools?
Many static code analysis tools are available, Sonar (also referred to as SonarQube) by SonarSource, being the most notorious. The graphics below, taken from the Google Trends interest over time, show that SonarQube is more popular than its competitors and the terms SAST and static code analysis. For this reason, we will focus on Sonar for the rest of the article.
How does Sonar work?
At the time of this writing, Sonar can perform static analysis for 30+ programming languages. For each language, tens or hundreds of rules will be checked.
Let’s take a JavaScript rule, for example. There is a rule called “Loops should not be infinite” that checks if control structures like for and while could run indefinitely without ever terminating. It is a potentially dangerous hazard since infinite loops consume too much CPU and can cause a program to hang or crash. So, if Sonar finds any piece of your code that can cause this behavior, it will flag it and let you know in which file and line it that particular condition can happen.
For example, this snippet would raise an issue:
What if you disagree with a specific rule? It turns out you are entitled to. If you and your team disagree with a specific rule, you can create and customize a new quality profile, disabling all the rules you don’t want. Some teams could choose to do so because of legacy code, project-specific needs, preferences, and subjectivity (especially in coding style and design). The rules are created by the SonarSource team based on best practices, common vulnerabilities, and feedback. If you find yourself disabling too many rules, seek feedback from your team, community, or even from SonarSource. Understanding the rationale behind specific rules can often clarify their importance.
Historically, Sonar displayed its findings grouped by the following types of issues:
-Bug - a mistake that can lead to unexpected behavior or an error during runtime. It should not be tolerated.
-Vulnerability - a point in the code that is open to attack. It should never be tolerated.
-Code smell - not an error per se, but a maintainability issue that makes the code confusing and difficult to maintain.
Besides these, Sonar will also flag security hotspots. The developer needs to review these security-sensitive pieces of code and determine if it’s safe or should be treated as a vulnerability.
Sonar also tracks code duplications, coverage (although your DevOps environment might have to run the tests and inform the results) and quantifies technical debt by calculating how much time, on average, should be enough to fix a set of issues. The concept of Quality Gate is used to assess the overall quality of a project. By default, a project will fail the quality gate if it crosses any metric threshold, like coverage is less than 80%, duplicated lines percentage is greater than 3%, security hotspots are not reviewed, etc.
Sonar has recently adopted the Clean Code concept and deprecated issue types. From now on, you can expect to see, for every issue, the software qualities impacted: security, reliability, and maintainability.
Here’s an example of what a SonarCloud dashboard looks like. You can explore open-source projects here.
How do you get started with static code analysis?
Currently, there are three different products in the Sonar solution.
-SonarLint is a tool that analyzes your code as you type and gives instant feedback. It’s available for free as an extension in most IDE marketplaces, like VS Code, JetBrains, and Eclipse.
-SonarQube is a self-managed static code analysis tool. You can run it locally or deploy it to a server in your cloud of choice. There’s a Community Edition which is free and can analyze 19 programming languages. There are other paid editions with more advanced tools (notably multi-branch and pull request analysis) and a couple more languages (notably C, C++, Obj-C, Swift).
-SonarCloud is a software-as-a-service solution for static code analysis. It integrates with a couple of clicks with cloud DevOps platforms like GitHub, GitLab, Bitbucket, and AzureDevops. It’s free for open-source projects and has paid plans for private code. Pricing depends on the number of lines of code analyzed, starting at 100k.
Let’s examine some scenarios to understand how Sonar can be helpful to a developer or team:
Every developer should have SonarLint installed on their IDE of choice. That will allow them to find issues, get feedback, and learn best practices on the fly. It’s especially useful for junior developers or when learning a new language.
Regarding open-source software, SonarCloud is highly recommended. It’s free, and you will not have to worry about hosting and configuring a server. For example, if a project is already hosted on GitHub, you can have it integrated in a matter of minutes.
Getting started with SonarQube Community Edition is a safer bet for a small team or a single developer. If you are the only developer, you can run it locally by installing the software or using docker. For a small team, it might make sense to deploy it to a server in the cloud, so the whole team can access it at any given time. In this case, you will not pay for SonarQube, but for the underlying infrastructure: a small-scale instance requires at least 3GB of RAM. For example, renting such a server on AWS costs around $28 per month (considering a t3a.medium EC2 instance running on Virginia). There are ready-made packages by Bitnami for AWS and Azure that will make the process much easier.
For bigger teams or specific project needs, SonarQube Developer Edition or the paid plans of SonarCloud can provide additional features. The development of native iOS apps is a good example since Objective-C and Swift languages are unavailable on the free plans. The pull request decoration is another feature that can improve the developer experience for large teams. As soon as a developer creates a pull request for the other developers to review, Sonar can chime in and inform the impact of these changes on the codebase: would it introduce any new bugs or vulnerabilities? Would it negatively impact test coverage or increase code duplication? This kind of information gives confidence during code review. It might be the case that for a particular deployment, it’s acceptable to add a little technical debt in the form of code smells or duplication, but at least it will be an informed decision.
Conclusion
While tools and technologies continuously evolve, the essence of coding remains the same: deliver effective and secure solutions. Static code analysis tools have been around for many years and have proven robust. Regardless of the team's size or the project's nature, incorporating static code analysis can significantly elevate the software's quality and reduce future technical debt. In this article, we explored different scenarios in which Sonar can be useful. If you haven’t yet, I strongly recommend you try it in your next project.
Resources
- SonarSource home page with information about products? SonarQube, SonarLint
- SonarCloud explore page with open-source projects
- Rules for all the programming languages that Sonar works on.