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
use std::path::PathBuf;
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(
name = "dotling",
version,
about = "A dotfiles management CLI — track, link, and sync your config files across machines",
long_about = None,
arg_required_else_help = true,
)]
pub struct Cli {
/// Show verbose output with hints.
#[arg(short, long, global = true)]
pub verbose: bool,
#[command(subcommand)]
pub command: Command,
}
#[derive(Subcommand)]
pub enum Command {
/// Initialize a new dotfiles repo or adopt an existing one.
Init {
/// Path to create the repo at, or a git URL to clone.
#[arg(default_value = "~/dotfiles")]
path: String,
},
/// Add files or directories to tracking.
Add {
/// Paths to add (files or directories).
#[arg(required = true)]
paths: Vec<PathBuf>,
/// Encrypt the file(s) using the vault password.
#[arg(long)]
encrypt: bool,
/// Deploy as a copy instead of a symlink.
#[arg(long)]
copy: bool,
/// Restrict to a specific OS (linux, macos, windows).
#[arg(long)]
os: Option<String>,
},
/// Remove entries from tracking.
Remove {
/// Source paths or target paths of entries to remove.
#[arg(required = true)]
entries: Vec<String>,
},
/// Synchronise tracked entries between the repo and the actual filesystem.
///
/// Pushes (repo → actual) entries that are missing or outdated,
/// and pulls (actual → repo) copy-mode entries that were modified locally.
Sync {
/// Show what would change without modifying anything.
#[arg(long)]
dry_run: bool,
/// Overwrite conflicting files.
#[arg(long)]
force: bool,
/// When both sides differ and timestamps are equal, prefer the actual
/// file over the repo (pull direction). Default is to prefer the repo.
#[arg(long)]
prefer_actual: bool,
},
/// Show status of all tracked entries.
Status {
/// Show inline diffs for modified entries.
#[arg(long)]
diff: bool,
},
/// Encrypt or decrypt tracked entries.
Encrypt {
/// Paths to encrypt.
#[arg(required = true)]
paths: Vec<String>,
},
/// Decrypt encrypted entries back to plaintext in the repo.
Decrypt {
/// Paths to decrypt.
#[arg(required = true)]
paths: Vec<String>,
},
/// Manage the encryption vault.
Vault {
#[command(subcommand)]
action: VaultAction,
},
/// Audit repository health and report issues.
Doctor,
}
#[derive(Subcommand)]
pub enum VaultAction {
/// Initialize a new vault with a password.
Init,
/// Show vault status and public info.
Show,
/// Export vault as a portable encrypted bundle.
Export {
/// Path to write the vault bundle.
path: PathBuf,
},
/// Import a vault bundle.
Import {
/// Path to the vault bundle to import.
path: PathBuf,
},
/// Change the vault password.
#[command(name = "change-password")]
ChangePassword,
}