@@ -19,6 +19,7 @@ use crate::workspace_dir;
1919use semver:: Version ;
2020use std:: path:: { Path , PathBuf } ;
2121use std:: str:: FromStr ;
22+ use toml_edit:: { DocumentMut , Item , TableLike } ;
2223
2324#[ derive( Debug , Clone ) ]
2425pub struct Package {
@@ -65,7 +66,7 @@ pub fn all_packages() -> Vec<Package> {
6566 // Integrations
6667 let dav_server = make_package ( "integrations/dav-server" , "0.7.0" , vec ! [ core. clone( ) ] ) ;
6768 let object_store = make_package ( "integrations/object_store" , "0.55.0" , vec ! [ core. clone( ) ] ) ;
68- let parquet = make_package ( "integrations/parquet" , "0.7 .0" , vec ! [ core. clone( ) ] ) ;
69+ let parquet = make_package ( "integrations/parquet" , "0.8 .0" , vec ! [ core. clone( ) ] ) ;
6970 let unftp_sbe = make_package ( "integrations/unftp-sbe" , "0.4.0" , vec ! [ core. clone( ) ] ) ;
7071
7172 // Binaries moved to separate repositories; no longer released from this repo
@@ -93,46 +94,174 @@ pub fn all_packages() -> Vec<Package> {
9394
9495pub fn update_package_version ( package : & Package ) -> bool {
9596 match package. name . as_str ( ) {
96- "core" => update_cargo_version ( & package. path , & package. version ) ,
97- "integrations/dav-server" => update_cargo_version ( & package. path , & package. version ) ,
98- "integrations/object_store" => update_cargo_version ( & package. path , & package. version ) ,
99- "integrations/parquet" => update_cargo_version ( & package. path , & package. version ) ,
100- "integrations/unftp-sbe" => update_cargo_version ( & package. path , & package. version ) ,
97+ "core" => update_cargo_version ( & package. path , & package. version , package. dependencies ( ) ) ,
98+ "integrations/dav-server" => {
99+ update_cargo_version ( & package. path , & package. version , package. dependencies ( ) )
100+ }
101+ "integrations/object_store" => {
102+ update_cargo_version ( & package. path , & package. version , package. dependencies ( ) )
103+ }
104+ "integrations/parquet" => {
105+ update_cargo_version ( & package. path , & package. version , package. dependencies ( ) )
106+ }
107+ "integrations/unftp-sbe" => {
108+ update_cargo_version ( & package. path , & package. version , package. dependencies ( ) )
109+ }
101110
102111 "bindings/c" => false , // C bindings has no version to update
103112 "bindings/cpp" => false , // C++ bindings has no version to update
104113 "bindings/lua" => false , // Lua bindings has no version to update
105114
106- "bindings/python" => update_cargo_version ( & package. path , & package. version ) ,
115+ "bindings/python" => update_cargo_version ( & package. path , & package. version , & [ ] ) ,
107116 "bindings/java" => update_maven_version ( & package. path , & package. version ) ,
108117 "bindings/nodejs" => update_nodejs_version ( & package. path , & package. version ) ,
109118
110119 name => panic ! ( "unknown package: {name}" ) ,
111120 }
112121}
113122
114- fn update_cargo_version ( path : & Path , version : & Version ) -> bool {
123+ fn update_cargo_version ( path : & Path , version : & Version , dependencies : & [ Package ] ) -> bool {
115124 let path = path. join ( "Cargo.toml" ) ;
116125 let manifest = std:: fs:: read_to_string ( & path) . unwrap ( ) ;
117- let mut manifest = toml_edit:: DocumentMut :: from_str ( manifest. as_str ( ) ) . unwrap ( ) ;
126+ let mut manifest = DocumentMut :: from_str ( manifest. as_str ( ) ) . unwrap ( ) ;
127+ let mut updated = update_manifest_version ( & mut manifest, version, & path) ;
118128
119- let old_version = match manifest[ "package" ] [ "version" ] . as_str ( ) {
120- Some ( version) => Version :: parse ( version) . unwrap ( ) ,
121- None => panic ! ( "missing version for package: {}" , path. display( ) ) ,
122- } ;
129+ for dependency in dependencies {
130+ updated |= update_dependency_version ( & mut manifest, dependency) ;
131+ }
123132
124- if & old_version != version {
125- manifest[ "package" ] [ "version" ] = toml_edit:: value ( version. to_string ( ) ) ;
133+ if updated {
126134 std:: fs:: write ( & path, manifest. to_string ( ) ) . unwrap ( ) ;
127- println ! (
128- "updating version for package: {} from {} to {}" ,
129- path. display( ) ,
130- old_version,
131- version
132- ) ;
133- true
134- } else {
135- false
135+ }
136+
137+ updated
138+ }
139+
140+ fn update_manifest_version ( manifest : & mut DocumentMut , version : & Version , path : & Path ) -> bool {
141+ if let Some ( old_version) = manifest[ "package" ] [ "version" ]
142+ . as_str ( )
143+ . map ( Version :: parse)
144+ . transpose ( )
145+ . unwrap ( )
146+ {
147+ if & old_version != version {
148+ manifest[ "package" ] [ "version" ] = toml_edit:: value ( version. to_string ( ) ) ;
149+ println ! (
150+ "updating version for package: {} from {} to {}" ,
151+ path. display( ) ,
152+ old_version,
153+ version
154+ ) ;
155+ return true ;
156+ }
157+
158+ return false ;
159+ }
160+
161+ if let Some ( old_version) = manifest[ "workspace" ] [ "package" ] [ "version" ]
162+ . as_str ( )
163+ . map ( Version :: parse)
164+ . transpose ( )
165+ . unwrap ( )
166+ {
167+ if & old_version != version {
168+ manifest[ "workspace" ] [ "package" ] [ "version" ] = toml_edit:: value ( version. to_string ( ) ) ;
169+ println ! (
170+ "updating version for package: {} from {} to {}" ,
171+ path. display( ) ,
172+ old_version,
173+ version
174+ ) ;
175+ return true ;
176+ }
177+
178+ return false ;
179+ }
180+
181+ panic ! ( "missing version for package: {}" , path. display( ) ) ;
182+ }
183+
184+ fn update_dependency_version ( manifest : & mut DocumentMut , dependency : & Package ) -> bool {
185+ let Some ( crate_name) = dependency. crate_name ( ) else {
186+ return false ;
187+ } ;
188+
189+ update_dependency_version_in_table ( manifest. as_table_mut ( ) , crate_name, dependency)
190+ }
191+
192+ fn update_dependency_version_in_table (
193+ table : & mut dyn TableLike ,
194+ crate_name : & str ,
195+ dependency : & Package ,
196+ ) -> bool {
197+ let mut updated = false ;
198+
199+ for table_name in [ "dependencies" , "dev-dependencies" , "build-dependencies" ] {
200+ let Some ( dependencies) = table. get_mut ( table_name) . and_then ( Item :: as_table_like_mut) else {
201+ continue ;
202+ } ;
203+
204+ updated |= update_dependency_version_in_dependencies ( dependencies, crate_name, dependency) ;
205+ }
206+
207+ let Some ( targets) = table. get_mut ( "target" ) . and_then ( Item :: as_table_like_mut) else {
208+ return updated;
209+ } ;
210+
211+ for ( _, target) in targets. iter_mut ( ) {
212+ let Some ( target) = target. as_table_like_mut ( ) else {
213+ continue ;
214+ } ;
215+ updated |= update_dependency_version_in_table ( target, crate_name, dependency) ;
216+ }
217+
218+ updated
219+ }
220+
221+ fn update_dependency_version_in_dependencies (
222+ dependencies : & mut dyn TableLike ,
223+ crate_name : & str ,
224+ dependency : & Package ,
225+ ) -> bool {
226+ let Some ( entry) = dependencies. get_mut ( crate_name) else {
227+ return false ;
228+ } ;
229+ let Some ( entry) = entry. as_table_like_mut ( ) else {
230+ return false ;
231+ } ;
232+ let Some ( "../../core" ) = entry. get ( "path" ) . and_then ( Item :: as_str) else {
233+ return false ;
234+ } ;
235+ let Some ( value) = entry. get_mut ( "version" ) else {
236+ return false ;
237+ } ;
238+
239+ let old_version = match value. as_str ( ) {
240+ Some ( version) => match Version :: parse ( version) {
241+ Ok ( version) => version,
242+ Err ( _) => return false ,
243+ } ,
244+ None => panic ! ( "missing dependency version for crate: {crate_name}" ) ,
245+ } ;
246+
247+ if old_version == dependency. version {
248+ return false ;
249+ }
250+
251+ * value = toml_edit:: value ( dependency. version . to_string ( ) ) ;
252+ println ! (
253+ "updating dependency version for crate: {} from {} to {}" ,
254+ crate_name, old_version, dependency. version
255+ ) ;
256+ true
257+ }
258+
259+ impl Package {
260+ fn crate_name ( & self ) -> Option < & ' static str > {
261+ match self . name . as_str ( ) {
262+ "core" => Some ( "opendal" ) ,
263+ _ => None ,
264+ }
136265 }
137266}
138267
@@ -193,3 +322,126 @@ fn update_nodejs_version(path: &Path, version: &Version) -> bool {
193322
194323 updated
195324}
325+
326+ #[ cfg( test) ]
327+ mod tests {
328+ use super :: * ;
329+
330+ fn temp_test_dir ( name : & str ) -> PathBuf {
331+ let nanos = std:: time:: SystemTime :: now ( )
332+ . duration_since ( std:: time:: UNIX_EPOCH )
333+ . unwrap ( )
334+ . as_nanos ( ) ;
335+ std:: env:: temp_dir ( ) . join ( format ! ( "odev-package-{name}-{nanos}" ) )
336+ }
337+
338+ #[ test]
339+ fn parquet_release_version_matches_manifest ( ) {
340+ let parquet = all_packages ( )
341+ . into_iter ( )
342+ . find ( |package| package. name ( ) == "integrations/parquet" )
343+ . unwrap ( ) ;
344+
345+ assert_eq ! ( parquet. version, Version :: parse( "0.8.0" ) . unwrap( ) ) ;
346+ }
347+
348+ #[ test]
349+ fn update_manifest_version_supports_workspace_package_version ( ) {
350+ let mut manifest = DocumentMut :: from_str (
351+ r#"
352+ [workspace.package]
353+ version = "0.55.0"
354+
355+ [package]
356+ name = "opendal"
357+ version = { workspace = true }
358+ "# ,
359+ )
360+ . unwrap ( ) ;
361+
362+ let updated = update_manifest_version (
363+ & mut manifest,
364+ & Version :: parse ( "0.56.0" ) . unwrap ( ) ,
365+ Path :: new ( "core/Cargo.toml" ) ,
366+ ) ;
367+
368+ assert ! ( updated) ;
369+ assert_eq ! (
370+ manifest[ "workspace" ] [ "package" ] [ "version" ] . as_str( ) ,
371+ Some ( "0.56.0" )
372+ ) ;
373+ assert ! ( !manifest[ "package" ] [ "version" ] . is_str( ) ) ;
374+ }
375+
376+ #[ test]
377+ fn update_dependency_version_only_touches_release_managed_core_constraints ( ) {
378+ let dir = temp_test_dir ( "dependency-sync" ) ;
379+ std:: fs:: create_dir_all ( & dir) . unwrap ( ) ;
380+
381+ let manifest_path = dir. join ( "Cargo.toml" ) ;
382+ std:: fs:: write (
383+ & manifest_path,
384+ r#"[package]
385+ name = "demo"
386+ version = "0.8.0"
387+
388+ [dependencies]
389+ opendal = { version = "0.55.0", path = "../../core" }
390+ serde = "1"
391+
392+ [dev-dependencies]
393+ opendal = { version = "0.55.0", path = "../../core", features = ["services-memory"] }
394+
395+ [build-dependencies]
396+ opendal = { version = ">=0", path = "../../core" }
397+
398+ [target.'cfg(unix)'.dependencies]
399+ opendal = { version = "0.55.0", path = "../../core" }
400+
401+ [target.'cfg(windows)'.dependencies]
402+ opendal = { version = "0.55.0", path = "../core" }
403+ "# ,
404+ )
405+ . unwrap ( ) ;
406+
407+ let dependency = Package {
408+ name : "core" . to_string ( ) ,
409+ path : PathBuf :: from ( "core" ) ,
410+ version : Version :: parse ( "0.56.0" ) . unwrap ( ) ,
411+ dependencies : vec ! [ ] ,
412+ } ;
413+
414+ let updated = update_cargo_version (
415+ dir. as_path ( ) ,
416+ & Version :: parse ( "0.8.0" ) . unwrap ( ) ,
417+ & [ dependency] ,
418+ ) ;
419+ assert ! ( updated) ;
420+
421+ let manifest = std:: fs:: read_to_string ( & manifest_path) . unwrap ( ) ;
422+ let manifest = DocumentMut :: from_str ( & manifest) . unwrap ( ) ;
423+
424+ assert_eq ! (
425+ manifest[ "dependencies" ] [ "opendal" ] [ "version" ] . as_str( ) ,
426+ Some ( "0.56.0" )
427+ ) ;
428+ assert_eq ! (
429+ manifest[ "dev-dependencies" ] [ "opendal" ] [ "version" ] . as_str( ) ,
430+ Some ( "0.56.0" )
431+ ) ;
432+ assert_eq ! (
433+ manifest[ "target" ] [ "cfg(unix)" ] [ "dependencies" ] [ "opendal" ] [ "version" ] . as_str( ) ,
434+ Some ( "0.56.0" )
435+ ) ;
436+ assert_eq ! (
437+ manifest[ "build-dependencies" ] [ "opendal" ] [ "version" ] . as_str( ) ,
438+ Some ( ">=0" )
439+ ) ;
440+ assert_eq ! (
441+ manifest[ "target" ] [ "cfg(windows)" ] [ "dependencies" ] [ "opendal" ] [ "version" ] . as_str( ) ,
442+ Some ( "0.55.0" )
443+ ) ;
444+
445+ std:: fs:: remove_dir_all ( dir) . unwrap ( ) ;
446+ }
447+ }
0 commit comments