Automate PSR Compliance through Jenkins

one of the reasons our society can function is our ability to communicate in a standard? well formed and universally %albeit with local + cultural variations% understandable way) this requires that not only symbols but also their usage be agreed? whether implicitly or explicitly? by both the transmitter + the receiver of information))if such uniformity were ~present? , one could write as it pleased him x her and if documents were interpreted in different ways by different individuals? we would live in a chaotic state of communication + our collective intellectual achievements ~~impossible=

The paragraph is hard to understand because some punctuation has been changed and formatting conventions altered: use of the plus sign to represent the conjunction ‘and’, question mark instead of a comma, and double closing parenthesis where you would expect a period. Had our accepted writing rules been used, the paragraph would instead look like this:

One of the reasons our society can function is our ability to communicate in a standard, well formed and universally – albeit with local and cultural variations – understandable way. This requires that not only symbols but also their usage be agreed, whether implicitly or explicitly, by both the transmitter and the receiver of information.

If such uniformity were not present, if one could write as it pleased him or her and if documents were interpreted in different ways by different individuals, we would live in a chaotic state of communication and our collective intellectual achievements would be impossible.

The need for standards in technical communication, including symbols in drawings, has been long realized and the International Organization for Standardization (ISO) and its brethren in all industrialized nations exist to respond to such need. In the arts, things are not so exacting, yet there are some rules called ‘styles’. Architects and poets are often bound to a bunch of them. Writers of prose and painters have much more freedom but still obey to some rules.

One particular type of artistic writer, like you and me, is the code writer, the software developer. In our trade things are not always clear. Like medicine, computer programming is part science, part technique, and part art. We have to abide to some rules so that the dumb machines we write for can understand our desires. But otherwise, we’re quite free to write what we want the way we want.

Or, are we?

It’s all very well and good to follow one’s own private programming rules (using camelCase variable names for example) when individually writing isolated applications like a small budget website. However, collaborative work requires an agreement of common rules or you know what happens – and if by any chance you don’t, I suggest you take a look at the tale I told in my article Continuous Integration (with Jenkins).

Nevertheless, if CI can cure the maladies typical of group development, it is powerless to deal with potential problems in the integration of different applications where wildly different styles may make understanding “source” code difficult (except, maybe, to the original developer) or even lead to name collisions. To address that need, a group of developers have proposed a standard for use with PHP, known as PSR-X, as described in Hari K T’s article PSR-1 and PSR-2 to be Approved as Standards.

Though it’s still early to guarantee that the PSRs will be widely adopted as the de facto standard for writing serious PHP applications, it is interesting to note that a code sniffer and fixer that looks for code deviations was developed by nobody less than Fabien Potencier, the creator of the Symfony framework. (Et bien, ils ne sont pas fous, ces français!) In the rest of the article we shall find out what his PHP-CS-Fixer does and how can it be integrated with a CI tool like Jenkins.

Fixer Installation and Basic Usage

According to its author, the PHP Coding Standards Fixer for PSR-1 and PSR-2 tool “fixes most issues in your code when you want to follow the PHP coding standards as defined in the PSR-1 and PSR-2 documents.” It does not solve all problems; and it does not claim to find every deviation from the standards, but, again quoting Fabien, it “comes with quite a few built-in fixers and finders, but everyone is more than welcome to contribute more of them.”

Fixer installation is straightforward, or rather, none at all. All you have to do is to download the latest version of php-cs-fixer.phar from this Sensiolabs website (the company behind Symfony). Because the fixer is conveniently packed as a PHAR archive, all you have to do is to place it in a convenient folder, like the root of your development server, and run it from the command line:

jajeronymo@desktop:~/www$ php php-cs-fixer.phar fix /path/to/dir

This will look for and fix PSR issues in all files in the directory (folder) at the end of /path/to/dir. If you want to check/fix just one file, instead use the path to the file:

jajeronymo@desktop:~/www$ php php-cs-fixer.phar fix /path/to/file

In order to test the fixer, I wrote a “Hello World” script with three intentional violations of PSR: an opening tag without the ‘php’ designator. a tab used for indentation instead of four blank spaces, and a closing tag in a PHP-only script:

<?
	echo "Hello World";
?>

The file was saved in the same folder as fixer-test.php. Then I ran:

jajeronymo@desktop:~/www$ php php-cs-fixer.phar fix fixer-test.php

The only response I received on the terminal was:

1) /home/prospero/www/fixer-test.php 

However, I checked fixer-test.php’s properties to find out that it had been modified at the time I ran the fixer. Opening the script, I noticed the fixer had added the ‘php’ designator after the opening tag, replaced the indentation tag with two blank spaces (uh oh, I expected four!), and did not remove the closing tag but rather added a linefeed after it – which complies with the standard’s requirement that a file must always end with an empty line feed. Out of curiosity I ran the fixer a second time and found out that the closing tag had been removed.

At this point we have successfully gotten PHP-CS-Fixer to work, though only in basic mode. The script has a fair number of options that can be explored by the user. See the usage section of the app’s web page for more details.

Jenkins, Will You Keep an Eye on This for Me, Please?

As explained in my articles mentioned in the opening part of this one, Jenkins is a tool for automating a series of tasks, including testing, that are required for continuous integration. If you don’t have Jenkins, please refer to the Setting Up Jenkins section of Continuous Integration (with Jenkins), Part 2. Install and start Jenkins and come back here.

Run Jenkins’ war file and point your browser to http://localhost:8080. Click in “create new jobs” and then select “Build a free-style software project”. Give the job a name. (Since the time I was learning programming on a Burroughs mainframe in I call my test jobs “Trotter”. I wonder if any of my readers can guess why.)

Check “Build periodically” and write “*/5 * * * *” in the schedule box to run a test every five minutes. Now there are two ways we can follow. To run just PHP-CS-Fixer, we need to execute a shell command (or, in Windows, a batch file) and Jenkins will act as a surrogate to the cron job control. To integrate with a more elaborate set of tests and tasks, one can add an Ant script to it.

To follow the first option, select “Execute shell” in the “Add build step” drop-down button in the Build section. On the text box put the command to execute the fixer using the absolute path to files or folders. For my test script that is:

php /home/jajeronymo/www/php-cs-fixer.phar fix /home/jajeronymo/www/fixer-test.php

Save the configuration. Until stopped or shut-down, Jenkins will run the fixer on file fixer-test.php every five minutes. To see the fixer in action, create some deviations in the test file, like suppressing the ‘php’ from the opening tag, and wait until Jenkins runs the fixer. Then open the test file to check the corrections made.

If no changes occur or if the builds list in Jenkins dashboard shows red balls, an error is occurring. Please click on the time of the job to open its record and then on the link “Console output” to see what’s, or what’s not, going on.

Finally, to run the fixer from an Ant script, add this to its existing contents:

<project name="user">
...
 <exec executable="php" failonerror="true">
  <arg line="/home/prospero/www/php-cs-fixer.phar fix /home/prospero/www/fixer-test.php" />
 </exec>
...
</project>

Summary

The adoption of coding standards is essential to reduce development costs of complex web applications as well as to guarantee that investment will be permanent and not dependent on the original programming team. The PSR proposition can be a way toward that and its ease of use with CI platforms like Jenkins is made possible by tools like PHP-CS-Fixer.

Image via Fotolia

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Juraj

    What was the point of you running it in Jenkins though? Are you then packaging the source code? Do you check the “fixed” code back into a CVS?