Skip to content

Commit 4d732d7

Browse files
committed
⚗️ add @archive support in stdio subcommand
Redesign @archive inclusion to preserve CLI argument order exactly. The previous implementation separated filesystem paths and @Archives before processing, which lost the original ordering. Key changes: - Add ItemSource, ArchiveSource, CollectedItem types to core.rs - Add collect_items_from_sources for unified processing - Process arguments one by one, maintaining order - Support @- for reading archives from stdin - Detect stdin conflicts (input archive from stdin vs @-)
1 parent 13d7548 commit 4d732d7

7 files changed

Lines changed: 1168 additions & 72 deletions

File tree

cli/src/command/append.rs

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ use crate::{
66
command::{
77
Command, ask_password, check_password,
88
core::{
9-
AclStrategy, CollectOptions, CollectedItem, CreateOptions, FflagsStrategy, KeepOptions,
10-
MacMetadataStrategy, PathFilter, PathTransformers, PathnameEditor,
11-
PermissionStrategyResolver, TimeFilterResolver, TimestampStrategyResolver,
9+
AclStrategy, CollectOptions, CollectedItem, CreateOptions, EntryResult, FflagsStrategy,
10+
KeepOptions, MacMetadataStrategy, PathFilter, PathTransformers, PathnameEditor,
11+
PermissionStrategyResolver, TimeFilterResolver, TimeFilters, TimestampStrategyResolver,
1212
XattrStrategy, collect_items_from_paths, create_entry, entry_option,
1313
re::{bsd::SubstitutionRule, gnu::TransformRule},
14-
read_paths, read_paths_stdin,
14+
read_archive_source, read_paths, read_paths_stdin,
1515
},
1616
},
1717
utils::{PathPartExt, VCS_FILES, fs::HardlinkResolver},
@@ -460,33 +460,65 @@ fn append_to_archive(args: AppendCommand) -> anyhow::Result<()> {
460460
time_filters: &time_filters,
461461
};
462462
let mut resolver = HardlinkResolver::new(collect_options.follow_links);
463-
let target_items = collect_items_from_paths(&files, &collect_options, &mut resolver)?;
463+
let target_items = collect_items_from_paths(&files, &collect_options, &mut resolver)?
464+
.into_iter()
465+
.map(CollectedItem::Filesystem)
466+
.collect::<Vec<_>>();
464467

465-
run_append_archive(&create_options, archive, target_items)
468+
run_append_archive(
469+
&create_options,
470+
archive,
471+
target_items,
472+
&filter,
473+
&time_filters,
474+
)
466475
}
467476

468477
pub(crate) fn run_append_archive(
469478
create_options: &CreateOptions,
470479
mut archive: Archive<impl io::Write>,
471480
target_items: Vec<CollectedItem>,
481+
filter: &PathFilter<'_>,
482+
time_filters: &TimeFilters,
472483
) -> anyhow::Result<()> {
473484
let (tx, rx) = std::sync::mpsc::channel();
474-
rayon::scope_fifo(|s| {
485+
rayon::scope_fifo(|s| -> anyhow::Result<()> {
475486
for item in target_items {
476-
let tx = tx.clone();
477-
s.spawn_fifo(move |_| {
478-
log::debug!("Adding: {}", item.path.display());
479-
tx.send(create_entry(&item, create_options))
480-
.unwrap_or_else(|e| log::error!("{e}: {}", item.path.display()));
481-
})
487+
match item {
488+
CollectedItem::Filesystem(entry) => {
489+
let tx = tx.clone();
490+
s.spawn_fifo(move |_| {
491+
log::debug!("Adding: {}", entry.path.display());
492+
tx.send(EntryResult::Single(create_entry(&entry, create_options)))
493+
.unwrap_or_else(|e| log::error!("{e}: {}", entry.path.display()));
494+
})
495+
}
496+
CollectedItem::ArchiveMarker(source) => {
497+
let result = read_archive_source(&source, create_options, filter, time_filters);
498+
tx.send(EntryResult::Batch(result))
499+
.unwrap_or_else(|e| log::error!("{e}: archive source {}", source));
500+
}
501+
}
482502
}
483503

484504
drop(tx);
485-
});
505+
Ok(())
506+
})?;
486507

487-
for entry in rx.into_iter() {
488-
if let Some(entry) = entry? {
489-
archive.add_entry(entry)?;
508+
for result in rx.into_iter() {
509+
match result {
510+
EntryResult::Single(entry) => {
511+
if let Some(entry) = entry? {
512+
archive.add_entry(entry)?;
513+
}
514+
}
515+
EntryResult::Batch(entries) => {
516+
for entry in entries? {
517+
if let Some(entry) = entry? {
518+
archive.add_entry(entry)?;
519+
}
520+
}
521+
}
490522
}
491523
}
492524
archive.finalize()?;

0 commit comments

Comments
 (0)