pex-tool / pex

A tool for generating .pex (Python EXecutable) files, lock files and venvs.
https://docs.pex-tool.org/
Apache License 2.0
2.52k stars 258 forks source link

pex lock update: mechanism to remove projects from lockfile requirements #2332

Closed cburroughs closed 7 months ago

cburroughs commented 7 months ago

With --project= one can add a new project without changing the version of other entries, but there is not currently a mechanism to remove them in the same manner. The lockfile needs to be recreated.

(I'd expect this to remove the "requirement" but not try to "force uninstall" the project from the lockfile. That is if I have a lockfile with the requirements (A>1.0.0, B<1.0.0) and A depends on B. I'd expect removing B to still leave whatever version was a dependency of A in the lock.)

jsirois commented 7 months ago

This will be a riff on pex3 lock export-subset, which contains all the logic to do this subtraction in-memory with no network calls, etc.

jsirois commented 7 months ago

Ok, The 1st character of a project name must be a letter or digit ^1; so +, -, = can all be used as prefixes to indicate add or slide (default with no prefix), remove or replace respectively. I think this covers handling the new feature here and in #2334 in a backwards compatible way. It seems like that or adding new --project-delete / -d, --project-replace / -r options for - and = respectively.

jsirois commented 7 months ago

As a point of procedure, it seems the right way to handle a complex lock update with a mixture of add or slide, replace and delete is to 1st perform an underlying pip download lock update for the combination of add or slide or replace adjustments, if any, and only after that, perform the in-memory delete.

jsirois commented 7 months ago

Ok, delete should really just accept a project name with no qualifications (no version specifier since there is only 1 version in a lock by definition). As such, it seems --project-delete / -d should probably be a separate option with different content semantics (ProjectName instead of Requirement).

kaos commented 7 months ago

Ok, delete should really just accept a project name with no qualifications (no version specifier since there is only 1 version in a lock by definition). As such, it seems --project-delete / -d should probably be a separate option with different content semantics (ProjectName instead of Requirement).

That sounds reasonable. I'm just thinking what it could mean if you say --project=-A<2.0. To me, this could be a guarded delete; the request is to delete project A that is in the lockfile with a version less than 2.0. If the version of A was locked to a higher version it would not be deleted (but perhaps issue a warning or error). Being a Requirement using --project=-A would also still be valid to unconditionally remove A from the lockfile regardless of which version it's been locked to.

If we don't want this guarded semantics, then a dedicated option using ProjectName only would definitely seem preferable as the version constraint would otherwise be a no-op.

Just throwing this in there, I have no strong opinion either way--but to me, it would seem nice to have consistency in terms of options to control this, everything else ~equal. (i.e. either one option per action, or one option for all actions.)

my $.02 :)

jsirois commented 7 months ago

Thanks, I think this is enough to suggest replace should get its own option (https://github.com/pantsbuild/pex/pull/2335#discussion_r1458201806). So:

Delete is very different in that you can only delete a top level requirement you wrote down in the 1st place; so the version specifier is completely superfluous. If a version of the project you're deleting is in the lock for any other reason, it can't be deleted without ruining lock integrity since that means something else depends on it.

jsirois commented 7 months ago

This is now implemented in https://github.com/pantsbuild/pex/releases/tag/v2.1.160