diff --git a/docs/cli.rst b/docs/cli.rst index bc412b45..478a88b9 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -81,6 +81,13 @@ If the fragments directory does not exist, it will be created. If the filename exists already, ``towncrier create`` will add (and then increment) a number after the fragment type until it finds a filename that does not exist yet. In the above example, it will generate ``123.bugfix.1.rst`` if ``123.bugfix.rst`` already exists. +To create a news fragment not tied to a specific issue (which towncrier calls an "orphan fragment"), start the fragment name with a ``+``. +If that is the entire fragment name, a random hash will be added for you:: + + $ towncrier create +.feature.rst + $ ls newsfragments/ + +fcc4dc7b.feature.rst + .. option:: --content, -c CONTENT A string to use for content. diff --git a/docs/tutorial.rst b/docs/tutorial.rst index 875ed1f3..75f99cf0 100644 --- a/docs/tutorial.rst +++ b/docs/tutorial.rst @@ -15,10 +15,13 @@ Configuration ``towncrier`` keeps its config in the `PEP-518 `_ ``pyproject.toml`` or a ``towncrier.toml`` file. If the latter exists, it takes precedence. -The most basic configuration is just telling ``towncrier`` where to look for news fragments:: +The most basic configuration is just telling ``towncrier`` where to look for news fragments and what file to generate:: [tool.towncrier] directory = "changes" + # Where you want your news files to come out, `NEWS.rst` is the default. + # This can be .rst or .md, towncrier's default template works with both. + # filename = "NEWS.rst" Which will look into "./changes" for news fragments and write them into "./NEWS.rst". @@ -32,9 +35,6 @@ If you're working on a Python project, you can also specify a package:: # but if you don't keep your code in a 'src' dir, remove the # config option package_dir = "src" - # Where you want your news files to come out. This can be .rst - # or .md, towncrier's default template works with both. - filename = "NEWS.rst" By default, ``towncrier`` will look for news fragments inside your Python package, in a directory named ``newsfragments``. With this example project, it will look in ``src/myproject/newsfragments/`` for them. diff --git a/noxfile.py b/noxfile.py index d3e7d025..e7a4bafe 100644 --- a/noxfile.py +++ b/noxfile.py @@ -20,6 +20,7 @@ def pre_commit(session: nox.Session) -> None: # Keep list in-sync with ci.yml/test-linux & pyproject.toml @nox.session(python=["pypy3.8", "3.8", "3.9", "3.10", "3.11", "3.12"]) def tests(session: nox.Session) -> None: + session.env["PYTHONWARNDEFAULTENCODING"] = "1" session.install("Twisted", "coverage[toml]") posargs = list(session.posargs) diff --git a/src/towncrier/_builder.py b/src/towncrier/_builder.py index 3d863548..a72a3982 100644 --- a/src/towncrier/_builder.py +++ b/src/towncrier/_builder.py @@ -13,15 +13,6 @@ from jinja2 import Template -def strip_if_integer_string(s: str) -> str: - try: - i = int(s) - except ValueError: - return s - - return str(i) - - # Returns ticket, category and counter or (None, None, None) if the basename # could not be parsed or doesn't contain a valid category. def parse_newfragment_basename( @@ -45,7 +36,11 @@ def parse_newfragment_basename( # NOTE: This allows news fragment names like fix-1.2.3.feature or # something-cool.feature.ext for projects that don't use ticket # numbers in news fragment names. - ticket = strip_if_integer_string(".".join(parts[0:i])) + ticket = ".".join(parts[0:i]).strip() + # If the ticket is an integer, remove any leading zeros (to resolve + # issue #126). + if ticket.isdigit(): + ticket = str(int(ticket)) counter = 0 # Use the following part as the counter if it exists and is a valid # digit. diff --git a/src/towncrier/create.py b/src/towncrier/create.py index 549da6a8..362b2ba9 100644 --- a/src/towncrier/create.py +++ b/src/towncrier/create.py @@ -69,6 +69,9 @@ def _main( * .doc - a documentation improvement, * .removal - a deprecation or removal of public API, * .misc - a ticket has been closed, but it is not of interest to users. + + If the FILENAME base is just '+' (to create a fragment not tied to an + issue), it will be appended with a random hex string. """ __main(ctx, directory, config, filename, edit, content) diff --git a/src/towncrier/newsfragments/561.misc.rst b/src/towncrier/newsfragments/561.misc.rst new file mode 100644 index 00000000..bdb991a5 --- /dev/null +++ b/src/towncrier/newsfragments/561.misc.rst @@ -0,0 +1 @@ +Enable reporting of EncodingWarnings when running tests. diff --git a/src/towncrier/newsfragments/586.doc b/src/towncrier/newsfragments/586.doc new file mode 100644 index 00000000..cbaf3461 --- /dev/null +++ b/src/towncrier/newsfragments/586.doc @@ -0,0 +1 @@ +The tutorial now introduces the `filename` option in the appropriate paragraph and mentions its default value. diff --git a/src/towncrier/newsfragments/588.bugfix b/src/towncrier/newsfragments/588.bugfix new file mode 100644 index 00000000..f1c3e8ef --- /dev/null +++ b/src/towncrier/newsfragments/588.bugfix @@ -0,0 +1 @@ +Orphan news fragments, fragments not associated with an issue, consisting of only digits (e.g. '+12345678.feature') now retain their leading marker character. diff --git a/src/towncrier/newsfragments/589.doc b/src/towncrier/newsfragments/589.doc new file mode 100644 index 00000000..3664626f --- /dev/null +++ b/src/towncrier/newsfragments/589.doc @@ -0,0 +1 @@ +Add docs to explain how ``towncrier create +.feature.rst`` (orphan fragments) works. diff --git a/src/towncrier/test/test_builder.py b/src/towncrier/test/test_builder.py index b62033ac..9608e0a2 100644 --- a/src/towncrier/test/test_builder.py +++ b/src/towncrier/test/test_builder.py @@ -125,3 +125,10 @@ def test_orphan_with_dotted_number(self): parse_newfragment_basename("+orphan_12.3.feature", ["feature"]), ("+orphan_12.3", "feature", 0), ) + + def test_orphan_all_digits(self): + """Orphaned snippets can consist of only digits.""" + self.assertEqual( + parse_newfragment_basename("+123.feature", ["feature"]), + ("+123", "feature", 0), + )