summaryrefslogtreecommitdiffstats
path: root/vendor/gix-discover/src/path.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/gix-discover/src/path.rs
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz
rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-discover/src/path.rs')
-rw-r--r--vendor/gix-discover/src/path.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/vendor/gix-discover/src/path.rs b/vendor/gix-discover/src/path.rs
new file mode 100644
index 000000000..89d260fe9
--- /dev/null
+++ b/vendor/gix-discover/src/path.rs
@@ -0,0 +1,69 @@
+use std::{io::Read, path::PathBuf};
+
+use crate::DOT_GIT_DIR;
+
+///
+pub mod from_gitdir_file {
+ /// The error returned by [`from_gitdir_file()`][crate::path::from_gitdir_file()].
+ #[derive(Debug, thiserror::Error)]
+ #[allow(missing_docs)]
+ pub enum Error {
+ #[error(transparent)]
+ Io(#[from] std::io::Error),
+ #[error(transparent)]
+ Parse(#[from] crate::parse::gitdir::Error),
+ }
+}
+
+fn read_regular_file_content_with_size_limit(path: impl AsRef<std::path::Path>) -> std::io::Result<Vec<u8>> {
+ let path = path.as_ref();
+ let mut file = std::fs::File::open(path)?;
+ let max_file_size = 1024 * 64; // NOTE: git allows 1MB here
+ let file_size = file.metadata()?.len();
+ if file_size > max_file_size {
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ format!(
+ "Refusing to open files larger than {} bytes, '{}' was {} bytes large",
+ max_file_size,
+ path.display(),
+ file_size
+ ),
+ ));
+ }
+ let mut buf = Vec::with_capacity(512);
+ file.read_to_end(&mut buf)?;
+ Ok(buf)
+}
+
+/// Reads a plain path from a file that contains it as its only content, with trailing newlines trimmed.
+pub fn from_plain_file(path: impl AsRef<std::path::Path>) -> Option<std::io::Result<PathBuf>> {
+ use bstr::ByteSlice;
+ let mut buf = match read_regular_file_content_with_size_limit(path) {
+ Ok(buf) => buf,
+ Err(err) if err.kind() == std::io::ErrorKind::NotFound => return None,
+ Err(err) => return Some(Err(err)),
+ };
+ let trimmed_len = buf.trim_end().len();
+ buf.truncate(trimmed_len);
+ Some(Ok(gix_path::from_bstring(buf)))
+}
+
+/// Reads typical `gitdir: ` files from disk as used by worktrees and submodules.
+pub fn from_gitdir_file(path: impl AsRef<std::path::Path>) -> Result<PathBuf, from_gitdir_file::Error> {
+ let path = path.as_ref();
+ let buf = read_regular_file_content_with_size_limit(path)?;
+ let mut gitdir = crate::parse::gitdir(&buf)?;
+ if let Some(parent) = path.parent() {
+ gitdir = parent.join(gitdir);
+ }
+ Ok(gitdir)
+}
+
+/// Conditionally pop a trailing `.git` dir if present.
+pub fn without_dot_git_dir(mut path: PathBuf) -> PathBuf {
+ if path.file_name().and_then(|n| n.to_str()) == Some(DOT_GIT_DIR) {
+ path.pop();
+ }
+ path
+}