- Add prof.supp with pthread TLS suppressions - Update ci-build.sh with test configurations - Document functional test best practices in CONTRIBUTING.md
8.4 KiB
Contributing to Profanity
Build
Please follow the build section in our user guide.
You might also take a look at the Dockerfile.* in the root directory.
Submitting patches
We recommend for people to always work on a dedicated git branch for each fix or feature. Don't work on master. So that they can easily pull master and rebase their work if needed.
For fixing (reported) bugs we usually use git switch -c fix/issuenumber-somedescription.
When working on a new feature we usually use git switch -c feature/optionalissuenumber-somedescription.
However this is not a rule just a recommendation to keep an overview of things. If your change isn't a bugfix or new feature you can also just use any branch name.
Commit messages
Write commit messages that make sense. Explain what and why you change. Write in present tense. Please give this guideline a read.
GitHub
We would like to encourage people to use GitHub to create pull requests. It makes it easy for us to review the patches, track WIP branches, organize branches with labels and milestones, and help others to see what's being worked on.
Also see the blogpost Contributing a Patch via GitHub.
In case GitHub is down or you can't use it for any other reason, you can send a patch to our mailing list.
We recommend that you follow the workflow mentioned above.
And create your patch using the git-format-patch tool: git format-patch master --stdout > feature.patch
Another git service
We prefer if you create a pull request on GitHub. Then our team can easily request reviews. And we have the history of the review saved in one place.
If using GitHub is out of the question but you are okay using another service (i.e.: GitLab, codeberg) then please message us in the MUC or send us an email. We will then pull from your repository and merge manually.
Rules
- When fixing a bug, describe it and how your patch fixes it.
- When fixing a reported issue add an
Fixes https://github.com/profanity-im/profanity/issues/23in the commit body. - When adding a new feature add a description of the feature and how it should be used (workflow).
- If your patch adds a new configuration option add this to the
profrc.examplefile. - If your patch adds a new theming option add this to the
theme_templatefile. - Each patch or pull request should only contain related modifications.
- Run the tests and code formatters before submitting (c.f. Chapter 'Check everything' of this README).
- When changing the UI it would be appreciated if you could add a before and after screenshot for comparison.
- Squash fixup commits into one
- If applicable, document how to test the functionality
Hints and Pitfalls
- When adding a new hotkey/shortcut make sure it's not registered in Profanity already. And also that it's not a default shortcut of readline.
- We ship a
.git-blame-ignore-revsfile containing banal commits which you will most likely want to ignore when usinggit blame. In case you are using vim and fugitivecommand Gblame Git blame --ignore-revs-file=.git-blame-ignore-revsmight be helpful in your vimrc. You can also set theblame.ignoreRevsFileoption in your git config to havegit blamegenerally ignore the listed commits.
Coding style
Follow the style already present ;-)
To make this easier for you we created a .clang-format file.
You'll need to have clang-format installed.
Then just run make format before you do any commit.
It might be a good idea to add a git pre-commit hook. So git automatically runs clang-format before doing a commit.
You can add the following snippet to .git/hooks/pre-commit:
for f in $(git diff --cached --name-only)
do
if [[ "$f" =~ \.(c|h)$ ]]; then
clang-format -i $f
fi
done
If you feel embarrassed every time the CI fails you can add the following
snippet to .git/hooks/pre-push:
#!/bin/sh
set -e
./ci-build.sh
This will run the same tests that the CI runs and refuse the push if it fails. Note that it will run on the actual content of the repository directory and not what may have been staged/committed.
If you're in a hurry you can add the --no-verify flag when issuing git push
and the pre-push hook will be skipped.
Note: We provide a config file that describes our coding style for clang. But due to a mistake on their side it might happen that you can get a different result that what we expect. See here and here for details. We will try to always run latest clang-format.
Finding mistakes
Test your changes with the following tools to find mistakes.
unit tests
Run make check to run the unit tests with your current configuration or ./ci-build.sh to check with different switches passed to configure.
valgrind
We provide a suppressions file prof.supp. It is a combination of the suppressions for shipped with glib2, python and custom rules.
G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --tool=memcheck --track-origins=yes --leak-check=full --leak-resolution=high --num-callers=30 --show-leak-kinds=definite --log-file=profval --suppressions=prof.supp ./profanity
There's also the option to create a "personalized" suppression file with the up-to-date glib2 and python suppressions.
make my-prof.supp
After executing this, you can replace the --suppressions=prof.supp argument in the above call, by --suppressions=my-prof.supp.
clang
Running the clang static code analyzer helps improving the quality too.
make clean
scan-build make
scan-view ...
Finding typos
We include a .codespellrc configuration file for codespell in the root directory.
Before committing it might make sense to run codespell to see if you made any typos.
You can run the make spell command for this.
Check everything
make doublecheck will run the code formatter, spell checker and unit tests.
Functional tests: moving away from brittle ID hooks
Historically the functional test suite relied on stabber's id based helpers like stbbr_for_id("prof_presence_1", ...) to register canned responses that would be sent once Profanity emitted a stanza carrying that exact id attribute. This made the tests fragile:
- Changes to stanza id generation (sequence, format) broke tests unexpectedly.
- Reordering internal requests produced hard-to-debug race conditions when an
idno longer matched. - Parallel additions of new features could shift which stanzas received a given id causing unrelated test failures.
We have migrated to content based stubbing using direct sends (stbbr_send) and query hooks (stbbr_for_query). Instead of tying a response to a predicted id we now send the required server stanzas explicitly after initiating actions. Example (see tests/functionaltests/proftest.c):
// Old brittle approach
stbbr_for_id("prof_presence_1", "<presence id='prof_presence_1' ...>");
// New approach: after authentication, send presence directly
stbbr_send("<presence from='stabber@localhost/profanity' to='stabber@localhost/profanity'>...caps...</presence>");
Benefits:
- Eliminates dependency on internal id sequencing.
- Clearer intent inside test code ("send presence now" vs "register hook and hope client triggers it").
- Simplifies adding new tests—no need to inspect logs for generated ids.
Guidelines when writing new functional tests:
- Prefer
stbbr_for_query(namespace, xml)for IQ roster or disco queries where the namespace is stable. - Use
stbbr_send(xml)for presence, message, and other push style stanzas. - Avoid
stbbr_for_idunless the protocol flow genuinely requires correlating a specific request/response pair not covered by a namespace query. - Keep assertions tolerant of ordering when possible; rely on
prof_output_regex()matches rather than hard-coded positions. - If timing flakiness appears, temporarily raise
prof_timeout()around the critical expectation and reset it immediately afterwards.
The migration from stbbr_for_id is complete. All functional tests now use content-based stubbing. When adding new tests, follow the guidelines above.