Skip to content

Commit

Permalink
Improve how we manage which PDM to use
Browse files Browse the repository at this point in the history
Move our PDM version pin to a separate file. This both makes it easier
to manage updates to the same and also allows the pinned version to be
usable outside of the venv_sync script. Teach venv_upgrade to use PDM
itself to generate this file, which accomplishes the outstanding goal of
being able to pin both PDM and its dependencies.  Also, modify venv_sync
to tell PDM to not complain about newer versions.
  • Loading branch information
mwoehlke-kitware committed Jan 9, 2025
1 parent f164831 commit d8a97da
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 13 deletions.
1 change: 1 addition & 0 deletions setup/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ exports_files([
"mac/source_distribution/Brewfile-maintainer-only",
"python/pdm.lock",
"python/pyproject.toml",
"python/requirements.txt",
"ubuntu/binary_distribution/packages-jammy.txt",
"ubuntu/source_distribution/packages-jammy.txt",
"ubuntu/source_distribution/packages-jammy-clang.txt",
Expand Down
3 changes: 3 additions & 0 deletions setup/python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ dependencies = [
]

[dependency-groups]
pdm = [
"pdm",
]
test = [
"flask",
"six",
Expand Down
12 changes: 12 additions & 0 deletions setup/python/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# This file does NOT describe the requirements for Drake itself, but for
# setting up the Python virtual environment that Drake will manage. It is used
# by Drake's @python, and also when preparing a virtual environment to support
# a Drake installation.
#
# This file will be generated by tools/workspace/python/venv_upgrade.
#
# The present contents are adequate to bootstrap the PDM installation, after
# which (the first subsequent time venv_upgrade is run) PDM itself will
# generate a complete list of its dependencies with pinned versions.

pdm==2.22.0
10 changes: 7 additions & 3 deletions tools/workspace/python/repository.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,13 @@ def _prepare_venv(repo_ctx, python):
if os_name != "mac os x":
return python

# Locate the lock file and mark it to be monitored for changes.
pylock = repo_ctx.path(Label("@drake//setup:python/pdm.lock")).realpath
repo_ctx.watch(pylock)
# Locate lock files and mark them to be monitored for changes.
requirements = repo_ctx.path(
Label("@drake//setup:python/requirements.txt"),
).realpath
pdmlock = repo_ctx.path(Label("@drake//setup:python/pdm.lock")).realpath
repo_ctx.watch(requirements)
repo_ctx.watch(pdmlock)

# Choose which dependencies to install.
if repo_ctx.attr.requirements_flavor == "test":
Expand Down
14 changes: 8 additions & 6 deletions tools/workspace/python/venv_sync
Original file line number Diff line number Diff line change
Expand Up @@ -53,32 +53,34 @@ fi
# Place the venv(s) in a sibling directory to the output base. That should be a
# suitable disk location for build artifacts, but without polluting the actual
# output base that Bazel owns.
readonly drake_root="$(cd "$(dirname $0)/../../.." && pwd)"
readonly bazel_output_base="$(cd "${repository}/../.." && pwd)"
readonly drake_python="${bazel_output_base}.drake_python"
mkdir -p "${drake_python}"

# Install PDM into a virtual environment. We segregate PDM from the environment
# it is managing, so that changes to the managed environment cannot break PDM.
readonly setup="${drake_root}/setup/python"
readonly venv_pdm="${drake_python}/venv.pdm"
mkvenv "${venv_pdm}"
# TODO(jeremy.nimmer) Ideally, we also would pin all of the dependencies of
# PDM here, but it's not obvious to me how to do that in a way which is easy to
# upgrade/re-pin over time.
"${venv_pdm}/bin/pip" install -U pdm==2.22.0
"${venv_pdm}/bin/pip" install -U -r "${setup}/requirements.txt"

# Don't nag about new versions of PDM; we'll update the above pin when we want
# to use something newer, and otherwise want to use the pinned version, so
# being informed about newer versions is just noise.
export PDM_CHECK_UPDATE=0

# Prepare the PDM "project directory".
readonly drake_root="$(cd "$(dirname $0)/../../.." && pwd)"
readonly setup="${drake_root}/setup/python"
readonly project="${drake_python}/project"
mkdir -p "${project}"
ln -nsf "${setup}/pyproject.toml" "${project}/pyproject.toml"
ln -nsf "${setup}/pdm.lock" "${project}/pdm.lock"

# Don't nag about new versions of PDM; venv_upgrade will check for those.
# Aside from that, we want to use the pinned version, so being informed about
# newer versions is just noise.
export PDM_CHECK_UPDATE=0

# Prepare the venv that will hold Drake's requirements.
readonly venv_drake="${drake_python}/venv.drake"
mkvenv "${venv_drake}"
Expand Down
33 changes: 29 additions & 4 deletions tools/workspace/python/venv_upgrade
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ cd "$(dirname $0)/../../.."
readonly drake_python="$(bazel info output_base).drake_python"
readonly project="${drake_python}/project"
readonly venv_pdm="${drake_python}/venv.pdm"
readonly python="${venv_pdm}/bin/python"
readonly workspace="$(pwd)/tools/workspace/python"

# If committing, check that the working tree is clean (enough). Note that the
# lock file is ignored.
Expand All @@ -47,11 +49,34 @@ readonly venv_pdm="${drake_python}/venv.pdm"
# Ensure venv exists.
bazel fetch @python --force

# Remove and recreate the lock file.
# Update the lock file.
readonly lockfile="./setup/python/pdm.lock"
rm -f "${lockfile}"
"${venv_pdm}/bin/pdm" lock -p "${project}" -L "${lockfile}"
files_to_commit+=($(git diff --name-only HEAD -- "${lockfile}"))
"${venv_pdm}/bin/pdm" lock -d -p "${project}" -L "${lockfile}"

# Update pins for PDM itself
readonly requirements="./setup/python/requirements.txt"
cat > "${requirements}" <<EOF
# This file does NOT describe the requirements for Drake itself, but for
# setting up the Python virtual environment that Drake will manage. It is used
# by Drake's @python, and also when preparing a virtual environment to support
# a Drake installation.
#
# This file is generated by tools/workspace/python/venv_upgrade.
EOF
"${venv_pdm}/bin/pdm" export -p "${project}" -G pdm --no-default |
grep -vE '^#' >> "${requirements}"
files_to_commit+=( "$(git diff --name-only HEAD -- "${requirements}")" )

if [ ${#files_to_commit[@]} -gt 0 ]; then
# PDM needs to be updated.
bazel fetch @python

# Update the lock file (again).
"${venv_pdm}/bin/pdm" lock -p "${project}" -L "${lockfile}"
fi

# Check for changes to the lock file.
files_to_commit+=( "$(git diff --name-only HEAD -- "${lockfile}")" )

# If committing, do the commit.
if [ -n "${commit}" ]; then
Expand Down

0 comments on commit d8a97da

Please sign in to comment.