xtask/tasks/fmt/lints/
package_info.rs1use super::Lint;
29use super::LintCtx;
30use super::Lintable;
31use toml_edit::DocumentMut;
32use toml_edit::Item;
33use toml_edit::Table;
34
35static VERSION_EXCEPTIONS: &[&str] = &["openvmm", "openvmm_build_info", "vmgstool"];
53
54pub struct PackageInfo;
55
56impl Lint for PackageInfo {
57 fn new(_ctx: &LintCtx) -> Self {
58 PackageInfo
59 }
60
61 fn enter_workspace(&mut self, _content: &Lintable<DocumentMut>) {}
62 fn enter_crate(&mut self, _content: &Lintable<DocumentMut>) {}
63 fn visit_file(&mut self, _content: &mut Lintable<String>) {}
64
65 fn exit_crate(&mut self, content: &mut Lintable<DocumentMut>) {
66 let package = content["package"].as_table().unwrap();
67 let excluded_from_workspace = package
68 .get("metadata")
69 .and_then(|x| x.get("xtask"))
70 .and_then(|x| x.get("house-rules"))
71 .and_then(|x| x.get("excluded-from-workspace"))
72 .and_then(|v| v.as_bool())
73 .unwrap_or(false);
74
75 let package_name = package["name"].as_str().unwrap();
76 let is_version_exception = VERSION_EXCEPTIONS.contains(&package_name);
77 let check_version = !is_version_exception;
78
79 let mut lints_table = Table::new();
80 lints_table.insert("workspace", Item::Value(true.into()));
81
82 let mut rust_version_field = Table::new();
83 rust_version_field.set_dotted(true);
84 rust_version_field.insert("workspace", Item::Value(true.into()));
85
86 let mut edition_field = Table::new();
87 edition_field.set_dotted(true);
88 edition_field.insert("workspace", Item::Value(true.into()));
89
90 let has_authors = package.contains_key("authors");
91 let has_version = check_version && package.contains_key("version");
92 let needs_publish_false =
93 is_version_exception && package.get("publish").and_then(Item::as_bool) != Some(false);
94 let needs_lints_fix = !excluded_from_workspace
95 && content.get("lints").map(|o| o.to_string()).as_deref()
96 != Some(&lints_table.to_string());
97 let needs_rust_version_fix = !excluded_from_workspace
98 && package
99 .get("rust-version")
100 .map(|o| o.to_string())
101 .as_deref()
102 != Some(&rust_version_field.to_string());
103 let needs_edition_fix = !excluded_from_workspace
104 && package.get("edition").map(|o| o.to_string()).as_deref()
105 != Some(&edition_field.to_string());
106
107 if has_authors {
108 content.fix("package should not have authors field", |doc| {
109 doc["package"].as_table_mut().unwrap().remove("authors");
110 });
111 }
112
113 if has_version {
114 content.fix("package should not have version field", |doc| {
115 doc["package"].as_table_mut().unwrap().remove("version");
116 });
117 }
118
119 if needs_publish_false {
120 content.fix("versioned package should set publish = false", |doc| {
121 doc["package"]
122 .as_table_mut()
123 .unwrap()
124 .insert("publish", Item::Value(false.into()));
125 });
126 }
127
128 if needs_lints_fix {
129 content.fix("lints should be workspaced", |doc| {
130 doc.insert("lints", Item::Table(lints_table));
131 });
132 }
133
134 if needs_rust_version_fix {
135 content.fix("rust-version should be workspaced", |doc| {
136 doc["package"]
137 .as_table_mut()
138 .unwrap()
139 .insert("rust-version", Item::Table(rust_version_field));
140 });
141 }
142
143 if needs_edition_fix {
144 content.fix("edition should be workspaced", |doc| {
145 doc["package"]
146 .as_table_mut()
147 .unwrap()
148 .insert("edition", Item::Table(edition_field));
149 });
150 }
151 }
152
153 fn exit_workspace(&mut self, _content: &mut Lintable<DocumentMut>) {}
154}