@@ -293,18 +293,33 @@ impl Repository {
293
293
. join ( Self :: relative_index_file ( name) )
294
294
}
295
295
296
+ /// Returns the relative path to the crate index file.
297
+ /// Does not perform conversion to lowercase.
298
+ fn relative_index_file_helper ( name : & str ) -> Vec < & str > {
299
+ match name. len ( ) {
300
+ 1 => vec ! [ "1" , name] ,
301
+ 2 => vec ! [ "2" , name] ,
302
+ 3 => vec ! [ "3" , & name[ ..1 ] , name] ,
303
+ _ => vec ! [ & name[ 0 ..2 ] , & name[ 2 ..4 ] , name] ,
304
+ }
305
+ }
306
+
296
307
/// Returns the relative path to the crate index file that corresponds to
297
- /// the given crate name.
308
+ /// the given crate name as a path (i.e. with platform-dependent folder separators) .
298
309
///
299
310
/// see <https://doc.rust-lang.org/cargo/reference/registries.html#index-format>
300
311
pub fn relative_index_file ( name : & str ) -> PathBuf {
301
312
let name = name. to_lowercase ( ) ;
302
- match name. len ( ) {
303
- 1 => Path :: new ( "1" ) . join ( & name) ,
304
- 2 => Path :: new ( "2" ) . join ( & name) ,
305
- 3 => Path :: new ( "3" ) . join ( & name[ ..1 ] ) . join ( & name) ,
306
- _ => Path :: new ( & name[ 0 ..2 ] ) . join ( & name[ 2 ..4 ] ) . join ( & name) ,
307
- }
313
+ Self :: relative_index_file_helper ( & name) . iter ( ) . collect ( )
314
+ }
315
+
316
+ /// Returns the relative path to the crate index file that corresponds to
317
+ /// the given crate name for usage in URLs (i.e. with `/` separator).
318
+ ///
319
+ /// see <https://doc.rust-lang.org/cargo/reference/registries.html#index-format>
320
+ pub fn relative_index_file_for_url ( name : & str ) -> String {
321
+ let name = name. to_lowercase ( ) ;
322
+ Self :: relative_index_file_helper ( & name) . join ( "/" )
308
323
}
309
324
310
325
/// Returns the [Object ID](git2::Oid) of the currently checked out commit
@@ -343,6 +358,50 @@ impl Repository {
343
358
self . push ( "refs/heads/master" )
344
359
}
345
360
361
+ /// Gets a list of files that have been modified since a given `starting_commit`
362
+ /// (use `starting_commit = None` for a list of all files).
363
+ pub fn get_files_modified_since (
364
+ & self ,
365
+ starting_commit : Option < & str > ,
366
+ ) -> anyhow:: Result < Vec < PathBuf > > {
367
+ let starting_commit = match starting_commit {
368
+ Some ( starting_commit) => {
369
+ let oid = git2:: Oid :: from_str ( starting_commit)
370
+ . context ( "failed to parse commit into Oid" ) ?;
371
+ let commit = self
372
+ . repository
373
+ . find_commit ( oid)
374
+ . context ( "failed to find commit" ) ?;
375
+ Some (
376
+ commit
377
+ . as_object ( )
378
+ . peel_to_tree ( )
379
+ . context ( "failed to find tree for commit" ) ?,
380
+ )
381
+ }
382
+ None => None ,
383
+ } ;
384
+
385
+ let head = self
386
+ . repository
387
+ . find_commit ( self . head_oid ( ) ?) ?
388
+ . as_object ( )
389
+ . peel_to_tree ( )
390
+ . context ( "failed to find tree for HEAD" ) ?;
391
+ let diff = self
392
+ . repository
393
+ . diff_tree_to_tree ( starting_commit. as_ref ( ) , Some ( & head) , None )
394
+ . context ( "failed to run diff" ) ?;
395
+ let files = diff
396
+ . deltas ( )
397
+ . map ( |delta| delta. new_file ( ) )
398
+ . filter ( |file| file. exists ( ) )
399
+ . map ( |file| file. path ( ) . unwrap ( ) . to_path_buf ( ) )
400
+ . collect ( ) ;
401
+
402
+ Ok ( files)
403
+ }
404
+
346
405
/// Push the current branch to the provided refname
347
406
fn push ( & self , refspec : & str ) -> anyhow:: Result < ( ) > {
348
407
let mut ref_status = Ok ( ( ) ) ;
0 commit comments