@@ -7,22 +7,30 @@ use crate::crates_io::api::{CratesIoApi, TrustedPublishingGitHubConfig};
77use anyhow:: Context ;
88use secrecy:: SecretString ;
99use std:: collections:: HashMap ;
10+ use std:: fmt:: { Display , Formatter } ;
1011
1112#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
1213struct CrateName ( String ) ;
1314
15+ impl Display for CrateName {
16+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
17+ self . 0 . fmt ( f)
18+ }
19+ }
20+
1421#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Debug ) ]
15- struct CratesIoPublishingConfig {
22+ struct CrateConfig {
1623 krate : CrateName ,
1724 repo_org : String ,
1825 repo_name : String ,
1926 workflow_file : String ,
2027 environment : String ,
28+ trusted_publishing_only : bool ,
2129}
2230
2331pub ( crate ) struct SyncCratesIo {
2432 crates_io_api : CratesIoApi ,
25- crates : HashMap < CrateName , CratesIoPublishingConfig > ,
33+ crates : HashMap < CrateName , CrateConfig > ,
2634}
2735
2836impl SyncCratesIo {
@@ -32,7 +40,7 @@ impl SyncCratesIo {
3240 dry_run : bool ,
3341 ) -> anyhow:: Result < Self > {
3442 let crates_io_api = CratesIoApi :: new ( token, dry_run) ;
35- let crates: HashMap < CrateName , CratesIoPublishingConfig > = team_api
43+ let crates: HashMap < CrateName , CrateConfig > = team_api
3644 . get_repos ( ) ?
3745 . into_iter ( )
3846 . flat_map ( |repo| {
@@ -44,12 +52,13 @@ impl SyncCratesIo {
4452 } ;
4553 Some ( (
4654 CrateName ( krate. name . clone ( ) ) ,
47- CratesIoPublishingConfig {
55+ CrateConfig {
4856 krate : CrateName ( krate. name . clone ( ) ) ,
4957 repo_org : repo. org . clone ( ) ,
5058 repo_name : repo. name . clone ( ) ,
5159 workflow_file : publishing. workflow_file . clone ( ) ,
5260 environment : publishing. environment . clone ( ) ,
61+ trusted_publishing_only : krate. trusted_publishing_only ,
5362 } ,
5463 ) )
5564 } )
@@ -65,6 +74,7 @@ impl SyncCratesIo {
6574
6675 pub ( crate ) fn diff_all ( & self ) -> anyhow:: Result < Diff > {
6776 let mut config_diffs: Vec < ConfigDiff > = vec ! [ ] ;
77+ let mut crate_diffs: Vec < CrateDiff > = vec ! [ ] ;
6878
6979 // Note: we currently only support one trusted publishing configuration per crate
7080 for ( krate, desired) in & self . crates {
@@ -102,6 +112,18 @@ impl SyncCratesIo {
102112
103113 // Non-matching configs should be deleted
104114 config_diffs. extend ( configs. into_iter ( ) . map ( ConfigDiff :: Delete ) ) ;
115+
116+ let trusted_publish_only_expected = desired. trusted_publishing_only ;
117+ let crates_io_crate = self
118+ . crates_io_api
119+ . get_crate ( & krate. 0 )
120+ . with_context ( || anyhow:: anyhow!( "Cannot load crate {krate}" ) ) ?;
121+ if crates_io_crate. trusted_publishing_only != trusted_publish_only_expected {
122+ crate_diffs. push ( CrateDiff :: SetTrustedPublishingOnly {
123+ krate : krate. to_string ( ) ,
124+ value : trusted_publish_only_expected,
125+ } ) ;
126+ }
105127 }
106128
107129 // We want to apply deletions first, and only then create new configs, to ensure that we
@@ -114,17 +136,29 @@ impl SyncCratesIo {
114136 ( ConfigDiff :: Create ( a) , ConfigDiff :: Create ( b) ) => a. cmp ( b) ,
115137 } ) ;
116138
117- Ok ( Diff { config_diffs } )
139+ Ok ( Diff {
140+ config_diffs,
141+ crate_diffs,
142+ } )
118143 }
119144}
120145
121146pub ( crate ) struct Diff {
122147 config_diffs : Vec < ConfigDiff > ,
148+ crate_diffs : Vec < CrateDiff > ,
123149}
124150
125151impl Diff {
126152 pub ( crate ) fn apply ( & self , sync : & SyncCratesIo ) -> anyhow:: Result < ( ) > {
127- for diff in & self . config_diffs {
153+ let Diff {
154+ config_diffs,
155+ crate_diffs,
156+ } = self ;
157+
158+ for diff in config_diffs {
159+ diff. apply ( sync) ?;
160+ }
161+ for diff in crate_diffs {
128162 diff. apply ( sync) ?;
129163 }
130164 Ok ( ( ) )
@@ -149,9 +183,10 @@ impl std::fmt::Display for Diff {
149183}
150184
151185enum ConfigDiff {
152- Create ( CratesIoPublishingConfig ) ,
186+ Create ( CrateConfig ) ,
153187 Delete ( TrustedPublishingGitHubConfig ) ,
154188}
189+
155190impl ConfigDiff {
156191 fn apply ( & self , sync : & SyncCratesIo ) -> anyhow:: Result < ( ) > {
157192 match self {
@@ -200,3 +235,31 @@ impl std::fmt::Display for ConfigDiff {
200235 Ok ( ( ) )
201236 }
202237}
238+
239+ enum CrateDiff {
240+ SetTrustedPublishingOnly { krate : String , value : bool } ,
241+ }
242+
243+ impl CrateDiff {
244+ fn apply ( & self , sync : & SyncCratesIo ) -> anyhow:: Result < ( ) > {
245+ match self {
246+ Self :: SetTrustedPublishingOnly { krate, value } => sync
247+ . crates_io_api
248+ . set_trusted_publishing_only ( krate, * value) ,
249+ }
250+ }
251+ }
252+
253+ impl std:: fmt:: Display for CrateDiff {
254+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
255+ match self {
256+ Self :: SetTrustedPublishingOnly { krate, value } => {
257+ writeln ! (
258+ f,
259+ " Setting trusted publishing only option for krate `{krate}` to `{value}`" ,
260+ ) ?;
261+ }
262+ }
263+ Ok ( ( ) )
264+ }
265+ }
0 commit comments