Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support archive inspection #797

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 31 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ percent-encoding = "2.3.1"
phf = { version = "0.11.2", features = ["macros"] }
plist = { version = "1.6.1", default-features = false }
uutils_term_grid = "0.6.0"
tar = { version = "0.4.40", optional = true }
terminal_size = "0.3.0"
timeago = { version = "0.4.2", default-features = false }
unicode-width = "0.1"
Expand Down Expand Up @@ -118,10 +119,11 @@ criterion = { version = "0.5.1", features = ["html_reports"] }
trycmd = "0.15"

[features]
default = ["git"]
default = ["git", "archive-inspection"]
git = ["git2"]
vendored-openssl = ["git2/vendored-openssl"]
vendored-libgit2 = ["git2/vendored-libgit2"]
archive-inspection = ["dep:tar"]
# Should only be used inside of flake.nix
nix = []
# Should only be used inside of flake.nix locally (not on CI)
Expand Down
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
pandoc
convco
zip
zlib

# For releases
b3sum
Expand Down
83 changes: 83 additions & 0 deletions src/fs/archives/archive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use std::io;
use std::path::PathBuf;
use std::slice::Iter as SliceIter;

use crate::fs::{File, Filelike};

use super::{ArchiveEntry, ArchiveFormat, Error};
#[cfg(feature = "archive-inspection")]
use super::{ArchiveReader, TarReader};

pub struct Archive {
pub format: ArchiveFormat,
pub path: PathBuf,

contents: Vec<Result<ArchiveEntry, Error>>,
}

#[derive(Clone)]
pub struct ArchiveIterator<'archive> {
inner: SliceIter<'archive, Result<ArchiveEntry, Error>>,
/// Path in archive whose content is iterated over
path: PathBuf,
}

impl<'archive> Iterator for ArchiveIterator<'archive> {
type Item = &'archive Result<ArchiveEntry, Error>;

fn next(&mut self) -> Option<Self::Item> {
while let Some(it) = self.inner.next() {
if it.is_err()
|| it.as_ref().is_ok_and(|x| {
if let Some(p) = x.path().parent() {
p == self.path
} else {
false
}
})
{
return Some(it);
}
}
None
}
}

impl Archive {
pub fn from_path(path: PathBuf) -> io::Result<Self> {
let extension = File::extension(path.as_path()).unwrap_or(String::new());
let format =
ArchiveFormat::from_extension(extension.as_str()).unwrap_or(ArchiveFormat::Unknown);
let contents = match format {
#[cfg(feature = "archive-inspection")]
ArchiveFormat::Tar => TarReader::read_dir(&path),
#[cfg(not(feature = "archive-inspection"))]
ArchiveFormat::Tar => Err(io::Error::new(
io::ErrorKind::Unsupported,
"Archive inspection not supported",
)),
ArchiveFormat::Unknown => {
return Err(io::Error::new(
io::ErrorKind::Unsupported,
"Unsupported archive format",
))
}
}?;
// TODO: could check if any in `contents` is Err and then
// return Err for silent fail
Ok(Archive {
format,
path,
contents,
})
}

/// Produce an iterator of IO results of trying to read all the files in
/// this directory.
pub fn files(&self, root: PathBuf) -> ArchiveIterator<'_> {
ArchiveIterator {
inner: self.contents.iter(),
path: root,
}
}
}
Loading
Loading