Rewrite contributing docs for v3

This commit is contained in:
Martin Hořeňovský 2020-10-06 12:34:40 +02:00
parent 60dfec559f
commit 340ff00058
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A

View File

@ -1,118 +1,123 @@
<a id="top"></a> <a id="top"></a>
# Contributing to Catch # Contributing to Catch2
**Contents**<br> **Contents**<br>
[Branches](#branches)<br> [Using Git(Hub)](#using-github)<br>
[Directory structure](#directory-structure)<br>
[Testing your changes](#testing-your-changes)<br> [Testing your changes](#testing-your-changes)<br>
[Documenting your code](#documenting-your-code)<br> [Writing documentation](#writing-documentation)<br>
[Examples](#examples)<br> [Writing code](#writing-code)<br>
[Code constructs to watch out for](#code-constructs-to-watch-out-for)<br> [CoC](#coc)<br>
So you want to contribute something to Catch? That's great! Whether it's a bug fix, a new feature, support for So you want to contribute something to Catch2? That's great! Whether it's
additional compilers - or just a fix to the documentation - all contributions are very welcome and very much appreciated. a bug fix, a new feature, support for additional compilers - or just
Of course so are bug reports and other comments and questions. a fix to the documentation - all contributions are very welcome and very
much appreciated. Of course so are bug reports, other comments, and
questions, but generally it is a better idea to ask questions in our
[Discord](https://discord.gg/4CWS9zD), than in the issue tracker.
If you are contributing to the code base there are a few simple guidelines to keep in mind. This also includes notes to
help you find your way around. As this is liable to drift out of date please raise an issue or, better still, a pull
request for this file, if you notice that.
## Branches This page covers some guidelines and helpful tips for contributing
to the codebase itself.
Ongoing development is currently on _master_. At some point an integration branch will be set-up and PRs should target ## Using Git(Hub)
that - but for now it's all against master. You may see feature branches come and go from time to time, too.
## Directory structure Ongoing development happens in the `devel` branch for Catch2 v3, and in
`v2.x` for maintenance updates to the v2 versions.
_Users_ of Catch primarily use the single header version. _Maintainers_ should work with the full source (which is still, Commits should be small and atomic. A commit is atomic when, after it is
primarily, in headers). This can be found in the `include` folder. There are a set of test files, currently under applied, the codebase, tests and all, still works as expected. Small
`projects/SelfTest`. The test app can be built via CMake from the `CMakeLists.txt` file in the root, or you can generate commits are also prefered, as they make later operations with git history,
project files for Visual Studio, XCode, and others (instructions in the `projects` folder). If you have access to CLion, whether it is bisecting, reverting, or something else, easier.
it can work with the CMake file directly.
As well as the runtime test files you'll also see a `SurrogateCpps` directory under `projects/SelfTest`. _When submitting a pull request please do not include changes to the
This contains a set of .cpp files that each `#include` a single header. amalgamated distribution files. This means do not include them in your
While these files are not essential to compilation they help to keep the implementation headers self-contained. git commits!_
At time of writing this set is not complete but has reasonable coverage.
If you add additional headers please try to remember to add a surrogate cpp for it.
The other directories are `tools/scripts` which contains a set of python scripts to help in testing Catch as well as When addressing review comments in a MR, please do not rebase/squash the
generating the single include, and `docs`, which contains the documentation as a set of markdown files. commits immediately. Doing so makes it harder to review the new changes,
slowing down the process of merging a MR. Instead, when addressing review
comments, you should append new commits to the branch and only squash
them into other commits when the MR is ready to be merged. We recommend
creating new commits with `git commit --fixup` (or `--squash`) and then
later squashing them with `git rebase --autosquash` to make things easier.
__When submitting a pull request please do not include changes to the single include, or to the version number file
as these are managed by the scripts!__
## Testing your changes ## Testing your changes
Obviously all changes to Catch's code should be tested. If you added new _Note: Running Catch2's tests requires Python3_
functionality, you should add tests covering and showcasing it. Even if you have
only made changes to Catch internals (i.e. you implemented some performance
improvements), you should still test your changes.
This means 2 things
* Compiling Catch's SelfTest project: Catch2 has multiple layers of tests that are then run as part of our CI.
The most obvious one are the unit tests compiled into the `SelfTest`
binary. These are then used in "Approval tests", which run (almost) all
tests from `SelfTest` through a specific reporter and then compare the
generated output with a known good output ("Baseline"). By default, new
tests should be placed here.
However, not all tests can be written as plain unit tests. For example,
checking that Catch2 orders tests randomly when asked to, and that this
random ordering is subset-invariant, is better done as an integration
test using an external check script. Catch2 integration tests are written
using CTest, either as a direct command invocation + pass/fail regex,
or by delegating the check to a Python script.
There are also two more kinds of tests, examples and "ExtraTests".
Examples present a small and self-contained snippets of code that
use Catch2's facilities for specific purpose. Currently they are assumed
passing if they compile. ExtraTests then are expensive tests, that we
do not want to run all the time. This can be either because they take
a long time to run, or because they take a long time to compile, e.g.
because they test compile time configuration and require separate
compilation.
Examples and ExtraTests are not compiled by default. To compile them,
add `-DCATCH_BUILD_EXAMPLES=ON` and `-DCATCH_BUILD_EXTRA_TESTS=ON` to
the invocation of CMake configuration step.
Bringing this all together, the steps below should configure, build,
and run all tests in the `Debug` compilation.
1. Regenerate the amalgamated distribution
``` ```
$ cd Catch2 $ cd Catch2
$ cmake -Bdebug-build -H. -DCMAKE_BUILD_TYPE=Debug $ ./tools/scripts/generateAmalgamatedFiles.py
```
2. Configure the full test build
```
$ cmake -Bdebug-build -H. -DCMAKE_BUILD_TYPE=Debug -DCATCH_BUILD_EXAMPLES=ON -DCATCH_BUILD_EXTRA_TESTS=ON
```
3. Run the actual build
```
$ cmake --build debug-build $ cmake --build debug-build
``` ```
because code that does not compile is evidently incorrect. Obviously, 4. Run the tests using CTest
you are not expected to have access to all the compilers and platforms
supported by Catch2, but you should at least smoke test your changes
on your platform. Our CI pipeline will check your PR against most of
the supported platforms, but it takes an hour to finish -- compiling
locally takes just a few minutes.
* Running the tests via CTest:
``` ```
$ cd debug-build $ cd debug-build
$ ctest -j 2 --output-on-failure $ ctest -j 4 --output-on-failure -C Debug
``` ```
__Note:__ When running your tests with multi-configuration generators like
Visual Studio, you might get errors "Test not available without configuration."
You then have to pick one configuration (e.g. ` -C Debug`) in the `ctest` call.
If you added new tests, approval tests are very likely to fail. If they If you added new tests, you will likely see `ApprovalTests` failure.
do not, it means that your changes weren't run as part of them. This After you check that the output difference is expected, you should
_might_ be intentional, but usually is not. run `tools/scripts/approve.py` to confirm them, and include these changes
in your commit.
The approval tests compare current output of the SelfTest binary in various
configurations against known good outputs. The reason it fails is,
_usually_, that you've added new tests but have not yet approved the changes
they introduce. This is done with the `scripts/approve.py` script, but
before you do so, you need to check that the introduced changes are indeed
intentional.
## Documenting your code ## Writing documentation
If you have added new feature to Catch2, it needs documentation, so that If you have added new feature to Catch2, it needs documentation, so that
other people can use it as well. This section collects some technical other people can use it as well. This section collects some technical
information that you will need for updating Catch2's documentation, and information that you will need for updating Catch2's documentation, and
possibly some generic advise as well. possibly some generic advise as well.
### Technicalities
First, the technicalities: First, the technicalities:
* We introduced version tags to the documentation, which show users in
which version a specific feature was introduced. This means that newly
written documentation should be tagged with a placeholder, that will
be replaced with the actual version upon release. There are 2 styles
of placeholders used through the documentation, you should pick one that
fits your text better (if in doubt, take a look at the existing version
tags for other features).
* `> [Introduced](link-to-issue-or-PR) in Catch X.Y.Z` - this
placeholder is usually used after a section heading
* `> X (Y and Z) was [introduced](link-to-issue-or-PR) in Catch X.Y.Z`
- this placeholder is used when you need to tag a subpart of something,
e.g. list
* Crosslinks to different pages should target the `top` anchor, like this
`[link to contributing](contributing.md#top)`.
* If you have introduced a new document, there is a simple template you * If you have introduced a new document, there is a simple template you
should use. It provides you with the top anchor mentioned above, and also should use. It provides you with the top anchor mentioned to link to
with a backlink to the top of the documentation: (more below), and also with a backlink to the top of the documentation:
```markdown ```markdown
<a id="top"></a> <a id="top"></a>
# Cool feature # Cool feature
@ -125,6 +130,22 @@ Text that explains how to use the cool feature.
[Home](Readme.md#top) [Home](Readme.md#top)
``` ```
* Crosslinks to different pages should target the `top` anchor, like this
`[link to contributing](contributing.md#top)`.
* We introduced version tags to the documentation, which show users in
which version a specific feature was introduced. This means that newly
written documentation should be tagged with a placeholder, that will
be replaced with the actual version upon release. There are 2 styles
of placeholders used through the documentation, you should pick one that
fits your text better (if in doubt, take a look at the existing version
tags for other features).
* `> [Introduced](link-to-issue-or-PR) in Catch X.Y.Z` - this
placeholder is usually used after a section heading
* `> X (Y and Z) was [introduced](link-to-issue-or-PR) in Catch X.Y.Z`
- this placeholder is used when you need to tag a subpart of something,
e.g. a list
* For pages with more than 4 subheadings, we provide a table of contents * For pages with more than 4 subheadings, we provide a table of contents
(ToC) at the top of the page. Because GitHub markdown does not support (ToC) at the top of the page. Because GitHub markdown does not support
automatic generation of ToC, it has to be handled semi-manually. Thus, automatic generation of ToC, it has to be handled semi-manually. Thus,
@ -132,44 +153,54 @@ if you've added a new subheading to some page, you should add it to the
ToC. This can be done either manually, or by running the ToC. This can be done either manually, or by running the
`updateDocumentToC.py` script in the `scripts/` folder. `updateDocumentToC.py` script in the `scripts/` folder.
### Contents
Now, for the generic tips: Now, for some content tips:
* Usage examples are good
* Don't be afraid to introduce new pages
* Try to be reasonably consistent with the surrounding documentation
## Examples * Usage examples are good. However, having large code snippets inline
can make the documentation less readable, and so the inline snippets
should be kept reasonably short. To provide more complex compilable
examples, consider adding new .cpp file to `examples/`.
The examples/ directory contains some example tests which should compile and * Don't be afraid to introduce new pages. The current documentation
run to show how to use Catch2. The code being tested should be trivial as the tends towards long pages, but a lot of that is caused by legacy, and
purpose of the examples is to show how the tests work. we know that some of the pages are overly big and unfocused.
The examples in the `examples/` directory are not built by default. To compile * When adding information to an existing page, please try to keep your
them add `-DCATCH_BUILD_EXAMPLES=ON` to your cmake command line. There will formatting, style and changes consistent with the rest of the page.
then be an `examples/` directory in your build directory, containing the
resulting test programs.
In general each file in `examples/` compiles to a stand-alone test program for * Any documentation has multiple different audiences, that desire
clarity. different information from the text. The 3 basic user-types to try and
cover are:
* A beginner to Catch2, who requires closer guidance for the usage of Catch2.
* Advanced user of Catch2, who want to customize their usage.
* Experts, looking for full reference of Catch2's capabilities.
The examples are compiled against the local copy of the _single header_ version
of catch. If you are building from git then this might not be up to date with
changes in the _full source_ version. Before trying to build the examples, go
to the top level of the source tree, and run the python script to prepare the
single header version (this requires Python3 to be installed):
``` ## Writing code
./scripts/generateSingleHeader.py
```
__When submitting a pull request please do not include changes to the single
include. This means do not include them in your git commits!__
## Code constructs to watch out for If want to contribute code, this section contains some simple rules
and tips on things like code formatting, code constructions to avoid,
and so on.
### Formatting
To make code formatting simpler for the contributors, Catch2 provides
its own config for `clang-format`. However, because it is currently
impossible to replicate existing Catch2's formatting in clang-format,
using it to reformat a whole file would cause massive diffs. To keep
the size of your diffs reasonable, you should only use clang-format
on the newly changed code.
### Code constructs to watch out for
This section is a (sadly incomplete) listing of various constructs that This section is a (sadly incomplete) listing of various constructs that
are problematic and are not always caught by our CI infrastructure. are problematic and are not always caught by our CI infrastructure.
### Naked exceptions and exceptions-related function
#### Naked exceptions and exceptions-related function
If you are throwing an exception, it should be done via `CATCH_ERROR` If you are throwing an exception, it should be done via `CATCH_ERROR`
or `CATCH_RUNTIME_ERROR` in `catch_enforce.h`. These macros will handle or `CATCH_RUNTIME_ERROR` in `catch_enforce.h`. These macros will handle
@ -180,7 +211,8 @@ CI, but luckily there should not be too many reasons to use these.
However, if you do, they should be kept behind a However, if you do, they should be kept behind a
`CATCH_CONFIG_DISABLE_EXCEPTIONS` macro. `CATCH_CONFIG_DISABLE_EXCEPTIONS` macro.
### Unqualified usage of functions from C's stdlib
#### Unqualified usage of functions from C's stdlib
If you are using a function from C's stdlib, please include the header If you are using a function from C's stdlib, please include the header
as `<cfoo>` and call the function qualified. The common knowledge that as `<cfoo>` and call the function qualified. The common knowledge that
@ -188,7 +220,32 @@ there is no difference is wrong, QNX and VxWorks won't compile if you
include the header as `<cfoo>` and call the function unqualified. include the header as `<cfoo>` and call the function unqualified.
---- ### New source file template
If you are adding new source file, there is a template you should use.
Specifically, every source file should start with the licence header:
```cpp
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
```
The include guards for header files should follow the pattern `{FILENAME}_INCLUDED`.
This means that for file `catch_matchers_foo`, the include guard should
be `CATCH_MATCHERS_FOO_INCLUDED`, for `catch_generators_bar`, the include
guard should be `CATCH_GENERATORS_BAR_INCLUDED`, and so on.
## CoC
This project has a [CoC](../CODE_OF_CONDUCT.md). Please adhere to it
while contributing to Catch2.
-----------
_This documentation will always be in-progress as new information comes _This documentation will always be in-progress as new information comes
up, but we are trying to keep it as up to date as possible._ up, but we are trying to keep it as up to date as possible._