PHP CS Fixer workflow automatisation for git commits
We all use the PHP Code Style Fixer. We all love it! But, we don't like to click "composer fix" button each time before we push our changes. I promise, you will love the Lefthook utility, because it automates one of the most frequent action in PHP projects.
Sooner or later, every developer in his life will know the joy of automatic code fixing tools. This saves us time and improves the quality of the code. However, over time, every developer faces the problem of automating such processes. We don't like to manually trigger code fixer workflows wasting our time and focus on such a basic things.
My journey through
I tried a different tools. From direct .git/hooks
directory commits to Husky. I was looking for a perfect solution for code fixes automatisation in my projects. One of the most popular tool for such purposes is Husky.
Why I do not like Husky?
-
Complex Setup. Husky configuration goes through too much steps and does not have out-of-box rich functions to simplify the configuration.
-
Node.js Environment. Such a simple tool requires NodeJS installation. It causes performance overhead during installation and usage.
-
Dependency Management. To install Husky you should have one of NPM/PNPM/Bun package manager. Any of them pollute your desktop with unnecessary things and make tool setup more complex.
I found the perfect solution for myself
Scrolling through the GitHub repository list I've discovered the ultimate developer tool named Lefthook. So, why I've liked it?
-
Compiled language used
-
Excellent performance
-
No package managers or runtime required
-
Can be integrated with any environment without headache
-
Delivered as a single binary
-
-
YAML syntax used for configuration files. YAML is well-know markup for config files in CI workflows for most projects. Github Actions, as an example. It's used in most of open-source projects.
-
Most setup can be configured with built-in utils. Lefthook has reach set of config options. No need to know git internals to configure basic task such as automatic code fix or code lint.
-
Nice monorepo support
Lefthook configuration with PHP CS Fixer
Too much introduction to such a short action. At the time of writing this article, the latest version of Lefthook is 1.6.4. Let's go step by step.
-
Install and configure PHP Code Style Fixer as described in their Readme.
-
Install Lefthook through any desired way listed in installation guide. On MacOS I do it through the brew package manager:
brew install lefthook
. -
Create a config file named
lefthook.yml
at the root of your project. Heads up! It should be the located in the root of git repository even if you use the monorepo. -
Put the following contents to
lefthook.yml
file.
pre-commit:
commands:
web-cs-fixer:
tags: style fixer
glob: "*.php"
stage_fixed: true
run: vendor/bin/php-cs-fixer --config=.php-cs-fixer.dist.php --allow-risky=yes fix {staged_files}
Run lefthook install
command to apply the changes. Heads up! Lefthook uses git hooks under the hood, so after any update of configuration file you should run lefthook install
again.
That's all. Enjoy coding!
Explanation of properties
-
{staged_files}
template is built-in variable used to provide list of changed files. -
glob
property used to filter file on which you want to run command. -
*.php
means PHP CS Fixer will run only on php files avoiding conflicts with other extensions. -
stage_fixed
is my favourite part. It cares about adding changed files back to git (no need to rungit add command
). -
run
contains command you want to run before each commit.
Monorepo setup
In one of my project I use docker mono repository design. One of the container is PHP Symfony application. There are simple solution for such case.
To run PHP CS Fixer in monorepo there is root property in config. Update your lefthook.yml
in the root of the project with the following config.
pre-commit:
commands:
web-cs-fixer:
tags: style fixer
root: "path/to/docker_containers/php_web_app/"
glob: "*.php"
stage_fixed: true
run: vendor/bin/php-cs-fixer --config=.php-cs-fixer.dist.php --allow-risky=yes fix {staged_files}
Replace path/to/docker_containers/php_web_app/
with path to your php project directory. Heads up! Path you should end with the trailing slash '/'.