-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modernize project infrastructure and switching to hatch #108
Conversation
Maybe one of the reviewer knows a fix for the sphinx build error
It is even more annoying than regular sphinx errors as it vanishes with the second run :) |
@@ -1,39 +1,8 @@ | |||
# Install pre-commit hooks via: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of you are not going to use pre-commit properly, then just remove it entirely
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some people (less on the developer side) are quite annoyed by the formatting as they always forget to apply it and then it makes the CI fail, so I included it in case people still want formatting to happen automatically. The formatting should be fast enough so it does effect commit speed. Also some people might be still used to manually run pre-commit for formatting, so these people can also keep using it.
line-length = 120 | ||
|
||
[tool.ruff.format] | ||
quote-style = 'single' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, this requires justification. It is an odd change to a perfectly sane default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only copied the config from aiida-core. I don't have any opinions on this. I removed it now, since the repo was differently structured and it creates a lot of noise in the changes.
source = ["src/{{cookiecutter.module_name}}"] | ||
|
||
[tool.ruff] | ||
line-length = 120 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference, this replaces the following previous configuration:
[tool.pylint.format]
max-line-length = 125
# ...
[tool.isort]
# Configuration of [isort](https://isort.readthedocs.io)
line_length = 120
# ...
It seems odd that there should have been two different values. I don't see that it makes a difference which of the two we pick going forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All configs are copied from aiida-core, no opinion. The parts I changed with intention, I mentioned in my first PR message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aiida-core's one is a legacy, just remove this and use the default (88)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems overall reasonable, just some details that need to be addressed.
- repo: local | ||
hooks: | ||
- id: pylint | ||
- id: fmt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see the reason for using the hatch
-provided isolated venv and hatch
version instead of letting pre-commit
maintain it's own.
However I can't quite see a reason not to run checks as well (hatch fmt --check
according to pyproject.toml
comments). Isn't the point of pre-commit that people like me, who would otherwise forget, don't have to manually run linting commands before commiting?
It might be even nicer to run the formatting and linting in separate passes (it would be visible at a glance which one got you). One hook for hatch fmt -f
and one hook for hatch fmt -l
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I now separated formatting and linting.
I think what you describe is already covered by pre-commit. hatch fmt
and hatch fmt --check
perform the same checks, the former just tries to fix also things. When the formatter changes the code, pre-commit will fail during the commit while already fixing the formatting (pre-commit fails once it detects a change after executing the commands). One can review the changes with git diff
and successfully commit them. pre-commit will fail if the fixes are not added as it stashes all unstaged files before running the hooks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had misread the hatch docs, my bad.
|
||
pre-commit: | ||
hatch: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hatch
is not very descriptive. pre-commit
clearly does formatting and linting. hatch
also does a lot of other things. I would suggest format-lint
or something along those lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the catch. I used static-analysis
in the other CI, because I wanted to optionally include mypy here in another PR (see #109), but I can also for now use format-lint
and when we decide on static type checking change the name. I can see that we move the static type checks in a different CI job. What you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think static-analysis
is better, because plugin developers will likely want to add all their static analysis here.
docs/.*| | ||
)$ | ||
entry: pylint | ||
types: [python] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would give plugin implementers an even better start to add general utilities here as well. Like the ones found in https://github.com/pre-commit/pre-commit-hooks. Markdown / yaml / toml formatters, trailing whitespace, endline fixers. Some of these are so basic (and run fast) there is no reason not to have them.
@@ -19,4 +19,4 @@ commands = | |||
cookiecutter --no-input . plugin_name={env:PLUGIN_NAME} | |||
git init -b main {env:PLUGIN_NAME} | |||
cd {env:PLUGIN_NAME} && git add -A | |||
pip install -e {env:PLUGIN_NAME}[testing,docs,pre-commit] | |||
pip install -e {env:PLUGIN_NAME} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there even still a reason for a tox.ini
, with hatch
in place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have integrated hatch only into the templated repo that did not have a tox.ini, but not in the cookiecutter template repo. We could replace the tox.ini
with a hatch.toml
and then also use hatch there, but since we want to only have a tool that runs scripts in isolated environments and not a repo management tool keeping tox as a tool seems more suitable to me. The tox.ini does need some work in general as it is not integrated in the CI which I did not want to do here, so I created an issue about it #110. I referenced your comment there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see.
update-aiida-diff.sh
Outdated
cd aiida-diff | ||
git init && git add -A | ||
pre-commit install | ||
pre-commit run | ||
hatch fmt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Old: runs linters, New: doesn't
hatch fmt | |
hatch fmt --check |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the script a little bit:
- I removed the
hatch fmt
, since it is anyway executed by the cookiecutter hook. We need to format, because once you replace the cookiecutter tokens, the formatting changes a bit, since the text is shorter or longer. - I removed the
git init
, since I want to update on top of the existing repo and not loose the whole history by reinitialization
Let me know if you agree.
I used it to make the update PR for aiida-diff aiidateam/aiida-diff#44 and it worked quite smoothly. Only the change in src structure I had to manually add.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine. Also, my original comment was wrong anyway.
line-length = 120 | ||
|
||
[tool.ruff.format] | ||
quote-style = 'single' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, this requires justification. It is an odd change to a perfectly sane default.
source = ["src/{{cookiecutter.module_name}}"] | ||
|
||
[tool.ruff] | ||
line-length = 120 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference, this replaces the following previous configuration:
[tool.pylint.format]
max-line-length = 125
# ...
[tool.isort]
# Configuration of [isort](https://isort.readthedocs.io)
line_length = 120
# ...
It seems odd that there should have been two different values. I don't see that it makes a difference which of the two we pick going forward.
Update project management to hatch fix linter maybe undo update .precommit file to do hatch fmt update post_gen_project hook apapt docs to src layout update further pyproject.toml update CI GitHub actions and usage to hatch Add CONTRIBUTING.md Contains explanations how to use the new project structure update pyproject.toml update ci update cookiecutter infrastructure update to unsafe-fixes to fix all issues update mypy settings should fix tests docs automatically update the repo with formatter options update cookiecutter ci update hook fix typo in ci update tox file fix typos in ci replace mypy in name in case we change in future move cd's one level before fix doc error use unique version that does conflict with building of package rm static type checker Revert "move cd's one level before" This reverts commit f6017c3. add ipdb class to adopts remove fragments of mypy add src to coverage add whitespaces move hatch version to hatch config section typo adopts --> addopts
- fix typos - fix unnecessary cd - change ci job name hatch -> static-analysis
- Remove `git init` in update aiida-diff script to base on current version - Remove `hatch fmt` at the end since it is done by hook properly
Having CI jobs run on PR and push without any further restrictions runs the CI jobs twice on a new PR, with this setting the CI is only run on pushes to main.
Now `hatch fmt` is executed twice, running it one time did not fix all isues. Needs to be investigated, if a reviewer has some ideas.
With fixing the formatting in the hook, we have to disable it, since we want to first init git before applying any formatting
Bug that appeears with aiida 2.6 (independent of this PR), it also goes away when building the docs twice. For now I ignore it.
It is nowhere used and I am not sure in which context it should be used. Installing aiida-core seems trivial. What would be useful is something for creating new profiles in the tests.
double quotes are default so nothing has to be changed
Because readthedocs can only use extra dependencies from the pyproject.toml, we move the deps of docs into one, so we can reference it in the readthedocs.yaml
I squashed the commits since the last review and tried to be quite verbose for new commits so it is easier for the reviewers to follow. |
Look this is fine, and I'm not really involved any more anyway, but ... I will see you back here in a year when you change this all again to use uv as the package manager 😏: https://astral.sh/blog/uv (rye is already better than hatch in many ways but a lacks a few things and will eventually be subsumed by uv astral-sh/rye#1164 (comment)) You can already think to activate uv in hatch: https://hatch.pypa.io/latest/how-to/environment/select-installer/#enabling-uv |
True we can make it at least an option when creating the repo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just this one typo.
Co-authored-by: Rico Haeuselmann <[email protected]>
With the modernization of the template I took the chance and switched to hatch which is the recommended tool by PyPA.
Project folder layout
Changed to project folder structure to src layout for import parity.
CONTRIBUTING.md
Added CONTRIBUTING.md that explains how the dev tools work. 90% of the functionalities are setting up the hatch inbuilt commands to work with our settings. Someone who is familiar with hatch does not need to know anything more about the internal project structure. This is different to tox for example where everyone has kind of the same environment names, but the still differ in naming and functionality enough that you need to re-adapt a bit. However, for most users hatch is a new tool, therefore I wrote down the most important commands so people can quickly adapt to the new tool.
Building system and publishing
The building system has been changed from flit to hatch. With hatch, building and publishing packages is also very easy. Please read the CONTRIBUTING.md how to build and publish. This is the only thing I have not yet tested myself locally.
Testing
Still using pytest. Updated Python version matrix to aiida-core one (Python 3.9 to 3.12). Updated dependencies to the same as in aiida-core. The only extension was to add ipdb as default debugger for autocompletion. Please read the CONTRIBUTING.md how to run tests.
Static code analysis (Formatting, linting, type checks)
I switched to ruff as formatter and linter as we use it in also aiida-core. Copied settings from aiida-core. Please read the CONTRIBUTING.md how to run these .
pre-commit now only runs
hatch-fmt
.Static type checker
mypy is run in a separate environment, since it needs project dependencies that the formatter and linter do not need. Again copied settings from aiida-core except the ones that were marked withRemoved this for now to simplify the PR, will do another PR for it.# these options reduce the strictness and should eventually be removed
. I am not yet sure if we should include it in the CI. I think it is kind of an advanced tool and the plugin developer can choose if he/she want to include it. Also the mypy checks fail and need to be fixed^^Building the docs
Small updates to work with src layout. Usage to build doc can be seen in CONTRIBUTING.md
CI
Updated GitHub actions to the same version as aiida-core and switched to hatch commands. Added a test run to the cookiecutter CI.
update-template-formatter.sh
This is a script initiates a new repo using the template with unique labels, applies the formatter, gets the git diff, replaces the unique labels with the cookie cutter identifier, then applies to on the template. It is not very robust and will fail for certain cases, but it can already safe a lot of work.
TODOs
update-template-formatter.sh
Demo
I put in my fork as default branch so people can try it out with