Skip to content

pyproject: standardise project layout#2

Open
shtrom wants to merge 14 commits intomainfrom
pyproject-setup
Open

pyproject: standardise project layout#2
shtrom wants to merge 14 commits intomainfrom
pyproject-setup

Conversation

@shtrom
Copy link
Member

@shtrom shtrom commented Mar 13, 2026

  • pyproject: standardise project layout
  • deps: add pip-tools to generate requirements.txt
  • deps: generate requirements[-dev].txt
  • lint: replace pytest-ruff with test_formatting.py using both black and ruff
  • pyproject: add setuptools-scm build-system
  • test: e2e test with exported script name
  • deps: update requirements
  • docker: install app using pip
  • workflows: run tests in container
  • docker: add REPO_URL and ORG_NAME support

@shtrom shtrom force-pushed the pyproject-setup branch 4 times, most recently from 50f6d81 to 3d3132e Compare March 13, 2026 06:39
@shtrom shtrom requested a review from a team as a code owner March 13, 2026 06:39
@shtrom shtrom force-pushed the pyproject-setup branch 3 times, most recently from 1b86870 to 6b5fb45 Compare March 13, 2026 06:49
pyproject.toml Outdated
dev = [
"pip-tools",
"pytest",
"pytest-ruff",
Copy link
Member

Choose a reason for hiding this comment

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

pytest-ruff looks like a small, mostly unmaintained project (last activity 9 months ago, adding Python 3.13 support). We should roll our own formatting tests as we do in other projects.

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe it's just feature complete? 😆

Copy link
Member Author

Choose a reason for hiding this comment

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

Lando uses both Black and Ruff. Why do we use both and not just one?

"rs_parsepatch",
]
description = "Select reviewers based on a diff and a set of rules"
dynamic = ["version"]
Copy link
Member

Choose a reason for hiding this comment

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

I think this field only needs to be set when using setuptools-scm. Perhaps we could add that now.

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 thought it would, and was surprised that it... just worked? (TBF, I haven't checked the version anywhere, but it just didn't choke on it).

I'm not sure we need setuptools at all considering we don't build sdist-type files.

OTOH, I have just tried adding a tag now, and the version is still 0.0.0 with or without setuptools-scm.

Copy link
Member

Choose a reason for hiding this comment

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

As this package is intended to be a library/client-side CLI tool (as opposed to server-side software) I don't think we need a requirements.txt. Specifying the requirements in pyproject.toml will allow the build to find packages that work for the client given other venv conflicts, as long as we ensure we specify any incompatible versions.

requirements-dev.txt is still valid for running local tests and builds against a known-good version.

Copy link
Member Author

@shtrom shtrom Mar 16, 2026

Choose a reason for hiding this comment

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

I think it's gonna be server-side: we build a docker container that will be used in response to hooks. If anything, as we refine the reviewer selection, this will be used as the shell to potentially bring in other libraries, but not the other way round.

It is, however, designed as a CLI for ease of testing in isolation, but I think having the requirements.txt here helps too, to recreate a known-good environment for the CLI.

resolve_reviewers,
)

MAIN_SCRIPT = "src/reviewer_selector.py"
Copy link
Member

Choose a reason for hiding this comment

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

If you want to test the script end-to-end, we should simply execute the name as defined in pyproject.toml:project.scripts (ie subprocess.run(["reviewer-selector"... in this case). Alternatively we could run the main() method directly. Executing the script in this way is brittle as changing the project structure will cause unrelated test failures. It also doesn't reflect any changes to the environment that may happen as part of the build/install.

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'll go with the installed script name, rather than the main, to be sure to test the whole flow (including correct installation of the script).

Copy link
Member

Choose a reason for hiding this comment

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

If this Docker container is used for running tests, perhaps we should use it in the GHA workflow instead of installing requirements-dev.txt and running pytest directly.

Copy link
Member Author

@shtrom shtrom Mar 16, 2026

Choose a reason for hiding this comment

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

This container is the main artifact that gets run by the TC hook. It's very very lean at the moment, but yeah... I'll see if I can keep the test dependencies out of the container.

@shtrom shtrom requested a review from cgsheeh March 18, 2026 05:24
* REPO_URL allows to fetch rules from the target repo
* ORG_NAME allows to prefix review groups correctly
Copy link
Member

@cgsheeh cgsheeh left a comment

Choose a reason for hiding this comment

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

LGTM!

Comment on lines +11 to +13
COPY . /app
RUN pip install -r requirements.txt \
&& pip install /app
Copy link
Member

Choose a reason for hiding this comment

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

Nit: it would be better to COPY the requirements file in and build the venv first, then copy the app code. That way we only re-build the container when the requirements.txt file changes, instead of each time the app code changes.

This is a nit as it's not super important for an MVP project. :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, I didn't think of that. In a previous installment I had a RUN --mount, but I removed it when I ended up COPYing everything. I'll restore that!

@@ -0,0 +1,73 @@
#!/bin/sh -eu
Copy link
Member

Choose a reason for hiding this comment

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

Small non-blocking request: could I trouble you to convert this into an entrypoint.py instead? As our team's stack is Python, it seems it would be easier to maintain. I can generally follow what's happening in this script, but if there was a subtle shell-script bug here I would have a hard time spotting it. :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, yeah. That shell script kinda grew a bit in size. I think the rewrite will happen naturally in the next few PR as I integrate TC and GitHub, and Python code ultimately becomes a shell around mots.

README.md Outdated
to set the reviewers on the target PR.
* If `DIFF_URL` is given, it will be fetched and passed into the selector's
stdin.
* If `GITHUB_TOKEN` and `PR_URL` are provided, the container will attempt
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* If `GITHUB_TOKEN` and `PR_URL` are provided, the container will attempt
* If `GITHUB_TOKEN` and `PR_URL` are provided, the container will attempt to set the reviewers on the target PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah! This one travelled all the way to the bottom of the file!

Comment on lines +26 to +29
"black",
"pip-tools",
"pytest",
"ruff",
Copy link
Member

Choose a reason for hiding this comment

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

Nit: it might be worth pinning these to specific versions.

Copy link
Member Author

Choose a reason for hiding this comment

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

What would be the rationale here? We are hard-pinned by the requirements.txt, so my instinct would be to have nothing more than a loose pinning here, likely if we encounter incompatibility with newer versions that we can't fix immediately.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants