<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Gustavo Silva</title>
    <description>The latest articles on Forem by Gustavo Silva (@gsandec).</description>
    <link>https://forem.com/gsandec</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F581098%2F24dec8cd-34be-4d60-95a5-620420e0c273.jpg</url>
      <title>Forem: Gustavo Silva</title>
      <link>https://forem.com/gsandec</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gsandec"/>
    <language>en</language>
    <item>
      <title>Code coverage best practices (Part I)</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Wed, 26 May 2021 11:49:33 +0000</pubDate>
      <link>https://forem.com/codacy/code-coverage-best-practices-part-i-1pnl</link>
      <guid>https://forem.com/codacy/code-coverage-best-practices-part-i-1pnl</guid>
      <description>&lt;p&gt;Hey all 👋, here's a two-part series about code coverage best practices. We hope you like it.&lt;/p&gt;

&lt;p&gt;It’s not easy being a software engineer — even though we’re trying to do our best, chances are we mess up from time to time.  Let’s minimize those mess-ups!&lt;/p&gt;

&lt;p&gt;In this first post, we’re going to take a closer look at the concept of code coverage itself — what it is, why is it important, and how can it be used to optimize your code.&lt;/p&gt;

&lt;h1&gt;
  
  
  The basics of code coverage
&lt;/h1&gt;

&lt;p&gt;As a programmer, we can’t just write code and and hope every line is flawless — we’re bound to make mistakes, and that’s why testing is such a critical part of the development workflow.&lt;/p&gt;

&lt;p&gt;In the most basic sense, code coverage is a way of using analytics to get an idea of how well an application has been tested. Our tests might return positive results across the board, but if they only cover 30 percent of the code it’s hard to be confident about the end product.&lt;/p&gt;

&lt;p&gt;That’s where code coverage comes in — the higher the value, the better, as a more thoroughly tested application generally has less show-stopping bugs or other flaws.&lt;/p&gt;

&lt;h1&gt;
  
  
  Calculating code coverage
&lt;/h1&gt;

&lt;p&gt;There are a couple of ways to determine how well the code is covered by the tests we run. These various metrics offer a different perspective on our code quality, and it’s useful to know the basics of each of them — that’s why we’ll run them down for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Statement coverage
&lt;/h2&gt;

&lt;p&gt;At the heart of code coverage there’s statement coverage, which checks how many statements in your program have been executed. This is the most widely used form of code coverage as it is found in most of the relevant code coverage tools. &lt;/p&gt;

&lt;h2&gt;
  
  
  Function coverage
&lt;/h2&gt;

&lt;p&gt;Another fairly basic example of code coverage. Especially important in applications that rely on a large number of functions, this coverage metric focuses on how many of the declared functions have been called during testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Branch coverage
&lt;/h2&gt;

&lt;p&gt;As a higher-level way of checking our code, the main reason to use branch coverage is to see how many branches of every control structure have been properly executed. If a program is able to jump, it should jump to all possible destinations — if there’s an ‘if’ statement, it checks if both the ‘true’ and ‘false’ branches have been executed.&lt;/p&gt;

&lt;p&gt;If the tests achieve full branch coverage, our app is protected against errors in all branches, which means that 100 percent branch coverage also indicates 100 percent statement coverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Condition coverage
&lt;/h2&gt;

&lt;p&gt;This metric looks at the various boolean sub-expressions in our code and if they were tested for both ‘true’ and ‘false’. Because expressions can get complicated, it’s hard to achieve 100 percent condition coverage — that’s why there are multiple ways of reporting this metric, all of which focus on covering the most important combinations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other kinds of coverage
&lt;/h2&gt;

&lt;p&gt;While these are the most important metrics, there are others to keep in mind when thinking about code coverage for our testing. One of these is &lt;em&gt;decision coverage&lt;/em&gt;, which is a combination of function coverage and branch coverage that checks if all entry and exit points, and all decisions and outcomes have been invoked at least once. Another metric is &lt;em&gt;multiple condition coverage&lt;/em&gt;, which requires all combinations of conditions inside decisions to be tested, effectively looking for full decision and condition coverage.&lt;/p&gt;

&lt;p&gt;Then there’s a host of less-important coverage metrics like &lt;em&gt;linear code sequence&lt;/em&gt; and &lt;em&gt;jump coverage&lt;/em&gt;, &lt;em&gt;path coverage&lt;/em&gt;, &lt;em&gt;entry/exit coverage&lt;/em&gt;, &lt;em&gt;loop coverage&lt;/em&gt; and &lt;em&gt;stage coverage&lt;/em&gt;. Because this article is meant to only offer a look at the basics of code coverage, we won’t dive into these — but it’s still good to know they exist.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to apply code coverage
&lt;/h1&gt;

&lt;p&gt;All in all, code coverage is an important way to see if our tests are comprehensively covering our code. In a large company the above metrics would be used by a team of Quality Assurance employees, but for startups and solo developers we should be looking out ourselves.&lt;/p&gt;

&lt;p&gt;It’s vital, however, that we stay critical of our code even when we achieve 100 percent coverage on the various metrics — while it can be a great way to indirectly check its quality, it relies on knowing what to test in the first place.&lt;/p&gt;

&lt;p&gt;In the next article of this two-part series we’ll take a look at how to set up code coverage in Codacy, and how it offers a smart way to analyze our code.&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>codereview</category>
      <category>testing</category>
      <category>productivity</category>
    </item>
    <item>
      <title>PostgreSQL: How to update large tables</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Tue, 11 May 2021 10:24:16 +0000</pubDate>
      <link>https://forem.com/codacy/postgresql-how-to-update-large-tables-3a2g</link>
      <guid>https://forem.com/codacy/postgresql-how-to-update-large-tables-3a2g</guid>
      <description>&lt;p&gt;Updating a large table in PostgreSQL, an advanced open-source database management system, is not straightforward. If you have a table with hundreds of millions of rows you will find those simple operations, such as adding a column or changing a column type, are hard to do in a timely manner.&lt;/p&gt;

&lt;p&gt;Doing these kinds of operations without downtime is an even harder challenge. In this blog post, we'll try to outline guidelines and strategies to minimize the impact on table availability while managing large data sets.&lt;/p&gt;

&lt;h2&gt;
  
  
  General Guidelines For PostgreSQL Table Updates
&lt;/h2&gt;

&lt;p&gt;When you update a value in a column, Postgres writes a whole new row in the disk, deprecates the old row, and then proceeds to update all indexes. This process is equivalent to an INSERT plus a DELETE for each row which takes a considerable amount of resources.&lt;/p&gt;

&lt;p&gt;Besides this, here is a list of things that you should know when you need to update large tables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is faster to create a new table from scratch than to update every single row. Sequential writes are faster than sparse updates.  You also don’t get dead rows at the end.&lt;/li&gt;
&lt;li&gt;Table constraints and indexes heavily delay every write. If possible, you should drop all the indexes, triggers, and foreign keys while the update runs and recreate them at the end.&lt;/li&gt;
&lt;li&gt;Adding a nullable column without a default value is a cheap operation. Writing the actual data of the column is the expensive part.&lt;/li&gt;
&lt;li&gt;Data stored in TOAST is not rewritten when the row is updated&lt;/li&gt;
&lt;li&gt;Converting between some data types does not require a full table rewrite since Postgres 9.2. Ex: conversion from VARCHAR(32) to VARCHAR(64).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Strategies To Update Tables In PostgresSQL
&lt;/h2&gt;

&lt;p&gt;With this in mind, let’s look at a few strategies that you can use to effectively update a large number of rows in your table in PostgreSQL:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Incremental updates
&lt;/h3&gt;

&lt;p&gt;If you can segment your data using, for example, sequential IDs, you can update rows incrementally in batches. This maximizes your table availability since you only need to keep locks for a short period of time. When adding a new column, you can temporarily set it as nullable then gradually fill it with new values.&lt;/p&gt;

&lt;p&gt;The main problem with this approach is the performance.  It is a very slow process because in-place updates are costly. It may also require more complex application logic during the migration.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create a new table
&lt;/h3&gt;

&lt;p&gt;The fastest way to update a large table is to create a new one.&lt;/p&gt;

&lt;p&gt;If you can safely drop the existing table and if there is enough disk space.  Then, the easiest way to perform the update is to insert the data into a new table and rename it afterward. Here is a script with the base structure for this operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;new_tbl&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;field1&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;field2&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;new_tbl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="c1"&gt;-- use your new logic here to insert the updated data&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="c1"&gt;-- add your constraints and indexes to new_tbl&lt;/span&gt;
&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;tbl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;tbl_new&lt;/span&gt; &lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;tbl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Recreate the existing table
&lt;/h3&gt;

&lt;p&gt;Even with the aforementioned optimizations, recreating your table in PostgreSQL is a slow operation. If you are running the queries in a live database you may need to handle concurrent write requests.&lt;/p&gt;

&lt;p&gt;The easiest way to do this is to force a SHARE LOCK on the table during the transaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;LOCK&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;tbl&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="k"&gt;SHARE&lt;/span&gt; &lt;span class="k"&gt;MODE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the write requests will wait until the lock is released or timeout if it takes too long. The requests that did not timeout will be executed once the transaction ends &lt;strong&gt;if the original parent table was not dropped&lt;/strong&gt;. Note that, even if you create a new table with the same name the requests will still fail because they use the table OID.&lt;/p&gt;

&lt;p&gt;Depending on the nature of your write requests you can also create custom &lt;a href="http://www.postgresql.org/docs/9.4/static/sql-createrule.html"&gt;rules&lt;/a&gt; to store changes made. For example, you can set a rule to record the deleted rows before you start the data migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;RULE&lt;/span&gt; &lt;span class="n"&gt;deleted_rule&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt;
&lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;tbl&lt;/span&gt;
&lt;span class="k"&gt;DO&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;tbl_deletes&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;OLD&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the migration ends, you just have to read the IDs from tbl_deletes and delete them on the new table. A similar method can be used to handle other types of requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Once you reach a certain size, operations that were once instantaneous can take several hours to prepare and execute. At Codacy we receive thousands of write requests every minute and we manage hundreds of gigabytes of data. Developing new features and improving the database performance without hurting availability is a challenge that we try to solve every day. This article contains some of the things we learned while dealing with these problems.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://www.postgresql.org/docs/"&gt;Postgresql documentation&lt;/a&gt; and some &lt;a href="http://stackoverflow.com/a/8290958/848330"&gt;stack exchange answers&lt;/a&gt; have more in-depth information about some topics mentioned here and are worth checking if you need more details on PostgreSQL.&lt;/p&gt;

&lt;p&gt;Feel free to ask questions and make suggestions in the comment section, we love to learn new and better ways of doing things while working at scale.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>codereview</category>
      <category>tutorial</category>
      <category>postgres</category>
    </item>
    <item>
      <title>List of tools for code review engineers</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Wed, 05 May 2021 09:28:40 +0000</pubDate>
      <link>https://forem.com/codacy/list-of-tools-for-code-review-engineers-2jjo</link>
      <guid>https://forem.com/codacy/list-of-tools-for-code-review-engineers-2jjo</guid>
      <description>&lt;h1&gt;
  
  
  List of tools for code review engineers
&lt;/h1&gt;

&lt;p&gt;If you perform code reviews at your company we hope that this list of tools adds value to your GitHub workflow.&lt;br&gt;
We created this &lt;a href="https://github.com/codacy/tools-for-code-review-engineers"&gt;list on GitHub&lt;/a&gt; recently and we'll periodically keep adding more tools.&lt;br&gt;
Feel free to contribute your suggestions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gitpod.io/"&gt;Gitpod&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Gitpod is an open-source Kubernetes application for automated and ready-to-code development environments that blends in your existing workflow. It enables you to describe your dev environment as code and start instant and fresh development environments for each new task directly from your browser.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pullreminders.com/"&gt;Pull Reminders&lt;/a&gt; (from Pull Panda)&lt;/td&gt;
&lt;td&gt;Review and merge pull requests faster with Slack reminders and notifications.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://pullpanda.com/assigner"&gt;Pull Assigner&lt;/a&gt; (from Pull Panda)&lt;/td&gt;
&lt;td&gt;Pull Assigner assigns code reviews to make your process more balanced and efficient: 1) Organize reviewers into groups using GitHub Teams 2) Assign pull requests to teams or automate it with CODEOWNERS 3) Pull Assigner auto-assigns one or more members of the team as reviewers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.gitify.io/"&gt;Gitify&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Gitify is all about making your life easier. Sitting on your menu bar, it informs you of any GitHub notifications without being annoying and of course without adverts. It just gets the job done. Works with GitHub and GitHub Enterprise. You can even connect multiple accounts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://steamclock.com/quests/"&gt;Quests&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Quests is similar to Gitify but with one important difference: Quest also supports GitLab.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://devhubapp.com/"&gt;DevHub&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Create columns for the repositories and people that matter to you; Receive Desktop Push Notifications; Manage Notifications, Issues, Pull Requests &amp;amp; Activities; Bookmark things for later.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.whitesourcesoftware.com/free-developer-tools/bolt"&gt;Bolt&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Designed to close the gap between code development and security, Bolt helps GitHub developers create more secure products. It detects and alerts you of vulnerable open source components in your repository.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://imgbot.net/"&gt;Imgbot&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Imgbot is a friendly robot that optimizes your images and saves you time by leveraging the power of pull requests.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>github</category>
      <category>tooling</category>
      <category>codereview</category>
      <category>productivity</category>
    </item>
    <item>
      <title>PHP Static Analysis Tools Review</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Wed, 28 Apr 2021 10:50:14 +0000</pubDate>
      <link>https://forem.com/codacy/php-static-analysis-tools-review-1dgb</link>
      <guid>https://forem.com/codacy/php-static-analysis-tools-review-1dgb</guid>
      <description>&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@benofthenorth?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Ben&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/php?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt; thank you 👌&lt;/p&gt;

&lt;p&gt;Performing PHP static analysis will help maintain your code quality over time, particularly as it becomes even harder in large projects developed by many programmers. Each person has different code styles and different ways to approach problems. Over time, this may result in confusing and unmaintainable code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static analysis tools can help developers&lt;/strong&gt; solve this problem, they enforce coding standards, detect common errors, and clean up code blocks.&lt;/p&gt;

&lt;p&gt;In this blog post, we'll take a look at the common code standards and tools used in PHP static analysis and show you how they can improve code quality and maintainability when integrated into the development process.&lt;/p&gt;

&lt;p&gt;These are all tools you can start using today for free.&lt;br&gt;
Make sure to check them for your PHP development.&lt;/p&gt;
&lt;h1&gt;
  
  
  Which PHP Static Analysis tool should you choose?
&lt;/h1&gt;
&lt;h2&gt;
  
  
  1: Code Sniffer
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pear.php.net/package/PHP_CodeSniffer/"&gt;Code Sniffer&lt;/a&gt; is arguably the most popular tool to enforce a strict style guide in your PHP code. It ships with support for popular coding standards such as &lt;a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md"&gt;PSR2&lt;/a&gt;,&lt;a href="https://framework.zend.com/manual/1.12/en/coding-standard.overview.html"&gt;Zend&lt;/a&gt;, &lt;a href="https://pear.php.net/manual/en/standards.php"&gt;PEAR&lt;/a&gt; among others. The PSR standard family is used by most people nowadays because it was created by the &lt;a href="https://www.php-fig.org/"&gt;FIG group&lt;/a&gt; so if you are looking for a standard to adopt, PSR2 is a good option. Code Sniffer also allows you to create your own coding standard. In most cases this won’t be necessary, but if you are feeling adventurous you can take a look at the &lt;a href="https://pear.php.net/manual/en/package.php.php-codesniffer.coding-standard-tutorial.php"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is an example of the output generated by Code Sniffer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;phpcs&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;standard&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="no"&gt;PSR2&lt;/span&gt;
&lt;span class="no"&gt;FILE&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;
&lt;span class="o"&gt;--------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="no"&gt;FOUND&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="no"&gt;ERRORS&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="no"&gt;WARNINGS&lt;/span&gt; &lt;span class="no"&gt;AFFECTING&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="no"&gt;LINES&lt;/span&gt;
&lt;span class="o"&gt;--------------------------------------------------------------------------&lt;/span&gt;
  &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;WARNING&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;Line&lt;/span&gt; &lt;span class="n"&gt;exceeds&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt; &lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;contains&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt; &lt;span class="n"&gt;characters&lt;/span&gt;
  &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;WARNING&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;Line&lt;/span&gt; &lt;span class="n"&gt;exceeds&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt; &lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;contains&lt;/span&gt; &lt;span class="mi"&gt;139&lt;/span&gt; &lt;span class="n"&gt;characters&lt;/span&gt;
  &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;ERROR&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;Each&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;must&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;of&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;least&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;leve&lt;/span&gt;
  &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;ERROR&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kd"&gt;Class&lt;/span&gt; &lt;span class="nc"&gt;name&lt;/span&gt; &lt;span class="s2"&gt;"foo_foo"&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;camel&lt;/span&gt; &lt;span class="n"&gt;caps&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;
 &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;ERROR&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;Method&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="s2"&gt;"foo_foo::bar_bar"&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;camel&lt;/span&gt; &lt;span class="n"&gt;caps&lt;/span&gt;
 &lt;span class="mi"&gt;23&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;ERROR&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;Each&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;must&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;itself&lt;/span&gt;
 &lt;span class="mi"&gt;23&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;ERROR&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;Each&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;must&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;of&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;least&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;leve&lt;/span&gt;
 &lt;span class="mi"&gt;33&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;ERROR&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;Expected&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt;
 &lt;span class="mi"&gt;33&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;ERROR&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="n"&gt;closing&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;permitted&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
&lt;span class="o"&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="no"&gt;PHPCBF&lt;/span&gt; &lt;span class="no"&gt;CAN&lt;/span&gt; &lt;span class="no"&gt;FIX&lt;/span&gt; &lt;span class="no"&gt;THE&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="no"&gt;MARKED&lt;/span&gt; &lt;span class="no"&gt;SNIFF&lt;/span&gt; &lt;span class="no"&gt;VIOLATIONS&lt;/span&gt; &lt;span class="no"&gt;AUTOMATICALLY&lt;/span&gt;
&lt;span class="o"&gt;-------------------------------------------------------------------------------&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, Code Sniffer shows you a detailed summary of the detected code violations. There are &lt;a href="https://pear.php.net/manual/en/package.php.php-codesniffer.reporting.php"&gt;several output formats&lt;/a&gt;, so if you want a less human-readable report for parsing purposes you can output XML or CSV data. Recently they even introduced an option to output a blame report showing the percentage of errors introduced by each developer.&lt;/p&gt;

&lt;p&gt;Although Code Sniffer can also prevent some common semantic errors, its main focus is enforcing code standards. There are other tools out there with better support for semantic error detection, but none can beat Code Sniffer when it comes to strictly follow a coding standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  2: PHPMD
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://phpmd.org/"&gt;PHP Mess Detector&lt;/a&gt; is a multi-faceted static analysis PHP Tool based on &lt;a href="https://pdepend.org/"&gt;PHP Depend&lt;/a&gt;. The kind of problems detected by PHPMD are divided into 5 main categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code SizeAnalyses code complexity and warns you if your project is starting to become unmanageable. You can define thresholds for maximum class length, method length, cyclomatic complexity, etc.&lt;/li&gt;
&lt;li&gt;DesignDetects software design-related issues, such as the use of eval, goto, exit, excessive coupling, etc.&lt;/li&gt;
&lt;li&gt;NamingEnsures that your variables, class names, and method names are appropriate (not too long, nor too short). Using good names is crucial for the person reading your code, so you should not underestimate this analysis.&lt;/li&gt;
&lt;li&gt;ControversialA few rules about naming conventions and other best practices that do not apply to every project&lt;/li&gt;
&lt;li&gt;UnusedDetects blocks of unused code that should be cleaned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is an example of PHPMD’s output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;phpmd&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="n"&gt;ruleset&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;foo_foo&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;named&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="nc"&gt;CamelCase&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt; &lt;span class="nv"&gt;$my_property&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;named&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;camelCase&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;    &lt;span class="nc"&gt;Avoid&lt;/span&gt; &lt;span class="n"&gt;unused&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt; &lt;span class="n"&gt;such&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s1"&gt;'$arg1'&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;    &lt;span class="nc"&gt;Avoid&lt;/span&gt; &lt;span class="n"&gt;unused&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt; &lt;span class="n"&gt;such&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s1"&gt;'$arg2'&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;    &lt;span class="n"&gt;bar_bar&lt;/span&gt; &lt;span class="n"&gt;accesses&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;super&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;variable&lt;/span&gt; &lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;    &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;bar_bar&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;named&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;camelCase&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;    &lt;span class="nc"&gt;Avoid&lt;/span&gt; &lt;span class="n"&gt;unused&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt; &lt;span class="n"&gt;such&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s1"&gt;'$some_name'&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;    &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;barBar&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;Consider&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;reduce&lt;/span&gt; &lt;span class="n"&gt;parameter&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="mf"&gt;10.&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;29&lt;/span&gt;    &lt;span class="nc"&gt;Avoid&lt;/span&gt; &lt;span class="n"&gt;unused&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt; &lt;span class="n"&gt;such&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s1"&gt;'$someName'&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ruleset is a XML file which contains a list of inspections that you want to enable. You can include any of the 5 main categories and even specify which rules should be used within these categories. For more information about how to create this file you can check the &lt;a href="https://phpmd.org/documentation/creating-a-ruleset.html"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Overall, PHPMD is a highly customizable static analyzer. Although it does not enforce a specific code standard, you can use it to clean your code, detect possible bugs and manage the complexity of your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  3: PHP Copy/Paste Detector
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/sebastianbergmann/phpcpd"&gt;PHPCPD&lt;/a&gt; is a small tool created by Sebastian Bergmann to detect clones in your project. Here is a short example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$phpcpd&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;phpcpd&lt;/span&gt; &lt;span class="mf"&gt;2.0.1&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="nc"&gt;Sebastian&lt;/span&gt; &lt;span class="nc"&gt;Bergmann&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="nc"&gt;Found&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;exact&lt;/span&gt; &lt;span class="n"&gt;clones&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt; &lt;span class="n"&gt;duplicated&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;
    &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;
&lt;span class="mf"&gt;1.32&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;duplicated&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="mi"&gt;1439&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Time: 21 ms, Memory: 2.50Mb You can control the verbosity of the output and the minimum number of lines/tokens that are considered a clone.&lt;/p&gt;

&lt;p&gt;Repeated code hides repeated bugs, therefore you should keep the percentage of duplicated lines as low as possible by refactoring the clones into a single method or class.&lt;/p&gt;

&lt;h2&gt;
  
  
  4: Automatic code fix
&lt;/h2&gt;

&lt;p&gt;Some tools go beyond error detection and try to automatically patch the code for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/fabpot/PHP-CS-Fixer"&gt;PHP Coding Standards Fixer&lt;/a&gt; suggests fixes according to the coding standard you specified. The following example lists the problems found in two files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fixer&lt;/span&gt; &lt;span class="n"&gt;fix&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dry&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;psr2&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;php&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;php_closing_tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eof_ending&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;php&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;braces&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;function_declaration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eof_ending&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PHPCBF is a script that can also fix some errors automatically for you. It ships with the latest version of Code Sniffer and you can run it simply like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;$ phpcbf –standard=PSR2 tests.php Patched 2 files&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Other tools
&lt;/h2&gt;

&lt;p&gt;There are other tools worth checking that I would like to mention. The first one is &lt;a href="https://pdepend.org/"&gt;PHPDepend&lt;/a&gt;, which generates an impressive set of &lt;a href="https://pdepend.org/documentation/software-metrics/index.html"&gt;metrics&lt;/a&gt; from your project code: package dependencies, cyclomatic complexity, coupling, etc. You can easily detect parts of your application that need to be refactored with this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sebastianbergmann/phploc"&gt;PHPLOC&lt;/a&gt; also shows interesting statistics about your project. It is not as powerful as PHPDepend, but you can also get an interesting overview of your code size, complexity, number of classes, etc.&lt;/p&gt;

&lt;p&gt;Finally, there is &lt;a href="https://security.sensiolabs.org/"&gt;Security Advisory Checker&lt;/a&gt;. This tool from Sensio Labs checks for security vulnerabilities in Composer dependencies. It matches your composer.lock file against a database with known security vulnerabilities and alerts you if an issue is found.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one should I choose?
&lt;/h2&gt;

&lt;p&gt;Ultimately, this is a personal choice depending on the needs of the project you are working on. You probably want to combine more than one tool to cover a wide range of possible errors and to ensure that your code remains clean and consistent. For example, you can configure Code Sniffer with your style guide and use it along with PHP Mess Detector. This will enforce consistency and, at the same time, it will detect hot spots on your project: unusually complex code, unused code sections, short variable names, etc. On top of that, you can always add other tools to complement the analysis, such as copy-paste detector for example.&lt;/p&gt;

&lt;h1&gt;
  
  
  Workflow
&lt;/h1&gt;

&lt;p&gt;To take the most out of static analysis you need to integrate it into your development cycle. If you use the tools independently you will forget about them after some time. There are several ways to do this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Directly into the IDESome editors, such as PHP Storm or Sublime Text, already have plugins that support static analysis tools. After you install and configure everything you will receive warnings and suggestions as you type. This will avoid later bug fixes because it will make you write better code from the start.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pre-commit hookIf your IDE does not support your preferred tools, of if you want stricter rules regarding commits that do not adhere to your specification, you can write a pre-commit hook in git. With this solution you can automatically abort the commit process if errors are found during the analysis.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Online analysisFinally, if you want a simple way to analyze your code without having to manually configure everything locally, you can use an online code review service such as &lt;a href="https://codacy.com"&gt;Codacy&lt;/a&gt; (shameless plug here). We already integrate some of the mentioned detection tools in this article and we are working every day to improve the service. The other main benefit of using automated code review tools is to allow you to monitor issues through time and to detect new and fixed issues one commit at a time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;PHP has an impressive set of good tools to statically analyze your code and guide you through development. You can enforce strict standards, manage complexity and detect semantic problems, which is undeniably a great help to tackle the maintainability issue of large software projects. If your team is developing in PHP without any of this, you should give it a try. Let me know how it goes in the comments.&lt;/p&gt;

</description>
      <category>php</category>
      <category>codequality</category>
      <category>codereview</category>
      <category>programming</category>
    </item>
    <item>
      <title>Local Analysis: are you getting the value you deserve from it?</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Wed, 21 Apr 2021 12:13:27 +0000</pubDate>
      <link>https://forem.com/codacy/local-analysis-are-you-getting-the-value-you-deserve-from-it-1399</link>
      <guid>https://forem.com/codacy/local-analysis-are-you-getting-the-value-you-deserve-from-it-1399</guid>
      <description>&lt;p&gt;This live session is today!&lt;/p&gt;

&lt;p&gt;Allow me to share here our first ever webinar 🎉&lt;/p&gt;

&lt;p&gt;We'll provide an overview of static code analysis, and detail how you can set up the CLI to run code analysis on your build server. &lt;/p&gt;

&lt;p&gt;You'll also get a better sense of the benefits and what you can achieve with a single command, as our experts, &lt;strong&gt;André Meira&lt;/strong&gt; and &lt;strong&gt;Hélio Rocha&lt;/strong&gt; will be showcasing the CLI tool performing analysis on the code before committing it. &lt;/p&gt;

&lt;p&gt;What you can achieve with a single command, and how to make the most out of it; you'll get better insights on how to execute code analysis locally and its advantages.&lt;/p&gt;

&lt;p&gt;Join us at 12 pm ET (9 am PT, 5 pm Lisbon). &lt;br&gt;
&lt;a href="https://hubs.li/H0LGpsl0"&gt;Register here&lt;/a&gt; &lt;/p&gt;

</description>
    </item>
    <item>
      <title>An In-Depth Explanation of Code Complexity</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Wed, 21 Apr 2021 09:38:02 +0000</pubDate>
      <link>https://forem.com/codacy/an-in-depth-explanation-of-code-complexity-1ld3</link>
      <guid>https://forem.com/codacy/an-in-depth-explanation-of-code-complexity-1ld3</guid>
      <description>&lt;p&gt;It’s no secret code is a complicated thing to write, debug, and maintain which is necessary for high software quality. Moreover, high code complexity brings with it a higher level of code defects, making the code costlier to maintain.&lt;/p&gt;

&lt;p&gt;So, by reducing code complexity, we can reduce the number of bugs and defects, along with its lifetime cost. What exactly is complex code? How can we objectively assess how complex a piece of code is, whether that’s an entire codebase or one small function?&lt;/p&gt;

&lt;p&gt;In this article, I’m going to walk through three complexity metrics for assessing code complexity. These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cyclomatic complexity&lt;/li&gt;
&lt;li&gt;Switch statement and logic condition complexity&lt;/li&gt;
&lt;li&gt;Developer skill&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll also go through some of the benefits of assessing and understanding code complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cyclomatic Complexity
&lt;/h2&gt;

&lt;p&gt;In 1976, Thomas McCabe Snr proposed a metric for calculating code complexity, called Cyclomatic Complexity. It’s defined as:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A Quantitative Measure Of The Number Of Linearly Independent Paths Through A Program’s Source Code…Computed Using The Control Flow Graph Of The Program.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you’re not familiar with a &lt;a href="https://en.wikipedia.org/wiki/Control_flow_graph"&gt;Control Flow Graph&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It Is A Representation, Using Graph Notation, Of All Paths That Might Be Traversed Through A Program During Its Execution.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Said more straightforwardly, the fewer the paths through a piece of code, and the less complex those paths are, the lower the Cyclomatic Complexity. As a result, the code is less complicated. To demonstrate the metric, let’s use three, somewhat arbitrary, Go code examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example One
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1 + 1 ="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As there’s only one path through the function, it has a Cyclomatic Complexity score of 1, which we can find by running &lt;a href="https://github.com/fzipp/gocyclo"&gt;gocyclo&lt;/a&gt; on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Two
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;November&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;2018&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Happy Go day!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The current month is"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we’re retrieving the current year, month, and day. With this information, we then check if the current date is the 10th of November 2018 with an if/else condition.&lt;/p&gt;

&lt;p&gt;If it is, then the code prints “Happy Go day!” to the console. If it isn’t, then it prints “The current month is” and the name of the current month. The code example is made more complicated as the if the condition is composed of three sub-conditions. Given that, it has a higher complexity score of 4.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Three
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;January&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The current month is January."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;February&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The current month is February."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;March&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The current month is March."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;April&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The current month is April."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The current month is May."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The current month is unknown."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we’re printing out the current month, based on the value of &lt;strong&gt;month&lt;/strong&gt;, retrieved from the call to &lt;strong&gt;time.Now().Date()&lt;/strong&gt;. There are seven paths through the function, one for each of the case statements and one for the default.&lt;/p&gt;

&lt;p&gt;As a result, its Cyclomatic Complexity is 7. If we’d accounted for all the months of the year, along with a default, however, its score would be fourteen. That happens because Gocyclo uses &lt;a href="https://github.com/fzipp/gocyclo/blob/master/README.md"&gt;the following calculation rules&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;1 is the base complexity of a function&lt;br&gt;
+1 for each ‘if’, ‘for’, ‘case’, ‘&amp;amp;&amp;amp;’ or ‘||’&lt;/p&gt;

&lt;p&gt;Using these three examples, we can see that by having a standard metric for calculating code complexity, we can quickly assess how complex a piece of code is.&lt;/p&gt;

&lt;p&gt;We can also see how different complex sections of code are in comparison with each other. However, Cyclomatic Complexity &lt;a href="https://www.cqse.eu/en/blog/mccabe-cyclomatic-complexity/"&gt;is not enough on its own&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Switch Statement and Logic Condition Complexity
&lt;/h2&gt;

&lt;p&gt;The next assessor of code complexity is the switch statement and logic condition complexity. In the code example below, I’ve taken the second Go example and split the compound if condition into three nested conditions; one for each of the original conditions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The current month is %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;November&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;2018&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Happy Go day!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which is easier to understand (or less complicated), the original one, or this one? Now let’s build on this, by considering the following three questions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What if we had, as we do above, multiple if conditions and each one was quite complex?&lt;/li&gt;
&lt;li&gt;What if we had multiple if conditions and the code in the body of each one were quite complex?&lt;/li&gt;
&lt;li&gt;Would the code be easier or harder to understand?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is fair to say that the greater the number of nested conditions and the higher the level of complexity within those conditions, the higher the complexity of the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software Developer Skill Level
&lt;/h2&gt;

&lt;p&gt;What about the skill level of the developer? Have a look at the C version of the second Go example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;time.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;time_t&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;tm&lt;/span&gt; &lt;span class="n"&gt;tm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;localtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;months&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"January"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"February"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"March"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"April"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"May"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"June"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"July"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"August"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"September"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"October"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"November"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"December"&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tm_year&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2018&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="n"&gt;strncmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;months&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tm_mon&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"November"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;months&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tm_mon&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;tm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tm_mday&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Happy C Day!.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The current month is %s.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;months&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tm_mon&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Technically, it does what the other examples do. However, it requires more code to achieve the same outcome. To be fair, if I had a greater familiarity with C, the code might be no longer than the Go example.&lt;/p&gt;

&lt;p&gt;However, let’s say this is the minimum required to achieve the same outcome. If you compare the two, given the more verbose nature of C’s syntax when compared to Go, it’s harder to understand.&lt;/p&gt;

&lt;p&gt;What’s more, if you had no prior experience with C, despite a comparatively similar Cyclomatic Complexity score, what would your perception be?&lt;/p&gt;

&lt;p&gt;Would you consider the code to be less or more complicated? So this is another essential factor in understanding code complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Benefits of Measuring Software Complexity
&lt;/h2&gt;

&lt;p&gt;There are four core benefits of measuring code complexity, plus one extra.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better Tests
&lt;/h3&gt;

&lt;p&gt;By knowing how many independent paths there are through a piece of code, we know how many paths there are to test.&lt;/p&gt;

&lt;p&gt;I’m not advocating for 100% code coverage by the way—that’s often a meaningless software metric. However, I always advocate for as high a level of code coverage as is both practical and possible.&lt;/p&gt;

&lt;p&gt;So, by knowing how many code paths there are, we can know how many paths we have to test. As a result, you have a measure of how many tests are required, at a minimum, to ensure that the code’s covered.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reduced Risk
&lt;/h3&gt;

&lt;p&gt;As the old saying goes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It’s Harder To Read Code Than To Write It.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What’s more:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Code is read far more than it is written&lt;/li&gt;
&lt;li&gt;A good software developer should never be assessed by the lines of code they’ve written (or changed), but by the quality of the code they’ve maintained.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Given that, by reducing code complexity, you reduce the risk of introducing defects; whether they’re small or large, slightly embarrassing or bankruptcy-inducing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lower Costs
&lt;/h3&gt;

&lt;p&gt;When the risk of potential defects is reduced, there are fewer defects to find—and remove. As a result, the maintenance cost also reduces.&lt;/p&gt;

&lt;p&gt;We’ve all seen and are familiar with the costs associated with finding defects at the various stages in a software’s life, as exemplified &lt;a href="https://www.seguetech.com/rising-costs-defects/"&gt;in the chart below&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U9HcVw87--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28sxki8b044ra9q6po2m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U9HcVw87--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28sxki8b044ra9q6po2m.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So it makes sense that, if we understand the complexity of our code, and which sections are more complicated than others, then we are in a far better position to reduce said complexity.&lt;/p&gt;

&lt;p&gt;So by reducing that complexity, we reduce the likelihood of introducing defects. That flows into all stages of a software’s life.&lt;/p&gt;

&lt;h3&gt;
  
  
  Greater Predictability
&lt;/h3&gt;

&lt;p&gt;By reducing software complexity, we can develop with greater predictability. What I mean by that is we’re better able to say—with confidence—how long a section of code takes to complete. By knowing this, we’re better able to predict how long a release takes to ship.&lt;/p&gt;

&lt;p&gt;Based on this knowledge the business or organization is better able to set its goals and expectations, especially ones that are directly dependent on said software. When this happens, it’s easier to set realistic budgets, forecasts, and so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Helps Developers Learn
&lt;/h3&gt;

&lt;p&gt;Helping developers learn and grow is the final benefit of understanding why their code is considered complex. The tools I’ve used to assess complexity up until this point don’t do that.&lt;/p&gt;

&lt;p&gt;What they do is provide an overall or granular complexity score. However, a comprehensive code complexity tool, such as Codacy, does.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7Zc3Ij7O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kcld6ajaqlhdrdg9pezn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Zc3Ij7O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kcld6ajaqlhdrdg9pezn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the screenshot above, we can see that, of the six files listed, one has a complexity of 30, a score usually considered quite high.&lt;/p&gt;

&lt;p&gt;Cyclomatic complexity is a great indicator to understand if code quality deteriorating for any given change. Cyclomatic complexity can be harder to reason when looking at it or comparing whole modules given its infinite scale and not being related to the module size. However, something that you might find useful is looking at &lt;a href="http://docs.codacy.com/repositories/files-view/"&gt;Codacy’s File list&lt;/a&gt; sorted by priority, which will help you understand which files are candidates of poor code quality, and then by consequence their modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  That’s a Wrap
&lt;/h2&gt;

&lt;p&gt;Also, this has been an in-depth discussion about what code complexity is, how it’s assessed, as well as the significant benefits of reducing it. While there is more to understanding code complexity than I’ve covered here, we’ve gone a long way to understanding it.&lt;/p&gt;

&lt;p&gt;If this is your first time hearing about the term or learning about any of the tools, I encourage you to explore the linked articles and tools, so that you learn more. If you don’t code in Go or C, then google “code complexity tool” plus your software language(s). You’re sure to find many tools available.&lt;/p&gt;

&lt;p&gt;Finally, if you want a comprehensive tool for assessing code quality, and one that helps your developers learn and grow, type on Google automated code reviews and you'll find a few tools worth testing, among them is Codacy.&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>codereview</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>7 drawbacks of linting tools</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Wed, 14 Apr 2021 14:27:06 +0000</pubDate>
      <link>https://forem.com/codacy/7-drawbacks-of-linting-tools-3a03</link>
      <guid>https://forem.com/codacy/7-drawbacks-of-linting-tools-3a03</guid>
      <description>&lt;p&gt;Linting tools (also known as linters or static analyzers) help automate the code review process. They perform basic static code analysis by flagging programming errors, bugs, style issues, and security vulnerabilities before code is compiled and actually runs. The overall aim is to &lt;strong&gt;improve software quality and reduce costs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While integrating these tools into your workflow is largely beneficial, some drawbacks exist which may not make them the best choice for long-term or more sophisticated software development.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Code Checks Limited To One Programming Language
&lt;/h2&gt;

&lt;p&gt;Many free, open-source linters perform code checks on only one coding language. This includes popular linters (per coding language) below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt;: Pylint, Pyflakes, Flake8 (&lt;a href="https://dev.to/codacy/which-python-static-analysis-tools-should-i-use-3838"&gt;read more&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java&lt;/strong&gt;: Checkstyle, PMD, FindBugs (&lt;a href="https://dev.to/codacy/review-of-java-static-analysis-tools-3jp7"&gt;read more&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ruby&lt;/strong&gt;: Brakemen, rust-clippy, Rubocop&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scala&lt;/strong&gt;: ScalaStyle, wart remover&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript&lt;/strong&gt;: ESLint, JSLint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These thirteen linters exemplify choices for less than 1% of coding languages that exist (sources like Wikipedia count more than 700).  While difficult to pinpoint the exact number of linting tools, we know that there are hundreds since just the top 189(!) have been identified by &lt;a href="//AwesomeOpenSource.com"&gt;AwesomeOpenSource.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Given such variety, technology stacks with multiple coding languages may need multiple tools integrated into the development workflow.  This may produce negative effects which we describe in more detail below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XaVfx78r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/etbey727bqafl9tceocz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XaVfx78r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/etbey727bqafl9tceocz.jpeg" alt="Diagram illustrating just some of the many open-source static analyzers such as pylint, flake8, eslint and golint."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Variable Functionality For A Narrow View Of Code Quality
&lt;/h2&gt;

&lt;p&gt;Similarly, the variety of functions among tools makes standardization difficult. Some focus on just one aspect of code quality like security, syntax, code coverage, or code style. For instance, among Python static analysis tools, Pyflakes analyzes code syntax whereas Flake8, another tool, is used for stylistic checks.&lt;/p&gt;

&lt;p&gt;With multiple tools performing a variety of functions, it is difficult to obtain an integrated, holistic view of code quality. Also, it is bothersome to have the same code errors flagged by multiple tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Difficulty Handling Complex Rules
&lt;/h2&gt;

&lt;p&gt;Linters analyze code for stylistic and programming errors against the rules they already know. While great for identifying errors using standard rules, this may pose problems for more unconventional code practices.&lt;/p&gt;

&lt;p&gt;Although you may be able to avoid errors by overriding defaults and adjusting or disabling rules for particular files, this could cost developers’ time.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. False Positives
&lt;/h2&gt;

&lt;p&gt;A common critique of linters is that they produce many false positives. In other words, they flag issues that are not true issues in source code. While most developers find false positives annoying some use them as a sign to adjust rules for particular files. &lt;/p&gt;

&lt;p&gt;However, adjusting rules becomes complicated when configuring multiple linters. Each linter has a different configuration file (with different syntaxes and semantics) that also needs to be adjusted. Therefore, in order to disable a rule considered false positive, developers should read the documentation of each linter before tweaking the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  5.  Reporting On Only Basic Metrics
&lt;/h2&gt;

&lt;p&gt;While linting tools are good for basic metrics, they may not be the best choice to report on more complex indicators of software quality. This includes cyclomatic complexity which gauges the complexity of a program. Also, it is key to integrate linting tools early in the development workflow so that reporting and incorporating code quality metrics occurs before production.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Limited Learnings
&lt;/h2&gt;

&lt;p&gt;While they identify best practices, linters do not ensure the teachings of best practices. Developers can use linting tools to improve code, but they might not be able to replicate the best practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Hidden Costs
&lt;/h2&gt;

&lt;p&gt;While open-source tools seem “free”, hidden costs related to many of their mentioned shortcomings exist. For instance, integrating multiple tools in the development workflow requires maintenance and monitoring of each tool. When new updates occur, changes will need to be implemented.&lt;/p&gt;

&lt;p&gt;This additional workload may fall on the plate of development or DevOps teams who could otherwise spend their time building new features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Review Suites
&lt;/h2&gt;

&lt;p&gt;Fortunately, advanced static analysis tools exist which mitigate most drawbacks of using individual linters.  Code review suites integrate some of the most well-known linting tools on one platform. This ensures the detection of problems across languages.  &lt;/p&gt;

&lt;p&gt;There are many great code review tools out there and if you Google it you'll find Codacy on the top of your search results. &lt;/p&gt;

&lt;p&gt;At Codacy, we integrate several linting tools plus their own rules in a continuous manner ensuring those tools are updated and new, useful tools are introduced. This helps support 40+ programming languages using one tool for code quality automation.  Also, rather than needing to read documentation in order to disable a rule considered false positive, users can click on one button to disable a rule on Codacy. &lt;/p&gt;

&lt;p&gt;While tools like Codacy may come at a &lt;a href="https://www.codacy.com/pricing"&gt;monthly cost&lt;/a&gt;, for some use cases it may be worth it. &lt;/p&gt;

&lt;p&gt;Overall linters are a strong tactic for automated code review and important to incorporate into your workflow. However, keep in mind the downsides before you incorporate too many of them as this may actually add costs rather than reduce them.&lt;/p&gt;

&lt;p&gt;Go ahead and take a look at which tool adds value to your workflow and work environment. You have plenty of good choices to choose from. &lt;/p&gt;

</description>
      <category>codereview</category>
      <category>codequality</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>Code Review vs. Testing</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Wed, 07 Apr 2021 11:27:56 +0000</pubDate>
      <link>https://forem.com/codacy/code-review-vs-testing-8b8</link>
      <guid>https://forem.com/codacy/code-review-vs-testing-8b8</guid>
      <description>&lt;p&gt;Among coding best practices, code review vs. testing are often compared. Here’s what you need to know about each.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Code Reviewing and Testing?
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Code Review
&lt;/h2&gt;

&lt;p&gt;Code refers to the act of inspecting code; this can be done in the search for bugs, code style policy violations, security vulnerabilities, the extreme complexity of code, etc. The goal is towards code quality but also making sure the code does what it is supposed to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Testing is actually a vague description, as it might refer to several types of testing; for the purpose of this article, we’ll consider Unit Tests: tests that are implemented and can be run automatically with every build or even every commit to making sure former bugs don’t show up again (other types of testing include Regression testing, Integration testing, and Smoke Testing, to name a few, but we’ll leave these for a future post).&lt;/p&gt;

&lt;h2&gt;
  
  
  Does Code Review replace Testing?
&lt;/h2&gt;

&lt;p&gt;Not at all.&lt;/p&gt;

&lt;p&gt;I have seen this quite too often: strong &lt;strong&gt;Code Review&lt;/strong&gt; processes in place with no deployments until everything is inspected by a senior member of the team, only to reintroduce bugs that were thought to be in the past.&lt;/p&gt;

&lt;p&gt;As codebases grow it becomes harder and harder to keep everything in one’s mind, and sometimes it’s easy to overlook the appropriate way to use a method, the appropriate parameters to use, or the side effect of an action in very a specific circumstance.&lt;/p&gt;

&lt;p&gt;With more than one reviewer present (unless it’s mandatory that code is reviewed by all of them) each reviewer begins accumulating blind areas of the codebase that are only known to certain members of the team.&lt;/p&gt;

&lt;p&gt;Couple with the fact that the larger the platform the harder it is to manually test everything after each deployment, the absence of Unit Testing renders every update into a minefield packet with bombs that will only go off whenever a user named Murphy comes along.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does Testing replace Code Review?
&lt;/h2&gt;

&lt;p&gt;The following actually happened: big company, big client, big solution. There was a dedicated testing team that implemented every possible scenario they could think of, and they ran the tests every single day.&lt;/p&gt;

&lt;p&gt;The client was a major political party about to use the platform for communication purposes on elections day.&lt;/p&gt;

&lt;p&gt;What could possibly go wrong, right?&lt;/p&gt;

&lt;p&gt;Sadly, when launched, the system simply didn’t work, and it being a Sunday meant that the team wasn’t readily available.&lt;/p&gt;

&lt;p&gt;What caused the problem?&lt;/p&gt;

&lt;p&gt;The fact that it was Sunday.&lt;/p&gt;

&lt;p&gt;And that the tests had only run from Monday to Friday.&lt;/p&gt;

&lt;p&gt;As it turns out, the platform had a bug that rendered it inoperable during Sundays (something to do with 0-indexed arrays).&lt;/p&gt;

&lt;p&gt;In retrospect, Code Review could have indeed saved the day, as analyzing the code with a thorough attitude could have caught this particular flaw.&lt;/p&gt;

&lt;p&gt;While testing is important, in this case, it didn’t really account for every possible scenario*.&lt;/p&gt;

&lt;p&gt;That’s where a human comes in, analyzing code with a critical mindset and thinking of possibilities that may have been neglected when the tests were written.&lt;/p&gt;

&lt;p&gt;Also, Code Review is not just about catching bugs that could’ve been caught through testing. Code Review also targets readability/maintainability, code complexity, performance, unused or duplicated code, etc.&lt;/p&gt;

&lt;p&gt;* — For those wondering whether it would be possible to test every possible scenario: the answer is no. &lt;/p&gt;

&lt;p&gt;While you could have tests running on weekends as well you’d still be missing all the other possibilities: nights, different machines, bugs that only manifest if the code hasn’t run for the past 3 hours, or even flaws that only become meaningful when a specific amount of users is connected to the platform (not necessarily a huge amount of users, which would be covered by Stress Testing, but rather a specific amount of users, such as 11).&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Review Vs. Testing: Conclusions
&lt;/h2&gt;

&lt;p&gt;When it comes to best practices, there’s hardly any that can replace another, and such is the case with Code Review and Testing.&lt;/p&gt;

&lt;p&gt;At most you’ll be deciding which one is a priority regarding the other or which one should come first in your workflow, but not which one to put in place in detriment of the other.&lt;/p&gt;

&lt;p&gt;Regarding Testing and Code Review, they don’t replace each other and they shouldn’t be mutually exclusive.&lt;/p&gt;

&lt;p&gt;You should test, and you should review your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  More about Code Reviews
&lt;/h3&gt;

&lt;p&gt;If you want to keep reading about code reviews, take a look at the article &lt;a href="https://dev.to/codacy/top-10-ways-to-perform-fast-code-reviews-1id1"&gt;10 ways to perform code reviews&lt;/a&gt;. I hope it adds value to your day!&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>codequality</category>
      <category>testing</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Top 10 ways to perform fast code reviews</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Thu, 01 Apr 2021 11:41:58 +0000</pubDate>
      <link>https://forem.com/codacy/top-10-ways-to-perform-fast-code-reviews-1id1</link>
      <guid>https://forem.com/codacy/top-10-ways-to-perform-fast-code-reviews-1id1</guid>
      <description>&lt;h1&gt;
  
  
  We always want to be fast at code reviews...
&lt;/h1&gt;

&lt;p&gt;How frequent is it for you to be reviewing code at 3 am?&lt;br&gt;
When code reviewing, do you find yourself thinking: “I mentioned this before.. We should have some sort of process”.&lt;/p&gt;

&lt;p&gt;We keep learning a lot with our user base which currently supports more than 200 000 developers.&lt;/p&gt;

&lt;p&gt;A big aspect is how developers waste themselves in the process of code reviewing.&lt;br&gt;
Code reviews (pull requests, commit validation or approval), can be tedious and exhausting.&lt;br&gt;
We’ve gathered some aspects from people who are doing it right.&lt;br&gt;
These are small hints that we’ve seen from our users that highly help so you don’t have to be alone at 5 am reviewing your team’s code.&lt;/p&gt;

&lt;h2&gt;
  
  
  1: Review less
&lt;/h2&gt;

&lt;p&gt;Smaller commits lead to smaller more manageable code reviews.&lt;br&gt;
Besides other clear benefits (&lt;a href="http://www.crealytics.de/blog/2010/07/09/5-reasons-keeping-git-commits-small-admin/"&gt;1&lt;/a&gt;, &lt;a href="https://softwareengineering.stackexchange.com/questions/10793/when-is-a-version-control-commit-too-large"&gt;2&lt;/a&gt;, &lt;a href="http://blog.bignerdranch.com/3867-small-distinct-commits-say-you-care/"&gt;3&lt;/a&gt;, &lt;a href="http://sethrobertson.github.io/GitBestPractices/"&gt;4&lt;/a&gt;), dividing work into smaller chunks leads to more understanding of the intent of the change (hence more understanding into ways to put it better).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: My team likes to have big bulky commits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Start dividing your work into smaller commits. When your team sees the clear benefits of reviewing your code, they will most likely follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  2: Time boxing
&lt;/h2&gt;

&lt;p&gt;Code reviewing tends to be secondary in the process. Hence, it’s common to see it slipping away through the day when finally you’re all alone in the office validating work from other people.&lt;/p&gt;

&lt;p&gt;A good way to help mitigate this is by assigning a time slot in the day to review the code.&lt;br&gt;
When that is not possible, try to apply a maximum value to it (like 60,70,80 minutes).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: My team ships code into production at crazy hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Prioritize your reviews by checking the essential when a complete review is not possible (see the review checklist below). When you see yourself not being able to properly review code, try to change the timing, deploy hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  3: Distribute/Delegate
&lt;/h2&gt;

&lt;p&gt;Make sure reviews don’t fall on the same person.&lt;br&gt;
I’ve seen companies centralizing code reviews on one person.&lt;br&gt;
It makes for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Overworked people&lt;/li&gt;
&lt;li&gt;Slower deploy times&lt;/li&gt;
&lt;li&gt;Bad reviews (reduced attention span)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: But my CTO is micromanaging the code reviews to make sure everything is alright&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem 2&lt;/strong&gt;: But I don’t trust my team to deploy code without my eyes on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Teach a man to fish. Also, make for your (or your boss's) review as an additional safeguard but not an essential blocking one.&lt;/p&gt;

&lt;h2&gt;
  
  
  4: Shared Code guidelines
&lt;/h2&gt;

&lt;p&gt;Before enforcing a best practice, one can always make sure everyone is on board with it.&lt;br&gt;
Take time to view what guidelines are important.&lt;br&gt;
Always hear when developers want to add to the guidelines.&lt;br&gt;
Good people always look for ways to improve their craft. Good developers always want to stay updated.&lt;/p&gt;

&lt;p&gt;For different programming languages, you have different coding guidelines.&lt;/p&gt;

&lt;p&gt;If you don’t yet have a coding guideline, here’s a list of them by programming language to start the conversation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.caliban.org/ruby/rubyguide.shtml"&gt;Ruby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bbatsov/ruby-style-guide"&gt;Community-driven&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/styleguide/ruby"&gt;Github’s style&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/616037/ruby-coding-style-guidelines"&gt;SO Answer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-doc.com/docs/ProgrammingRuby/"&gt;Rubydoc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml"&gt;Javascript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://javascript.crockford.com/code.html"&gt;Crockford’s guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/felixge/node-style-guide"&gt;Felix’s Node style&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript_Tips"&gt;Mozilla&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rwaldron/idiomatic.js"&gt;Idiomatic.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://google-styleguide.googlecode.com/svn/trunk/pyguide.html"&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://legacy.python.org/dev/peps/pep-0008/"&gt;Guido’s PEP8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.python-guide.org/en/latest/writing/style/"&gt;python-guide.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/"&gt;PHP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.toPear"&gt;Pear&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.php-fig.org/"&gt;PHP-FIG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md"&gt;PSR-0: Autoloader Standard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md"&gt;PSR-1: Basic Coding Standard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md"&gt;PSR-2: Coding Style Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Taking community-driven standards (or at least basing your company’s code style in it) it’s a great idea since it ease’s new developer onboarding and better community help.&lt;/p&gt;

&lt;h2&gt;
  
  
  5: Create a checklist upon review
&lt;/h2&gt;

&lt;p&gt;Having a checklist to review code greatly improves the efficiency of the process.&lt;br&gt;
Sometimes in the middle of a review, we identify an issue and we remember we haven’t been really paying attention to that specific problem previously (which then leaves you with the uncertainty of an incomplete job).&lt;/p&gt;

&lt;p&gt;Ideally, one should have every important aspect in one’s head (since for N lines of code, checking each one for N code rules is O(N2) — absurd of course but you get the point).&lt;/p&gt;

&lt;p&gt;Also, the inverse of having coding guidelines (point 4) is enforcing them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: There are a lot of engineering issues that don’t fit into the checklist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Definitely right. These can be addressed afterward in a team/one-to-one short meeting. Overall, this is a learning process, and is much more important to start doing some early and learn from what is missing or being left out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s a small suggestion of a code review checklist to start the conversation in your team:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is the code style according to our own?&lt;/li&gt;
&lt;li&gt;Is this code according to the best practices we/community defined?&lt;/li&gt;
&lt;li&gt;Is this code problematic/inefficient/error-prone/not clear/previously proved bad/not compatible with the architecture&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt;/&lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;SRP&lt;/a&gt;/&lt;a href="http://en.wikipedia.org/wiki/KISS_principle"&gt;KISS&lt;/a&gt;/&lt;a href="http://en.wikipedia.org/wiki/YAGNI"&gt;YAGNI&lt;/a&gt;/&lt;a href="http://en.wikipedia.org/wiki/Code_smell"&gt;Smell&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are other checklists you might find interesting as well: &lt;a href="http://arkhitech.com/checklist-code-review-web-applications"&gt;1&lt;/a&gt;, &lt;a href="http://www.codeproject.com/Articles/593751/Code-Review-Checklist-and-Guidelines-for-Csharp-De"&gt;2&lt;/a&gt;, &lt;a href="http://smartbear.com/SmartBear/media/pdfs/WP-CC-11-Best-Practices-of-Peer-Code-Review.pdf"&gt;3&lt;/a&gt;, &lt;a href="http://courses.cs.washington.edu/courses/cse403/12wi/sections/12wi_code_review_checklist.pdf"&gt;4&lt;/a&gt;, &lt;a href="http://stackoverflow.com/questions/4262693/what-to-look-for-in-a-code-review"&gt;5&lt;/a&gt;, &lt;a href="https://www.liberty.edu/media/1414/%5B6401%5Dcode_review_checklist.pdf"&gt;6&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6: Use collaborative review tools
&lt;/h2&gt;

&lt;p&gt;Doing Git (or repository-based) reviews only (by looking at logs, diffs, and commits) is time-consuming.&lt;br&gt;
One should look for a tool that allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quickly review what changed&lt;/li&gt;
&lt;li&gt;Quickly be able to communicate with people&lt;/li&gt;
&lt;li&gt;Decide to approve (or not) the commit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By concentrating these three aspects into one tool, you can be more efficient at the underlying actions we need to execute a code review.&lt;/p&gt;

&lt;p&gt;If you’re choosing a tool, choose one that you can get your whole team on board.&lt;br&gt;
Github, Bitbucket, and GitLab both have pull requests which represent a workflow with built-in code reviews.&lt;/p&gt;

&lt;h2&gt;
  
  
  7: Do a little, even if no time
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: It’s Thursday and you want to deploy some features into production (because you don’t deploy code on Fridays). However, it’s been a specially tough week and so you haven’t really been paying attention to how code evolved.&lt;br&gt;
Before you know it you have 200 commits to review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Prioritize your checks and don’t strain yourself. Only check for major issues. Code style can be checked later or automatically through linting afterward.&lt;/p&gt;

&lt;p&gt;Knowing the history of the project (and the problems you’ve had), you also have a sense of the more important aspects to look for.&lt;/p&gt;

&lt;p&gt;The important part is sharing ownership and sharing knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  8: Use short-circuiting
&lt;/h2&gt;

&lt;p&gt;When time is of the essence and reviewing every line written is not an option, take an incremental approach.&lt;/p&gt;

&lt;p&gt;When you’ve found a possible buffer overflow or a function call you know it will blow up in production, it shouldn’t really matter to review code style.&lt;/p&gt;

&lt;p&gt;In your code review checks, you can insert short-circuiting elements: if a commit has a big enough problem that needs to have further development, one can ignore smaller less important problems for a future review of that code when it is corrected.&lt;/p&gt;

&lt;h2&gt;
  
  
  9: Helpful commits
&lt;/h2&gt;

&lt;p&gt;Concise and to the point commit messages with code that is commented really narrows the focus of the review.&lt;br&gt;
The code reviewer will have a much easier job if you talk about the implemented feature and the design decisions behind it.&lt;br&gt;
Helping your team members is a good way for them to see how valuable a proper commit is.&lt;br&gt;
Take a look at how the Linux kernel guides their own submission: &lt;a href="https://www.kernel.org/doc/Documentation/SubmittingPatches"&gt;https://www.kernel.org/doc/Documentation/SubmittingPatches&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  10: Add automated code review tools to your workflow
&lt;/h2&gt;

&lt;p&gt;A final and great way to reduce the time it takes to review code is by reducing the number of aspects of your checklist that you need to pay attention to.&lt;/p&gt;

&lt;p&gt;By adding automated code review tools you can automate some aspects of your code reviews such as code style, best practices, and common issues. This frees you to only check for what matters.&lt;/p&gt;

&lt;p&gt;Automation lets you be better and save time. Combined with the aspects on top, you’re on your way to make sure you don’t spend more time than you have on code reviews.&lt;/p&gt;

&lt;p&gt;Because you care and because you always want to be better, automation is a great way to optimize your review workflow process. Go ahead and do a quick search on Google for automated code reviews and see who better fits your workflow. You'll find &lt;a href="https://codacy.com"&gt;Codacy&lt;/a&gt; on your Google search and we hope you like what we do.&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>codereview</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Top 6 items for your code review checklist</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Thu, 25 Mar 2021 17:06:01 +0000</pubDate>
      <link>https://forem.com/codacy/top-6-items-for-your-code-review-checklist-4k6g</link>
      <guid>https://forem.com/codacy/top-6-items-for-your-code-review-checklist-4k6g</guid>
      <description>&lt;p&gt;At Codacy we set high standards, and care about the quality of the code we produce. In order to provide optimal experiences for our users, we highly suggest having a process in place for code review. To help, below are the top 6 items for your code review checklist.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why do code review?
&lt;/h1&gt;

&lt;p&gt;First, let’s go over the top three reasons that those involved in the software development process should perform code review.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Avoid bugs&lt;/strong&gt;: the cost of a bug increases exponentially the later you catch it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharing&lt;/strong&gt;: being subjected to a good code review is a master learning experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Culture&lt;/strong&gt;: foster a positive collaborative environment toward a common goal.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Automatic code review tools
&lt;/h2&gt;

&lt;p&gt;Automatic tools such as compilers, testing libraries, linters and formatters have improved the effectiveness of code review in recent years. They do an effective job reducing heavy lifting and boring parts of the code review process.&lt;/p&gt;

&lt;p&gt;While there may be initial setup costs, integrating these tools yields immediate returns. I suggest you seize the opportunity to use these tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top 6 items for better code review
&lt;/h2&gt;

&lt;p&gt;Since automation alone cannot cover all aspects of a code review below are the top six bullet points to handle the other parts:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Review your code first
&lt;/h3&gt;

&lt;p&gt;Always review your own code first – don’t rush by pressing the button to open a pull request. I suggest following a checklist to help you catch silly mistakes, typos, and other distractions in order to ultimately save time and effort. To challenge and stretch yourself it may be helpful to answer questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this the correct level of abstraction?&lt;/li&gt;
&lt;li&gt;Is the approach the best one given the constraints?&lt;/li&gt;
&lt;li&gt;How would I improve this solution?&lt;/li&gt;
&lt;li&gt;Are there quick wins we can tackle within the scope of code change? &lt;/li&gt;
&lt;li&gt;Can this be broken down into smaller code changes?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Understand the purpose
&lt;/h3&gt;

&lt;p&gt;Make sure you understand the reason why the code change exists in the first place. Is it to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fix a bug?&lt;/li&gt;
&lt;li&gt;Add a feature?&lt;/li&gt;
&lt;li&gt;Change functionality?&lt;/li&gt;
&lt;li&gt;Improve a technical aspect?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There should be &lt;strong&gt;only one purpose of a code change&lt;/strong&gt;. If you confirm that multiple reasons exist stop and ask the author if the code change can be split. Splitting code change allows you to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focus on one reason&lt;/li&gt;
&lt;li&gt;Avoid distractions&lt;/li&gt;
&lt;li&gt;Review smaller chunks &lt;/li&gt;
&lt;li&gt;Provide cleaner and better project history&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Read all code changes
&lt;/h3&gt;

&lt;p&gt;Go through the code (without skimming) imagining the code is a novel with a story to tell. In doing so, you will surely catch typos and inconsistencies. You can think twice about the names used for variables, methods and more.  Ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are they descriptive?&lt;/li&gt;
&lt;li&gt;Are they concise?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Though naming in software is difficult, agreeing on common rules of thumb will help make it less painful. Check that the style guide rules that your code formatter cannot catch are followed.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Ask (and answer) questions
&lt;/h3&gt;

&lt;p&gt;As a reviewer be sure to ask all the questions that come to mind. Don’t be shy, take the opportunity to learn something new!&lt;/p&gt;

&lt;p&gt;As an author, accept all comments in the most positive and open way. Remember, there are no personal comments. Be open to listening and considering the views of others even if you have strong opinions. Explain your choices thoroughly, exhibiting little bias.&lt;/p&gt;

&lt;p&gt;Code reviews are an incredible opportunity to learn. Asking questions will improve the experience of everyone involved. A written discussion in a GitHub comment thread can also dramatically help when someone needs to go through an old review while tracking down a bug.&lt;/p&gt;

&lt;p&gt;The only golden rule to bear in mind in these conversations is to stay nice and kind! &lt;a href="https://developers.redhat.com/blog/2019/07/08/10-tips-for-reviewing-code-you-dont-like/"&gt;This Red-Hat blog post&lt;/a&gt; is a great summary on conducting these conversations.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Air control
&lt;/h3&gt;

&lt;p&gt;Look at the code change from a big picture, high-level point of view.  Ask yourself is it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Going in the right architectural direction?&lt;/li&gt;
&lt;li&gt;Introducing dependencies that can be avoided?&lt;/li&gt;
&lt;li&gt;Rebuilding the wheel and can be simplified by using external dependencies?&lt;/li&gt;
&lt;li&gt;Submitted to the appropriate codebase?&lt;/li&gt;
&lt;li&gt;Placed in the right place within the codebase?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Challenge your answers and try to think of a simpler way to tackle the problem in the first place. Think about flows in your system and verify that changes respect patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Ground control
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Zoom in to the details of the implementation:&lt;/li&gt;
&lt;li&gt;Is the CI (continuous integration) green and is it passing tests? If not, why?&lt;/li&gt;
&lt;li&gt;Are the tests covering all the edge cases?&lt;/li&gt;
&lt;li&gt;Are the tests covering the error cases and not solely the happy path (main control flow) of the program?&lt;/li&gt;
&lt;li&gt;Is the code readable, explicit and deliberate in what it does?&lt;/li&gt;
&lt;li&gt;Is business logic properly separated from integration?&lt;/li&gt;
&lt;li&gt;Are exceptions handled properly?&lt;/li&gt;
&lt;li&gt;Does the code use appropriate data structures?&lt;/li&gt;
&lt;li&gt;Do the algorithms have an excessive computational complexity?&lt;/li&gt;
&lt;li&gt;Are heavy resources (like DB access and network calls) used carefully?&lt;/li&gt;
&lt;li&gt;Are all the used operators/methods completely clear?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep in mind that code can hardly be &lt;strong&gt;perfect&lt;/strong&gt; from all points of view. In most cases, for example, you might want to encourage readability over performance. It’s much easier to optimize correct code rather than fixing optimized but incorrect code. Avoid premature optimizations, but, be mindful and avoid evident de-optimizations. The code should be easy to substitute and change – engineer it right to the point and no more. Avoid introducing premature extension points as they increase code complexity. Refactor only after proven need, but do it thoroughly when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;While my top items may enhance the code review process for individual developers, teams and enterprises, there are many other actions and resources you may want to consider. &lt;/p&gt;

&lt;p&gt;In addition to some of &lt;a href="https://blog.codacy.com/tag/code-review/"&gt;Codacy’s own resources&lt;/a&gt;, many articles exist on the internet about code reviews. The following particularly caught my attention:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://auth0.com/blog/conducting-effective-code-review"&gt;https://auth0.com/blog/conducting-effective-code-review&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thoughtbot/guides/tree/master/code-review"&gt;https://github.com/thoughtbot/guides/tree/master/code-review&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.michaelagreiler.com/code-review-checklist/"&gt;https://www.michaelagreiler.com/code-review-checklist/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deepsource.io/blog/code-review-best-practices/"&gt;https://deepsource.io/blog/code-review-best-practices/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/palantir/code-review-best-practices-19e02780015f"&gt;https://medium.com/palantir/code-review-best-practices-19e02780015f&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.digitalocean.com/how-to-conduct-effective-code-reviews/"&gt;https://blog.digitalocean.com/how-to-conduct-effective-code-reviews/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>programming</category>
      <category>codequality</category>
      <category>codereview</category>
    </item>
    <item>
      <title>How to code review in a Pull Request</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Wed, 17 Mar 2021 18:09:39 +0000</pubDate>
      <link>https://forem.com/codacy/how-to-code-review-in-a-pull-request-3p4o</link>
      <guid>https://forem.com/codacy/how-to-code-review-in-a-pull-request-3p4o</guid>
      <description>&lt;p&gt;This article discusses how to code review within a pull request in order to improve your code quality. Let's start with pull requests first.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are Pull Requests?
&lt;/h1&gt;

&lt;p&gt;For those unfamiliar, pull requests are used to get peer approval before changes are merged within a version control system, like GitHub, Bitbucket or GitLab. You can find more documentation about it on &lt;a href="https://help.github.com/articles/about-pull-requests/"&gt;GitHub&lt;/a&gt;, &lt;a href="https://www.atlassian.com/git/tutorials/making-a-pull-request"&gt;Bitbucket&lt;/a&gt; and &lt;a href="https://docs.gitlab.com/ee/user/project/merge_requests/"&gt;GitLab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This approval typically comes after the code is reviewed and no further changes are requested. This process is often referred to as code review.&lt;/p&gt;

&lt;p&gt;Bear in mind adding code reviews to your development process is quite time-consuming, meaning management has to be okay with your weekly hour expenditure on code reviewing. &lt;/p&gt;

&lt;p&gt;Today you can add automated code review tools to your workflow so you can get even faster code reviews. Go ahead and type automated code review tools on Google and select your favorite one.&lt;/p&gt;

&lt;h1&gt;
  
  
  Integrating code review into your development workflow
&lt;/h1&gt;

&lt;p&gt;Having code reviews in your development workflow certainly constitutes a process and many dislike it.&lt;/p&gt;

&lt;p&gt;Among the reasons I’ve seen listed by people who dislike the process: 1) they consider Pull Requests a step to validate the technical details they’re sure are correct 2) acquaints other with the code they wrote 3) hurdle getting in the way of what they love doing: coding.&lt;/p&gt;

&lt;p&gt;I’m going to argue otherwise.&lt;/p&gt;

&lt;p&gt;Quoting GitHub documentation: “&lt;a href="https://help.github.com/articles/about-pull-request-reviews/"&gt;Reviews allow for discussion of proposed changes and help ensure that the changes meet the repository’s contributing guidelines and other quality standards.&lt;/a&gt;“. Thus Pull Requests are a medium for discussion. The discussion implies questioning, debate, iteration back and forth for the sake of a better codebase.&lt;/p&gt;

&lt;p&gt;The point is to both improve the code and improve all of the contributors’ understanding of it. You’re trading iterations for more polished code and increased overall knowledge.&lt;/p&gt;

&lt;p&gt;Of course, this way of thinking also annoys any programmers who dislike communicating and/or discussing code. And though every human being differs in the topics they enjoy talking about, or the amount of interaction they are comfortable with, in the realities I came across as a professional developer, programming has always been a team sport.&lt;/p&gt;

&lt;h1&gt;
  
  
  Comments
&lt;/h1&gt;

&lt;p&gt;There are two things to keep in mind when commenting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;There are places where the code must be changed, and there are suggestions which you believe are improvements. On the latter, it’s okay to think otherwise. You should try and be explicit in the case of each comment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your comments should be directed at the code, &lt;strong&gt;never&lt;/strong&gt; the author. This may seem counterintuitive, but I assure you it’s of vital importance. The correct tone is the difference between a healthy discussion or making someone feel diminished.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What to look for
&lt;/h1&gt;

&lt;p&gt;I’ve already talked about the where and the why, but not the how. You know you need to read the code and comment. But what should you be looking for within the code? The basis for a pull request is the difference between two commits. So, what happened between those two commits?&lt;/p&gt;

&lt;h1&gt;
  
  
  The intent of the changes
&lt;/h1&gt;

&lt;p&gt;Stating the obvious: changes are made for a reason. If your project’s work is split into tasks, there was a task at hand. To understand the issue your colleague was tackling, you can read the task given before reading the implemented solution.&lt;/p&gt;

&lt;h1&gt;
  
  
  Common pitfall: do not review a PR with the author
&lt;/h1&gt;

&lt;p&gt;When you don’t understand what a part of the new code does, what do you do? You ask the author. And then he or she explains this part and then the rest. Now you’re reviewing the code with the author. You will inherit the author’s biases. Everything you read is within the lens of the author’s view, making you understand things you will not understand next time you read them unless you remember the explanation. And you might even agree with things you would not to, due to context.&lt;/p&gt;

&lt;p&gt;My general advice is to avoid reviewing code with the author. This is controversial, but I believe the benefits outweigh the disadvantages, and it’s more often than not a mistake.&lt;/p&gt;

&lt;h1&gt;
  
  
  Impact of the changes
&lt;/h1&gt;

&lt;p&gt;Do the changes fit the application flow? Do they change the way something interacts with something else? Can something break?&lt;/p&gt;

&lt;p&gt;When you were learning to program, you created mental models matching what code does. So, as a developer, you kind of can compile and run code in your head. You are able to reason about a flow. You can apply this mighty skill to code reviews. Run the code in your head and wonder if it goes wrong. It could be the changed code or other parts of the application.&lt;/p&gt;

&lt;h1&gt;
  
  
  Spot something fishy? Checkout the branch
&lt;/h1&gt;

&lt;p&gt;Did you find something odd on the implementation and you’re not quite sure if it works? Checkout the branch and investigate a little bit more. Follow the flow within your editor of choice, and you will find either a mismatch in what you thought the code does or in what the code was supposed to do. So either a bug or more in-depth understanding. It’s a win-win. It is vital you understand each and every change you’re approving.&lt;/p&gt;

&lt;h1&gt;
  
  
  Spot bad practices
&lt;/h1&gt;

&lt;p&gt;Code reviews are a great way to educate. If you spot anything you believe to be a bad practice, you can point it out. Something as simple as “One letter variables aren’t good because the name conveys no meaning” points out both the mistake and the reason why it’s a mistake. Pointing out again: PRs are a place for discussion. So prepare yourself for some amicable arguing.&lt;/p&gt;

&lt;h1&gt;
  
  
  Readability matters
&lt;/h1&gt;

&lt;p&gt;Code is read way more often than it is written or modified. So you should, within reasonable limits, optimize for readability, because that is where you and your teammates will spend most of your time.&lt;/p&gt;

&lt;p&gt;If you don’t think a variable name accurately represents what’s in it, suggest a better one.&lt;/p&gt;

&lt;h1&gt;
  
  
  Navigating big PRs
&lt;/h1&gt;

&lt;p&gt;Most PRs should not be big. Big changes happen sometimes, but they are not the most common. So if someone is consistently making PRs with lots of changes, chances are they’re not separating the multiple concerns they’re tackling into separate PRs.&lt;/p&gt;

&lt;p&gt;Here are a couple rules of thumb you can use and advise others to do so.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Keep refactors in separate PRs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tackle one issue per PR&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, when you have a massive PR to review, here are some things you can do to help you navigate the logic and understand faster:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Look into the individual commits&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Look at the new tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reading first the files you know have relevant changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Reviewing Tests
&lt;/h1&gt;

&lt;p&gt;Tests are also code that needs to be maintained, code in need of reviewing. A lot of people dismiss tests when they’re reviewing code, but this can reduce the quality of your tests.&lt;/p&gt;

&lt;h1&gt;
  
  
  Think of the corner cases
&lt;/h1&gt;

&lt;p&gt;Corner cases need to be tested. So think of the corner cases you would check. See if they’re covered within the test cases written.&lt;/p&gt;

&lt;h1&gt;
  
  
  Do the tests look like they would fail?
&lt;/h1&gt;

&lt;p&gt;When you’re writing a test, it’s important to see it fail. So in a review, it’s important to look out for the same kind of mistake. Do the tests look like they would fail if the tested code is malfunctioning?&lt;/p&gt;

&lt;h1&gt;
  
  
  Reject any test that was made based on an output
&lt;/h1&gt;

&lt;p&gt;Sometimes people get real data to test their code, and they don’t trim the data down to the most relevant parts. So what happens is, they use that data and assume that non-empty values are correct. You can spot these in high numbers or big lists.&lt;/p&gt;

&lt;h1&gt;
  
  
  It gets easier over time
&lt;/h1&gt;

&lt;p&gt;Reviews are especially hard when you’re not used to them or not familiar with the affected codebase. But don’t get discouraged. Like pretty much anything else in software development, it’s a learnable skill.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Review of Java Static Analysis Tools
</title>
      <dc:creator>Gustavo Silva</dc:creator>
      <pubDate>Tue, 09 Mar 2021 16:04:42 +0000</pubDate>
      <link>https://forem.com/codacy/review-of-java-static-analysis-tools-3jp7</link>
      <guid>https://forem.com/codacy/review-of-java-static-analysis-tools-3jp7</guid>
      <description>&lt;p&gt;If you code in Java and code reviews are part of your workflow we recommend you to go through the list below. Here are some of the Java Static Analysis tools you should know about:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. PMD Java
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pmd.github.io/"&gt;PMD&lt;/a&gt; scans Java source code and looks for &lt;a href="https://pmd.github.io/pmd-5.4.1/pmd-java/rules/index.html"&gt;potential problems&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Problems range from breaking naming conventions and unused code or variables to performance and complexity of code, not forgetting lots of possible bugs.&lt;/p&gt;

&lt;p&gt;The PMD project also supports JavaScript, PLSQL, Apache Velocity, XML and XSL. It also ships with a CPD, a tool to detect duplicated code in several languages.&lt;/p&gt;

&lt;p&gt;PMD integrates with several tools and editors, including Eclipse, NetBeans, IntelliJ IDEA, TextPad, Maven, Ant and Emacs.&lt;/p&gt;

&lt;p&gt;Here’s a sample of what running PMD through some code looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;pmd&lt;/span&gt; &lt;span class="n"&gt;pmd&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="no"&gt;R&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;basic&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;unusedcode&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pmd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Avoid&lt;/span&gt; &lt;span class="n"&gt;unused&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="n"&gt;such&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;classVar2&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pmd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Avoid&lt;/span&gt; &lt;span class="n"&gt;unused&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="n"&gt;such&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;instanceVar3&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can suppress warnings (in a variety of ways) and you can also write your own rules in either Java or XPath..&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Checkstyle
&lt;/h2&gt;

&lt;p&gt;As the name implies, &lt;a href="http://checkstyle.sourceforge.net/"&gt;Checkstyle&lt;/a&gt; checks that your code adheres to a coding standard.&lt;/p&gt;

&lt;p&gt;The tool is configurable, which makes it able to support different code style conventions. Two examples are the &lt;a href="http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html"&gt;Sun Code Conventions&lt;/a&gt; and &lt;a href="http://checkstyle.sourceforge.net/reports/google-java-style.html"&gt;Google Java Style&lt;/a&gt; (although the one from Sun hasn’t been maintained since 1999).&lt;/p&gt;

&lt;p&gt;You can find a &lt;a href="https://github.com/checkstyle/checkstyle/blob/3e4367941c3e9680703e8ea8400abbd5dc78e1d9/src/main/resources/google_checks.xml"&gt;configuration file&lt;/a&gt; for Google’s Java Style on the checkstyle repository.&lt;/p&gt;

&lt;p&gt;Speaking of configuration, this is done in an XML file where you set which modules are to be used. Here’s a (tiny) example of a configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;checkstyle&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;checkstyle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;xml&lt;/span&gt; &lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="nc"&gt;Starting&lt;/span&gt; &lt;span class="n"&gt;audit&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;checkstyle&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Blah&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;does&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;checkstyle&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Line&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;trailing&lt;/span&gt; &lt;span class="n"&gt;spaces&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;checkstyle&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Line&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;trailing&lt;/span&gt; &lt;span class="n"&gt;spaces&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="nc"&gt;Audit&lt;/span&gt; &lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="nc"&gt;Checkstyle&lt;/span&gt; &lt;span class="n"&gt;ends&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. FindBugs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://findbugs.sourceforge.net/"&gt;FindBugs&lt;/a&gt; looks for bugs in Java Code, and this means over &lt;a href="http://findbugs.sourceforge.net/bugDescriptions.html"&gt;400 different bugs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Patterns are separated into several categories: bad practice, correctness, malicious code vulnerability, multithreaded correctness, performance, security and dodgy code (two additional categories exist, with just a couple of patterns each: experimental and internationalization).&lt;/p&gt;

&lt;p&gt;There are several ways of running FindBugs, but here’s what the &lt;a href="http://findbugs.sourceforge.net/manual/running.html"&gt;command line interface&lt;/a&gt; can feel like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;findbugs&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;textui&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="no"&gt;M&lt;/span&gt; &lt;span class="no"&gt;P&lt;/span&gt; &lt;span class="nl"&gt;UuF:&lt;/span&gt; &lt;span class="nc"&gt;Unused&lt;/span&gt; &lt;span class="nl"&gt;field:&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;classVar2&lt;/span&gt;  &lt;span class="nc"&gt;In&lt;/span&gt; &lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="no"&gt;M&lt;/span&gt; &lt;span class="no"&gt;P&lt;/span&gt; &lt;span class="nl"&gt;UuF:&lt;/span&gt; &lt;span class="nc"&gt;Unused&lt;/span&gt; &lt;span class="nl"&gt;field:&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instanceVar3&lt;/span&gt;  &lt;span class="nc"&gt;In&lt;/span&gt; &lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="no"&gt;M&lt;/span&gt; &lt;span class="no"&gt;D&lt;/span&gt; &lt;span class="nl"&gt;UuF:&lt;/span&gt; &lt;span class="nc"&gt;Unused&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nl"&gt;field:&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instanceVar2&lt;/span&gt;  &lt;span class="nc"&gt;In&lt;/span&gt; &lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="no"&gt;M&lt;/span&gt; &lt;span class="no"&gt;D&lt;/span&gt; &lt;span class="nl"&gt;UuF:&lt;/span&gt; &lt;span class="nc"&gt;Unused&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nl"&gt;field:&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;classVar1&lt;/span&gt;  &lt;span class="nc"&gt;In&lt;/span&gt; &lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="no"&gt;M&lt;/span&gt; &lt;span class="no"&gt;D&lt;/span&gt; &lt;span class="nl"&gt;UuF:&lt;/span&gt; &lt;span class="nc"&gt;Unused&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nl"&gt;field:&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instanceVar1&lt;/span&gt;  &lt;span class="nc"&gt;In&lt;/span&gt; &lt;span class="nc"&gt;Deck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="nc"&gt;Warnings&lt;/span&gt; &lt;span class="nl"&gt;generated:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first letter in the output refers to the severity of the (potential) bug (low, medium, high) and the second is the category (in this case P for Performance and D for Dodgy Code).&lt;/p&gt;

&lt;p&gt;It integrates with Eclipse, Maven, Netbeans, Jenkins, Hudson and IntelliJ.&lt;/p&gt;

&lt;p&gt;FindBugs supports a plugin architecture that allows anyone to add new bug detectors; which brings us to…&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Find Security Bugs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://find-sec-bugs.github.io/"&gt;Find Security Bugs&lt;/a&gt; is a plugin for FindBugs which adds checks for &lt;a href="http://find-sec-bugs.github.io/bugs.htm"&gt;80 additional different vulnerability types&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You’ll find a range of patterns that relate to &lt;a href="https://www.owasp.org/index.php/OWASP_Top_10"&gt;OWASP 10&lt;/a&gt; vulnerabilities, from different types of injection and XSS protection to sensitive data exposure and unvalidated redirects.&lt;/p&gt;

&lt;p&gt;There are also several patterns that are specific for Android.&lt;/p&gt;

&lt;p&gt;There’s also other common things such as hashing methods and DOS vulnerabilities, not forgetting simpler things such as hard coded passwords.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As with similar tools in different languages, these Java Static Analysis tools complement each other, and we do recommend that you check them out if you care about Code Quality and avoiding technical debt.&lt;/p&gt;

&lt;p&gt;Both PMD and CheckStyle are already integrated with automated code reviews such as Codacy, which means you can start using them right now.&lt;/p&gt;

&lt;p&gt;Using an automated code review tool means you’ll get all of these analyses done for you automatically every time you do a commit, plus a list of issues that are expansible to reveal additional detail on the particular problem and how to solve it.&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>performance</category>
      <category>java</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
