== Documentation

Since Fedora contributors live around the world and don't often have the
opportunity to meet in person, it's important to maintain up-to-date
high quality documentation for all our projects. Our preferred
documentation tool is http://www.sphinx-doc.org/[Sphinx]. In fact, this
documentation is written using http://www.sphinx-doc.org/[Sphinx]!

A project's documentation should at a minimum contain:

* An introduction to the project
* A user guide
* A contributor guide
* API documentation.

The easiest way to maintain up-to-date documentation is to include the
majority of the documentation in the code itself.
http://www.sphinx-doc.org/[Sphinx] includes several extensions to turn
Python documentation into HTML pages.

[NOTE]
====
Improving documentation is a great way to get involved in a project.
When adding new documentation or cleaning up existing documentation,
please follow the guidelines below.
====

=== Style

Sphinx supports three different documentation styles. By default, Sphinx
expects ReStructuredText. However, it has included an extension to
support the
https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html#example-google[Google style]
and the https://www.sphinx-doc.org/en/master/usage/extensions/example_numpy.html#example-numpy[NumPy
style] since version 1.3. The style of the documentation blocks is left
up to the individual project, but it should document the choice and be
consistent.

=== Introduction

The project introduction should be easy to find - preferably it should
be the documentation's index page. It should provide an overview of the
project and should be easy for a complete new-comer to understand.

=== User Guide

Have a clear user guide that covers most, if not all, features of the
project as well as potential use cases. Keep in mind that your users may
be non-technical as well as technical. Some users will want to use the
project's web interface, while others are interested in the API and the
documentation should make it easy for both types of users to find the
documentation for them.

=== Contributor Guide

Documenting how to start contributing makes it much easier for new
contributors to get involved. This is a good place to cover the
expectations about code style, documentation, tests, etc.

=== API Documentation

All APIs should be documented. Users should never have to consult the
source code to use the project's API.

==== Python

Python API documentation is easily generated by using the
http://www.sphinx-doc.org/en/stable/tutorial.html#autodoc[autodoc]
extension. Following these steps will create rich HTML, PDF, EPUB, or
man format documentation:

[arabic]
. All modules should contain a documentation block at the top of the
file that describes the module's purpose and documents module-level
attributes it provides as part of its public interface. In the case of a
package's `__init__.py`, this should document the package's purpose.
. All classes should have documentation blocks that describe their
purpose, any attributes they have, and example usage if appropriate.
. All methods and functions should have documentation blocks that
describe their purpose, the arguments they accept, the types of those
arguments, and example usage if appropriate.
. Make use of Sphinx's
http://www.sphinx-doc.org/en/stable/domains.html#cross-referencing-python-objects[cross-referencing]
feature. This will generate links between objects in the documentation.

==== HTTP APIs

Many projects provide an HTTP-based API. Use
https://sphinxcontrib-httpdomain.readthedocs.io/en/stable/[sphinxcontrib-httpdomain]
to produce the HTTP interface documentation. This task is made
significantly easier if the project using a web framework that
https://sphinxcontrib-httpdomain.readthedocs.io/en/stable/[sphinxcontrib-httpdomain]
supports, like Flask. In that case, all you need to do is add the
https://sphinxcontrib-httpdomain.readthedocs.io/en/stable/[sphinxcontrib-httpdomain]
ReStructuredText directives to the functions or classes that provide the
Flask endpoints.

After that, all you need to do is use the `autoflask` ReStructuredText
directive.

=== Release Notes and ChangeLog

The release notes (or the changelog) can be managed using
https://pypi.org/project/towncrier/[towncrier]. It can build a release
notes files by assembling items that would be written in separate files
by each pull request (or commit). This way, the different commits will
not conflict by writing in the same changelog file, and a link to the
issue, the pull request or the commit is automatically inserted.

In your project root, add a `pyproject.toml` file with a
`tool.towncrier` section similar to the one in our CookieCutter template's
https://github.com/fedora-infra/cookiecutter-python-app/blob/main/%7B%7B%20cookiecutter.slug%20%7D%7D/pyproject.toml[pyproject.toml]
file.


Create a `changelog.d` directory where the changelog items will be written,
and inthere create a `_template.md` file with a content similar to the one in
https://raw.githubusercontent.com/fedora-infra/cookiecutter-python-app/main/%7B%7B%20cookiecutter.slug%20%7D%7D/changelog.d/_template.md[our template].

Of course, replace the first section (the `reference` macro) with the
project's Github URL. Or just use the CookieCutter template.

Then create a `docs/changelog.rst` file (location configured in the
`pyproject.toml` file) with a content similar to:

....
# Release Notes

<!-- towncrier release notes start -->
....

Then each commit can add a file in the `changelog.d` folder to document the
change. The format is described in our CookieCutter template's
https://github.com/fedora-infra/cookiecutter-python-app/blob/main/%7B%7B%20cookiecutter.slug%20%7D%7D/docs/contributing.rst#release-notes[contributing]
document.

A preview of the release notes can be generated with
`towncrier build --draft`.

When running `towncrier build`, the tool will write the changelog file and
remove the individual changelog item files. These changes can then be
committed as part of the release commit.
