7
7
use axum:: extract:: Path ;
8
8
use axum:: Json ;
9
9
use crates_io_worker:: BackgroundJob ;
10
- use diesel:: { ExpressionMethods , RunQueryDsl } ;
10
+ use diesel:: { ExpressionMethods , QueryDsl , RunQueryDsl } ;
11
11
use diesel_async:: async_connection_wrapper:: AsyncConnectionWrapper ;
12
12
use http:: request:: Parts ;
13
13
use http:: StatusCode ;
@@ -142,7 +142,47 @@ fn apply_yank_update(
142
142
) -> AppResult < ( ) > {
143
143
// Try to update the yank state first, to avoid unnecessary checks.
144
144
update_version_yank_state ( version, update_data) ?;
145
+ perform_version_yank_update ( state, req, conn, version, krate) ?;
145
146
147
+ Ok ( ( ) )
148
+ }
149
+
150
+ fn update_version_yank_state ( version : & mut Version , update_data : & VersionUpdate ) -> AppResult < ( ) > {
151
+ match ( update_data. yanked , & update_data. yank_message ) {
152
+ ( Some ( true ) , Some ( message) ) => {
153
+ version. yanked = true ;
154
+ version. yank_message = Some ( message. clone ( ) ) ;
155
+ }
156
+ ( Some ( yanked) , None ) => {
157
+ version. yanked = yanked;
158
+ version. yank_message = None ;
159
+ }
160
+ ( Some ( false ) , Some ( _) ) => {
161
+ return Err ( bad_request ( "Cannot set yank message when unyanking" ) ) ;
162
+ }
163
+ ( None , Some ( message) ) => {
164
+ if version. yanked {
165
+ version. yank_message = Some ( message. clone ( ) ) ;
166
+ } else {
167
+ return Err ( bad_request (
168
+ "Cannot update yank message for a version that is not yanked" ,
169
+ ) ) ;
170
+ }
171
+ }
172
+ // If both yanked and yank_message are None, do nothing.
173
+ // This function only cares about updating the yanked state and yank message.
174
+ ( None , None ) => { }
175
+ }
176
+ Ok ( ( ) )
177
+ }
178
+
179
+ pub fn perform_version_yank_update (
180
+ state : & AppState ,
181
+ req : & Parts ,
182
+ conn : & mut impl Conn ,
183
+ version : & Version ,
184
+ krate : & Crate ,
185
+ ) -> AppResult < ( ) > {
146
186
// Add authentication check
147
187
let auth = AuthCheck :: default ( )
148
188
. with_endpoint_scope ( EndpointScope :: Yank )
@@ -168,12 +208,27 @@ fn apply_yank_update(
168
208
} else {
169
209
return Err ( custom (
170
210
StatusCode :: FORBIDDEN ,
171
- "must already be an owner to update version " ,
211
+ "must already be an owner to yank or unyank " ,
172
212
) ) ;
173
213
}
174
214
}
175
215
176
- diesel:: update ( & * version)
216
+ // Check if the yanked state or yank message has changed
217
+ let ( yanked, yank_message) = crate :: schema:: versions:: table
218
+ . find ( version. id )
219
+ . select ( (
220
+ crate :: schema:: versions:: yanked,
221
+ crate :: schema:: versions:: yank_message,
222
+ ) )
223
+ . first :: < ( bool , Option < String > ) > ( conn) ?;
224
+
225
+ if yanked == version. yanked && yank_message == version. yank_message {
226
+ // No changes, return early
227
+ return Ok ( ( ) ) ;
228
+ }
229
+
230
+ // Proceed with the update
231
+ diesel:: update ( version)
177
232
. set ( (
178
233
crate :: schema:: versions:: yanked. eq ( version. yanked ) ,
179
234
crate :: schema:: versions:: yank_message. eq ( & version. yank_message ) ,
@@ -194,32 +249,3 @@ fn apply_yank_update(
194
249
195
250
Ok ( ( ) )
196
251
}
197
-
198
- fn update_version_yank_state ( version : & mut Version , update_data : & VersionUpdate ) -> AppResult < ( ) > {
199
- match ( update_data. yanked , & update_data. yank_message ) {
200
- ( Some ( true ) , Some ( message) ) => {
201
- version. yanked = true ;
202
- version. yank_message = Some ( message. clone ( ) ) ;
203
- }
204
- ( Some ( yanked) , None ) => {
205
- version. yanked = yanked;
206
- version. yank_message = None ;
207
- }
208
- ( Some ( false ) , Some ( _) ) => {
209
- return Err ( bad_request ( "Cannot set yank message when unyanking" ) ) ;
210
- }
211
- ( None , Some ( message) ) => {
212
- if version. yanked {
213
- version. yank_message = Some ( message. clone ( ) ) ;
214
- } else {
215
- return Err ( bad_request (
216
- "Cannot update yank message for a version that is not yanked" ,
217
- ) ) ;
218
- }
219
- }
220
- // If both yanked and yank_message are None, do nothing.
221
- // This function only cares about updating the yanked state and yank message.
222
- ( None , None ) => { }
223
- }
224
- Ok ( ( ) )
225
- }
0 commit comments