Skip to content

Commit cb26c9b

Browse files
committed
⚗️ Add .mtree support
1 parent 5ee2d6d commit cb26c9b

5 files changed

Lines changed: 1344 additions & 23 deletions

File tree

cli/src/command/core.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
pub(crate) mod iter;
2+
#[cfg(unix)]
3+
pub(crate) mod mtree;
24
pub(crate) mod path;
35
mod path_filter;
46
pub(crate) mod path_lock;
@@ -1610,6 +1612,70 @@ pub(crate) fn transform_archive_entries<R: io::Read>(
16101612
}
16111613

16121614
/// Reads entries from an archive source (file or stdin) and transforms them.
1615+
///
1616+
/// This function auto-detects the format of the source:
1617+
/// - PNA archive: Copies entries with optional transformation
1618+
/// - mtree manifest: Reads files from filesystem with metadata overrides (Unix only)
1619+
#[cfg(unix)]
1620+
pub(crate) fn read_archive_source(
1621+
source: &ArchiveSource,
1622+
create_options: &CreateOptions,
1623+
filter: &PathFilter<'_>,
1624+
time_filters: &TimeFilters,
1625+
password: Option<&[u8]>,
1626+
) -> io::Result<Vec<io::Result<Option<NormalEntry>>>> {
1627+
match source {
1628+
ArchiveSource::File(path) => {
1629+
let file = fs::File::open(path)
1630+
.map_err(|e| io::Error::new(e.kind(), format!("{}: {}", path.display(), e)))?;
1631+
let mut reader = io::BufReader::with_capacity(64 * 1024, file);
1632+
1633+
let format = mtree::detect_format(&mut reader)
1634+
.map_err(|e| io::Error::new(e.kind(), format!("{}: {}", path.display(), e)))?;
1635+
1636+
match format {
1637+
mtree::SourceFormat::Pna => transform_archive_entries(
1638+
reader,
1639+
create_options,
1640+
filter,
1641+
time_filters,
1642+
password,
1643+
)
1644+
.map_err(|e| io::Error::new(e.kind(), format!("{}: {}", path.display(), e))),
1645+
mtree::SourceFormat::Mtree => {
1646+
mtree::transform_mtree_entries(reader, create_options, filter, time_filters)
1647+
.map_err(|e| io::Error::new(e.kind(), format!("{}: {}", path.display(), e)))
1648+
}
1649+
}
1650+
}
1651+
ArchiveSource::Stdin => {
1652+
let mut reader = io::BufReader::new(io::stdin().lock());
1653+
1654+
let format = mtree::detect_format(&mut reader)
1655+
.map_err(|e| io::Error::new(e.kind(), format!("<stdin>: {}", e)))?;
1656+
1657+
match format {
1658+
mtree::SourceFormat::Pna => transform_archive_entries(
1659+
reader,
1660+
create_options,
1661+
filter,
1662+
time_filters,
1663+
password,
1664+
)
1665+
.map_err(|e| io::Error::new(e.kind(), format!("<stdin>: {}", e))),
1666+
mtree::SourceFormat::Mtree => {
1667+
mtree::transform_mtree_entries(reader, create_options, filter, time_filters)
1668+
.map_err(|e| io::Error::new(e.kind(), format!("<stdin>: {}", e)))
1669+
}
1670+
}
1671+
}
1672+
}
1673+
}
1674+
1675+
/// Reads entries from an archive source (file or stdin) and transforms them.
1676+
///
1677+
/// On non-Unix platforms, only PNA format is supported. mtree format is not available.
1678+
#[cfg(not(unix))]
16131679
pub(crate) fn read_archive_source(
16141680
source: &ArchiveSource,
16151681
create_options: &CreateOptions,

0 commit comments

Comments
 (0)