1- use super :: CrateVersion ;
2- use serde_json;
1+ use super :: { Change , CrateVersion } ;
32use std:: path:: Path ;
43
54use git2:: {
6- build:: RepoBuilder , Delta , DiffFormat , Error as GitError , ErrorClass , Object , ObjectType , Oid ,
7- Reference , Repository , Tree ,
5+ build:: RepoBuilder , Delta , Error as GitError , ErrorClass , Object , ObjectType , Oid , Reference ,
6+ Repository , Tree ,
87} ;
98use std:: str;
109
@@ -24,7 +23,9 @@ pub struct Index {
2423
2524/// Options for use in `Index::from_path_or_cloned_with_options`
2625pub struct CloneOptions < ' a > {
26+ /// The url from which the repository should be cloned.
2727 pub repository_url : String ,
28+ /// Git2 fetch options to control exactly how to clone.
2829 pub fetch_options : Option < git2:: FetchOptions < ' a > > ,
2930}
3031
@@ -44,7 +45,7 @@ impl Index {
4445 }
4546
4647 /// Return the reference pointing to the state we have seen after calling `fetch_changes()`.
47- pub fn last_seen_reference ( & self ) -> Result < Reference , GitError > {
48+ pub fn last_seen_reference ( & self ) -> Result < Reference < ' _ > , GitError > {
4849 self . repo . find_reference ( self . seen_ref_name )
4950 }
5051
@@ -103,7 +104,7 @@ impl Index {
103104 CloneOptions {
104105 repository_url,
105106 fetch_options,
106- } : CloneOptions ,
107+ } : CloneOptions < ' _ > ,
107108 ) -> Result < Index , GitError > {
108109 let mut repo_did_exist = true ;
109110 let repo = Repository :: open ( path. as_ref ( ) ) . or_else ( |err| {
@@ -147,11 +148,11 @@ impl Index {
147148 }
148149
149150 /// As `peek_changes_with_options`, but without the options.
150- pub fn peek_changes ( & self ) -> Result < ( Vec < CrateVersion > , git2:: Oid ) , GitError > {
151+ pub fn peek_changes ( & self ) -> Result < ( Vec < Change > , git2:: Oid ) , GitError > {
151152 self . peek_changes_with_options ( None )
152153 }
153154
154- /// Return all `CrateVersion `s that are observed between the last time `fetch_changes(…)` was called
155+ /// Return all `Change `s that are observed between the last time `fetch_changes(…)` was called
155156 /// and the latest state of the `crates.io` index repository, which is obtained by fetching
156157 /// the remote called `origin`.
157158 /// The `last_seen_reference()` will not be created or updated.
@@ -169,7 +170,7 @@ impl Index {
169170 pub fn peek_changes_with_options (
170171 & self ,
171172 options : Option < & mut git2:: FetchOptions < ' _ > > ,
172- ) -> Result < ( Vec < CrateVersion > , git2:: Oid ) , GitError > {
173+ ) -> Result < ( Vec < Change > , git2:: Oid ) , GitError > {
173174 let from = self
174175 . last_seen_reference ( )
175176 . and_then ( |r| {
@@ -186,9 +187,7 @@ impl Index {
186187 None ,
187188 )
188189 } ) ?;
189- let latest_fetched_commit_oid =
190- self . repo . refname_to_id ( "refs/remotes/origin/master" ) ?;
191- latest_fetched_commit_oid
190+ self . repo . refname_to_id ( "refs/remotes/origin/master" ) ?
192191 } ;
193192
194193 Ok ( (
@@ -201,11 +200,11 @@ impl Index {
201200 }
202201
203202 /// As `fetch_changes_with_options`, but without the options.
204- pub fn fetch_changes ( & self ) -> Result < Vec < CrateVersion > , GitError > {
203+ pub fn fetch_changes ( & self ) -> Result < Vec < Change > , GitError > {
205204 self . fetch_changes_with_options ( None )
206205 }
207206
208- /// Return all `CrateVersion `s that are observed between the last time this method was called
207+ /// Return all `Change `s that are observed between the last time this method was called
209208 /// and the latest state of the `crates.io` index repository, which is obtained by fetching
210209 /// the remote called `origin`.
211210 /// The `last_seen_reference()` will be created or adjusted to point to the latest fetched
@@ -221,7 +220,7 @@ impl Index {
221220 pub fn fetch_changes_with_options (
222221 & self ,
223222 options : Option < & mut git2:: FetchOptions < ' _ > > ,
224- ) -> Result < Vec < CrateVersion > , GitError > {
223+ ) -> Result < Vec < Change > , GitError > {
225224 let ( changes, to) = self . peek_changes_with_options ( options) ?;
226225 self . set_last_seen_reference ( to) ?;
227226 Ok ( changes)
@@ -253,7 +252,7 @@ impl Index {
253252 & self ,
254253 from : impl AsRef < str > ,
255254 to : impl AsRef < str > ,
256- ) -> Result < Vec < CrateVersion > , GitError > {
255+ ) -> Result < Vec < Change > , GitError > {
257256 self . changes_from_objects (
258257 & self . repo . revparse_single ( from. as_ref ( ) ) ?,
259258 & self . repo . revparse_single ( to. as_ref ( ) ) ?,
@@ -264,10 +263,10 @@ impl Index {
264263 /// to either `Commit`s or `Tree`s.
265264 pub fn changes_from_objects (
266265 & self ,
267- from : & Object ,
268- to : & Object ,
269- ) -> Result < Vec < CrateVersion > , GitError > {
270- fn into_tree < ' a > ( repo : & ' a Repository , obj : & Object ) -> Result < Tree < ' a > , GitError > {
266+ from : & Object < ' _ > ,
267+ to : & Object < ' _ > ,
268+ ) -> Result < Vec < Change > , GitError > {
269+ fn into_tree < ' a > ( repo : & ' a Repository , obj : & Object < ' _ > ) -> Result < Tree < ' a > , GitError > {
271270 repo. find_tree ( match obj. kind ( ) {
272271 Some ( ObjectType :: Commit ) => obj
273272 . as_commit ( )
@@ -285,24 +284,43 @@ impl Index {
285284 Some ( & into_tree ( & self . repo , to) ?) ,
286285 None ,
287286 ) ?;
288- let mut res: Vec < CrateVersion > = Vec :: new ( ) ;
289- diff. print ( DiffFormat :: Patch , |delta, _, diffline| {
290- if diffline. origin ( ) != LINE_ADDED_INDICATOR {
291- return true ;
292- }
287+ let mut changes: Vec < Change > = Vec :: new ( ) ;
288+ let mut deletes: Vec < String > = Vec :: new ( ) ;
289+ diff. foreach (
290+ & mut |delta, _| {
291+ if delta. status ( ) == Delta :: Deleted {
292+ if let Some ( path) = delta. new_file ( ) . path ( ) {
293+ if let Some ( file_name) = path. file_name ( ) {
294+ deletes. push ( file_name. to_string_lossy ( ) . to_string ( ) ) ;
295+ }
296+ }
297+ }
298+ true
299+ } ,
300+ None ,
301+ None ,
302+ Some ( & mut |delta, _hunk, diffline| {
303+ if diffline. origin ( ) != LINE_ADDED_INDICATOR {
304+ return true ;
305+ }
306+ if !matches ! ( delta. status( ) , Delta :: Added | Delta :: Modified ) {
307+ return true ;
308+ }
293309
294- if !match delta. status ( ) {
295- Delta :: Added | Delta :: Modified => true ,
296- _ => false ,
297- } {
298- return true ;
299- }
310+ if let Ok ( crate_version) =
311+ serde_json:: from_slice :: < CrateVersion > ( diffline. content ( ) )
312+ {
313+ if crate_version. yanked {
314+ changes. push ( Change :: Yanked ( crate_version) ) ;
315+ } else {
316+ changes. push ( Change :: Added ( crate_version) ) ;
317+ }
318+ }
319+ true
320+ } ) ,
321+ ) ?;
300322
301- if let Ok ( c) = serde_json:: from_slice ( diffline. content ( ) ) {
302- res. push ( c)
303- }
304- true
305- } )
306- . map ( |_| res)
323+ changes. extend ( deletes. iter ( ) . map ( |krate| Change :: Deleted ( krate. clone ( ) ) ) ) ;
324+ Ok ( changes)
307325 }
308326}
0 commit comments