-
Notifications
You must be signed in to change notification settings - Fork 602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add minimum version tracking to deleted crates #10016
base: main
Are you sure you want to change the base?
Conversation
This calculates the next semver-incompatible version of the crate being deleted and inserts it as `deleted_crates.min_version`.
macro_rules! assert_result_failed { | ||
($result:expr) => {{ | ||
let text = assert_result_status!($result); | ||
assert_snapshot!(text); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to write the snapshots to files because long lines make my eye twitch, but I don't feel very strongly about this.
let response = $result.unwrap_err().response(); | ||
assert_eq!(response.status(), StatusCode::UNPROCESSABLE_ENTITY); | ||
|
||
String::from_utf8( | ||
axum::body::to_bytes(response.into_body(), usize::MAX) | ||
.await | ||
.unwrap() | ||
.into(), | ||
) | ||
.unwrap() | ||
}}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about extending tests::util
to be able to use the same response helpers on a bare axum::response::Response
without the full boilerplate to fake a full request, but decided to keep this more self-contained for now. I can bring that code back if that sounds useful, though.
"A crate with the name `{name}` was previously deleted.\n\n* {}", | ||
messages.join("\n* "), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is basically the shitty version of our conversation about representing multiple errors in a single response in #9904. 💩
I guess now comes the question: is it worth it? 😂 one potential issue with this I discovered yesterday: when someone name-squats as mentioned in #9912 (comment), I'm curious what the situation at other registries looks like regarding this situation, for user-issued deletions, but also when admins delete packages/versions for whatever reason. |
If a crate has been deleted before, `deleted_crates.min_version` is enforced when validating a crate version that is being published. This also refactors the deleted crate check in general into a new module to make it easier to unit test and reason about. Mostly the latter, honestly.
9c7f396
to
edbf30a
Compare
All right, all right, I'll go actually ask some people. grumbles about this being as bad as having to phone someone on an actual phone |
So, yeah, that's an issue. On the other hand, there's also kind of an issue here with the "specifically allow semver-incompatible versions" rule as well, which is that it's potentially hard to explain. If someone publishes, say: Of course, a crate having that set of versions in the first place might be a sign that the name is associated with someone with... unusual ideas on versioning. 😆 |
As discussed in #9904 and #9912, this PR:
deleted_crates
table that indicates the first version that can be used when publishing a new crate version with the same name.crates-admin delete-crate
is run.Implementation wise, most of the noise here is actually moving the
deleted_crates
publish checks into a sub-module, mostly because the original version I wrote inline in the controller was ugly as hell. Instead, we now get to enjoy a slightly overengineered state machine. I'm open to suggestions.(Although, on the bright side, if we ever do need the more complex semver compatibility check rather than just checking against a minimum version, having the validation logic separated out already should make that easier to implement.)
I added new integration tests for the controller, but most of the specifics are tested in unit tests in said new sub-module. Redundant? Probably. 🤷
As for the deletion side of things, we're going to need the same
min_version
population behaviour (specifically the use ofTopVersions
) that I added tocrates-admin
when #9904 lands, but I was struggling a bit to figure out how to integrate that intomodels::krate
, sincecrates-admin
never actually constructs amodels::krate::Crate
when deleting a crate. I played around with doing a partial build ofNewDeletedCrateBuilder
based on aCrate
, but the type signatures were driving me slightly bonkers, and it didn't really feel cleaner anyway, so I just did it inline for now.Honestly, it might be simple enough that it's easiest to just copy/paste/adapt the same general logic into #9904.
I have a couple of other, more specific open questions that I'll throw into the inline review after I publish this, but I guess the main question here is whether this feels directionally correct.