Contributing the open source is a topic raised time and again on blogs, during conferences, meetups and barcamps.

This happens because of several reasons – many programmers want to be involved in extraordinary projects, create

useful solutions or leave their marks on a masterpiece of software.



I have always wanted to be a part of open source community, be proud of my work and share it with the world. My

dream

goal is to create a useful application or contribute to existing project which supports developers in their

everyday struggle with code.

In the article below, I’ll share one of my latest open source experience.

Ant

I decided to start with something uncomplicated – a simple solution that could help me solve a prosaic, but

annoying issue. For instance, XML format. No, I won’t fight with it. I see it as great and practical, however

mostly I don’t need so sophisticated code to cover my needs – the yaml usually fits the purpose.

Let’s imagine a complex xml file, responsible for installing an application. Sounds familiar? That’s right – this

is the Apache Ant. Ant in theory, it’s kind of like make, just without all make‘s bells and

whistles.

Normally, the xml file for Ant dedicated to keep thresholds in code looks like this:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15 <?xml version = class="st0">“1.0” encoding = class="st0">“UTF-8″ ?>

<project name = class="st0">“phpmd.example” default = “example” class="re0">basedir= “.” class="re2">> class="st0">“UTF-8″class="re0">basedir=class="re2">> <taskdef class="re0">name=“phpmd” class="re0">classname=“org.phpmd.ant.PHPMDTask” class="re2">/> <target class="re0">name=“example”>

<phpmd class="re0">rulesetfiles=“unusedcode” failonerror= class="st0">“off”>

class="re1"><formatter type= class="st0">“xml” toFile=“${basedir}/pmd.xml” class="re2">/>

<fileset class="re0">dir=“${basedir}/PHPMD” class="re2">>

<include class="re0">name=“*.php” />

</fileset class="re2">>

</phpmd class="re2">>

</target class="re2">> </project>

This is much too long, too complex, isn’t it?

Composer

Yet, do I really need this flexibility when I use vagrant or docker to maintain the same environment as on the

production? For 90% of PHP projects probably I won’t use all of the features of the virtualization tools. I only

want to install necessary libraries, check the code quality before committing or introduce fixtures. Most of

those points are easily feasible in composer.

Making the composer responsible for installing and checking the environment, vendors, plugins and modules is what

the tool was created for. Moreover, you can define your own script and run it by the composer to load fixtures

into the database:

1

2

3

4

5

6 “scripts” :

{

“db-seed” : class="br0">[

“composer db-clean” class="sy0">,

“app/console doctrine:fixtures:load”

]

}

At this point you only need to execute the following command to fill the database with your sample data.

1 composer db-seed

Code Quality Thresholds

However, I came across a little bit more complex example, which made me stick to the Ant for a while – measuring

and detecting the code violations by code fixer, mess detector, copy paste detector, duplicated code detector.

All of them require a very long command to run and check how many code abuses have been made.

The composer’s example for the mess detector might look like this:

1

2

3

4

5 “scripts” :

{

“check” : class="br0">[

“php vendor/phpmd/phpmd/src/bin/phpmd src/ text cleancode,codesize,unusedcode | wc -l”

]

}

The problem is, the system won’t throw an error, but just show the number of violations and we would like to stop

the build always when one of indicator will exceed the threshold.

CodeQualityThreshold

How to achieve that? Please meet CodeQualityThreshold – I have created a module that will break the build when

too many errors occur. By adding a command into the composer all tools can be checked and run automatically

during every single build – phpmd, phpcs, phpdcd and phpcpd. Just like in the Ant.

1

2

3

4

5 “scripts” :

{

“quality-test” : class="br0">[

“piotrpasich \\ CodeQualityThreshold class="es0">\\ Composer \\ ScriptHandler::checkThresholds”

]

}

Then, you are able to execute the command composer quality-test or also add this line to already existing

scripts like post-update-cmd. All passed tests are green and when one of threshold will be exceeded the

exception will appear:

width="943" height="138" class="alignnone size-full wp-image-2780">

How does it work?

The heart of the module is a yaml config file where you can put all information about what and how you would like

to scan in the project. You can select folders or single files, specify tools for them, declare rules and

thresholds.

By default the module checks the app folder with 0 thresholds in all available tools. This behavior is

changeable. This requires an extra field added to composer.json file:

1

2

3

4

5 “extra” : class="br0">{

“cqt-parameters” : class="br0">{

“file” : class="st0">“app/Config/cqt.yml”

}

}

Then, you can create a new app/Config/cqt.yml file and define totally new rules for your project. The pattern

for configuration is simple.

Example

1

2

3

4

5

6

7

8

9

10

11

12

13 : #name -

should be unique

class :

piotrpasich\CodeQualityThreshold\Tool\Phpmd #The class dedicated class="kw1">for tool

options :

threshold : 42

#Your custom threshold

directory : src #Folder to be scan

rules : Config / Phpmd class="sy0">/ruleset. xml #Custom ruleset phpmd#nameshould be uniquepiotrpasich\CodeQualityThreshold\Tool\Phpmd #Thededicatedclass="kw1">for tooloptionsthreshold#Your custom thresholddirectorysrc #Folder to be scanrulesConfigPhpmdclass="sy0">/ruleset.#Custom ruleset #example for second folder

phpmd_app_resources:

class:

piotrpasich\CodeQualityThreshold\Tool\Phpmd

options:

threshold: 0

directory: app/Resources

As you have noticed, not every field is mandatory – all options have default values specified in each tools

classes. Required are the name and class.

Custom tools classes

Certainly, there are a few available tools predefined in the plugin. You can add more of them. To do this you

need to create a class extending `piotrpasich\CodeQualityThreshold\Tool\Tool` which has a couple abstract

methods which must be overwritten.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36 /**

* Returns a string with bash command to execute

*

* @return string

*/

abstract public function

composeCommand ( ) ; abstractcomposeCommand /**

* Creates a command to return full report

* Most time it will be the composeCommand without threshold checker

*

* @return string

*/

abstract public function

composeReportCommand() class="sy0">; /**

* Returns an integer with the threshold

* Should be taken from cofniguration

*

* @return Integer

*/

abstract public function

getThreshold(); /**

* Returns error message if exception occurs

*

* @return string

*/

abstract public function

getErrorMessage() class="sy0">; /**

* Returns a message when succeed

*

* @return string

*/

abstract public function

getSuccessMessage();

After that, there should be added a new record to custom config file.

It works!

I must admit, after introducing this feature all my installation’s needs are covered and I can drop the Ant and

fully move to building and checking the projects from composer. This module was developed, tested and used in

one of the projects conducted by onclick="javascript:_gaq.push(['_trackEvent','outbound-article','http://x-team.com']);"

target="_blank">X-Team, but after I showed CQT to a couple of old

friends, they decided (to my great pleasure) to use it as well. I hope my adventure with the open source will

encourage you to try it by yourselves – it’s a great fun, but at the same time you can be proud of it.

The CodeQualityThreshold module is available on github href="https://github.com/piotrpasich/CodeQualityThreshold"

onclick="javascript:_gaq.push(['_trackEvent','outbound-article','http://github.com']);"

target="_blank">https://github.com/piotrpasich/CodeQualityThreshold .