@@ -160,6 +160,8 @@ fn get_readme(
160
160
version : & Version ,
161
161
krate_name : & str ,
162
162
) -> Option < String > {
163
+ let pkg_name = format ! ( "{}-{}" , krate_name, version. num) ;
164
+
163
165
let location = uploader. crate_location ( krate_name, & version. num . to_string ( ) ) ;
164
166
165
167
let location = match uploader {
@@ -175,47 +177,41 @@ fn get_readme(
175
177
let response = match client. get ( & location) . headers ( extra_headers) . send ( ) {
176
178
Ok ( r) => r,
177
179
Err ( err) => {
178
- println ! (
179
- "[{}-{}] Unable to fetch crate: {}" ,
180
- krate_name, version. num, err
181
- ) ;
180
+ println ! ( "[{}] Unable to fetch crate: {}" , pkg_name, err) ;
182
181
return None ;
183
182
}
184
183
} ;
185
184
186
185
if !response. status ( ) . is_success ( ) {
187
186
println ! (
188
- "[{}-{}] Failed to get a 200 response: {}" ,
189
- krate_name,
190
- version. num,
187
+ "[{}] Failed to get a 200 response: {}" ,
188
+ pkg_name,
191
189
response. text( ) . unwrap( )
192
190
) ;
193
191
return None ;
194
192
}
195
193
196
194
let reader = GzDecoder :: new ( response) ;
197
- let mut archive = Archive :: new ( reader) ;
198
- let mut entries = archive. entries ( ) . unwrap_or_else ( |_| {
199
- panic ! (
200
- "[{}-{}] Invalid tar archive entries" ,
201
- krate_name, version. num
202
- )
203
- } ) ;
195
+ let archive = Archive :: new ( reader) ;
196
+ render_pkg_readme ( archive, & pkg_name)
197
+ }
198
+
199
+ fn render_pkg_readme < R : Read > ( mut archive : Archive < R > , pkg_name : & str ) -> Option < String > {
200
+ let mut entries = archive
201
+ . entries ( )
202
+ . unwrap_or_else ( |_| panic ! ( "[{}] Invalid tar archive entries" , pkg_name) ) ;
203
+
204
204
let manifest: Manifest = {
205
- let path = format ! ( "{}-{}/Cargo.toml" , krate_name, version. num) ;
206
- let contents = find_file_by_path ( & mut entries, Path :: new ( & path) , version, krate_name) ;
207
- toml:: from_str ( & contents) . unwrap_or_else ( |_| {
208
- panic ! (
209
- "[{}-{}] Syntax error in manifest file" ,
210
- krate_name, version. num
211
- )
212
- } )
205
+ let path = format ! ( "{}/Cargo.toml" , pkg_name) ;
206
+ let contents = find_file_by_path ( & mut entries, Path :: new ( & path) , pkg_name) ;
207
+ toml:: from_str ( & contents)
208
+ . unwrap_or_else ( |_| panic ! ( "[{}] Syntax error in manifest file" , pkg_name) )
213
209
} ;
214
210
215
211
let rendered = {
216
212
let readme_path = manifest. package . readme . as_ref ( ) ?;
217
- let path = format ! ( "{}-{} /{}" , krate_name , version . num , readme_path) ;
218
- let contents = find_file_by_path ( & mut entries, Path :: new ( & path) , version , krate_name ) ;
213
+ let path = format ! ( "{}/{}" , pkg_name , readme_path) ;
214
+ let contents = find_file_by_path ( & mut entries, Path :: new ( & path) , pkg_name ) ;
219
215
text_to_html (
220
216
& contents,
221
217
readme_path,
@@ -240,8 +236,7 @@ fn get_readme(
240
236
fn find_file_by_path < R : Read > (
241
237
entries : & mut tar:: Entries < ' _ , R > ,
242
238
path : & Path ,
243
- version : & Version ,
244
- krate_name : & str ,
239
+ pkg_name : & str ,
245
240
) -> String {
246
241
let mut file = entries
247
242
. find ( |entry| match * entry {
@@ -254,28 +249,91 @@ fn find_file_by_path<R: Read>(
254
249
filepath == path
255
250
}
256
251
} )
257
- . unwrap_or_else ( || {
258
- panic ! (
259
- "[{}-{}] couldn't open file: {}" ,
260
- krate_name,
261
- version. num,
262
- path. display( )
263
- )
264
- } )
265
- . unwrap_or_else ( |_| {
266
- panic ! (
267
- "[{}-{}] file is not present: {}" ,
268
- krate_name,
269
- version. num,
270
- path. display( )
271
- )
272
- } ) ;
252
+ . unwrap_or_else ( || panic ! ( "[{}] couldn't open file: {}" , pkg_name, path. display( ) ) )
253
+ . unwrap_or_else ( |_| panic ! ( "[{}] file is not present: {}" , pkg_name, path. display( ) ) ) ;
254
+
273
255
let mut contents = String :: new ( ) ;
274
- file. read_to_string ( & mut contents) . unwrap_or_else ( |_| {
275
- panic ! (
276
- "[{}-{}] Couldn't read file contents" ,
277
- krate_name, version. num
278
- )
279
- } ) ;
256
+ file. read_to_string ( & mut contents)
257
+ . unwrap_or_else ( |_| panic ! ( "[{}] Couldn't read file contents" , pkg_name) ) ;
280
258
contents
281
259
}
260
+
261
+ #[ cfg( test) ]
262
+ mod tests {
263
+ use std:: io:: Write ;
264
+ use tar;
265
+
266
+ use super :: render_pkg_readme;
267
+
268
+ fn add_file < W : Write > ( pkg : & mut tar:: Builder < W > , path : & str , content : & [ u8 ] ) {
269
+ let mut header = tar:: Header :: new_gnu ( ) ;
270
+ header. set_size ( content. len ( ) as u64 ) ;
271
+ header. set_cksum ( ) ;
272
+ pkg. append_data ( & mut header, path, content) . unwrap ( ) ;
273
+ }
274
+
275
+ #[ test]
276
+ fn test_render_pkg_readme ( ) {
277
+ let mut pkg = tar:: Builder :: new ( vec ! [ ] ) ;
278
+ add_file (
279
+ & mut pkg,
280
+ "foo-0.0.1/Cargo.toml" ,
281
+ br#"
282
+ [package]
283
+ readme = "README.md"
284
+ "# ,
285
+ ) ;
286
+ add_file ( & mut pkg, "foo-0.0.1/README.md" , b"readme" ) ;
287
+ let serialized_archive = pkg. into_inner ( ) . unwrap ( ) ;
288
+ let result =
289
+ render_pkg_readme ( tar:: Archive :: new ( & * serialized_archive) , "foo-0.0.1" ) . unwrap ( ) ;
290
+ assert ! ( result. contains( "readme" ) )
291
+ }
292
+
293
+ #[ test]
294
+ fn test_render_pkg_readme_w_link ( ) {
295
+ let mut pkg = tar:: Builder :: new ( vec ! [ ] ) ;
296
+ add_file (
297
+ & mut pkg,
298
+ "foo-0.0.1/Cargo.toml" ,
299
+ br#"
300
+ [package]
301
+ readme = "README.md"
302
+ repository = "https://github.com/foo/foo"
303
+ "# ,
304
+ ) ;
305
+ add_file (
306
+ & mut pkg,
307
+ "foo-0.0.1/README.md" ,
308
+ b"readme [link](./Other.md)" ,
309
+ ) ;
310
+ let serialized_archive = pkg. into_inner ( ) . unwrap ( ) ;
311
+ let result =
312
+ render_pkg_readme ( tar:: Archive :: new ( & * serialized_archive) , "foo-0.0.1" ) . unwrap ( ) ;
313
+ assert ! ( result. contains( "\" https://github.com/foo/foo/blob/HEAD/./Other.md\" " ) )
314
+ }
315
+
316
+ #[ test]
317
+ fn test_render_pkg_readme_not_at_root ( ) {
318
+ let mut pkg = tar:: Builder :: new ( vec ! [ ] ) ;
319
+ add_file (
320
+ & mut pkg,
321
+ "foo-0.0.1/Cargo.toml" ,
322
+ br#"
323
+ [package]
324
+ readme = "docs/README.md"
325
+ repository = "https://github.com/foo/foo"
326
+ "# ,
327
+ ) ;
328
+ add_file (
329
+ & mut pkg,
330
+ "foo-0.0.1/docs/README.md" ,
331
+ b"docs/readme [link](./Other.md)" ,
332
+ ) ;
333
+ let serialized_archive = pkg. into_inner ( ) . unwrap ( ) ;
334
+ let result =
335
+ render_pkg_readme ( tar:: Archive :: new ( & * serialized_archive) , "foo-0.0.1" ) . unwrap ( ) ;
336
+ assert ! ( result. contains( "docs/readme" ) ) ;
337
+ assert ! ( result. contains( "\" https://github.com/foo/foo/blob/HEAD/docs/./Other.md\" " ) )
338
+ }
339
+ }
0 commit comments