@@ -10,40 +10,47 @@ use std::path::{Path, PathBuf};
10
10
use std:: sync:: atomic:: Ordering ;
11
11
use std:: time:: { Duration , Instant } ;
12
12
13
+ pub type ProgressItem = gix:: progress:: DoOrDiscard < gix:: progress:: prodash:: tree:: Item > ;
14
+
15
+ pub struct State {
16
+ pub progress : ProgressItem ,
17
+ pub gitoxide_version : String ,
18
+ pub trace_to_progress : bool ,
19
+ pub reverse_trace_lines : bool ,
20
+ }
21
+
13
22
impl Engine {
14
23
/// Open the corpus DB or create it.
15
- pub fn open_or_create (
16
- db : PathBuf ,
17
- gitoxide_version : String ,
18
- progress : corpus:: Progress ,
19
- trace_to_progress : bool ,
20
- reverse_trace_lines : bool ,
21
- ) -> anyhow:: Result < Engine > {
24
+ pub fn open_or_create ( db : PathBuf , state : State ) -> anyhow:: Result < Engine > {
22
25
let con = crate :: corpus:: db:: create ( db) . context ( "Could not open or create database" ) ?;
23
- Ok ( Engine {
24
- progress,
25
- con,
26
- gitoxide_version,
27
- trace_to_progress,
28
- reverse_trace_lines,
29
- } )
26
+ Ok ( Engine { con, state } )
30
27
}
31
28
32
29
/// Run on the existing set of repositories we have already seen or obtain them from `path` if there is none yet.
33
- pub fn run ( & mut self , corpus_path : PathBuf , threads : Option < usize > ) -> anyhow:: Result < ( ) > {
30
+ pub fn run (
31
+ & mut self ,
32
+ corpus_path : PathBuf ,
33
+ threads : Option < usize > ,
34
+ dry_run : bool ,
35
+ repo_sql_suffix : Option < String > ,
36
+ allowed_task_names : Vec < String > ,
37
+ ) -> anyhow:: Result < ( ) > {
38
+ let tasks = self . tasks_or_insert ( & allowed_task_names) ?;
39
+ if tasks. is_empty ( ) {
40
+ bail ! ( "Cannot run without any task to perform on the repositories" ) ;
41
+ }
34
42
let ( corpus_path, corpus_id) = self . prepare_corpus_path ( corpus_path) ?;
35
43
let gitoxide_id = self . gitoxide_version_id_or_insert ( ) ?;
36
44
let runner_id = self . runner_id_or_insert ( ) ?;
37
- let repos = self . find_repos_or_insert ( & corpus_path, corpus_id) ?;
38
- let tasks = self . tasks_or_insert ( ) ?;
39
- self . perform_run ( & corpus_path, gitoxide_id, runner_id, & tasks, repos, threads)
45
+ let repos = self . find_repos_or_insert ( & corpus_path, corpus_id, repo_sql_suffix) ?;
46
+ self . perform_run ( & corpus_path, gitoxide_id, runner_id, & tasks, repos, threads, dry_run)
40
47
}
41
48
42
49
pub fn refresh ( & mut self , corpus_path : PathBuf ) -> anyhow:: Result < ( ) > {
43
50
let ( corpus_path, corpus_id) = self . prepare_corpus_path ( corpus_path) ?;
44
51
let repos = self . refresh_repos ( & corpus_path, corpus_id) ?;
45
- self . progress . set_name ( "refresh repos" ) ;
46
- self . progress . info ( format ! (
52
+ self . state . progress . set_name ( "refresh repos" ) ;
53
+ self . state . progress . info ( format ! (
47
54
"Added or updated {} repositories under {corpus_path:?}" ,
48
55
repos. len( )
49
56
) ) ;
@@ -52,6 +59,7 @@ impl Engine {
52
59
}
53
60
54
61
impl Engine {
62
+ #[ allow( clippy:: too_many_arguments) ]
55
63
fn perform_run (
56
64
& mut self ,
57
65
corpus_path : & Path ,
@@ -60,24 +68,42 @@ impl Engine {
60
68
tasks : & [ ( db:: Id , & ' static Task ) ] ,
61
69
mut repos : Vec < db:: Repo > ,
62
70
threads : Option < usize > ,
71
+ dry_run : bool ,
63
72
) -> anyhow:: Result < ( ) > {
64
73
let start = Instant :: now ( ) ;
65
- let task_progress = & mut self . progress ;
74
+ let task_progress = & mut self . state . progress ;
66
75
task_progress. set_name ( "run" ) ;
67
76
task_progress. init ( Some ( tasks. len ( ) ) , gix:: progress:: count ( "tasks" ) ) ;
68
77
let threads = gix:: parallel:: num_threads ( threads) ;
69
78
let db_path = self . con . path ( ) . expect ( "opened from path on disk" ) . to_owned ( ) ;
70
79
for ( task_id, task) in tasks {
71
80
let task_start = Instant :: now ( ) ;
72
81
let mut repo_progress = task_progress. add_child ( format ! ( "run '{}'" , task. short_name) ) ;
73
- repo_progress. init ( Some ( repos. len ( ) ) , gix:: progress:: count ( "repos" ) ) ;
74
-
75
- if task. execute_exclusive || threads == 1 {
82
+ if task. execute_exclusive || threads == 1 || dry_run {
83
+ if dry_run {
84
+ task_progress. set_name ( "WOULD run" ) ;
85
+ for repo in & repos {
86
+ task_progress. info ( format ! (
87
+ "{}" ,
88
+ repo. path
89
+ . strip_prefix( corpus_path)
90
+ . expect( "corpus contains repo" )
91
+ . display( )
92
+ ) ) ;
93
+ task_progress. inc ( ) ;
94
+ }
95
+ task_progress. info ( format ! ( "with {} tasks" , tasks. len( ) ) ) ;
96
+ for ( _, task) in tasks {
97
+ task_progress. info ( format ! ( "task '{}' ({})" , task. description, task. short_name) )
98
+ }
99
+ continue ;
100
+ }
101
+ repo_progress. init ( Some ( repos. len ( ) ) , gix:: progress:: count ( "repos" ) ) ;
76
102
let mut run_progress = repo_progress. add_child ( "set later" ) ;
77
103
let ( _guard, current_id) = corpus:: trace:: override_thread_subscriber (
78
104
db_path. as_str ( ) ,
79
- self . trace_to_progress . then ( || task_progress. add_child ( "trace" ) ) ,
80
- self . reverse_trace_lines ,
105
+ self . state . trace_to_progress . then ( || task_progress. add_child ( "trace" ) ) ,
106
+ self . state . reverse_trace_lines ,
81
107
) ?;
82
108
83
109
for repo in & repos {
@@ -180,13 +206,21 @@ impl Engine {
180
206
Ok ( ( corpus_path, corpus_id) )
181
207
}
182
208
183
- fn find_repos ( & mut self , corpus_path : & Path , corpus_id : db:: Id ) -> anyhow:: Result < Vec < db:: Repo > > {
184
- self . progress . set_name ( "query db-repos" ) ;
185
- self . progress . init ( None , gix:: progress:: count ( "repos" ) ) ;
209
+ fn find_repos (
210
+ & mut self ,
211
+ corpus_path : & Path ,
212
+ corpus_id : db:: Id ,
213
+ sql_suffix : Option < & str > ,
214
+ ) -> anyhow:: Result < Vec < db:: Repo > > {
215
+ self . state . progress . set_name ( "query db-repos" ) ;
216
+ self . state . progress . init ( None , gix:: progress:: count ( "repos" ) ) ;
186
217
187
218
Ok ( self
188
219
. con
189
- . prepare ( "SELECT id, rela_path, odb_size, num_objects, num_references FROM repository WHERE corpus = ?1" ) ?
220
+ . prepare ( & format ! (
221
+ "SELECT id, rela_path, odb_size, num_objects, num_references FROM repository WHERE corpus = ?1 {}" ,
222
+ sql_suffix. unwrap_or_default( )
223
+ ) ) ?
190
224
. query_map ( [ corpus_id] , |r| {
191
225
Ok ( db:: Repo {
192
226
id : r. get ( 0 ) ?,
@@ -196,17 +230,17 @@ impl Engine {
196
230
num_references : r. get ( 4 ) ?,
197
231
} )
198
232
} ) ?
199
- . inspect ( |_| self . progress . inc ( ) )
233
+ . inspect ( |_| self . state . progress . inc ( ) )
200
234
. collect :: < Result < _ , _ > > ( ) ?)
201
235
}
202
236
203
237
fn refresh_repos ( & mut self , corpus_path : & Path , corpus_id : db:: Id ) -> anyhow:: Result < Vec < db:: Repo > > {
204
238
let start = Instant :: now ( ) ;
205
- self . progress . set_name ( "refresh" ) ;
206
- self . progress . init ( None , gix:: progress:: count ( "repos" ) ) ;
239
+ self . state . progress . set_name ( "refresh" ) ;
240
+ self . state . progress . init ( None , gix:: progress:: count ( "repos" ) ) ;
207
241
208
242
let repos = std:: thread:: scope ( {
209
- let progress = & mut self . progress ;
243
+ let progress = & mut self . state . progress ;
210
244
let con = & mut self . con ;
211
245
|scope| -> anyhow:: Result < _ > {
212
246
let threads = std:: thread:: available_parallelism ( )
@@ -278,13 +312,23 @@ impl Engine {
278
312
Ok ( repos)
279
313
}
280
314
281
- fn find_repos_or_insert ( & mut self , corpus_path : & Path , corpus_id : db:: Id ) -> anyhow:: Result < Vec < db:: Repo > > {
315
+ fn find_repos_or_insert (
316
+ & mut self ,
317
+ corpus_path : & Path ,
318
+ corpus_id : db:: Id ,
319
+ sql_suffix : Option < String > ,
320
+ ) -> anyhow:: Result < Vec < db:: Repo > > {
282
321
let start = Instant :: now ( ) ;
283
- let repos = self . find_repos ( corpus_path, corpus_id) ?;
322
+ let repos = self . find_repos ( corpus_path, corpus_id, sql_suffix . as_deref ( ) ) ?;
284
323
if repos. is_empty ( ) {
285
- self . refresh_repos ( corpus_path, corpus_id)
324
+ let res = self . refresh_repos ( corpus_path, corpus_id) ;
325
+ if sql_suffix. is_some ( ) {
326
+ self . find_repos ( corpus_path, corpus_id, sql_suffix. as_deref ( ) )
327
+ } else {
328
+ res
329
+ }
286
330
} else {
287
- self . progress . show_throughput ( start) ;
331
+ self . state . progress . show_throughput ( start) ;
288
332
Ok ( repos)
289
333
}
290
334
}
0 commit comments