@@ -4,6 +4,7 @@ use regex::Regex;
44use clap:: Parser as ClapParser ;
55use petgraph:: graph:: DiGraph ;
66use petgraph:: algo:: toposort;
7+ use crates_io_api:: SyncClient ;
78//use petgraph::dot::{Dot, Config}; // Used for debugging graphs
89
910const LINE_COUNT_DIR : & str = "source/tools/line_count" ;
@@ -164,6 +165,16 @@ fn src_modified(dir: &Path, commit: &str) -> bool {
164165 !status. success ( ) // A successful exit code of 0 means no changes
165166}
166167
168+ fn read_toml_version ( dir : & Path ) -> String {
169+ let cargo_toml_path = dir. join ( "Cargo.toml" ) ;
170+
171+ // Read the Cargo.toml file
172+ let content = fs:: read_to_string ( & cargo_toml_path) . expect ( format ! ( "Failed to read {}" , cargo_toml_path. display( ) ) . as_str ( ) ) ;
173+ let doc = content. parse :: < DocumentMut > ( ) . expect ( "Failed to parse Cargo.toml" ) ;
174+
175+ doc[ "package" ] [ "version" ] . to_string ( )
176+ }
177+
167178fn update_toml_version ( dir : & Path ) {
168179 let cargo_toml_path = dir. join ( "Cargo.toml" ) ;
169180
@@ -302,18 +313,32 @@ fn update_crates(crates: Vec<Crate>) {
302313 }
303314}
304315
305- fn publish_crates ( crate_graph : DiGraph < Crate , ( ) > , dry_run : bool ) {
316+ fn publish_crates ( crate_graph : DiGraph < Crate , ( ) > , dry_run : bool ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
317+ let crates_io_client = SyncClient :: new (
318+ "verus-version-bumper" ,
319+ std:: time:: Duration :: from_secs ( 1 ) ,
320+ ) ?;
306321 let sorted_nodes = toposort ( & crate_graph, None ) . expect ( "Dependency graph has cycles" ) ;
307322 //println!("{:?}", Dot::with_config(&crate_graph, &[Config::EdgeNoLabel]));
308323 for node_index in sorted_nodes {
309324 let krate = & crate_graph[ node_index] ;
325+ // Before publishing, check if this version already exists on crates.io
326+ let crate_version = read_toml_version ( & Path :: new ( & krate. path ) ) ;
327+ let metadata = crates_io_client. get_crate ( & krate. name ) ?;
328+ let version_exists = metadata. versions . iter ( ) . any ( |v| v. num == crate_version && !v. yanked ) ;
329+ if version_exists {
330+ println ! ( "Crate {} version {} already exists on crates.io, skipping publish." , krate. name, crate_version) ;
331+ continue ;
332+ }
333+
310334 if dry_run {
311335 println ! ( "Performing a dry-run publish of crate {}" , krate. name) ;
312336 } else {
313337 println ! ( "Publishing crate {}" , krate. name) ;
314338 }
315339 publish ( & Path :: new ( & krate. path ) , dry_run) ;
316340 }
341+ Ok ( ( ) )
317342}
318343
319344fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
@@ -357,7 +382,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
357382 let dep_map = compute_immediate_deps ( & crates) ;
358383 let graph = dep_map_to_graph ( & dep_map) ;
359384 display_dep_map ( & dep_map, 2 ) ;
360- publish_crates ( graph, * dry_run)
385+ publish_crates ( graph, * dry_run) ?
361386 }
362387 }
363388
0 commit comments