Jonathan Scheiber

My Taskfile configuration for Symfony

Read time: 4 minutes 6 comments
My Taskfile configuration for Symfony

Being reluctant to use Makefiles, I recently fell in love with Taskfile, which allows to do pretty much the same thing, but with a simpler syntax.

What is Taskfile?

Taskfile is a task launcher written in Go, which implies that it is in fact an executable that can be installed simply by putting it in a folder located in the system's PATH for example.

The syntax of Taskfile is quite easy to learn. It's YAML, to be written to a Taskfile.yml file. As a bonus, native support for Windows!

A lot of things are possible with Taskfile, just like with Makefile:

  • dependency between tasks
  • possibility of performing several tasks in parallel
  • avoid executing a command if nothing has changed (in composer.lock or yarn.lock files for example)
  • better readability
  • description of the tasks available by entering a simple key

Let's take an example: I want to run Docker containers, Symfony server and fixtures. I'll run the following command: task start fixtures, so the start task (for Docker and the Symfony binary) and fixtures task will be run one after the other. By adding the --parallel option, both tasks will be started at the same time.

My Taskfile for Symfony

Here is my Taskfile.yml file (each task is described so that we know what it is doing):

version: '3'

tasks:
    fixtures:
        desc: Generate fixtures for dev environment
        cmds:
            - symfony console d:d:d --force --if-exists --quiet
            - symfony console d:d:c --quiet
            - symfony console d:s:u --force --quiet
            - symfony console d:m:sync-metadata-storage --quiet
            - symfony console d:m:v --add --all --quiet
            - symfony console h:f:l --no-interaction --quiet

    composer:
        desc: Install PHP vendors
        cmds:
            - composer install
        sources:
            - composer.lock
        generates:
            - vendor/**/*

    start:
        desc: Start Docker containers & Symfony server
        cmds:
            - docker-compose up -d
            - symfony serve -d

    stop:
        desc: Stop Docker containers & Symfony server
        cmds:
            - docker-compose stop
            - symfony server:stop

    test:
        desc: Run tests
        cmds:
            - task: setup_tests
            - symfony run bin/phpunit

    coverage:
        desc: Run tests with coverage
        cmds:
            - task: setup_tests
            - symfony php -dpcov.enabled=1 bin/phpunit --coverage-html=public/coverage
    
    setup_tests:
        cmds:
            - symfony console d:d:d --force --if-exists --quiet --env=test
            - symfony console d:d:c --quiet --env=test
            - symfony console d:s:u --force --quiet --env=test
            - symfony console h:f:l --no-interaction --quiet --env=test

    ci:
        desc: Check code style, static analysis...
        cmds:
            - symfony composer ci

    cs-fix:
        desc: Fix code style
        cmds:
            - symfony composer cs:fix

    node_modules:
        desc: Update frontend vendors
        cmds:
            - yarn install
        sources:
            - yarn.lock
        generates:
            - node_modules/**/*

    assets:
        desc: Build frontend assets
        cmds:
            - task: node_modules
            - yarn run dev
        sources:
            - assets/**/*
        generates:
            - public/build/**/*

Some explanations

Each task can be documented using the desc key, so that by running the task -l command, we get a list of each documented task looking like this:

  • assets: Build frontend assets
  • ci: Check code style, static analysis...
  • composer: Install PHP vendors
  • coverage: Run tests with coverage
  • cs-fix: Fix code style
  • fixtures: Generate fixtures for dev environment
  • node_modules: Update frontend vendors
  • start: Start Docker containers & Symfony server
  • stop: Stop Docker containers & Symfony server
  • test: Run tests

Note that the setup_tests task does not appear in this list, as it is not documented. So much the better, I did not intend to use it without launching the tests after.

As for a Makefile, you can define dependencies between tasks. For example, the assets task first requires the node_modules task to be performed.

Note that a system makes it possible not to execute the task in question if nothing has changed since the last launch. For example for the composer task, it does not need to be executed if the composer.lock file has not been modified since the last execution.

Speaking of which, don't forget to add the exclusion of the /.task folder in eg. your .gitignore file. This folder notably contains the checksum of the files entered by the sources parameter, which prevents the unnecessary execution of a task.

Et voilà! :) If you have any questions, comments, suggestions... Feel free to post a comment below :)

Comments

Posted by Nicolas on 27/11/2020 at 11:06.
Bonjour,

Ne connaissant pas Taskfile, j'ai trouvé ton article très instructif.

Au tout début de ton article tu mets que tu es très réticent à l'utilisation d'un Makefile et je suis curieux de savoir pourquoi ?

Merci d'avance.

Nicolas
Posted by jmsche on 30/11/2020 at 14:08.
Bonjour Nicolas,

Je trouve simplement que la syntaxe du Makefile n'est pas des plus claires et lisibles.
Évidemment les réfractaires au YAML peuvent dire la même chose du Taskfile :)

Un gros avantage est également la prise en charge native de Windows, ce qui n'est pas le cas avec Makefile, même s'il existe plusieurs variantes pour Windows qui fonctionnent plus ou moins.

jmsche
Posted by Brian on 02/12/2020 at 21:12.
I think there is a typo in the fixtures task.

symfony console h:f:l --no-interaction --quiet

should be

symfony console d:f:l --no-interaction --quiet

Thank you for making this, I'm already using it on a new Symfony project.
Posted by jmsche on 02/12/2020 at 21:17.
Hi Brian,

Thanks for your comment :)

It's not a typo :) I use hautelook/alice-bundle for fixtures, not doctrine/doctrine-fixtures-bundle, hence the difference :)
Posted by Jonathan on 17/03/2021 at 14:35.
Super pratique j'avais déjà vu ça dans un projet mais j'avais pas capté l'utilité .
Posted by jb dev labs on 13/06/2022 at 08:54.
Effectivement, le YAML est plus clair et plus strict que la syntaxe du Makefile et ça le rends plus interopérable. C'est un outils plus destiné aux projets dont les postes de dev sont hétérogène.

Add a comment