Skip to main content

Crate vcs_modify_guard

Crate vcs_modify_guard 

Source
Expand description

Help CLI tools decide whether it is safe to modify files in a VCS working tree.

vcs-modify-guard helps CLI tools enforce --allow-dirty, --allow-staged, and --allow-no-vcs style checks before they modify files.

Currently, this crate supports Git repositories. Backend selection is controlled by Cargo features; see Feature flags.

§API overview

This crate provides two layers of API:

  • AllowOptions is the main entry point. It implements cargo fix-style safe-to-modify checks and returns a ModificationSafety describing whether modification is safe. By default, checks are scoped to the queried path.
  • repository::Repository is a lower-level API for tools that need to discover a repository and inspect whether files are dirty and/or staged to implement their own policy. Dirty files include modified tracked files and untracked files.

Most users should start with AllowOptions. Reach for repository::Repository only when you need custom behavior beyond the built-in --allow-* semantics.

§Feature flags

This crate currently supports Git repositories via selectable Git backends.

§Backend selection features

  • git-default (enabled by default) enables the default Git backend. Currently, this enables git-gix.
  • git-gix enables the gix backend.
  • git-libgit2 enables the libgit2 backend.
  • git-cli enables the Git CLI backend.

To opt out of the default backend, disable default features and enable the desired backend feature(s) explicitly:

[dependencies]
vcs-modify-guard = {
  version = "0.1.0",
  default-features = false,
  features = ["git-libgit2"]
}

If multiple backends are enabled, they are tried in this fixed priority order: gix, then libgit2, then the Git CLI.

If no backend selection features are enabled, repository discovery reports that no supported repository was found.

§Backend configuration features

  • vendored-libgit2 forwards to git2’s vendored-libgit2 feature when git-libgit2 is enabled.

§Example

The following example shows how to validate whether a target path is safe to modify before performing an operation that may modify files.

use std::path::{Path, PathBuf};

use clap::Parser;
use vcs_modify_guard::{AllowOptions, ModificationSafety, UnsafeModificationReason};

#[derive(Debug, Parser)]
struct Args {
    /// Process code even if a VCS was not detected.
    #[arg(long)]
    allow_no_vcs: bool,
    /// Process code even if the target path has modified, staged, or
    /// untracked files under it.
    #[arg(long)]
    allow_dirty: bool,
    /// Process code even if the target path has staged changes under it.
    #[arg(long)]
    allow_staged: bool,
    /// Target path to process. Defaults to the current working directory.
    target: Option<PathBuf>,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args = Args::parse();

    let target = args.target.as_deref().unwrap_or_else(|| Path::new("."));
    let safety = AllowOptions::new()
        .allow_no_vcs(args.allow_no_vcs)
        .allow_dirty(args.allow_dirty)
        .allow_staged(args.allow_staged)
        .check_safe_to_modify(target)?;

    match safety {
        ModificationSafety::Safe => {}
        ModificationSafety::Unsafe(reason) => match reason {
            UnsafeModificationReason::NoVcs => {
                return Err("blocked by no VCS".into());
            }
            UnsafeModificationReason::Dirty { .. } => {
                return Err("blocked by dirty files".into());
            }
            UnsafeModificationReason::Staged { .. } => {
                return Err("blocked by staged changes".into());
            }
            _ => {
                return Err("blocked by unsafe modifications".into());
            }
        },
    }

    eprintln!("Proceeding...");

    Ok(())
}

See the allow_options example for a complete command-line application.

If you need custom policy logic instead of the built-in --allow-* behavior, see the repository module for direct repository discovery and change query APIs.

Modules§

repository
Lower-level repository change query APIs.

Structs§

AllowOptions
Options for --allow-* style safety checks before modifying files.

Enums§

GitCliBackendErrorgit-cli
Errors returned by git-cli backend operations.
GixBackendErrorgit-gix
Errors returned by gix backend operations.
Libgit2BackendErrorgit-libgit2
Errors returned by libgit2 backend operations.
ModificationSafety
Whether modification of the queried target is considered safe under the current --allow-* policy.
ModifyGuardError
Errors returned by vcs-modify-guard operations.
UnsafeModificationReason
The reason modification of the queried target is considered unsafe under the current --allow-* policy.