Skip to main content

DataStore

Trait DataStore 

Source
pub trait DataStore: Send + Sync {
    // Required methods
    fn create_data_link(
        &self,
        pack: &str,
        handler: &str,
        source_file: &Path,
    ) -> Result<PathBuf>;
    fn create_user_link(
        &self,
        datastore_path: &Path,
        user_path: &Path,
    ) -> Result<()>;
    fn run_and_record(
        &self,
        pack: &str,
        handler: &str,
        executable: &str,
        arguments: &[String],
        sentinel: &str,
        force: bool,
    ) -> Result<()>;
    fn has_sentinel(
        &self,
        pack: &str,
        handler: &str,
        sentinel: &str,
    ) -> Result<bool>;
    fn remove_state(&self, pack: &str, handler: &str) -> Result<()>;
    fn has_handler_state(&self, pack: &str, handler: &str) -> Result<bool>;
    fn list_pack_handlers(&self, pack: &str) -> Result<Vec<String>>;
    fn list_handler_sentinels(
        &self,
        pack: &str,
        handler: &str,
    ) -> Result<Vec<String>>;
    fn write_rendered_file(
        &self,
        pack: &str,
        handler: &str,
        filename: &str,
        content: &[u8],
    ) -> Result<PathBuf>;
    fn write_rendered_dir(
        &self,
        pack: &str,
        handler: &str,
        relative: &str,
    ) -> Result<PathBuf>;
    fn sentinel_path(
        &self,
        pack: &str,
        handler: &str,
        sentinel: &str,
    ) -> PathBuf;
}
Expand description

Dodot’s storage interface.

State is represented entirely by symlinks and sentinel files in the filesystem — no database, no lock files. The 8 methods break into three groups:

Mutations — modify state:

Queries — read state:

Required Methods§

Creates an intermediate symlink in the datastore: handler_data_dir(pack, handler) / filename -> source_file

Returns the absolute path of the created datastore link. Idempotent: if the link exists and already points to the correct source, this is a no-op.

Creates a user-visible symlink: user_path -> datastore_path

This is the second leg of the double-link architecture. Creates parent directories as needed.

Source

fn run_and_record( &self, pack: &str, handler: &str, executable: &str, arguments: &[String], sentinel: &str, force: bool, ) -> Result<()>

Executes command via shell and records a sentinel on success.

Idempotent: if the sentinel already exists, the command is not re-run. The sentinel file stores completed|{timestamp}.

Edge case: if the command succeeds but the sentinel write fails, a subsequent call will re-run the command. This is by design — re-running is safer than falsely marking as complete. Install scripts should be idempotent to handle this.

Source

fn has_sentinel( &self, pack: &str, handler: &str, sentinel: &str, ) -> Result<bool>

Checks whether a sentinel exists for this pack/handler.

Source

fn remove_state(&self, pack: &str, handler: &str) -> Result<()>

Removes all state for a pack/handler pair.

Deletes the handler data directory and everything in it.

Source

fn has_handler_state(&self, pack: &str, handler: &str) -> Result<bool>

Checks if any state exists for a pack/handler pair.

Source

fn list_pack_handlers(&self, pack: &str) -> Result<Vec<String>>

Lists handler names that have state for a pack.

Source

fn list_handler_sentinels( &self, pack: &str, handler: &str, ) -> Result<Vec<String>>

Lists sentinel file names for a pack/handler.

Source

fn write_rendered_file( &self, pack: &str, handler: &str, filename: &str, content: &[u8], ) -> Result<PathBuf>

Writes a regular file (not a symlink) into the datastore.

Used for preprocessor-expanded files where the datastore holds rendered content rather than a symlink to the source. Returns the absolute path of the written file. Idempotent: overwrites if the file already exists.

filename must be a safe relative path — no absolute paths, no .. components. Callers (typically the preprocessing pipeline) are expected to validate before calling. Implementations should also reject unsafe paths as defense-in-depth.

Source

fn write_rendered_dir( &self, pack: &str, handler: &str, relative: &str, ) -> Result<PathBuf>

Creates a directory (mkdir -p) inside the datastore and returns its absolute path. Used for preprocessor-expanded directory entries (e.g. directory markers from tar archives).

Same path-safety constraints as [write_rendered_file].

Source

fn sentinel_path(&self, pack: &str, handler: &str, sentinel: &str) -> PathBuf

Returns the absolute path where a sentinel file would be stored.

Implementors§