Skip to content

commit message formatting #327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/commit_formatting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Commit message check

on: [push, pull_request]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: '100'
- uses: actions/setup-python@v5
- name: Check commit message formatting
run: source tools/ci.sh && ci_commit_formatting_run
10 changes: 9 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,12 @@ repos:
- id: clang-format
args: ["-style=file:config/clang-format/.clang-format"]
exclude: ^cores/(avr|usblib|xmc_lib)/
files: \.(c|cpp|h|hpp)$
files: \.(c|cpp|h|hpp)$
- repo: local
hooks:
- id: verifygitlog
name: git commit message format checker
entry: python3 tools/verifygitlog.py --check-file --ignore-rebase
language: python
verbose: true
stages: [commit-msg]
206 changes: 206 additions & 0 deletions CODE_CONVENTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
Code Conventions
==================

Introduction
============

This document outlines the coding conventions to be followed for this project. Adhering to these conventions ensures consistency, readability, and maintainability of the codebase.

Acknowledgment
==============

This coding convention document is inspired by and partially derived from the [MicroPython project](https://github.com/Infineon/micropython/blob/ports-psoc6-main/CODECONVENTIONS.md). We acknowledge and thank the MicroPython community for their contributions.

Git commit conventions
======================

Each commit message should start with a directory or full file path
prefix, so it was clear which part of codebase a commit affects. If
a change affects one file, it's better to use path to a file. If it
affects few files in a subdirectory, using subdirectory as a prefix
is ok. For longish paths, it's acceptable to drop intermediate
components, which still should provide good context of a change.
It's also ok to drop file extensions.

Besides prefix, first line of a commit message should describe a
change clearly and to the point, and be a grammatical sentence with
final full stop. First line must fit within 72 characters. Examples
of good first line of commit messages:

py/objstr: Add splitlines() method.
py: Rename FOO to BAR.
docs/machine: Fix typo in reset() description.
ports: Switch to use lib/foo instead of duplicated code.

After the first line add an empty line and in the following lines describe
the change in a detail, if needed, with lines fitting within 75 characters
(with an exception for long items like URLs which cannot be broken). Any
change beyond 5 lines would likely require such detailed description.

To get good practical examples of good commits and their messages, browse
the `git log` of the project.

When committing you must sign-off your commit by adding "Signed-off-by:"
line(s) at the end of the commit message, e.g. using `git commit -s`. You
are then certifying and signing off against the following:

* That you wrote the change yourself, or took it from a project with
a compatible license (in the latter case the commit message, and possibly
source code should provide reference where the implementation was taken
from and give credit to the original author, as required by the license).
* That you are allowed to release these changes to an open-source project
(for example, changes done during paid work for a third party may require
explicit approval from that third party).
* Your contribution including commit message will be publicly and
indefinitely available for anyone to access, including redistribution
under the terms of the project's license.
* Your signature for all of the above, which is the "Signed-off-by" line,
includes your full real name and a valid and active email address by
which you can be contacted in the foreseeable future.

Code auto-formatting
====================

Both C and Python code formatting are controlled for consistency across the codebase.
C code is formatted using the `tools/codeformat.py`
script which uses [uncrustify](https://github.com/uncrustify/uncrustify).
Python code is linted and formatted using
[ruff & ruff format](https://github.com/astral-sh/ruff).
After making changes, and before committing, run `tools/codeformat.py` to
reformat your C code and `ruff format` for any Python code. Without
arguments this tool will reformat all source code (and may take some time
to run). Otherwise pass as arguments to the tool the files that changed,
and it will only reformat those.


Automatic Pre-Commit Hooks
==========================

To have code formatting and commit message conventions automatically checked,
a configuration file is provided for the [pre-commit](https://pre-commit.com/)
tool.

First install `pre-commit`, either from your system package manager or via
`pip`. When installing `pre-commit` via pip, it is recommended to use a
virtual environment. Other sources, such as Brew are also available, see
[the docs](https://pre-commit.com/index.html#install) for details.

```
$ apt install pre-commit # Ubuntu, Debian
$ pacman -Sy python-precommit # Arch Linux
$ brew install pre-commit # Brew
$ pip install pre-commit # PyPI
```

Next, install [uncrustify (see above)](#uncrustify). Other dependencies are managed by
pre-commit automatically, but uncrustify needs to be installed and available on
the PATH.

Then, inside the repository, register the git hooks for pre-commit
by running:

```
$ pre-commit install --hook-type pre-commit --hook-type commit-msg
```

pre-commit will now automatically run during `git commit` for both code and
commit message formatting.

The same formatting checks will be run by CI for any Pull Request submitted.
Pre-commit allows you to see any failure more quickly, and in many
cases will automatically correct it in your local working copy.

To unregister `pre-commit` from your repository, run:

```
$ pre-commit uninstall --hook-type pre-commit --hook-type commit-msg
```

Tips:

* To skip pre-commit checks on a single commit, use `git commit -n` (for
`--no-verify`).
* To ignore the pre-commit message format check temporarily, start the commit
message subject line with "WIP" (for "Work In Progress").

Running pre-commit manually
===========================

Once pre-commit is installed as per the previous section it can be manually
run against the codebase to update file formatting on demand, with either:
* `pre-commit run --all-files` to fix all files in the codebase
* `pre-commit run --file ./path/to/my/file` to fix just one file
* `pre-commit run --file ./path/to/my/folder/*` to fix just one folder

C/C++ code conventions
======================

C code is auto-formatted using [uncrustify](https://github.com/uncrustify/uncrustify)
and the corresponding configuration file `tools/uncrustify.cfg`, with a few
minor fix-ups applied by `tools/codeformat.py`. When writing new C code please
adhere to the existing style and use `tools/codeformat.py` to check any changes.
The main conventions, and things not enforceable via the auto-formatter, are
described below.

- Follow the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html).
- Use `snake_case` for variable names and `CamelCase` for class names.

White space:
- Expand tabs to 4 spaces.
- Don't leave trailing whitespace at the end of a line.
- For control blocks (if, for, while), put 1 space between the
keyword and the opening parenthesis.
- Put 1 space after a comma, and 1 space around operators.

Braces:
- Use braces for all blocks, even no-line and single-line pieces of
code.
- Put opening braces on the end of the line it belongs to, not on
a new line.
- For else-statements, put the else on the same line as the previous
closing brace.

Header files:
- Header files should be protected from multiple inclusion with #if
directives. See an existing header for naming convention.

Names:
- Use underscore_case, not camelCase for all names.
- Use CAPS_WITH_UNDERSCORE for enums and macros.
- When defining a type use underscore_case and put '_t' after it.

Comments:
- Be concise and only write comments for things that are not obvious.
- Use `// ` prefix, NOT `/* ... */`. No extra fluff.
- Use comments to explain the "why" behind complex code.

Memory allocation:
- Use m_new, m_renew, m_del (and friends) to allocate and free heap memory.
These macros are defined in py/misc.h.

Examples
--------

Braces, spaces, names and comments:

#define TO_ADD (123)

// This function will always recurse indefinitely and is only used to show
// coding style
int foo_function(int x, int some_value) {
if (x < some_value) {
foo(some_value, x);
} else {
foo(x + TO_ADD, some_value - 1);
}

for (int my_counter = 0; my_counter < x; ++my_counter) {
}
}

Type declarations:

typedef struct _my_struct_t {
int member;
void *data;
} my_struct_t;
23 changes: 23 additions & 0 deletions tools/ci.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

if which nproc > /dev/null; then
MAKEOPTS="-j$(nproc)"
else
MAKEOPTS="-j$(sysctl -n hw.ncpu)"
fi

# Ensure known OPEN_MAX (NO_FILES) limit.
ulimit -n 1024

########################################################################################
# commit formatting

function ci_commit_formatting_run {
git remote add upstream https://github.com/Infineon/XMC-for-Arduino.git
git fetch --depth=100 upstream master
# If the common ancestor commit hasn't been found, fetch more.
git merge-base upstream/master HEAD || git fetch upstream master
# For a PR, upstream/master..HEAD ends with a merge commit into master, exclude that one.
python tools/verifygitlog.py -v upstream/master..HEAD --no-merges
}

39 changes: 39 additions & 0 deletions tools/dev-setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash

# Change dir to the directory where this script is located
cd $(dirname $0)
echo ${PWD}

function git_submodule_setup {
git submodule update --init --recursive
}

function core_api_setup {

cores_xmc_dir="${PWD}/../cores/xmc"
core_api_submodule_dir="${PWD}/../extras/arduino-core-api"

# Create symbolic link (overwrite) to the api/
# folder of ArduinoCore-API submodule.
# Note: Symlinks might not work without full paths
# https://stackoverflow.com/questions/8601988/symlinks-not-working-when-link-is-made-in-another-directory
if [ ! -d "$cores_xmc_dir" ]; then
mkdir -p "$cores_xmc_dir"
echo "Directory created: $cores_xmc_dir"
fi
ln -sf ${core_api_submodule_dir}/api ${cores_xmc_dir}
}


# Check if a function name is passed as an argument
if [ $# -gt 0 ]; then
if declare -f "$1" > /dev/null; then
"$1"
else
echo "Function $1 not found"
exit 1
fi
else
git_submodule_setup
core_api_setup
fi
Loading
Loading