baobao_codegen/pipeline/phases/validate/lints/
empty_description.rs1use baobao_manifest::Manifest;
4
5use super::super::Lint;
6use crate::pipeline::Diagnostic;
7
8pub struct EmptyDescriptionLint;
10
11impl Lint for EmptyDescriptionLint {
12 fn name(&self) -> &'static str {
13 "empty-description"
14 }
15
16 fn description(&self) -> &'static str {
17 "Warn about commands missing descriptions"
18 }
19
20 fn check(&self, manifest: &Manifest, diagnostics: &mut Vec<Diagnostic>) {
21 for (name, cmd) in &manifest.commands {
22 if cmd.description.is_empty() {
23 diagnostics.push(
24 Diagnostic::warning(
25 "validate",
26 format!("command '{}' has no description", name),
27 )
28 .at(format!("commands.{}", name)),
29 );
30 }
31
32 check_subcommand_descriptions(name, cmd, diagnostics);
33 }
34 }
35}
36
37fn check_subcommand_descriptions(
38 parent_path: &str,
39 cmd: &baobao_manifest::Command,
40 diagnostics: &mut Vec<Diagnostic>,
41) {
42 for (name, subcmd) in &cmd.commands {
43 let path = format!("{}.{}", parent_path, name);
44 if subcmd.description.is_empty() {
45 diagnostics.push(
46 Diagnostic::warning("validate", format!("command '{}' has no description", path))
47 .at(format!("commands.{}", path)),
48 );
49 }
50 check_subcommand_descriptions(&path, subcmd, diagnostics);
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 fn parse_manifest(content: &str) -> Manifest {
59 toml::from_str(content).expect("Failed to parse test manifest")
60 }
61
62 #[test]
63 fn test_empty_description() {
64 let manifest = parse_manifest(
65 r#"
66 [cli]
67 name = "test"
68 language = "rust"
69
70 [commands.deploy]
71 description = ""
72 "#,
73 );
74
75 let mut diagnostics = Vec::new();
76 EmptyDescriptionLint.check(&manifest, &mut diagnostics);
77
78 assert_eq!(diagnostics.len(), 1);
79 assert!(diagnostics[0].message.contains("deploy"));
80 assert!(diagnostics[0].severity.is_warning());
81 }
82
83 #[test]
84 fn test_has_description() {
85 let manifest = parse_manifest(
86 r#"
87 [cli]
88 name = "test"
89 language = "rust"
90
91 [commands.deploy]
92 description = "Deploy the application"
93 "#,
94 );
95
96 let mut diagnostics = Vec::new();
97 EmptyDescriptionLint.check(&manifest, &mut diagnostics);
98
99 assert!(diagnostics.is_empty());
100 }
101}