1
- use super :: CrateVersion ;
2
- use serde_json;
1
+ use super :: { Change , CrateVersion } ;
3
2
use std:: path:: Path ;
4
3
5
4
use 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 ,
8
7
} ;
9
8
use std:: str;
10
9
@@ -24,7 +23,9 @@ pub struct Index {
24
23
25
24
/// Options for use in `Index::from_path_or_cloned_with_options`
26
25
pub struct CloneOptions < ' a > {
26
+ /// The url from which the repository should be cloned.
27
27
pub repository_url : String ,
28
+ /// Git2 fetch options to control exactly how to clone.
28
29
pub fetch_options : Option < git2:: FetchOptions < ' a > > ,
29
30
}
30
31
@@ -44,7 +45,7 @@ impl Index {
44
45
}
45
46
46
47
/// 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 > {
48
49
self . repo . find_reference ( self . seen_ref_name )
49
50
}
50
51
@@ -103,7 +104,7 @@ impl Index {
103
104
CloneOptions {
104
105
repository_url,
105
106
fetch_options,
106
- } : CloneOptions ,
107
+ } : CloneOptions < ' _ > ,
107
108
) -> Result < Index , GitError > {
108
109
let mut repo_did_exist = true ;
109
110
let repo = Repository :: open ( path. as_ref ( ) ) . or_else ( |err| {
@@ -147,11 +148,11 @@ impl Index {
147
148
}
148
149
149
150
/// 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 > {
151
152
self . peek_changes_with_options ( None )
152
153
}
153
154
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
155
156
/// and the latest state of the `crates.io` index repository, which is obtained by fetching
156
157
/// the remote called `origin`.
157
158
/// The `last_seen_reference()` will not be created or updated.
@@ -169,7 +170,7 @@ impl Index {
169
170
pub fn peek_changes_with_options (
170
171
& self ,
171
172
options : Option < & mut git2:: FetchOptions < ' _ > > ,
172
- ) -> Result < ( Vec < CrateVersion > , git2:: Oid ) , GitError > {
173
+ ) -> Result < ( Vec < Change > , git2:: Oid ) , GitError > {
173
174
let from = self
174
175
. last_seen_reference ( )
175
176
. and_then ( |r| {
@@ -186,9 +187,7 @@ impl Index {
186
187
None ,
187
188
)
188
189
} ) ?;
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" ) ?
192
191
} ;
193
192
194
193
Ok ( (
@@ -201,11 +200,11 @@ impl Index {
201
200
}
202
201
203
202
/// 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 > {
205
204
self . fetch_changes_with_options ( None )
206
205
}
207
206
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
209
208
/// and the latest state of the `crates.io` index repository, which is obtained by fetching
210
209
/// the remote called `origin`.
211
210
/// The `last_seen_reference()` will be created or adjusted to point to the latest fetched
@@ -221,7 +220,7 @@ impl Index {
221
220
pub fn fetch_changes_with_options (
222
221
& self ,
223
222
options : Option < & mut git2:: FetchOptions < ' _ > > ,
224
- ) -> Result < Vec < CrateVersion > , GitError > {
223
+ ) -> Result < Vec < Change > , GitError > {
225
224
let ( changes, to) = self . peek_changes_with_options ( options) ?;
226
225
self . set_last_seen_reference ( to) ?;
227
226
Ok ( changes)
@@ -253,7 +252,7 @@ impl Index {
253
252
& self ,
254
253
from : impl AsRef < str > ,
255
254
to : impl AsRef < str > ,
256
- ) -> Result < Vec < CrateVersion > , GitError > {
255
+ ) -> Result < Vec < Change > , GitError > {
257
256
self . changes_from_objects (
258
257
& self . repo . revparse_single ( from. as_ref ( ) ) ?,
259
258
& self . repo . revparse_single ( to. as_ref ( ) ) ?,
@@ -264,10 +263,10 @@ impl Index {
264
263
/// to either `Commit`s or `Tree`s.
265
264
pub fn changes_from_objects (
266
265
& 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 > {
271
270
repo. find_tree ( match obj. kind ( ) {
272
271
Some ( ObjectType :: Commit ) => obj
273
272
. as_commit ( )
@@ -285,24 +284,43 @@ impl Index {
285
284
Some ( & into_tree ( & self . repo , to) ?) ,
286
285
None ,
287
286
) ?;
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
+ }
293
309
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
+ ) ?;
300
322
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)
307
325
}
308
326
}
0 commit comments