pub struct ShepPaths {
pub home: PathBuf,
pub daemon_config: PathBuf,
pub snapshot: PathBuf,
pub logs: PathBuf,
pub pids: PathBuf,
pub run: PathBuf,
pub socket: PathBuf,
pub barks: PathBuf,
pub kv: PathBuf,
}Expand description
Resolved filesystem layout for one shep home
All paths are derived from $SHEP_HOME (default <home>/.shep); nothing
here touches the filesystem. The root itself is created by the CLI’s own
ensure_home, for the commands that need it before any daemon exists
(startup above all), and everything under it by
shep_daemon::boot::init_dirs on each boot.
Fields§
§home: PathBufRoot: $SHEP_HOME
daemon_config: PathBufDaemon config: shep.toml
snapshot: PathBufFlock snapshot (muster roll): flock.json
logs: PathBufLog directory
pids: PathBufPid-file directory
run: PathBufRuntime dir (sockets; created 0700)
socket: PathBufThe control address the client dials and the daemon answers on.
Two different kinds of thing behind one field, on purpose. On
unix it is a filesystem path, run/shep.sock, and a real AF_UNIX
socket file lives there. On Windows it is Self::pipe_name — a
named pipe’s \\.\pipe\... name, which is path-shaped but names an
object in the kernel’s pipe namespace rather than a file on any
volume.
One field rather than two because every consumer in the workspace
treats this as an opaque address it hands to Client::connect, and a
second field would make all of them choose. The one place the
difference is load-bearing is a caller that treats this as a file —
shep-cli’s wait_for_socket_to_disappear is the only one, and it
carries its own Windows arm because a pipe has no directory entry to
watch: it stops existing when its last handle closes, so “has the
daemon gone” is a connect attempt there, not a Path::exists.
A corollary worth stating because it silently breaks otherwise:
socket.parent() is $SHEP_HOME/run on unix and the meaningless
\\.\pipe on Windows. Nothing may derive a directory from this field.
barks: PathBufBark history ring: barks.jsonl
kv: PathBufKey/value store: kv.json
Implementations§
Source§impl ShepPaths
impl ShepPaths
Sourcepub fn pipe_name(&self) -> String
pub fn pipe_name(&self) -> String
Windows named-pipe identity for this home:
\\.\pipe\shep-<sanitized>-<digest>
The readable half is the home path with every non-alphanumeric
character collapsed to -, capped, so an operator reading a pipe name
can tell which home it belongs to. That half alone does not identify
a home: \, :, ., _ and a literal - all become -, so
C:\a\b and C:\a-b sanitize to one string. The pipe namespace is
machine-global and crate::transport::Listener::bind asks for
first_pipe_instance, so a collision does not surface as an error: the
second home’s daemon is refused as already running, and that home’s CLI
then drives the first home’s flock. No handshake field carries a home,
so nothing downstream would catch it.
The appended digest of the full home path is what makes the name distinct. Changing this derivation is a breaking change for any already-running daemon: it stays bound under a name a client built afterward would never dial.
Sourcepub fn resolve(env: &dyn Fn(&str) -> Option<String>, home_dir: &Path) -> Self
pub fn resolve(env: &dyn Fn(&str) -> Option<String>, home_dir: &Path) -> Self
Resolves the layout from an environment lookup and the user’s home dir
Self::socket resolves per-platform — a socket file under run/ on
unix, a \\.\pipe\... name on Windows — for the reason that field’s
own doc gives. Everything else is identical on both.
Trait Implementations§
impl Eq for ShepPaths
impl StructuralPartialEq for ShepPaths
Auto Trait Implementations§
impl Freeze for ShepPaths
impl RefUnwindSafe for ShepPaths
impl Send for ShepPaths
impl Sync for ShepPaths
impl Unpin for ShepPaths
impl UnsafeUnpin for ShepPaths
impl UnwindSafe for ShepPaths
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.