From 879da3615d52e628c759124cc167b9267c699868 Mon Sep 17 00:00:00 2001
From: Adi Roiban <adi.roiban@chevah.com>
Date: Sat, 16 Jul 2022 16:05:51 +0100
Subject: [PATCH 1/2] Initial removal of incremental internal usage.

---
 setup.cfg                               |  2 ++
 setup.py                                | 13 ++++---------
 src/towncrier/__init__.py               |  3 +--
 src/towncrier/_project.py               | 11 ++++++++---
 src/towncrier/_shell.py                 |  5 +++--
 src/towncrier/_version.py               | 12 ------------
 src/towncrier/newsfragments/308.removal |  4 ++++
 7 files changed, 22 insertions(+), 28 deletions(-)
 create mode 100644 setup.cfg
 delete mode 100644 src/towncrier/_version.py
 create mode 100644 src/towncrier/newsfragments/308.removal

diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 00000000..a520f005
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,2 @@
+[metadata]
+version = attr: towncrier.__version__
diff --git a/setup.py b/setup.py
index cdaf2ed3..3a3f3eb5 100644
--- a/setup.py
+++ b/setup.py
@@ -1,10 +1,4 @@
 #!/usr/bin/env python
-
-
-# If incremental is not present then setuptools just silently uses v0.0.0 so
-# let's import it and fail instead.
-import incremental  # noqa
-
 from setuptools import find_packages, setup
 
 
@@ -36,17 +30,18 @@
         "Programming Language :: Python :: Implementation :: CPython",
         "Programming Language :: Python :: Implementation :: PyPy",
     ],
-    use_incremental=True,
     python_requires=">=3.7",
     install_requires=[
         "click",
         "click-default-group",
-        "incremental",
         "jinja2",
         "setuptools",
         "tomli",
     ],
-    extras_require={"dev": ["packaging"]},
+    extras_require={
+        "dev": ["packaging"],
+        "incremental": ["incremental"],
+    },
     package_dir={"": "src"},
     packages=find_packages("src"),
     license="MIT",
diff --git a/src/towncrier/__init__.py b/src/towncrier/__init__.py
index ba09c39a..ef72282f 100644
--- a/src/towncrier/__init__.py
+++ b/src/towncrier/__init__.py
@@ -5,7 +5,6 @@
 towncrier, a builder for your news files.
 """
 
-from ._version import __version__
-
+__version__ = "21.9.1.dev0"
 
 __all__ = ["__version__"]
diff --git a/src/towncrier/_project.py b/src/towncrier/_project.py
index c5e4676f..ced4c619 100644
--- a/src/towncrier/_project.py
+++ b/src/towncrier/_project.py
@@ -10,7 +10,12 @@
 
 from importlib import import_module
 
-from incremental import Version
+
+# Incremental is a soft dependency.
+try:
+    from incremental import Version as IncrementalVersion
+except ImportError:
+    IncrementalVersion = None
 
 
 def _get_package(package_dir, package):
@@ -47,7 +52,7 @@ def get_version(package_dir, package):
     if isinstance(version, str):
         return version.strip()
 
-    if isinstance(version, Version):
+    if IncrementalVersion and isinstance(version, IncrementalVersion):
         return version.base().strip()
 
     if isinstance(version, tuple):
@@ -73,6 +78,6 @@ def get_project_name(package_dir, package):
     if isinstance(version, str):
         return package.title()
 
-    if isinstance(version, Version):
+    if IncrementalVersion and isinstance(version, IncrementalVersion):
         # Incremental has support for package names
         return version.package
diff --git a/src/towncrier/_shell.py b/src/towncrier/_shell.py
index f550003f..ff18055e 100644
--- a/src/towncrier/_shell.py
+++ b/src/towncrier/_shell.py
@@ -9,14 +9,15 @@
 
 from click_default_group import DefaultGroup
 
-from ._version import __version__
+from towncrier import __version__
+
 from .build import _main as _build_cmd
 from .check import _main as _check_cmd
 from .create import _main as _create_cmd
 
 
 @click.group(cls=DefaultGroup, default="build", default_if_no_args=True)
-@click.version_option(__version__.public())
+@click.version_option(__version__)
 def cli():
     pass
 
diff --git a/src/towncrier/_version.py b/src/towncrier/_version.py
deleted file mode 100644
index 11115e27..00000000
--- a/src/towncrier/_version.py
+++ /dev/null
@@ -1,12 +0,0 @@
-"""
-Provides towncrier version information.
-"""
-
-# This file is auto-generated! Do not edit!
-# Use `python -m incremental.update towncrier` to change this file.
-
-from incremental import Version
-
-
-__version__ = Version("towncrier", 21, 9, 1, dev=0)
-__all__ = ["__version__"]
diff --git a/src/towncrier/newsfragments/308.removal b/src/towncrier/newsfragments/308.removal
new file mode 100644
index 00000000..7962767d
--- /dev/null
+++ b/src/towncrier/newsfragments/308.removal
@@ -0,0 +1,4 @@
+Towncrier no longer used `incremental` to manage its version.
+Extracting the target project name and version from an `incremental Version`
+instance is still supported.
+You will need to intall the `incremental` extra dependency.

From 0cfca981ed47004152cd0c553e810890d98ca1ea Mon Sep 17 00:00:00 2001
From: Adi Roiban <adi.roiban@chevah.com>
Date: Sat, 16 Jul 2022 16:23:36 +0100
Subject: [PATCH 2/2] Add test for top level cli version.

---
 src/towncrier/_shell.py          |  8 ++++----
 src/towncrier/test/test_shell.py | 23 +++++++++++++++++++++++
 2 files changed, 27 insertions(+), 4 deletions(-)
 create mode 100644 src/towncrier/test/test_shell.py

diff --git a/src/towncrier/_shell.py b/src/towncrier/_shell.py
index ff18055e..f844801e 100644
--- a/src/towncrier/_shell.py
+++ b/src/towncrier/_shell.py
@@ -18,10 +18,10 @@
 
 @click.group(cls=DefaultGroup, default="build", default_if_no_args=True)
 @click.version_option(__version__)
-def cli():
+def towncrier():
     pass
 
 
-cli.add_command(_build_cmd)
-cli.add_command(_check_cmd)
-cli.add_command(_create_cmd)
+towncrier.add_command(_build_cmd)
+towncrier.add_command(_check_cmd)
+towncrier.add_command(_create_cmd)
diff --git a/src/towncrier/test/test_shell.py b/src/towncrier/test/test_shell.py
new file mode 100644
index 00000000..f0798c57
--- /dev/null
+++ b/src/towncrier/test/test_shell.py
@@ -0,0 +1,23 @@
+#
+# Tests for the high-level CLI command.
+# Sub-commands are tested via separate test files.
+#
+from click.testing import CliRunner
+from twisted.trial.unittest import TestCase
+
+from towncrier import __version__
+from towncrier._shell import towncrier
+
+
+class TestCli(TestCase):
+    def test_version(self):
+        """
+        The top level `--version` arguments returns towncrier own version.
+        """
+
+        runner = CliRunner()
+
+        result = runner.invoke(towncrier, ["--version"])
+
+        self.assertEqual(0, result.exit_code)
+        self.assertEqual(result.output.strip(), f"towncrier, version {__version__}")