Display Git informations in the Symfony WebProfiler

Today we’ll manipulate the Symfony webprofiler, and add some information from Git. Be aware that this feature sould be avaible only in dev environment.

Here is the source code but follow me it’s an easy task !


1- Create a Symfony Project

composer create-project symfony/website-skeleton project

2- Inside the project, create a simple Controller

<?php

namespace
App\Controller;


use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller
{
/**
*
@Route("/")
*/
public function profiler()
{
return $this->render('base.html.twig');
}
}

3- Create a Service for retrieve the information from Git

In src, create a directory BranchLoader. Inside this folder, create a class GitLoader that will contains the logic to retrieve the Git informations

The idea comes from stackoverflow, feel free to improve the code but keep in mind that it’s not our first goal here ;-)

<?php
//src/BranchLoader/GitLoader.php

namespace App\BranchLoader;


class GitLoader
{
private $projectDir;

public function __construct($projectDir)
{
$this->projectDir = $projectDir;
}

public function getBranchName()
{
$gitHeadFile = $this->projectDir.'/.git/HEAD';
$branchname = 'no branch name';

$stringFromFile = file_exists($gitHeadFile) ? file($gitHeadFile, FILE_USE_INCLUDE_PATH) : "";

if(isset($stringFromFile) && is_array($stringFromFile)) {
//get the string from the array
$firstLine = $stringFromFile[0];
//seperate out by the "/" in the string
$explodedString = explode("/", $firstLine, 3);

$branchname = trim($explodedString[2]);
}

return $branchname;
}

public function getLastCommitMessage()
{
$gitCommitMessageFile = $this->projectDir.'/.git/COMMIT_EDITMSG';
$commitMessage = file_exists($gitCommitMessageFile) ? file($gitCommitMessageFile, FILE_USE_INCLUDE_PATH) : "";

return \is_array($commitMessage) ? trim($commitMessage[0]) : "";
}

public function getLastCommitDetail()
{
$logs = [];
$gitLogFile = $this->projectDir.'/.git/logs/HEAD';
$gitLogs = file_exists($gitLogFile) ? file($gitLogFile, FILE_USE_INCLUDE_PATH) : "";

$logExploded = explode(' ', end($gitLogs));
$logs['author'] = $logExploded[2] ?? 'not defined';
$logs['date'] = isset($logExploded[4]) ? date('Y/m/d H:i', $logExploded[4]) : "not defined";

return $logs;
}
}

4- Declare this class in services.yaml to get the kernel.project_dir parameter

# config/services.yaml
App\BranchLoader\GitLoader:
arguments:
['%kernel.project_dir%']

5- Create our custom data collector : GitDataCollector the name is arbitrary

Now we have access to the Git informations, we just have to add them to the DataCollector.

Our custom class will extends DataCollectorsee documentation for more details.

<?php

//src/DataCollector/GitDataCollector.php
namespace
App\DataCollector;


use App\BranchLoader\GitLoader;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;

class GitDataCollector extends DataCollector
{
private $gitLoader;

public function __construct(GitLoader $gitLoader)
{
$this->gitLoader = $gitLoader;
}

public function collect(Request $request, Response $response, \Exception $exception = null)
{
// We add the git informations in $data[]
$this->data = [
'git_branch' => $this->gitLoader->getBranchName(),
'last_commit_message' => $this->gitLoader->getLastCommitMessage(),
'logs' => $this->gitLoader->getLastCommitDetail(),
];
}
    // we will use this name in the config later
public function getName()
{
return 'app.git_data_collector';
}

public function reset()
{
$this->data = array();
}
    //Some helpers to access more easily to infos in the template
public function getGitBranch()
{
return $this->data['git_branch'];
}

public function getLastCommitMessage()
{
return $this->data['last_commit_message'];
}

public function getLastCommitAuthor()
{
return $this->data['logs']['author'];
}

public function getLastCommitDate()
{
return $this->data['logs']['date'];
}
}

6- Create the template git_data.html.twig

{# templates/data_collector/git_data.html.twig #}
{% extends '@WebProfiler/Profiler/layout.html.twig' %}

{% block toolbar %}
{% set icon %}
{# this is the content displayed as a panel in the toolbar #}
{# this big svg is just the Git icon #}
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="97px" height="97px" viewBox="0 0 97 97" enable-background="new 0 0 97 97" xml:space="preserve">
<g>
<path fill="#F05133" d="M92.71,44.408L52.591,4.291c-2.31-2.311-6.057-2.311-8.369,0l-8.33,8.332L46.459,23.19
c2.456-0.83,5.272-0.273,7.229,1.685c1.969,1.97,2.521,4.81,1.67,7.275l10.186,10.185c2.465-0.85,5.307-0.3,7.275,1.671
c2.75,2.75,2.75,7.206,0,9.958c-2.752,2.751-7.208,2.751-9.961,0c-2.068-2.07-2.58-5.11-1.531-7.658l-9.5-9.499v24.997
c0.67,0.332,1.303,0.774,1.861,1.332c2.75,2.75,2.75,7.206,0,9.959c-2.75,2.749-7.209,2.749-9.957,0c-2.75-2.754-2.75-7.21,0-9.959
c0.68-0.679,1.467-1.193,2.307-1.537V36.369c-0.84-0.344-1.625-0.853-2.307-1.537c-2.083-2.082-2.584-5.14-1.516-7.698
L31.798,16.715L4.288,44.222c-2.311,2.313-2.311,6.06,0,8.371l40.121,40.118c2.31,2.311,6.056,2.311,8.369,0L92.71,52.779
C95.021,50.468,95.021,46.719,92.71,44.408z"/>
</g>
</svg>
<span class="sf-toolbar-value">{{ collector.gitBranch }}</span>
{% endset %}

{% set text %}
{# this is the content displayed when hovering the mouse over
the toolbar panel #}
<div class="sf-toolbar-info-piece">

<b>Last commit : </b>
<span>{{ collector.lastCommitDate }} </span>

</div>
<div class="sf-toolbar-info-piece">
<b>Author : </b>
<span>{{ collector.lastCommitAuthor }} </span>
</div>
<div class="sf-toolbar-info-piece">
<b>Message : </b>
<span>{{ collector.lastCommitMessage }} </span>
</div>

{% endset %}

{# the 'link' value set to 'false' means that this panel doesn't
show a section in the web profiler #}
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: false }) }}
{% endblock %}

7- Enable the template

To enable the data collector template, override the service configuration to specify a tag that contains the template.

# config/services.yaml
# ...

App\DataCollector\GitDataCollector:
tags:
-
name: data_collector
template: 'data_collector/git_data.html.twig'
# must match the value returned by the getName() method
id: 'app.git_data_collector'
public: false

8- Result !

Did you see the Git logo with the current branch name ? Victory !!

Bonus : The last commit details are displayed when hovering the zone.


Thanks for reading, Clap me if you liked and feel free to comment or ask question.