Repository: twisted/towncrier

Issue:
Ability to use towncrier in non-python project
At the moment it's not possible, due to the fact, that towncrier tries to detect version if not passed in command line.

I'll create a pull request in a minute with ability to pass both project_name and project_version through config files, allowing the config based version to be maintaned by the tools like bumpversion as well, and just use the standard set of commands without the need to pass arbitrary arguments in command line.

Discussion:
fizyk: Also, I'd gladly squash commits and rework commit message if that'd be something you want.
altendky: My personal preference is to never change public history, so no need to go squashing etc for my sake.
altendky: @fizyk looks like you lost most of the changes in the readme.  https://github.com/twisted/towncrier/pull/166/commits/215a80aabf30f3cb4585546f5c343ca9368fb14a
fizyk: > @fizyk looks like you lost most of the changes in the readme. [215a80a](https://github.com/twisted/towncrier/commit/215a80aabf30f3cb4585546f5c343ca9368fb14a)

🤦🏻‍♂️ fixed it
altendky: @fizyk, sorry for the delay here.  Looks good to me.  I've got the CI fixed up properly now so I'm going to go ahead and update the branch here from master.  Hopefully that'll just work and I'll merge this but I wanted to give you a heads up so you don't go trying to push new work without pulling and get a surprise.

Patch:
diff --git a/.gitignore b/.gitignore
index 45ecce4..0bf4874 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,4 +21,5 @@ apidocs/
 .tox/
 .coverage.*
 .vscode
+.idea
 .python-version
\ No newline at end of file
diff --git a/README.rst b/README.rst
index 9cf5013..a424a8e 100644
--- a/README.rst
+++ b/README.rst
@@ -32,7 +32,7 @@ Install from PyPI::
 .. note::
 
    ``towncrier``, as a command line tool, works on Python 3.5+ only.
-   It is usable by projects written in other languages, provided you give it the version of the project when invoking it.
+   It is usable by projects written in other languages, provided you specify the project version either in the configuration file or on the command line.
    For Python 2/3 compatible projects, the version can be discovered automatically.
 
 In your project root, add a ``pyproject.toml`` file.
@@ -64,13 +64,21 @@ Using the above example, your news fragments would be ``src/myproject/newsfragme
 
     This will keep the folder around, but otherwise "empty".
 
-``towncrier`` needs to know what version your project is, and there are two ways you can give it:
+``towncrier`` needs to know what version your project is, and there are three ways you can give it:
 
 - For Python 2/3 compatible projects, a ``__version__`` in the top level package.
   This can be either a string literal, a tuple, or an `Incremental <https://github.com/hawkowl/incremental>`_ version.
 
 - Manually passing ``--version=<myversionhere>`` when interacting with ``towncrier``.
 
+- Definining a ``version`` option in a configuration file:
+
+.. code-block:: ini
+
+    [tool.towncrier]
+    # ...
+    version = "1.2.3"  # project version if maintained separately
+
 To create a new news fragment, use the ``towncrier create`` command.
 For example::
 
@@ -123,6 +131,8 @@ Towncrier has the following global options, which can be specified in the toml f
     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_line = "start of generated content"
     title_format = "{name} {version} ({project_date})"  # or false if template includes title
diff --git a/src/towncrier/_settings.py b/src/towncrier/_settings.py
index 57ab2d3..f84dcb9 100644
--- a/src/towncrier/_settings.py
+++ b/src/towncrier/_settings.py
@@ -144,6 +144,8 @@ def parse_toml(base_path, config):
         "single_file": single_file,
         "filename": config.get("filename", "NEWS.rst"),
         "directory": config.get("directory"),
+        "version": config.get("version"),
+        "name": config.get("name"),
         "sections": sections,
         "types": types,
         "template": template,
diff --git a/src/towncrier/build.py b/src/towncrier/build.py
index d1f87b8..2824598 100644
--- a/src/towncrier/build.py
+++ b/src/towncrier/build.py
@@ -119,20 +119,24 @@ def __main(
     )
 
     if project_version is None:
-        project_version = get_version(
-            os.path.join(base_directory, config["package_dir"]), config["package"]
-        ).strip()
+        project_version = config.get('version')
+        if project_version is None:
+            project_version = get_version(
+                os.path.join(base_directory, config["package_dir"]), config["package"]
+            ).strip()
 
     if project_name is None:
-        package = config.get("package")
-        if package:
-            project_name = get_project_name(
-                os.path.abspath(os.path.join(base_directory, config["package_dir"])),
-                package,
-            )
-        else:
-            # Can't determine a project_name, but maybe it is not needed.
-            project_name = ""
+        project_name = config.get('name')
+        if not project_name:
+            package = config.get("package")
+            if package:
+                project_name = get_project_name(
+                    os.path.abspath(os.path.join(base_directory, config["package_dir"])),
+                    package,
+                )
+            else:
+                # Can't determine a project_name, but maybe it is not needed.
+                project_name = ""
 
     if project_date is None:
         project_date = _get_date().strip()
diff --git a/src/towncrier/newsfragments/165.feature.rst b/src/towncrier/newsfragments/165.feature.rst
new file mode 100644
index 0000000..3a8deb6
--- /dev/null
+++ b/src/towncrier/newsfragments/165.feature.rst
@@ -0,0 +1,2 @@
+Allow definition of the project ``version`` and ``name`` in the configuration file.
+This allows use of towncrier seamlessly with non-Python projects.


Test patch:
diff --git a/src/towncrier/test/test_build.py b/src/towncrier/test/test_build.py
index bee1ca1..3e59445 100644
--- a/src/towncrier/test/test_build.py
+++ b/src/towncrier/test/test_build.py
@@ -343,6 +343,90 @@ class TestCli(TestCase):
             ).lstrip(),
         )
 
+    def test_version_in_config(self):
+        """The calling towncrier with version defined in configfile.
+
+        Specifying a version in toml file will be helpful if version
+        is maintained by i.e. bumpversion and it's not a python project.
+        """
+        runner = CliRunner()
+
+        with runner.isolated_filesystem():
+            with open("pyproject.toml", "w") as f:
+                f.write("[tool.towncrier]\n" 'version = "7.8.9"\n')
+            os.mkdir("newsfragments")
+            with open("newsfragments/123.feature", "w") as f:
+                f.write("Adds levitation")
+
+            result = runner.invoke(
+                _main, ["--date", "01-01-2001", "--draft"]
+            )
+
+        self.assertEqual(0, result.exit_code, result.output)
+        self.assertEqual(
+            result.output,
+            dedent(
+                """
+            Loading template...
+            Finding news fragments...
+            Rendering news fragments...
+            Draft only -- nothing has been written.
+            What is seen below is what would be written.
+
+            7.8.9 (01-01-2001)
+            ==================
+
+            Features
+            --------
+
+            - Adds levitation (#123)
+
+            """
+            ).lstrip(),
+        )
+
+    def test_project_name_in_config(self):
+        """The calling towncrier with project name defined in configfile.
+
+        Specifying a project name in toml file will be helpful to keep the
+        project name consistent as part of the towncrier configuration, not call.
+        """
+        runner = CliRunner()
+
+        with runner.isolated_filesystem():
+            with open("pyproject.toml", "w") as f:
+                f.write("[tool.towncrier]\n" 'name = "ImGoProject"\n')
+            os.mkdir("newsfragments")
+            with open("newsfragments/123.feature", "w") as f:
+                f.write("Adds levitation")
+
+            result = runner.invoke(
+                _main, ["--version", "7.8.9", "--date", "01-01-2001", "--draft"]
+            )
+
+        self.assertEqual(0, result.exit_code, result.output)
+        self.assertEqual(
+            result.output,
+            dedent(
+                """
+            Loading template...
+            Finding news fragments...
+            Rendering news fragments...
+            Draft only -- nothing has been written.
+            What is seen below is what would be written.
+
+            ImGoProject 7.8.9 (01-01-2001)
+            ==============================
+
+            Features
+            --------
+
+            - Adds levitation (#123)
+
+            """
+            ).lstrip(),
+        )
+
     def test_no_package_changelog(self):
         """The calling towncrier with any package argument.