1
1
use crate :: background_jobs:: Environment ;
2
- use crate :: schema;
2
+ use crate :: { models , schema} ;
3
3
use anyhow:: Context ;
4
4
use cargo_registry_index:: Crate ;
5
5
use chrono:: Utc ;
6
6
use diesel:: prelude:: * ;
7
- use std:: fs:: { self , OpenOptions } ;
7
+ use std:: fs:: { self , File } ;
8
8
use std:: io:: ErrorKind ;
9
9
use std:: process:: Command ;
10
- use swirl:: PerformError ;
10
+ use swirl:: { Job , PerformError } ;
11
11
12
12
#[ swirl:: background_job]
13
13
pub fn add_crate ( env : & Environment , conn : & PgConnection , krate : Crate ) -> Result < ( ) , PerformError > {
14
- use std:: io:: prelude:: * ;
15
-
16
- let repo = env. lock_index ( ) ?;
17
- let dst = repo. index_file ( & krate. name ) ;
18
-
19
- // Add the crate to its relevant file
20
- fs:: create_dir_all ( dst. parent ( ) . unwrap ( ) ) ?;
21
- let mut file = OpenOptions :: new ( ) . append ( true ) . create ( true ) . open ( & dst) ?;
22
- serde_json:: to_writer ( & mut file, & krate) ?;
23
- file. write_all ( b"\n " ) ?;
24
-
25
14
let message: String = format ! ( "Updating crate `{}#{}`" , krate. name, krate. vers) ;
26
- repo. commit_and_push ( & message, & dst) ?;
27
-
28
- // Queue another background job to update the http-based index as well.
29
- update_crate_index ( krate. name . clone ( ) ) . enqueue ( conn) ?;
30
- Ok ( ( ) )
15
+ sync ( env, conn, & krate. name , & message)
31
16
}
32
17
33
18
#[ swirl:: background_job]
@@ -47,10 +32,7 @@ pub fn update_crate_index(env: &Environment, crate_name: String) -> Result<(), P
47
32
Ok ( ( ) )
48
33
}
49
34
50
- /// Yanks or unyanks a crate version. This requires finding the index
51
- /// file, deserlialise the crate from JSON, change the yank boolean to
52
- /// `true` or `false`, write all the lines back out, and commit and
53
- /// push the changes.
35
+ /// Yanks or unyanks a crate version.
54
36
#[ swirl:: background_job]
55
37
pub fn sync_yanked (
56
38
env : & Environment ,
@@ -70,38 +52,39 @@ pub fn sync_yanked(
70
52
71
53
trace ! ( ?krate, ?version_num, yanked) ;
72
54
55
+ let action = if yanked { "Yanking" } else { "Unyanking" } ;
56
+ let message = format ! ( "{action} crate `{krate}#{version_num}`" ) ;
57
+ sync ( env, conn, & krate, & message)
58
+ }
59
+
60
+ /// Re-generates an index file from the database for a single crate.
61
+ pub fn sync (
62
+ env : & Environment ,
63
+ conn : & PgConnection ,
64
+ krate : & str ,
65
+ commit_message : & str ,
66
+ ) -> Result < ( ) , PerformError > {
67
+ use std:: io:: Write ;
68
+ trace ! ( ?krate, "Update crate from database" ) ;
69
+ let db_krate: models:: Crate = models:: Crate :: by_exact_name ( krate)
70
+ . first ( conn)
71
+ . context ( "failed to find crate in database" ) ?;
72
+ let new = db_krate
73
+ . index_metadata ( conn)
74
+ . context ( "failed to generate index metadata" ) ?;
75
+
73
76
let repo = env. lock_index ( ) ?;
74
- let dst = repo. index_file ( & krate) ;
75
-
76
- let prev = fs:: read_to_string ( & dst) ?;
77
- let new = prev
78
- . lines ( )
79
- . map ( |line| {
80
- let mut git_crate = serde_json:: from_str :: < Crate > ( line)
81
- . map_err ( |_| format ! ( "couldn't decode: `{line}`" ) ) ?;
82
- if git_crate. name != krate || git_crate. vers != version_num {
83
- return Ok ( line. to_string ( ) ) ;
84
- }
85
- git_crate. yanked = Some ( yanked) ;
86
- Ok ( serde_json:: to_string ( & git_crate) ?)
87
- } )
88
- . collect :: < Result < Vec < _ > , PerformError > > ( ) ;
89
- let new = new?. join ( "\n " ) + "\n " ;
90
-
91
- if new != prev {
92
- fs:: write ( & dst, new. as_bytes ( ) ) ?;
93
-
94
- let action = if yanked { "Yanking" } else { "Unyanking" } ;
95
- let message = format ! ( "{action} crate `{krate}#{version_num}`" ) ;
96
-
97
- repo. commit_and_push ( & message, & dst) ?;
98
- } else {
99
- debug ! ( "Skipping `yanked` update because index is up-to-date" ) ;
77
+ let dst = repo. index_file ( krate) ;
78
+ if fs:: read ( & dst) . ok ( ) . as_ref ( ) == Some ( & new) {
79
+ debug ! ( "Skipping `{krate}` update because index is up-to-date" ) ;
80
+ return Ok ( ( ) ) ;
100
81
}
82
+ fs:: create_dir_all ( dst. parent ( ) . unwrap ( ) ) ?;
83
+ File :: create ( & dst) ?. write_all ( & new) ?;
84
+ repo. commit_and_push ( commit_message, & dst) ?;
101
85
102
86
// Queue another background job to update the http-based index as well.
103
- update_crate_index ( krate. clone ( ) ) . enqueue ( conn) ?;
104
-
87
+ update_crate_index ( krate. to_string ( ) ) . enqueue ( conn) ?;
105
88
Ok ( ( ) )
106
89
}
107
90
0 commit comments