Description
As discussed during the CMake rework, code in the Machinekit-HAL codebase (all Machinekit's codebases, really) should be formatted based on some deterministic rules and then linted for common mistakes and errors.
The changes should happen in two stages:
- Modifying the old code to satisfy the new requirements
- Automatic checking of new code proposed for merge for compliance
This should happen for any language (or file) for which the required tools (formatter and/or linter) exist or are easy to develop or are otherwise required and essential for Machinekit-HAL. (Obviously, the easy will be a lot quicker while the hard ones may not even happen.)
From minimal standpoint, the targeted languages should be:
- C (code and headers)
- C++ (code and headers)
- Bash
- Python
- Cython
- IComp
- CMake
- Dockerfile
- YAML
- JSON
The instrumentation for checking of the proposed changes should be two fold:
- Local checking at the developer's machine via
git hooks
functionality - Remote checking as part of Continuous Integration workflow
The git hooks option run locally on the developer's side should be very soft requirement. Nobody should be forced to use the predefined workflow, use the pre-selected toolchain or run it at specific times. Given that the end result will the the same, of course. The CI part should be, on the other hard, very hard requirement. Without successful run, the code should not be eligible for merge as defined by C4.
The CI part should be implemented as separate Github Actions (or other free for Open-Source) provider independently from the rest of the testing workflow.
The local git hooks part should be implemented via git hook manager and actionable commands isolated in it's own runtime (script and Docker image, in layman terms). So the action is deterministic and not dependent on any (additional) installed software on the developer's system. Any update to this setup should be manual and definitely not automatic.
To the git hooks manager, I was originally thinking about the Lefthook project as it is simple Go compiled executable (so the runtime is packed inside), however issues with operating on staged files and connected status checking make the usage very hard. (Not unusable, but it is like making you own bread and beating your own butter, when you just want to eat something in the morning before you go to work - death by thousand paper-cuts defined.) So, in the face of this, I have been looking deeper into the pre-commit project. This software is written in Python, thus it requires Python interpreter version higher than 3.6
. It is also failing on the pythonic way of thinking (i.e. Python is a big, bad hammer with which every nail is bashed in, regardless if it was actually a screw), so their idea how to run a clang-format is to wrap it into wheel, but one can work around it with the docker
approach.
The idea is to run the pre-commit
hook (not the project, idiotic naming) for formatters, so each commit has the right format from the get go. Run the linters as part of the pre-push
hook as that will be time consuming.
Work-plan itinerary
- Work on formatters first, linters second
- Work on the C and C++ first, then Python, then the rest
- Implement the CI and local git hook at the same time
- Implement
clanf-format
rules for C and C++ - Implement CI checking
- Implement the
pre-commit
configuration