@@ -4,14 +4,15 @@ use crate::{
4
4
db:: Pool ,
5
5
impl_axum_webpage,
6
6
repositories:: RepositoryStatsUpdater ,
7
+ storage:: PathNotFoundError ,
7
8
web:: {
8
9
cache:: CachePolicy ,
9
10
encode_url_path,
10
11
error:: { AxumNope , AxumResult } ,
11
12
} ,
12
13
Storage ,
13
14
} ;
14
- use anyhow:: { bail , Context , Result } ;
15
+ use anyhow:: { Context , Result } ;
15
16
use axum:: {
16
17
extract:: { Extension , Path } ,
17
18
response:: { IntoResponse , Response as AxumResponse } ,
@@ -92,34 +93,6 @@ pub struct Release {
92
93
pub target_name : String ,
93
94
}
94
95
95
- #[ fn_error_context:: context( "fetching readme for {name} {version}" ) ]
96
- fn fetch_readme_from_source (
97
- storage : & Storage ,
98
- name : & str ,
99
- version : & str ,
100
- archive_storage : bool ,
101
- ) -> anyhow:: Result < String > {
102
- let manifest = storage. fetch_source_file ( name, version, "Cargo.toml" , archive_storage) ?;
103
- let manifest = String :: from_utf8 ( manifest. content )
104
- . context ( "parsing Cargo.toml" ) ?
105
- . parse :: < toml:: Value > ( )
106
- . context ( "parsing Cargo.toml" ) ?;
107
- let paths = match manifest. get ( "package" ) . and_then ( |p| p. get ( "readme" ) ) {
108
- Some ( toml:: Value :: Boolean ( true ) ) => vec ! [ "README.md" ] ,
109
- Some ( toml:: Value :: Boolean ( false ) ) => vec ! [ ] ,
110
- Some ( toml:: Value :: String ( path) ) => vec ! [ path. as_ref( ) ] ,
111
- _ => vec ! [ "README.md" , "README.txt" , "README" ] ,
112
- } ;
113
- for path in & paths {
114
- if let Ok ( readme) = storage. fetch_source_file ( name, version, path, archive_storage) {
115
- let readme = String :: from_utf8 ( readme. content )
116
- . with_context ( || format ! ( "parsing {path} content" ) ) ?;
117
- return Ok ( readme) ;
118
- }
119
- }
120
- bail ! ( "couldn't find readme in stored source, checked {paths:?}" )
121
- }
122
-
123
96
impl CrateDetails {
124
97
pub fn new (
125
98
conn : & mut impl GenericClient ,
@@ -266,11 +239,40 @@ impl CrateDetails {
266
239
Ok ( Some ( crate_details) )
267
240
}
268
241
269
- fn enrich_readme ( & mut self , storage : & Storage ) -> Result < ( ) > {
270
- let readme =
271
- fetch_readme_from_source ( storage, & self . name , & self . version , self . archive_storage ) ?;
272
- self . readme = Some ( readme) ;
273
- Ok ( ( ) )
242
+ #[ fn_error_context:: context( "fetching readme for {} {}" , self . name, self . version) ]
243
+ fn fetch_readme ( & self , storage : & Storage ) -> anyhow:: Result < Option < String > > {
244
+ let manifest = storage. fetch_source_file (
245
+ & self . name ,
246
+ & self . version ,
247
+ "Cargo.toml" ,
248
+ self . archive_storage ,
249
+ ) ?;
250
+ let manifest = String :: from_utf8 ( manifest. content )
251
+ . context ( "parsing Cargo.toml" ) ?
252
+ . parse :: < toml:: Value > ( )
253
+ . context ( "parsing Cargo.toml" ) ?;
254
+ let paths = match manifest. get ( "package" ) . and_then ( |p| p. get ( "readme" ) ) {
255
+ Some ( toml:: Value :: Boolean ( true ) ) => vec ! [ "README.md" ] ,
256
+ Some ( toml:: Value :: Boolean ( false ) ) => vec ! [ ] ,
257
+ Some ( toml:: Value :: String ( path) ) => vec ! [ path. as_ref( ) ] ,
258
+ _ => vec ! [ "README.md" , "README.txt" , "README" ] ,
259
+ } ;
260
+ for path in & paths {
261
+ match storage. fetch_source_file ( & self . name , & self . version , path, self . archive_storage ) {
262
+ Ok ( readme) => {
263
+ let readme = String :: from_utf8 ( readme. content )
264
+ . with_context ( || format ! ( "parsing {path} content" ) ) ?;
265
+ return Ok ( Some ( readme) ) ;
266
+ }
267
+ Err ( err) if err. is :: < PathNotFoundError > ( ) => {
268
+ continue ;
269
+ }
270
+ Err ( err) => {
271
+ return Err ( err) ;
272
+ }
273
+ }
274
+ }
275
+ Ok ( None )
274
276
}
275
277
276
278
/// Returns the latest non-yanked, non-prerelease release of this crate (or latest
@@ -395,16 +397,17 @@ pub(crate) async fn crate_details_handler(
395
397
& version,
396
398
& version_or_latest,
397
399
Some ( & repository_stats_updater) ,
398
- ) ?;
399
- if let Some ( ref mut details) = details {
400
- if let Err ( e) = details. enrich_readme ( & storage) {
401
- tracing:: debug!( "{e:?}" )
402
- }
400
+ ) ?
401
+ . ok_or ( AxumNope :: VersionNotFound ) ?;
402
+
403
+ match details. fetch_readme ( & storage) {
404
+ Ok ( readme) => details. readme = readme. or ( details. readme ) ,
405
+ Err ( e) => report_error ( & e) ,
403
406
}
407
+
404
408
Ok ( details)
405
409
} )
406
- . await ?
407
- . ok_or ( AxumNope :: VersionNotFound ) ?;
410
+ . await ?;
408
411
409
412
let mut res = CrateDetailsPage { details } . into_response ( ) ;
410
413
res. extensions_mut ( )
0 commit comments