jaraco / skeleton

A generic project skeleton for Python projects.
http://blog.jaraco.com/skeleton/
MIT License
123 stars 36 forks source link

Move project metadata to `pyproject.toml` #122

Closed bswck closed 7 months ago

bswck commented 7 months ago

Closes jaraco/skeleton#121.

bswck commented 7 months ago

How do you imagine mass-scale migration in downstream projects?

jaraco commented 7 months ago

How do you imagine mass-scale migration in downstream projects?

Great question. First, I should probably sync all projects with skeleton prior to merging this change. Then, I'll want to make sure the automatic merge conflict resolution takes into account pyproject.toml (where it currently expects setup.cfg). That won't help with populating placeholders for this change, though, because pyproject.toml won't conflict, so I'll also want a routine to populate the placeholders. Still, that won't be enough to cause any customizations in setup.cfg to make it to pyproject.toml. Probably what we need if we want to help mechanize that process is a tool to convert the setup.cfg to pyproject.toml first in each project. Then at least we can use conflict resolution tools to facilitate the resolution.

I found at least two tools that promise to do the job:

jaraco commented 7 months ago

Looks like ini2toml[full] does a pretty good job:

 tempora main @ pip-run 'ini2toml[full]' -- -m ini2toml setup.cfg
DEPRECATION: Loading egg at /opt/homebrew/Cellar/tbb/2021.12.0/lib/python3.12/site-packages/TBB-0.2-py3.12-macosx-14.0-arm64.egg is deprecated. pip 24.3 will enforce this behaviour change. A possible replacement is to use pip for package installation.. Discussion can be found at https://github.com/pypa/pip/issues/12330
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
openvino 2024.0.0 requires openvino-telemetry>=2023.2.1, which is not installed.
[build-system]
requires = ["setuptools>=61.2"]
build-backend = "setuptools.build_meta"

[project]
name = "tempora"
authors = [{name = "Jason R. Coombs", email = "jaraco@jaraco.com"}]
description = "Objects and routines pertaining to date and time (tempora)"
readme = "README.rst"
classifiers = [
    "Development Status :: 5 - Production/Stable",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: MIT License",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3 :: Only",
]
urls = {Homepage = "https://github.com/jaraco/tempora"}
requires-python = ">=3.8"
dependencies = [
    "pytz",
    "jaraco.functools>=1.20",
]
dynamic = ["version"]

[project.optional-dependencies]
testing = [
    # upstream
    "pytest >= 6, != 8.1.*",
    "pytest-checkdocs >= 2.4",
    "pytest-cov",
    "pytest-mypy",
    "pytest-enabler >= 2.2",
    "pytest-ruff >= 0.2.1",
    # local
    "pytest-freezer",
    "types-pytz",
]
docs = [
    # upstream
    "sphinx >= 3.5",
    "jaraco.packaging >= 9.3",
    "rst.linker >= 1.9",
    "furo",
    "sphinx-lint",
    # tidelift
    "jaraco.tidelift >= 1.4",
    # local
]

[project.scripts]
calc-prorate = "tempora:calculate_prorated_values"

[tool.setuptools]
include-package-data = true
bswck commented 7 months ago

Looks like ini2toml[full] does a pretty good job:

```toml tempora main @ pip-run 'ini2toml[full]' -- -m ini2toml setup.cfg DEPRECATION: Loading egg at /opt/homebrew/Cellar/tbb/2021.12.0/lib/python3.12/site-packages/TBB-0.2-py3.12-macosx-14.0-arm64.egg is deprecated. pip 24.3 will enforce this behaviour change. A possible replacement is to use pip for package installation.. Discussion can be found at https://github.com/pypa/pip/issues/12330 ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. openvino 2024.0.0 requires openvino-telemetry>=2023.2.1, which is not installed. [build-system] requires = ["setuptools>=61.2"] build-backend = "setuptools.build_meta" [project] name = "tempora" authors = [{name = "Jason R. Coombs", email = "jaraco@jaraco.com"}] description = "Objects and routines pertaining to date and time (tempora)" readme = "README.rst" classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", ] urls = {Homepage = "https://github.com/jaraco/tempora"} requires-python = ">=3.8" dependencies = [ "pytz", "jaraco.functools>=1.20", ] dynamic = ["version"] [project.optional-dependencies] testing = [ # upstream "pytest >= 6, != 8.1.*", "pytest-checkdocs >= 2.4", "pytest-cov", "pytest-mypy", "pytest-enabler >= 2.2", "pytest-ruff >= 0.2.1", # local "pytest-freezer", "types-pytz", ] docs = [ # upstream "sphinx >= 3.5", "jaraco.packaging >= 9.3", "rst.linker >= 1.9", "furo", "sphinx-lint", # tidelift "jaraco.tidelift >= 1.4", # local ] [project.scripts] calc-prorate = "tempora:calculate_prorated_values" [tool.setuptools] include-package-data = true ```

Looks promising. There are 2 incompatibilities that could potentially cause a mess, I think. First, I would apply this fix:

-authors = [{name = "Jason R. Coombs", email = "jaraco@jaraco.com"}]
+authors = [
+    { name = "Jason R. Coombs", email = "jaraco@jaraco.com" },
+]

to facilitate merging the skeleton.

Another fix would be:

-urls = {Homepage = "https://github.com/jaraco/tempora"}
+[project.urls]
+Homepage = "https://github.com/jaraco/tempora"

so, again, it is easier to merge the skeleton when additional URLs are added in a downstream project.

bswck commented 7 months ago

First, I should probably sync all projects with skeleton prior to merging this change. Then, I'll want to make sure the automatic merge conflict resolution takes into account pyproject.toml (where it currently expects setup.cfg). That won't help with populating placeholders for this change, though, because pyproject.toml won't conflict, so I'll also want a routine to populate the placeholders. Still, that won't be enough to cause any customizations in setup.cfg to make it to pyproject.toml. Probably what we need if we want to help mechanize that process is a tool to convert the setup.cfg to pyproject.toml first in each project. Then at least we can use conflict resolution tools to facilitate the resolution.

I found at least two tools that promise to do the job:

Sounds like a great plan. If neither of these tools do things fully as we need technically (they are very specific and have to do with whitespaces and final TOML tokens), I suggest adding an extra routine in jaraco.develop that first invokes ini2toml/pyproject-migrator and later applies some tweaks programmatically to be compatible with skeleton's pyproject.toml format. As for now, I'm thinking that tomlkit would be the best tool we could use for round-trip TOML "post-processing".

jaraco commented 7 months ago

There are 2 incompatibilities that could potentially cause a mess, I think.

I'm thinking rather than address these proactively, maybe just let the conflicts occur (between the generated form and the skeleton) and then use skeleton "known merge" features to reconcile. I'll try that concept and see how it goes.

Well, I tried it on tempora, and I can see it's going to be more complicated than known merges, mostly due to ordering differences.

image

I hadn't fully grasped that project.urls was being defined in two different scopes (as a value of project or in its own section). Now I agree, the conversion should make some of these tweaks early.

jaraco commented 7 months ago

Looking good:

image

I'm a little annoyed that an exact match on authors still gets included in the conflict, but c'est la vie.

jaraco commented 7 months ago

Diff for tempora is perfect now. Close enough that I may not even bother developing a mechanical merge resolution and may just push through with --strategy ours. I'll spot check a few more repos.

image

bswck commented 7 months ago

Let's go, let's go! 🚀