diff --git a/rust-bindings/rust/src/lib.rs b/rust-bindings/rust/src/lib.rs index 0e29c88d..89e49dbc 100644 --- a/rust-bindings/rust/src/lib.rs +++ b/rust-bindings/rust/src/lib.rs @@ -50,9 +50,9 @@ pub use crate::object_name::*; mod repo; pub use crate::repo::*; -#[cfg(any(feature = "v2018_2", feature = "dox"))] +#[cfg(any(feature = "v2016_8", feature = "dox"))] mod repo_checkout_at_options; -#[cfg(any(feature = "v2018_2", feature = "dox"))] +#[cfg(any(feature = "v2016_8", feature = "dox"))] pub use crate::repo_checkout_at_options::*; mod se_policy; diff --git a/rust-bindings/rust/src/repo_checkout_at_options.rs b/rust-bindings/rust/src/repo_checkout_at_options.rs index 2a570c58..7d92e546 100644 --- a/rust-bindings/rust/src/repo_checkout_at_options.rs +++ b/rust-bindings/rust/src/repo_checkout_at_options.rs @@ -4,8 +4,9 @@ use libc::c_char; use ostree_sys::*; use std::path::PathBuf; +#[cfg(any(feature = "v2018_2", feature = "dox"))] mod repo_checkout_filter; - +#[cfg(any(feature = "v2018_2", feature = "dox"))] pub use self::repo_checkout_filter::RepoCheckoutFilter; pub struct RepoCheckoutAtOptions { @@ -15,8 +16,11 @@ pub struct RepoCheckoutAtOptions { pub enable_fsync: bool, pub process_whiteouts: bool, pub no_copy_fallback: bool, + #[cfg(any(feature = "v2017_6", feature = "dox"))] pub force_copy: bool, + #[cfg(any(feature = "v2017_7", feature = "dox"))] pub bareuseronly_dirs: bool, + #[cfg(any(feature = "v2018_9", feature = "dox"))] pub force_copy_zerosized: bool, pub subpath: Option, pub devino_to_csum_cache: Option, @@ -29,7 +33,9 @@ pub struct RepoCheckoutAtOptions { /// an FFI boundary and into the libostree C code (which is Undefined Behavior). If you prefer to /// swallow the panic rather than aborting, you can use `std::panic::catch_unwind` inside your /// callback to catch and silence any panics that occur. + #[cfg(any(feature = "v2018_2", feature = "dox"))] pub filter: Option, + #[cfg(any(feature = "v2017_6", feature = "dox"))] pub sepolicy: Option, pub sepolicy_prefix: Option, } @@ -43,12 +49,17 @@ impl Default for RepoCheckoutAtOptions { enable_fsync: false, process_whiteouts: false, no_copy_fallback: false, + #[cfg(feature = "v2017_6")] force_copy: false, + #[cfg(feature = "v2017_7")] bareuseronly_dirs: false, + #[cfg(feature = "v2018_9")] force_copy_zerosized: false, subpath: None, devino_to_csum_cache: None, + #[cfg(feature = "v2018_2")] filter: None, + #[cfg(feature = "v2017_6")] sepolicy: None, sepolicy_prefix: None, } @@ -83,9 +94,21 @@ impl<'a> ToGlibPtr<'a, *const OstreeRepoCheckoutAtOptions> for RepoCheckoutAtOpt options.enable_fsync = self.enable_fsync.to_glib(); options.process_whiteouts = self.process_whiteouts.to_glib(); options.no_copy_fallback = self.no_copy_fallback.to_glib(); - options.force_copy = self.force_copy.to_glib(); - options.bareuseronly_dirs = self.bareuseronly_dirs.to_glib(); - options.force_copy_zerosized = self.force_copy_zerosized.to_glib(); + + #[cfg(feature = "v2017_6")] + { + options.force_copy = self.force_copy.to_glib(); + } + + #[cfg(feature = "v2017_7")] + { + options.bareuseronly_dirs = self.bareuseronly_dirs.to_glib(); + } + + #[cfg(feature = "v2018_9")] + { + options.force_copy_zerosized = self.force_copy_zerosized.to_glib(); + } // We keep these complex values alive by returning them in our Stash. Technically, some of // these are being kept alive by `self` already, but it's better to be consistent here. @@ -95,12 +118,22 @@ impl<'a> ToGlibPtr<'a, *const OstreeRepoCheckoutAtOptions> for RepoCheckoutAtOpt options.sepolicy_prefix = sepolicy_prefix.0; let devino_to_csum_cache = self.devino_to_csum_cache.to_glib_none(); options.devino_to_csum_cache = devino_to_csum_cache.0; - let sepolicy = self.sepolicy.to_glib_none(); - options.sepolicy = sepolicy.0; - if let Some(filter) = &self.filter { - options.filter_user_data = filter.to_glib_none().0; - options.filter = Some(repo_checkout_filter::filter_trampoline_unwindsafe); + #[cfg(feature = "v2017_6")] + let sepolicy = { + let sepolicy = self.sepolicy.to_glib_none(); + options.sepolicy = sepolicy.0; + sepolicy + }; + #[cfg(not(feature = "v2017_6"))] + let sepolicy = None.to_glib_none(); + + #[cfg(feature = "v2018_2")] + { + if let Some(filter) = &self.filter { + options.filter_user_data = filter.to_glib_none().0; + options.filter = Some(repo_checkout_filter::filter_trampoline_unwindsafe); + } } Stash( @@ -119,8 +152,6 @@ impl<'a> ToGlibPtr<'a, *const OstreeRepoCheckoutAtOptions> for RepoCheckoutAtOpt #[cfg(test)] mod tests { use super::*; - use crate::RepoCheckoutFilterResult; - use gio::{File, NONE_CANCELLABLE}; use glib_sys::{GFALSE, GTRUE}; use std::ffi::{CStr, CString}; use std::ptr; @@ -137,16 +168,22 @@ mod tests { assert_eq!((*ptr).enable_fsync, GFALSE); assert_eq!((*ptr).process_whiteouts, GFALSE); assert_eq!((*ptr).no_copy_fallback, GFALSE); + #[cfg(feature = "v2017_6")] assert_eq!((*ptr).force_copy, GFALSE); + #[cfg(feature = "v2017_7")] assert_eq!((*ptr).bareuseronly_dirs, GFALSE); + #[cfg(feature = "v2018_9")] assert_eq!((*ptr).force_copy_zerosized, GFALSE); assert_eq!((*ptr).unused_bools, [GFALSE; 4]); assert_eq!((*ptr).subpath, ptr::null()); assert_eq!((*ptr).devino_to_csum_cache, ptr::null_mut()); assert_eq!((*ptr).unused_ints, [0; 6]); assert_eq!((*ptr).unused_ptrs, [ptr::null_mut(); 3]); + #[cfg(feature = "v2018_2")] assert_eq!((*ptr).filter, None); + #[cfg(feature = "v2018_2")] assert_eq!((*ptr).filter_user_data, ptr::null_mut()); + #[cfg(feature = "v2017_6")] assert_eq!((*ptr).sepolicy, ptr::null_mut()); assert_eq!((*ptr).sepolicy_prefix, ptr::null()); } @@ -161,13 +198,22 @@ mod tests { enable_fsync: true, process_whiteouts: true, no_copy_fallback: true, + #[cfg(feature = "v2017_6")] force_copy: true, + #[cfg(feature = "v2017_7")] bareuseronly_dirs: true, + #[cfg(feature = "v2018_9")] force_copy_zerosized: true, subpath: Some("sub/path".into()), devino_to_csum_cache: Some(RepoDevInoCache::new()), - filter: RepoCheckoutFilter::new(|_repo, _path, _stat| RepoCheckoutFilterResult::Skip), - sepolicy: Some(SePolicy::new(&File::new_for_path("a/b"), NONE_CANCELLABLE).unwrap()), + #[cfg(feature = "v2018_2")] + filter: RepoCheckoutFilter::new(|_repo, _path, _stat| { + crate::RepoCheckoutFilterResult::Skip + }), + #[cfg(feature = "v2017_6")] + sepolicy: Some( + SePolicy::new(&gio::File::new_for_path("a/b"), gio::NONE_CANCELLABLE).unwrap(), + ), sepolicy_prefix: Some("prefix".into()), }; let stash = options.to_glib_none(); @@ -182,8 +228,11 @@ mod tests { assert_eq!((*ptr).enable_fsync, GTRUE); assert_eq!((*ptr).process_whiteouts, GTRUE); assert_eq!((*ptr).no_copy_fallback, GTRUE); + #[cfg(feature = "v2017_6")] assert_eq!((*ptr).force_copy, GTRUE); + #[cfg(feature = "v2017_7")] assert_eq!((*ptr).bareuseronly_dirs, GTRUE); + #[cfg(feature = "v2018_9")] assert_eq!((*ptr).force_copy_zerosized, GTRUE); assert_eq!((*ptr).unused_bools, [GFALSE; 4]); assert_eq!( @@ -196,11 +245,14 @@ mod tests { ); assert_eq!((*ptr).unused_ints, [0; 6]); assert_eq!((*ptr).unused_ptrs, [ptr::null_mut(); 3]); + #[cfg(feature = "v2018_2")] assert!((*ptr).filter == Some(repo_checkout_filter::filter_trampoline_unwindsafe)); + #[cfg(feature = "v2018_2")] assert_eq!( (*ptr).filter_user_data, options.filter.as_ref().unwrap().to_glib_none().0, ); + #[cfg(feature = "v2017_6")] assert_eq!((*ptr).sepolicy, options.sepolicy.to_glib_none().0); assert_eq!( CStr::from_ptr((*ptr).sepolicy_prefix), diff --git a/rust-bindings/rust/tests/repo/checkout_at.rs b/rust-bindings/rust/tests/repo/checkout_at.rs index 01bfac9d..94028642 100644 --- a/rust-bindings/rust/tests/repo/checkout_at.rs +++ b/rust-bindings/rust/tests/repo/checkout_at.rs @@ -2,7 +2,6 @@ use crate::util::*; use gio::NONE_CANCELLABLE; use ostree::*; use std::os::unix::io::AsRawFd; -use std::path::PathBuf; #[test] fn should_checkout_at_with_none_options() { @@ -60,12 +59,7 @@ fn should_checkout_at_with_options() { mode: RepoCheckoutMode::User, overwrite_mode: RepoCheckoutOverwriteMode::AddFiles, enable_fsync: true, - force_copy: true, - force_copy_zerosized: true, devino_to_csum_cache: Some(RepoDevInoCache::new()), - filter: RepoCheckoutFilter::new(|_repo, _path, _stat| { - RepoCheckoutFilterResult::Allow - }), ..Default::default() }), dirfd.as_raw_fd(), @@ -79,7 +73,10 @@ fn should_checkout_at_with_options() { } #[test] +#[cfg(feature = "v2018_2")] fn should_checkout_at_with_filter() { + use std::path::Path; + let test_repo = TestRepo::new(); let checksum = test_repo.test_commit("test"); let checkout_dir = tempfile::tempdir().expect("checkout dir"); @@ -90,7 +87,7 @@ fn should_checkout_at_with_filter() { .checkout_at( Some(&RepoCheckoutAtOptions { filter: RepoCheckoutFilter::new(|_repo, path, _stat| { - if path == PathBuf::from("/testdir/testfile") { + if path == Path::new("/testdir/testfile") { RepoCheckoutFilterResult::Skip } else { RepoCheckoutFilterResult::Allow