librariesio / libraries.io

:books: The Open Source Discovery Service
https://libraries.io
GNU Affero General Public License v3.0
1.11k stars 203 forks source link

Allow existing pypi project versions to change statuses #3178

Closed jhan217 closed 1 year ago

jhan217 commented 1 year ago

This PR allows changes to the status field on existing Pypi project version.

For Pypi projects, the existing code short circuits updating the version if Libraries already knows about the version. I suspect this is due to not wanting to make multiple external API calls per project version on lookup of a project's versions, especially for the individual version's license & published_ats. This makes sense, as it would get extremely expensive for projects that have tens of thousands of releases, and we don't expect versions to change that much after they get published (e.g. once a version is published, we don't expect its published date to change). Doing this set of lookups/updates only when we see a new version that we haven't seen before mitigates that concern.

However, this existing short circuit prevents us from updating project versions if something changes about it after publication -- such as when a specific version gets yanked. This PR changes that behavior slightly to allow updates to the status if we see that the version has been yanked, which we get from the main project API call. If the version is marked with yanked: true, we will change the version.status to 'Removed'; if it is not, then we either keep the existing status or set the status to nil (the "unyanking" case). Setting the version.status is done in the Pypi specific version processor, and the update happens in the add_version call, which is more of an upsert at this point. This means the deprecate_version method is effectively not doing anything for Pypi projects, but I've left a note there that it may need to get updated to support the "libraries knows about the version, but pypi doesn't (probably because it was hard deleted on the package manager side)" scenario.