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
use clap::{Parser, Subcommand, ValueEnum};
use clap_complete::Shell;
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(
name = "svccat",
version,
about = "Service catalog drift detection for multi-service repositories",
long_about = "\
svccat reads your declared service manifest and compares it against what \
actually exists in the repo, flagging drift before it becomes toil.\n\n\
Typical workflow:\n \
svccat check # inspect drift in the current repo\n \
svccat check --fail-on-drift # gate CI on zero drift\n \
svccat graph # emit a Mermaid diagram for docs\n \
svccat export --format json # machine-readable catalog snapshot"
)]
pub struct Cli {
/// Repository root (defaults to current directory)
#[arg(short, long, global = true)]
pub root: Option<PathBuf>,
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
/// Check declared services against the repo and report drift
Check {
/// Path to the manifest file (auto-detected if omitted)
#[arg(short, long)]
manifest: Option<PathBuf>,
/// Output format
#[arg(short, long, value_enum, default_value_t = OutputFormat::Terminal)]
format: OutputFormat,
/// Exit with code 1 when drift is detected (useful in CI)
#[arg(long)]
fail_on_drift: bool,
/// Ping each service URL and report reachability
#[arg(long)]
ping: bool,
/// Glob patterns to exclude from discovery (repeatable, e.g. --ignore "examples/*")
#[arg(long, value_name = "PATTERN")]
ignore: Vec<String>,
},
/// Generate a Mermaid or Markdown view of the service catalog
Graph {
/// Path to the manifest file (auto-detected if omitted)
#[arg(short, long)]
manifest: Option<PathBuf>,
/// Output format
#[arg(short, long, value_enum, default_value_t = GraphFormat::Mermaid)]
format: GraphFormat,
},
/// Export the full service catalog with drift summary
Export {
/// Path to the manifest file (auto-detected if omitted)
#[arg(short, long)]
manifest: Option<PathBuf>,
/// Export format
#[arg(short, long, value_enum, default_value_t = ExportFormat::Json)]
format: ExportFormat,
/// Glob patterns to exclude from discovery (repeatable)
#[arg(long, value_name = "PATTERN")]
ignore: Vec<String>,
},
/// Scaffold a services.yaml by auto-discovering services in the repo
Init {
/// Where to write the manifest (default: services.yaml in repo root)
#[arg(short, long)]
output: Option<PathBuf>,
/// Overwrite an existing manifest file
#[arg(long)]
force: bool,
},
/// Compare two svccat export JSON snapshots and show what changed
///
/// Generate snapshots with: svccat export --format json > snapshot.json
Diff {
/// Path to the older snapshot (JSON)
before: std::path::PathBuf,
/// Path to the newer snapshot (JSON)
after: std::path::PathBuf,
},
/// Print shell completion script to stdout
///
/// Source the output to enable tab completion, e.g.:
/// source <(svccat completions bash)
/// svccat completions zsh > ~/.zfunc/_svccat
Completions {
/// Shell to generate completions for
shell: Shell,
},
}
#[derive(Debug, Clone, ValueEnum, PartialEq)]
pub enum OutputFormat {
Terminal,
Json,
}
#[derive(Debug, Clone, ValueEnum, PartialEq)]
pub enum GraphFormat {
Mermaid,
Markdown,
}
#[derive(Debug, Clone, ValueEnum, PartialEq)]
pub enum ExportFormat {
Json,
Markdown,
}