Skip to content

Conversation

@pedro-psb
Copy link
Member

@pedro-psb pedro-psb commented Jan 26, 2026

As proposed here: https://discourse.pulpproject.org/t/proposal-using-pre-commit-for-static-checks/2170/5

This also adds pre-commit to the plugin_template repository itself.

Further improvements are:

  • Automate having plugin's and plugin-template's tool versions in sync
    • Example: the plugin lint requirement is synced with pre-commit because it's templated, but the plugin-template's lint_requirements isn't. Maybe use an scheduled update PR and use templating in plugin-template itself (or just a sed-like script)?
  • Automate bumping pre-commit hook versions in sync.
    • Example: a schduled workflow that uses pre-commit autoupdate and update plugin-template script

Test PR: pulp/pulpcore#7267

@pedro-psb pedro-psb force-pushed the add-pre-commit branch 5 times, most recently from 01fd5eb to 08b2c10 Compare January 28, 2026 14:43
@pedro-psb pedro-psb marked this pull request as ready for review January 28, 2026 14:52
then
pip install -r lint_requirements.txt
black .
pre-commit run -a black || true # always zero exit-code
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In what conditions does this exit non-zero?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it modifies files, which means linting failed. But here we don't care, we want auto-format.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it still communicate "Failed to reformat"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of. I see this as an unexpected error:

pre-commit exits with specific codes:

1: a detected / expected error
3: an unexpected error
130: the process was interrupted by ^C

https://pre-commit.com/#command-line-interface

cd "$(dirname "$(realpath -e "$0")")"/../..

set -uv
set -u
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be "set -eu"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this makes it harder to have the output we want of, because it will error immediately after failure (e.g, if we invert grep exit code with $(! grep ...)).

ERROR: Detected mix of f-strings and gettext:
{RESULT}

There might be one, but I don't know a clever way of achieve this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this should work:

EXIT_CODE=0
RESULT=$(grep -n "$PATTERN" "$@") || EXIT_CODE=$?

Also I believe this script is lightweight enough to run on sh instead of bash.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That raised an unbound variable error on the error case.
I found other option still using -e.

plugin-template Outdated
Comment on lines 384 to 393
subprocess.run(["black", "--quiet", "."], cwd=plugin_root_dir)
subprocess.run(["pre-commit", "run", "-a", "black"], cwd=plugin_root_dir)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably check the exit code here too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intent looks the same as the update_ci part: auto-format if it can, and ignore either way.
Hence the supress error handling if the binary is not found.
Actually, this looks redundant. We'll run auto-format when we apply the template and on the CI update.
Should I drop it here (or on upadate_ci)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I dropped it when running plugin-template. If you're running it manually you can apply the template and then run pre-commit to format on a different commit)

Comment on lines +6 to +7
- repo: 'https://github.com/pre-commit/pre-commit-hooks'
rev: {{ precommit_versions["pre-commit-hooks"] | quote }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean these are installed from git? I'd rather have them installed from pypi.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I believe the reason is that it's supposed to be language agnostic.
If you are concerned about mutability we could use the commit sha.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess not. sha values are unmaintainable.
I just had a feeling that this is odd, now you gave me the argument I was lacking.
Thinking more about it, I don't like the fact that precommit needs to "own" the installation in the first place.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the benefit over precommit "just" calling make format or make lint?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does some things, like handling file finding/filtering (non-trivial e.g, recognize shebang scripts), parallelization and owning the installation (python interpreter, packages, caching).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And in some cases, skip checking if there are no changes.

Comment on lines 16 to 21
else
# original behavior (check all)
set -v
RESULT=$(grep -n -r --include \*.py "$PATTERN")
EXIT_CODE=$?
fi
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need this then?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept it for compatibility, similar to lint_requirements.
Although it's less likely that is actually used manually. Should I drop it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that is how we are going to use it, then yes don't keep dead codepaths around.

Added a pre-commit config using the same linting steps as the lint
CI job. Also added a layer to keep pre-commit and lint_requirements
in sync. Slightly changed some lint scripts to adpat to pre-commit.
fi

if [ $? -ne 1 ]; then
# grep returns 1 if it doesn't find a match
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Failure is success" ;)

@pedro-psb
Copy link
Member Author

Ok, no more pushes until a new review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants