Skip to main content

WorkspaceSet

Struct WorkspaceSet 

Source
pub struct WorkspaceSet { /* private fields */ }
Expand description

An install’s many named workspaces: linked groups (multi-repo graphs) and standalone singletons (one-repo graphs), keyed by name in stable order (ADR-0008 multi-workspace). The outer layer over Workspace: it selects which workspace a command operates on, then hands back that Workspace to resolve projects within it. Built from normalised config (WorkspaceSet::from_resolved) so the serve/links selection logic is shared.

Implementations§

Source§

impl WorkspaceSet

Source

pub fn from_workspaces<I>(entries: I) -> Self
where I: IntoIterator<Item = (String, Workspace, bool)>,

Assemble a set from pre-built named workspaces — the shared core of WorkspaceSet::from_resolved and the test constructor. With exactly one entry, that workspace is the default (a bare selection resolves to it).

Source

pub fn from_single( name: impl Into<String>, workspace: Arc<Workspace>, linked: bool, ) -> Self

Wrap an already-built Workspace (shared via Arc) as a one-entry set under name, with linked recording whether that workspace is a cross-linked multi-repo group. Used where a single Workspace is served as the whole set — e.g. roteiro serve merges the read-only graph API over the one workspace it already holds for its model tools and MCP router, so the API’s flat routes resolve to it as the sole (default) workspace. The store handles are shared, never re-opened.

Source

pub fn from_resolved( resolved: Vec<ResolvedWorkspace>, ) -> Result<Self, WorkspaceError>

Build a set from normalised config groups: each group’s roots/repos are discovered into member repo paths and opened as Workspaces. A linked group becomes one multi-repo graph. A standalone (linked = false) group becomes one single-repo graph per member repo — the invariant that a standalone workspace is exactly one repo is upheld here, by splitting, so a hand-built group can never collapse several repos into one unlinked multi-repo graph (the config normaliser already emits standalone as per-repo singletons, so in practice each such group has exactly one repo and the split is a no-op). On a split, the extra members take a -2/-3 suffix off the group name. A group that resolves to no repos is skipped, so a stale root never aborts the whole set.

§Errors

WorkspaceError::Discover if a group’s root cannot be read, or WorkspaceError::Git if an explicit repo path is not inside a git repo.

Source

pub fn plan_reload( &self, resolved: Vec<ResolvedWorkspace>, ) -> Result<SetReloadPlan, WorkspaceError>

Re-discover resolved into the set a reload would install, without touching the live set. All of the reload’s I/O (root scans, git discovery) happens here; WorkspaceSet::apply_reload is then a swap.

A workspace whose name and linkage survive the reload keeps its very Arc<Workspace> — so its open stores stay warm and any handle already shared out (workspace_handles, a scoped tool registry) keeps pointing at the live workspace — and receives a planned ReloadPlan for its own project registry, which retains warm connections per Workspace::apply_reload. A workspace that is new, gone, or has flipped between linked and standalone is rebuilt or dropped, because in those cases the name no longer denotes the same thing.

Planning reads the current entries; concurrent reloads must be serialised by the caller (the SIGHUP handler holds one lock for the whole reload), or the later plan simply wins.

§Errors

As WorkspaceSet::from_resolved.

Source

pub fn apply_reload( &self, plan: SetReloadPlan, ) -> Result<Vec<String>, WorkspaceError>

Install a SetReloadPlan, returning the new workspace names in stable order. Does no I/O: each retained workspace’s planned registry is swapped in, then the entry map is replaced under one write lock.

§Errors

WorkspaceError::Poisoned if a lock was poisoned.

Source

pub fn reload_from_resolved( &self, resolved: Vec<ResolvedWorkspace>, ) -> Result<Vec<String>, WorkspaceError>

Re-discover resolved and install it — WorkspaceSet::plan_reload followed by WorkspaceSet::apply_reload. Use the halves separately when another registry must be swapped in the same breath.

§Errors

As WorkspaceSet::plan_reload.

Source

pub fn names(&self) -> Vec<String>

The configured workspace names, in stable order.

Source

pub fn workspace_handles(&self) -> Vec<(String, Arc<Workspace>)>

Each configured workspace as a (name, shared handle) pair, in stable name order. The Arc<Workspace> is the very handle the set holds, so a caller can build a per-workspace view — e.g. a tool registry confined to one workspace’s projects — over the same lazily-opened stores, never re-opening them. Used by serve to scope the workspace-level Ask to the selected workspace (ADR-0008), mirroring how WorkspaceSet::select scopes the read-only /v1/graph/workspaces/{ws}/… routes.

Source

pub fn linked(&self, name: &str) -> Option<bool>

Whether workspace name is linked (Some(true)), standalone (Some(false)), or unknown (None).

Source

pub fn select( &self, name: Option<&str>, ) -> Result<Arc<Workspace>, WorkspaceError>

Select a workspace by name, or the default when name is None.

Hands back the shared Arc rather than a borrow, because the set is reloadable: a caller that held a reference into the entry map would pin it against the swap. The handle stays valid across a reload — a retained workspace is reloaded in place, so a caller reading through it sees the new project set rather than a detached snapshot.

§Errors

WorkspaceError::UnknownWorkspace if named but absent, WorkspaceError::AmbiguousWorkspace if omitted with several configured, or WorkspaceError::Empty if none are configured.

Source

pub fn select_name(&self, name: Option<&str>) -> Result<String, WorkspaceError>

The name of the workspace WorkspaceSet::select resolves for name: the given name when present (and valid), else the sole/default workspace’s name. Same resolution and errors as select, but returns the concrete name — so a caller (e.g. the /follow endpoint) can report which workspace it actually resolved in, even on a flat route where the default was implicit.

§Errors

As WorkspaceSet::select.

Source

pub fn containing(&self, cwd_repo_db: &Path) -> Option<String>

The name of the workspace whose member repos include the repo whose graph is cwd_repo_db (<repo>/.git/roteiro/graph.db), or None if no workspace contains it. Used to default --workspace-name to the workspace the current directory belongs to.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.