1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! 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](#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:
//!
//! ```toml
//! [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.
//!
//! ```no_run
//! 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.
pub use *;
pub use ;