Looking back at the 45th meeting of PHP UG Rheinhessen

Looking back at the 45th meeting of PHP UG Rheinhessen

Yesterday, the first meeting of 2017 took place at netz98 in Mainz. We had actually planned "Build automation" as the topic. Unfortunately, the topic had to be postponed. That did not matter, though, because we always find good "ad hoc topics". This evening was no exception. Jan Unger started with a project presentation.

Symfony project "Solar Panels"

The project Jan presented, "Solvation", is a Symfony application. The purpose of the application is to provide a rough cost estimate for equipping your house with solar panels. The special thing about the system is that customers can find their own house through a Google Maps integration. They can then roughly measure the house at the closest zoom level. The application then "tiles" the solar panels directly onto the roof in Google Maps. The angle of inclination still needs to be set, and a rough calculation can be generated. The application is separated into services and can also be used as a white-label solution. Part of the application involves generating PDF files. Jan showed us his approach to testing the generated files, which led directly into the next discussion about unit tests.

PHPUnit - calling static assert methods

Should PHPUnit asserts be called statically? The topic has already been discussed elsewhere too. There is also a corresponding GitHub issue for PHPUnit. The basic point is that you should use $this instead of self:: out of habit. On the other hand, code checkers in IDEs such as PHPStorm then flag this. We also discussed the possibility of more extensive checks with the PHPStorm plugin "Ea Extended".

Side topics

Side topics included the Chrome plugin Octotree, which makes it possible to get a nice tree view as a sidebar in GitHub. The PHPStorm plugin "Power Mode 2" also caused some laughter. Just take a look…. It is not my thing.

RoboTask

One topic was RoboTask, which makes it easy to create tasks for a PHP project. Compared with other task tools, it is very quick to get a result here.

Example Robo file:

<?php

/**
 * This is project's console commands configuration for Robo task runner.
 *
 * @see http://robo.li/
 */
class RoboFile extends \Robo\Tasks
{
    public function composerInstall()
    {
        $this->taskComposerInstall()
            ->preferDist()
            ->run();
    }

    /**
     * @param array $opts
     */
    public function runPhpcsfixer($opts = ['diff' => false, 'dry-run' => false])
    {
        $task = $this->taskExec('vendor/bin/php-cs-fixer')
            ->arg('fix')
            ->option('config-file', __DIR__ . '/.php_cs')
            ->option('-v');

        if ($opts['diff']) {
            $task->option('diff');
        }

        if ($opts['dry-run']) {
            $task->option('dry-run');
        }

        $task->run();
    }

    /**
     * @param array $opts
     */
    public function runTests($opts = ['debug' => false, 'coverage|c' => false, 'testdox' => false])
    {
        $pathToPhpUnit = 'vendor/bin/phpunit';

        $task = $this->taskPHPUnit($pathToPhpUnit)
            ->configFile('tests/unit');

        if ($opts['testdox']) {
            $task->option('testdox');
        }

        if ($opts['debug']) {
            $task->debug();
        }

        if ($opts['coverage']) {
            $task->configFile('tests/unit')
                ->xml('build/output/phpunit/junit.xml')
                ->option('coverage-clover', 'build/output/phpunit/clover.xml')
                ->option('coverage-html', 'build/output/phpunit/html');
        }

        $task->run();
    }

    public function composerValidate()
    {
        $this->taskComposerValidate()
            ->strict()
            ->run();
    }

    public function runCi()
    {
        $this->stopOnFail();

        $this->composerValidate();
        $this->composerInstall();
        $this->runPhpcsfixer(['diff' => true, 'dry-run' => true]);
        $this->runTests(['coverage' => true, 'debug' => true, 'testdox' => true]);
    }
}

All public methods are translated directly into executable commands. Behind the scenes, several Symfony components such as "Console", "Filesystem", or "Process" do the work, keeping the tool's actual codebase lean. Using it as a framework, or generating your own CLI application as a Phar file, is also interesting. I had not come across this approach to CLI applications before.

Pre-commits

After tasks, it made sense to discuss GIT pre-commit hooks as well. More specifically, this is about a pre-commit framework that provides a simple and reusable solution. It makes it possible to move part of quality assurance to the client, or to reduce the number of unimportant builds in the CI system. I recently wrote an article about this on the new dev98.de blog, titled "A framework to prevent invalid stuff in your git repository".

For PHP developers, the hook repository from Hootsuite is interesting. It extends the framework with PHP hooks.

Pre-Build PHP Hooks (Hootsuite)

As an alternative, we briefly looked at GrumPHP.

Conclusion

Even without fixed topics, yesterday was once again a lot of fun, exchanging ideas about current projects and tools. I am already looking forward to the next meeting.

**UPDATE**:

Apparently, it was actually already the 46th meeting. That is what happens when you do not write a blog post about every meeting. I am trying to keep track. Thanks, Matthias.