toggle/cli.rs
1// Command-line interface for the Toggle CLI
2
3use clap::Parser;
4use clap_complete::Shell;
5use std::path::PathBuf;
6
7#[derive(Parser)]
8#[command(author, version, about)]
9pub struct Cli {
10 /// File or directory paths to process
11 pub paths: Vec<PathBuf>,
12
13 /// Line range in format <start_line>:<end_line> or <start_line>:+<count> (repeatable)
14 #[arg(short = 'l', long = "line", action = clap::ArgAction::Append)]
15 pub lines: Vec<String>,
16
17 /// Section ID to toggle. Use `group:variant` (e.g. `db:postgres`) for variant ops:
18 /// `-S group` flips a 2-variant pair; `-S group:variant` activates one variant
19 /// and comments siblings; `-S group --force on/off` applies to every variant.
20 #[arg(short = 'S', long = "section", action = clap::ArgAction::Append)]
21 pub sections: Vec<String>,
22
23 /// Recursively walk directories
24 #[arg(short = 'R', long = "recursive")]
25 pub recursive: bool,
26
27 /// List all section IDs found in files (discovery mode, no toggling)
28 #[arg(long = "list-sections")]
29 pub list_sections: bool,
30
31 /// Force toggle state (on/off/invert)
32 #[arg(short = 'f', long = "force", visible_short_alias = 'F')]
33 pub force: Option<String>,
34
35 /// Comment mode (auto/single/multi)
36 #[arg(short = 'm', long = "mode", default_value = "auto")]
37 pub mode: String,
38
39 /// Human-readable log lines to stderr
40 #[arg(short = 'v', long = "verbose")]
41 pub verbose: bool,
42
43 /// Machine-readable single-line JSON to stdout
44 #[arg(long = "json")]
45 pub json: bool,
46
47 /// Extension for atomic temp file
48 #[arg(short = 't', long = "temp-suffix")]
49 pub temp_suffix: Option<String>,
50
51 /// Override file codec (UTF-8 only in Phase 0)
52 #[arg(short = 'e', long = "encoding", default_value = "utf-8")]
53 pub encoding: String,
54
55 /// Error if target is not .py
56 #[arg(long = "strict-ext")]
57 pub strict_ext: bool,
58
59 /// Operate on symlink itself instead of target
60 #[arg(short = 'N', long = "no-dereference")]
61 pub no_dereference: bool,
62
63 /// EOL normalization: preserve, lf, or crlf
64 #[arg(long = "eol", default_value = "preserve")]
65 pub eol: String,
66
67 /// Map exit codes to sysexits.h values
68 #[arg(short = 'x', long = "posix-exit")]
69 pub posix_exit: bool,
70
71 /// Override comment style: SINGLE [MULTI_START MULTI_END]
72 #[arg(long = "comment-style", num_args = 1..=3, value_names = ["SINGLE", "MULTI_START", "MULTI_END"])]
73 pub comment_style: Vec<String>,
74
75 /// Prompt before modifying each file
76 #[arg(short = 'i', long = "interactive")]
77 pub interactive: bool,
78
79 /// Show diff of changes without writing files
80 #[arg(long = "dry-run")]
81 pub dry_run: bool,
82
83 /// Create backup with given extension before modifying (e.g. --backup .bak)
84 #[arg(long = "backup")]
85 pub backup: Option<String>,
86
87 /// Extend the last --line range to the end of file
88 #[arg(long = "to-end")]
89 pub to_end: bool,
90
91 /// Scan for section IDs without modifying files
92 #[arg(long = "scan")]
93 pub scan: bool,
94
95 /// Validate section integrity without modifying files. Requires --scan.
96 #[arg(long = "check")]
97 pub check: bool,
98
99 /// Enforce exactly 2 variants in the targeted group; error otherwise.
100 /// Pre-execution check — no file modifications occur on failure.
101 #[arg(long = "pair")]
102 pub pair: bool,
103
104 /// Path to .toggleConfig TOML file
105 #[arg(long = "config")]
106 pub config: Option<PathBuf>,
107
108 /// Enable atomic multi-file mode: all files succeed or none are modified.
109 /// Implies --backup unless --no-backup is explicitly passed.
110 #[arg(long = "atomic")]
111 pub atomic: bool,
112
113 /// Disable backup creation in atomic mode. Only valid with --atomic.
114 /// WARNING: Without backups, rollback is not possible if the rename phase fails.
115 #[arg(long = "no-backup")]
116 pub no_backup: bool,
117
118 /// Recover from an interrupted atomic operation. Default: rollback.
119 #[arg(long = "recover")]
120 pub recover: bool,
121
122 /// Complete an interrupted atomic commit instead of rolling back.
123 /// Must be combined with --recover.
124 #[arg(long = "recover-forward")]
125 pub recover_forward: bool,
126
127 /// Generate shell completions for the given shell to stdout.
128 /// Example: `toggle --completions bash > /etc/bash_completion.d/toggle`
129 #[arg(long = "completions", value_name = "SHELL")]
130 pub completions: Option<Shell>,
131
132 /// Generate a roff-formatted man page to stdout.
133 /// Example: `toggle --man > toggle.1 && man ./toggle.1`
134 #[arg(long = "man")]
135 pub man: bool,
136}