Exakat 1.7.4 Review

This week, Exakat 1.7.4 opened the bug hunt season. Many analysis bugs were tracked and removed from the code, leading to the cleanest version of Exakat yet. Identical files in a code repository are now omitted, but one, automatically. And it is possible to configure the target reports from the command line, at execution time. Finally, we discuss the current coverage for OOP definitions in the engine. The true secret of a happy code lies in taking a genuine interest in the Exakat 1.7.4 review! 

Omission of Identical Files

As promised last week, Exakat ignores any duplicate file, but the first. During the loading phase, Exakat takes a hash of every processed file. More often than it should, duplicate files make their way into a repository.

Duplicate files are now ignored, but for the first. The comparison is made with the file as a whole: so, classes in different namespaces, or function with slight differences are still processed simultaneously. 

The impact on the tree may be significant. For example, multiple identical class loaded in the AST means that each new A leads to several possible definition. Any analysis that must check the definition of a class, now has to check several times the same code, for the same output. 

Configuration from the command line

Until version 1.7.4, there were two ways to obtain a specific report from Exakat: configure the project or request it from the command line. 

Configuring the project ensures that Exakat will run the prerequisite analysis for that specific report. Running the report from the command line works any time after the audit itself, as long as the rule sets are available. It is also the way to get results which don’t depend on specific analysis: for example, the Text report may list any analysis at all. 

Since Exakat 1.7.4, it is possible to specify a report from the command line, at execution time. Let’s review the different possible configurations.

Configure a project report

Configuring the project in the config.ini file makes Exakat produce the report each execution. It won’t be forgotten next time. 

Open the projects/<name>/config.ini file. If this was never edited, you’ll find a list of project_* configuration. There, you may add one or multiple project_reports[], like this: 

;Description of the project
project_name        = "myself";
project_url         = "./";
project_vcs         = "git";
project_description = "";
project_branch      = "";
project_tag         = "master";

; My reports 
project_reports[]   = "Diplomat";
project_reports[]   = "Phpcity";
project_reports[]   = "Drillinspector";

Save, and run exakat. 

> php exakat.phar project -p <name>

You’ll find the new report in the projects/<name>/ projects. 

Building a report afterwards

The command report builds a report from an already-run audit. The command gives access to results that are stored in the final audit, even after the Exakat engine has started working on another audit. 

First, run the project, then build a report. 

> php exakat.phar project -p <name>
> php exakat.phar report -p <name> -format Phpcity 

The report command also allows for naming the destination file: 

> php exakat.phar report -p <name> -format Phpcity -file phpcity.json

Some reports require a fixed set of rule sets’ results. When those results are not available, the report will be incomplete and probably inconsistent. Exakat emits an error when trying to build a report without sufficient results. 

For example, the ‘Ambassador’ report has the most complete set of results, and it depends on a large number of rule sets. By default, the ‘Diplomat’ report is built, based on a smaller set of analysis. Thus, requesting the ‘Ambassador’ report after running project with ‘Diplomat’ leads to an error. On the other hand, if ‘Ambassador’ was configured (see previous and following sections), then ‘Diplomat’ may be reported as all its rule sets are already run. 

From the command line

Adding reports in the command line is convenient for a one-time run, or a quick check. It relies on the -format option, which may be repeated, like this: 

> php exakat.phar project -p <name> -format Diplomat -format Phpcity -format Drillinspector

They are immediately produced and available at the end of the run. 

All the reports

All the default Exakat reports is described in the manual. Mistyped reports are ignored.

Detecting Typehint automatically

While building the network of tokens, the Exakat engine also infers definitions for objects. This means that a methodcall like the following is automatically linked to its definition.

<?php

class foo {
  function bar() { <-----
                        |
  }                     |
}                       | DEFINITION
                        |
$x = new foo();         |
$x->bar();  -------------

? >

The example here above shows it all: $x is a variable, that contains a Foo object. When used in a method call, the bar method from the Foo class is called.

This link is very important. It is the base for simple analysis like Undefined class constants, or wrong number of arguments, or for complex analysis like Dependant traits or class dependencies.

Exakat works hard behind the scenes to link objects with classes. This is based on variable tracking: it starts with instantiations, which are the creation of objects, and requires following the variables during their processing to link the usage and the definition. 

Currently, with PHP 7.3.4, Exakat is able to cover the following amount of code with their definition. 

Static constants    : 89.54 %
Static properties   : 97.05 %
Static method calls : 77.82 %
Properties          : 76.71 %
Methodcalls         : 35.48 %

Static calls are usually easier to link, unless they are dynamic static calls sic (when the class is a variable). This leads to a good level of coverage. 

Normal calls to properties and methods are less covered. In particular, objects are passed around, and used in various scopes. Noticeably, when passed around blindly, objects are more often used for methodcalls than property access. Scopes that call one or two methods on an unspecified argument are very common, leading to missing definitions. 

Where are the definitions?

In this process, following the creation and objects and their usage is very efficient and doesn’t require anything more than the code itself. This is exactly what we do as a developer: follow the track of variables. 

Using modern PHP helps. Typehinting helps tremendously: may it be in arguments, in return types or at properties level. Typehint simplifies the search for the origin, and leads to more efficient linking. The last realm not covered by typehint are local variables. Those are used without specifications, and they may hold any kind of data at any point. 

The ultimate goal of this coverage can’t be 100%: there are a lot of missing definitions in PHP code. Either the class is defined in a C extension (PDO, stdClass,…) and will never have an explicit definition in the code; either the class is defined in a component (or library, or framework), and the definition may be omitted from the audit by the configuration; either the dynamic calls, which are black holes in any static audit.

We still have more work planned to improve the coverage of methods and properties. Typehints or not, we can track a useful amount of method calls. 

The Weekly Audits: 2019, Week #14

Exakat includes a ‘weekly’ report: this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you: you’ll find programmers facing the same challenges.

To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.

# Init the project (skip when it is already done)    
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git 

# Run the project (skip when it is already done)    
php exakat.phar project -p <yourproject> 

# Export the weekly project (every monday)    
php exakat.phar report -p <yourproject> -format Weekly 

# Open projects/<yourproject>/weekly/index.html in your browser    

Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming 

Weekly recommendations for PHP code review: 2019, week 2019-15

Happy PHP Code Reviews 

All the 356 analyzers are presented in the docs, including the honest: Empty Function: Function or method whose body is empty.

It is a frequent issue: 71% of PHP project have empty methods

You can check all of the Exakat reports at the gallery: exakat gallery.

Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.