diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b8a2fc..134a8cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Python now generates a `run` command and cli entry point for clients and services. + +### Changed +- Python now uses `pyproject` instead of `setuptools` by default. Template for targetSetup + has been updated accordingly. It also conforms to `ruff`s checks and formatting by default. + ### Fixed - Python's config merger now handles mypy overrides targeting multiple packages. diff --git a/python/component-template/@mainPackage@/main.py b/python/component-template/@mainPackage@/main.py index e16297c..265ed8b 100644 --- a/python/component-template/@mainPackage@/main.py +++ b/python/component-template/@mainPackage@/main.py @@ -1,6 +1,6 @@ -""" @desc@ """ +"""@desc@""" def main() -> None: - """ main function of @mainPackage@ """ + """Main function of @mainPackage@.""" raise NotImplementedError diff --git a/python/component-template/pyproject.toml b/python/component-template/pyproject.toml new file mode 100644 index 0000000..b66c1a5 --- /dev/null +++ b/python/component-template/pyproject.toml @@ -0,0 +1,18 @@ +[build-system] +requires = ["setuptools"] + +[project] +name = "@pname@" +version = "@version@" +description = "@desc@" +authors = [{name = "@author@", email = "@email@"}] + +[setuptools.packages.find] +exclude = ["tests*"] + +[urls] +Homepage = "@url@" + +[project.scripts] +@entryPoint@ + diff --git a/python/component-template/setup.py b/python/component-template/setup.py deleted file mode 100644 index 6b06b41..0000000 --- a/python/component-template/setup.py +++ /dev/null @@ -1,13 +0,0 @@ -""" Package setup for the component @pname@ """ -from setuptools import find_packages, setup - -setup( - name="@pname@", - version="@version@", - url="@url@", - author="@author@", - author_email="@email@", - description="@desc@", - packages=find_packages(exclude=["tests"]), - entry_points=@entryPoint@, -) diff --git a/python/component-template/tests/test_main.py b/python/component-template/tests/test_main.py index eaf4487..a8e4964 100644 --- a/python/component-template/tests/test_main.py +++ b/python/component-template/tests/test_main.py @@ -1,6 +1,7 @@ -""" Tests for @mainPackage@ in @pname@ """ +"""Tests for @mainPackage@ in @pname@.""" import @mainPackage@.main + def test_main() -> None: - """ Tests for the main function """ + """Tests for the main function.""" @mainPackage@.main.main() diff --git a/python/main.py.in b/python/main.py.in new file mode 100644 index 0000000..76c13b7 --- /dev/null +++ b/python/main.py.in @@ -0,0 +1,3 @@ + +if __name__ == "__main__": + main() diff --git a/python/package.nix b/python/package.nix index 8de66f6..7c08a23 100644 --- a/python/package.nix +++ b/python/package.nix @@ -71,7 +71,7 @@ let inherit version; pname = name; mainPackage = lib.toLower (builtins.replaceStrings [ "-" " " ] [ "_" "_" ] name); - entryPoint = if setuptoolsLibrary then "{}" else "{\\\"console_scripts\\\": [\\\"${name}=${mainPackage}.main:main\\\"]}"; + entryPoint = if setuptoolsLibrary then "" else "${name}=\\\"${mainPackage}.main:main\\\""; } // args.targetSetup.variables or { }; variableQueries = { desc = "✍️ Write a short description for your component:"; @@ -79,13 +79,18 @@ let email = "📧 Enter author email:"; url = "🏄 Enter author website url:"; } // args.targetSetup.variableQueries or { }; - initCommands = "black ."; + initCommands = '' + ${if ! setuptoolsLibrary then "cat ${./main.py.in} >>$mainPackage/main.py" else ""} + ruff format . + ruff check --fix --unsafe-fixes . + ''; }); pythonPackageArgs = attrs // { inherit version preBuild doStandardTests pythonVersion propagatedBuildInputs; src = if lib.isStorePath src then src else filteredSrc; pname = name; + format = attrs.format or "pyproject"; # Don't install dependencies with pip, let nix handle that preInstall = '' @@ -170,7 +175,16 @@ let Show the config Nedryland has generated for a linter, one of: black, coverage, flake8, isort, mypy, pylint, pytest''; }; - } // attrs.shellCommands or { }); + } // ( + lib.optionalAttrs + (! setuptoolsLibrary) + { + run = { + script = ''python -m ${name}.main "$@"''; + description = "Run the main module."; + }; + }) + // attrs.shellCommands or { }); }; in pythonPkgs.buildPythonPackage pythonPackageArgs