@@ -194,28 +194,25 @@ fn get_readme(
194
194
}
195
195
196
196
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
- } ) ;
197
+ let archive = Archive :: new ( reader) ;
198
+ render_pkg_readme ( archive, & format ! ( "{}-{}" , krate_name, version. num) )
199
+ }
200
+
201
+ fn render_pkg_readme < R : Read > ( mut pkg : Archive < R > , pkg_name : & str ) -> Option < String > {
202
+ let mut entries = pkg
203
+ . entries ( )
204
+ . unwrap_or_else ( |_| panic ! ( "[{}] Invalid tar archive entries" , pkg_name) ) ;
204
205
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
- } )
206
+ let path = format ! ( "{}/Cargo.toml" , pkg_name) ;
207
+ let contents = find_file_by_path ( & mut entries, Path :: new ( & path) , pkg_name) ;
208
+ toml:: from_str ( & contents)
209
+ . unwrap_or_else ( |_| panic ! ( "[{}] Syntax error in manifest file" , pkg_name) )
213
210
} ;
214
211
215
212
let rendered = {
216
213
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 ) ;
214
+ let path = format ! ( "{}/{}" , pkg_name , readme_path) ;
215
+ let contents = find_file_by_path ( & mut entries, Path :: new ( & path) , pkg_name ) ;
219
216
text_to_html (
220
217
& contents,
221
218
readme_path,
@@ -240,8 +237,7 @@ fn get_readme(
240
237
fn find_file_by_path < R : Read > (
241
238
entries : & mut tar:: Entries < ' _ , R > ,
242
239
path : & Path ,
243
- version : & Version ,
244
- krate_name : & str ,
240
+ pkg_name : & str ,
245
241
) -> String {
246
242
let mut file = entries
247
243
. find ( |entry| match * entry {
@@ -254,28 +250,90 @@ fn find_file_by_path<R: Read>(
254
250
filepath == path
255
251
}
256
252
} )
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
- } ) ;
253
+ . unwrap_or_else ( || panic ! ( "[{}] couldn't open file: {}" , pkg_name, path. display( ) ) )
254
+ . unwrap_or_else ( |_| panic ! ( "[{}] file is not present: {}" , pkg_name, path. display( ) ) ) ;
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