#[non_exhaustive]pub enum TreeError {
ManifestNotFound(PathBuf),
ManifestRead(String),
ManifestParse {
path: PathBuf,
detail: String,
},
Git(GitError),
CycleDetected {
chain: Vec<String>,
},
PackNameMismatch {
got: String,
expected: String,
path: PathBuf,
},
ChildPathInvalid {
child_name: String,
path: String,
reason: String,
},
LegacyLockfileDetected {
path: PathBuf,
},
UntrackedGitRepos {
paths: Vec<PathBuf>,
},
DirtyTreeRefusal {
path: PathBuf,
kind: DirtyTreeRefusalKind,
},
ManifestPathEscape {
path: String,
reason: String,
},
}Expand description
Errors raised during a pack-tree walk.
Marked #[non_exhaustive] so later slices (credentials, submodules,
partial walks) can add variants without breaking consumers.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
ManifestNotFound(PathBuf)
The walker expected a pack.yaml at the given location but could not
find one (or its enclosing .grex/ directory was missing).
ManifestRead(String)
The manifest file existed but could not be read from disk.
ManifestParse
The manifest file was read but did not parse as a valid pack.yaml.
Fields
Git(GitError)
A git operation (clone, fetch, checkout, …) failed while hydrating a
child pack. The underlying GitError is preserved in full.
CycleDetected
A cycle was detected during the walk. chain lists the pack URLs (or
paths for the root) from the outermost pack down to the recurrence.
PackNameMismatch
A cloned child’s pack.yaml declared a name that does not match
what the parent pack expected for that children: entry.
Fields
ChildPathInvalid
A children[].path (or URL-derived tail) violated the bare-name
rule. Surfaced by the walker BEFORE any clone of the offending
child fires so a malicious path: ../escape in a parent pack
cannot materialise a directory outside the pack root. This is a
security boundary, not a soft validation concern — see
crates/grex-core/src/pack/validate/child_path.rs for the shared
rejection logic.
Fields
LegacyLockfileDetected
A v1.1.1-shape lockfile was encountered without the
--migrate-lockfile opt-in. v1.2.0 changed the on-disk lockfile
schema; the operator must explicitly run the migrator to convert
pre-existing lockfiles. Emitted by Stage 1.h walker entry-point
before any pack-tree work begins. Dormant until 1.h wires the
detector.
UntrackedGitRepos
One or more declared children own a .git/ directory but lack a
.grex/pack.yaml, and the v1.2.0 nested-children semantics
preclude the v1.1.1 “synthesize plain-git pack” fallback (e.g.
because a sibling explicitly opted out, or the parent manifest
disabled synthesis). Aggregated by Stage 1.e Phase 1; the walker
reports every offender in one go so the operator can fix the
manifest with a single pass.
DirtyTreeRefusal
Stage 1.f Phase 2 prune refused to remove a destination because
the recursive consent walk returned a non-Clean verdict.
kind discriminates the specific safety violation so the CLI
can suggest the correct override flag.
Fields
kind: DirtyTreeRefusalKindSpecific consent violation that triggered the refusal.
ManifestPathEscape
Stage 1.c validator rejected a child manifest segment that
resolved outside the parent pack root. Distinct from
TreeError::ChildPathInvalid — that variant rejects the
literal path: syntax (slashes, dots, absolute paths);
ManifestPathEscape is the post-resolution boundary check that
catches symlink-driven and platform-specific escapes.
Trait Implementations§
Source§impl Error for TreeError
impl Error for TreeError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Auto Trait Implementations§
impl Freeze for TreeError
impl RefUnwindSafe for TreeError
impl Send for TreeError
impl Sync for TreeError
impl Unpin for TreeError
impl UnsafeUnpin for TreeError
impl UnwindSafe for TreeError
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more