Now let's take a silly one
1use std::path::Path;
2
3use knot_git::{INCOMING_PREFIX, Repo, Staging};
4
5use crate::error::PackError;
6use crate::meter::PackLimits;
7use crate::objects;
8
9pub(crate) struct Quarantine {
10 staging: Staging,
11}
12
13impl Quarantine {
14 pub(crate) fn stage(
15 live: &Repo,
16 pack: &[u8],
17 limits: &PackLimits,
18 kind: gix::hash::Kind,
19 ) -> Result<Self, PackError> {
20 let staging = Staging::new(live)?;
21 objects::index_pack(&staging.repo().objects_dir(), pack, limits, kind)?;
22 Ok(Self { staging })
23 }
24
25 pub(crate) fn repo(&self) -> &Repo {
26 self.staging.repo()
27 }
28
29 pub(crate) fn migrate_into(&self, live: &Repo) -> Result<(), PackError> {
30 self.staging.migrate_into(live).map_err(PackError::from)
31 }
32}
33
34pub fn sweep_incoming(scan_path: &Path) -> usize {
35 walkdir::WalkDir::new(scan_path)
36 .into_iter()
37 .filter_entry(|entry| entry.file_name().to_str() != Some("objects"))
38 .filter_map(Result::ok)
39 .filter(|entry| entry.file_type().is_dir())
40 .filter(|entry| {
41 entry
42 .file_name()
43 .to_str()
44 .is_some_and(|name| name.starts_with(INCOMING_PREFIX))
45 })
46 .map(|entry| entry.into_path())
47 .collect::<Vec<_>>()
48 .into_iter()
49 .filter(|path| std::fs::remove_dir_all(path).is_ok())
50 .count()
51}