Skip to content

Commit

Permalink
Default markdown template (#483)
Browse files Browse the repository at this point in the history
* Add default markdown template

* Update tutorial.rst to mention markdown

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Typing fixes, fix template issue, full test coverage

* Add newsfragment

* Apply suggestions from code review

Markdown caps, test formatting

Co-authored-by: Hynek Schlawack <hs@ox.cx>

* Update docs/tutorial.rst

Co-authored-by: Hynek Schlawack <hs@ox.cx>

* Update docs/configuration.rst

Co-authored-by: Hynek Schlawack <hs@ox.cx>

* towncrier doesn't use .rst extensions for fragments

* Applying suggested changes

* "Version" doc improvements

* Another change for consistency in docs

* Remove ordereddict and redundant os.mkdirs

* Make Config.underlines a tuple by default

* Fix what Github suggestions messed up

* Fix dicts that were OrderedDicts

* Fix documentation link

* Re-add the required os.mkdirs and abstract the common use case in test_settings

* Use Python 3.10 compatible importlib_resources

* Fix markdown in fragment

* Fix comment to show what fragments actually returns now

* Importlib test helper can keep using builtin

* Revert to old template open method to try and fix a windows error

* Make ruff's sort work the same as actual isort

* Make config.template use a tuple instead of a string if it's a resource template

* Improve docs for directory configuration key

* Document template configuration key

* Change default start_string configuration when using markdown

* Change newsfile docs to use `code-block`s
(and fix typo in documented markdown start_string)

* Use helpers read/write for new tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Better configuration doc formatting

* Document Section Path Behaviour

* Improve configuration docs re: python projects

* Fix test that was altered to use dedent

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Hynek Schlawack <hs@ox.cx>
  • Loading branch information
3 people authored May 4, 2023
1 parent 622ba4f commit 4493cce
Show file tree
Hide file tree
Showing 16 changed files with 926 additions and 505 deletions.
277 changes: 197 additions & 80 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,206 @@ Configuration Reference
=======================

``towncrier`` has many knobs and switches you can use, to customize it to your project's needs.
The setup in the `Tutorial <tutorial.html>`_ doesn't touch on many, but this document will detail each of these options for you!
The setup in the :doc:`tutorial` doesn't touch on many, but this document will detail each of these options for you!

For how to perform common customization tasks, see `Customization <customization/index.html>`_.
For how to perform common customization tasks, see :doc:`customization/index`.

``[tool.towncrier]``
--------------------

All configuration for ``towncrier`` sits inside ``pyproject.toml``, under the ``tool.towncrier`` namespace.
All configuration for ``towncrier`` sits inside ``towncrier.toml`` or ``pyproject.toml``, under the ``tool.towncrier`` namespace.
Please see https://toml.io/ for how to write TOML.

A minimal configuration for a Python project looks like this:

.. code-block:: toml
# pyproject.toml
[tool.towncrier]
package = "myproject"
A minimal configuration for a non-Python project looks like this:

.. code-block:: toml
# towncrier.toml
[tool.towncrier]
name = "My Project"
Top level keys
~~~~~~~~~~~~~~

- ``directory`` -- If you are not storing your news fragments in your Python package, or aren't using Python, this is the path to where your newsfragments will be put.
- ``filename`` -- The filename of your news file.
``NEWS.rst`` by default.
- ``package`` -- The package name of your project.
(Python projects only)
- ``package_dir`` -- The folder your package lives. ``./`` by default, some projects might need to use ``src``.
(Python projects only)
- ``template`` -- Path to an alternate template for generating the news file, if you have one.
- ``start_string`` -- The magic string that ``towncrier`` looks for when considering where the release notes should start.
``.. towncrier release notes start`` by default.
- ``title_format`` -- A format string for the title of your project.
``{name} {version} ({project_date})`` by default.
- ``issue_format`` -- A format string for rendering the issue/ticket number in newsfiles.
``#{issue}`` by default.
- ``underlines`` -- The characters used for underlining headers.
``["=", "-", "~"]`` by default.
``name``
The name of your project.

For Python projects that provide a ``package`` key, if left empty then the name will be automatically determined.

``""`` by default.

``version``
The version of your project.

Python projects that provide the ``package`` key can have the version to be automatically determined from a ``__version__`` variable in the package's module.

If not provided or able to be determined, the version must be passed explicitly by the command line argument ``--version``.

``directory``
The directory storing your news fragments.

For Python projects that provide a ``package`` key, the default is a ``newsfragments`` directory within the package.
Otherwise the default is a ``newsfragments`` directory relative to the configuration file.

``filename``
The filename of your news file.

``"NEWS.rst"`` by default.

``template``
Path to the template for generating the news file.

If the path looks like ``<some.package>:<filename.ext>``, it is interpreted as a template bundled with an installed Python package.

``"towncrier:default.rst"`` by default unless ``filename`` ends with ``.md``, in which case the default is ``"towncrier:default.md"``.

``start_string``
The magic string that ``towncrier`` looks for when considering where the release notes should start.

``".. towncrier release notes start\n"`` by default unless ``filename`` ends with ``.md``, in which case the default is ``"<!-- towncrier release notes start -->\n"``.

``title_format``
A format string for the title of your project.

The explicit value of ``False`` will disable the title entirely.
Any other empty value means the template should render the title (the bundled templates use ``<name> <version> (<date>)``).
Strings should use the following keys to render the title dynamically: ``{name}``, ``{version}``, and ``{project_date}``.

``""`` by default.

``issue_format``
A format string for rendering the issue/ticket number in newsfiles.

If none, the issues are rendered as ``#<issue>`` if for issues that are integers, or just ``<issue>`` otherwise.
Use the ``{issue}`` key in your string render the issue number, for example Markdown projects may want to use ``"[{issue}]: https://<your bug tracker>/{issue}"``.

``None`` by default.

``underlines``
The characters used for underlining headers.

Not used in the bundled Markdown template.

``["=", "-", "~"]`` by default.

``wrap``
Boolean value indicating whether to wrap news fragments to a line length of 79.

``false`` by default.

``all_bullets``
Boolean value indicating whether the template uses bullets for each news fragment.

``true`` by default.

``single_file``
Boolean value indicating whether to write all news fragments to a single file.

If ``false``, the ``filename`` should use the following keys to render the filenames dynamically:
``{name}``, ``{version}``, and ``{project_date}``.

``true`` by default.

``orphan_prefix``
The prefix used for orphaned news fragments.

``"+"`` by default.

Extra top level keys for Python projects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``package``
The Python package name of your project.

Allows ``name`` and ``version`` to be automatically determined from the Python package.
Changes the default ``directory`` to be a ``newsfragments`` directory within this package.

``package_dir``
The folder your package lives.

``"."`` by default, some projects might need to use ``"src"``.


Sections
--------

``towncrier`` supports splitting fragments into multiple sections, each with its own news of fragment types.

Add an array of tables your ``.toml`` configuration file named ``[[tool.towncrier.section]]``.

Each table within this array has the following mandatory keys:


``name``
The name of the section.

``path``
The path to the directory containing the news fragments for this section, relative to the configured ``directory``.
Use ``""`` for the root directory.

For example:

.. code-block:: toml
[[tool.towncrier.section]]
name = "Main Platform"
path = ""
[[tool.towncrier.section]]
name = "Secondary"
path = "secondary"
Section Path Behaviour
~~~~~~~~~~~~~~~~~~~~~~

The path behaviour is slightly different depending on whether ``directory`` is explicitly set.

If ``directory`` is not set, "newsfragments" is added to the end of each path. For example, with the above sections, the paths would be:

:Main Platform: ./newsfragments
:Secondary: ./secondary/newsfragments

If ``directory`` *is* set, the section paths are appended to this path. For example, with ``directory = "changes"`` and the above sections, the paths would be:

:Main Platform: ./changes
:Secondary: ./changes/secondary


Custom fragment types
---------------------
``towncrier`` allows defining custom fragment types.
Custom fragment types will be used instead ``towncrier`` default ones, they are not combined.

There are two ways to add custom fragment types.
``towncrier`` has the following default fragment types: ``feature``, ``bugfix``, ``doc``, ``removal``, and ``misc``.

You can use either of the two following method to define custom types instead (you will need to redefine any of the default types you want to use).


Defining Custom Fragment Types With a TOML Mapping
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Use TOML tables (alphabetical order)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Users can configure each of their own custom fragment types by adding tables to
the pyproject.toml named ``[tool.towncrier.fragment.<a custom fragment type>]``.
Adding tables to your ``.toml`` configuration file named ``[tool.towncrier.fragment.<a custom fragment type>]``.

These tables may include the following optional keys:
These may include the following optional keys:

* ``name``: The description of the fragment type, as it must be included in the news file.
If omitted, it defaults to its fragment type, but capitalized.
* ``showcontent``: Whether if the fragment contents should be included in the news file. If omitted, it defaults to ``true``

``name``
The description of the fragment type, as it must be included in the news file.

Defaults to its fragment type, but capitalized.

``showcontent``
A boolean value indicating whether the fragment contents should be included in the news file.

``true`` by default.

For example, if you want your custom fragment types to be ``["feat", "fix", "chore",]`` and you want all of them to use the default configuration except ``"chore"`` you can do it as follows:

Expand All @@ -70,25 +219,30 @@ For example, if you want your custom fragment types to be ``["feat", "fix", "cho
.. warning::

Since TOML mappings aren't ordered, the sections are always rendered alphabetically.
Since TOML mappings aren't ordered, types defined using this method are always rendered alphabetically.


Use a TOML Array (defined order)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Defining Custom Fragment Types With an Array of TOML Tables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Add an array of tables to your ``.toml`` configuration file named ``[[tool.towncrier.type]]``.

Users can create their own custom fragment types by adding an array of
tables to the pyproject.toml named ``[[tool.towncrier.type]]``.
If you use this way to configure custom fragment types, ensure there is no ``tool.towncrier.fragment`` table.

If you use this way to configure custom fragment types, please note that ``fragment_types`` must be empty or not provided.
Each table within this array has the following mandatory keys:

Each custom type (``[[tool.towncrier.type]]``) has the following
mandatory keys:

* ``directory``: The type / category of the fragment.
* ``name``: The description of the fragment type, as it must be included
in the news file.
* ``showcontent``: Whether if the fragment contents should be included in the
news file.
``directory``
The type / category of the fragment.

``name``
The description of the fragment type, as it must be included
in the news file.

``showcontent``
A boolean value indicating whether the fragment contents should be included in the news file.

``true`` by default.

For example:

Expand All @@ -104,40 +258,3 @@ For example:
directory = "chore"
name = "Other Tasks"
showcontent = false
All Options
-----------

``towncrier`` has the following global options, which can be specified in the toml file:

.. code-block:: toml
[tool.towncrier]
package = ""
package_dir = "."
single_file = true # if false, filename is formatted like `title_format`.
filename = "NEWS.rst"
directory = "directory/of/news/fragments"
version = "1.2.3" # project version if maintained separately
name = "arbitrary project name"
template = "path/to/template.rst"
start_string = "Text used to detect where to add the generated content in the middle of a file. Generated content added after this text. Newline auto added."
title_format = "{name} {version} ({project_date})" # or false if template includes title
issue_format = "format string for {issue} (issue is the first part of fragment name)"
underlines = "=-~"
wrap = false # Wrap text to 79 characters
all_bullets = true # make all fragments bullet points
orphan_prefix = "+" # Prefix for orphan news fragment files, set to "" to disable.
If ``single_file`` is set to ``true`` or unspecified, all changes will be written to a single fixed newsfile, whose name is literally fixed as the ``filename`` option.
In each run of ``towncrier build``, content of new changes will append at the top of old content, and after ``start_string`` if the ``start_string`` already appears in the newsfile.
If the corresponding ``top_line``, which is formatted as the option 'title_format', already exists in newsfile, ``ValueError`` will be raised to remind you "already produced newsfiles for this version".

If ``single_file`` is set to ``false`` instead, each versioned ``towncrier build`` will generate a separate newsfile, whose name is formatted as the pattern given by option ``filename``.
For example, if ``filename="{version}-notes.rst"``, then the release note with version "7.8.9" will be written to the file "7.8.9-notes.rst".
If the newsfile already exists, its content will be overwritten with new release note, without throwing a ``ValueError`` warning.

If ``title_format`` is unspecified or an empty string, the default format will be used.
If set to ``false``, no title will be created.
This can be useful if the specified template creates the title itself.
35 changes: 24 additions & 11 deletions docs/customization/newsfile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,36 @@ Adding Content Above ``towncrier``
----------------------------------

If you wish to have content at the top of the news file (for example, to say where you can find the tickets), you can use a special rST comment to tell ``towncrier`` to only update after it.
In your existing news file (e.g. ``NEWS.rst``), add the following line above where you want ``towncrier`` to put content::
In your existing news file (e.g. ``NEWS.rst``), add the following line above where you want ``towncrier`` to put content:

.. towncrier release notes start
.. code-block:: restructuredtext
In an existing news file, it'll look something like this::
.. towncrier release notes start
This is the changelog of my project. You can find the
issue tracker at http://blah.
In an existing news file, it'll look something like this:

.. towncrier release notes start
.. code-block:: restructuredtext
myproject 1.0.2 (2018-01-01)
============================
This is the changelog of my project. You can find the
issue tracker at http://blah.
Bugfixes
--------
.. towncrier release notes start
- Fixed, etc...
myproject 1.0.2 (2018-01-01)
============================
Bugfixes
--------
- Fixed, etc...
``towncrier`` will not alter content above the comment.

Markdown
~~~~~~~~

If your news file is in Markdown (e.g. ``NEWS.md``), use the following comment instead:

.. code-block:: html

<!-- towncrier release notes start -->
6 changes: 5 additions & 1 deletion docs/tutorial.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Tutorial
========

This tutorial assumes you have a Python project with a *reStructuredText* (rst) news file (also known as changelog) file that you wish to use ``towncrier`` on, to generate its news file.
This tutorial assumes you have a Python project with a *reStructuredText* (rst) or *Markdown* (md) news file (also known as changelog) that you wish to use ``towncrier`` on, to generate its news file.
It will cover setting up your project with a basic configuration, which you can then feel free to `customize <customization/index.html>`_.

Install from PyPI::
Expand Down Expand Up @@ -144,6 +144,8 @@ You should get an output similar to this::

- #1, #2

Note: if you configure a Markdown file (for example, ``filename = "CHANGES.md"``) in your configuration file, the titles will be output in Markdown format instead.


Producing News Files In Production
----------------------------------
Expand All @@ -161,6 +163,8 @@ If you wish to have content at the top of the news file (for example, to say whe

``towncrier`` will then put the version notes after this comment, and leave your existing content that was above it where it is.

Note: if you configure a Markdown file (for example, ``filename = "CHANGES.md"``) in your configuration file, the comment should be ``<!-- towncrier release notes start -->`` instead.


Finale
------
Expand Down
Loading

0 comments on commit 4493cce

Please sign in to comment.