#![cfg_attr(
all(doc, feature = "document-features"),
doc = ::document_features::document_features!()
)]
#![cfg_attr(all(doc, feature = "document-features"), feature(doc_cfg))]
#![deny(missing_docs)]
#![forbid(unsafe_code)]
use std::path::PathBuf;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
pub struct Capabilities {
pub precompose_unicode: bool,
pub ignore_case: bool,
pub executable_bit: bool,
pub symlink: bool,
}
mod capabilities;
mod file;
pub use file::{FileOrSymlink, open_options_no_follow, open_read_only_no_follow};
mod snapshot;
pub use snapshot::{FileSnapshot, SharedFileSnapshot, SharedFileSnapshotMut};
pub mod symlink;
mod precompose;
pub mod read_dir;
pub use read_dir::function::read_dir;
#[cfg(feature = "walkdir")]
pub mod walkdir;
#[cfg(feature = "walkdir")]
pub use walkdir::{WalkDir, walkdir_new, walkdir_sorted_new};
pub mod dir;
pub fn current_dir(precompose_unicode: bool) -> std::io::Result<PathBuf> {
let cwd = std::env::current_dir()?;
Ok(if precompose_unicode {
gix_utils::str::precompose_path(cwd.into()).into_owned()
} else {
cwd
})
}
pub fn adjust_shared_repository_permissions(
permissions: std::fs::Permissions,
shared_repository_permissions: i32,
) -> std::fs::Permissions {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
if shared_repository_permissions == 0 {
return permissions;
}
let mut permissions = permissions;
let mode = permissions.mode();
let mut tweak = shared_repository_permissions.unsigned_abs();
if mode & 0o200 == 0 {
tweak &= !0o222;
}
if mode & 0o100 != 0 {
tweak |= (tweak & 0o444) >> 2;
}
let mut adjusted = if shared_repository_permissions < 0 {
(mode & !0o777) | tweak
} else {
mode | tweak
};
if mode & 0o170000 == 0o040000 {
adjusted |= (adjusted & 0o444) >> 2;
if !cfg!(any(target_os = "freebsd", target_os = "openbsd")) && adjusted & 0o060 != 0 {
adjusted |= 0o2000;
}
}
permissions.set_mode(adjusted);
permissions
}
#[cfg(not(unix))]
{
let _ = shared_repository_permissions;
permissions
}
}
pub fn set_shared_repository_permissions(
path: &std::path::Path,
shared_repository_permissions: i32,
) -> std::io::Result<()> {
#[cfg(unix)]
if shared_repository_permissions != 0 {
let current = std::fs::metadata(path)?.permissions();
let adjusted = adjust_shared_repository_permissions(current.clone(), shared_repository_permissions);
if current != adjusted {
std::fs::set_permissions(path, adjusted)?;
}
}
#[cfg(not(unix))]
let _ = (path, shared_repository_permissions);
Ok(())
}
#[derive(Clone)]
pub struct Stack {
root: PathBuf,
current: PathBuf,
current_relative: PathBuf,
valid_components: usize,
current_is_directory: bool,
}
#[cfg(unix)]
pub fn is_executable(metadata: &std::fs::Metadata) -> bool {
use std::os::unix::fs::MetadataExt;
(metadata.mode() & 0o111) != 0
}
pub mod io_err {
use std::io::ErrorKind;
pub fn is_not_found(err: ErrorKind, _raw_err: Option<i32>) -> bool {
err == ErrorKind::NotFound || err == ErrorKind::NotADirectory
}
}
#[cfg(not(unix))]
pub fn is_executable(_metadata: &std::fs::Metadata) -> bool {
false
}
pub mod stack;