xtask\tasks\fmt\house_rules/
package_info.rs1use anyhow::Context;
24use std::ffi::OsStr;
25use std::path::Path;
26use toml_edit::Item;
27use toml_edit::Table;
28
29pub fn check_package_info(f: &Path, fix: bool) -> anyhow::Result<()> {
30 if f.file_name() != Some(OsStr::new("Cargo.toml")) {
31 return Ok(());
32 }
33
34 let contents = fs_err::read_to_string(f)?;
35 let mut parsed = contents.parse::<toml_edit::DocumentMut>()?;
36
37 let mut excluded_from_workspace = false;
38 if let Some(metadata) = parsed
39 .get("package")
40 .and_then(|x| x.get("metadata"))
41 .and_then(|x| x.get("xtask"))
42 .and_then(|x| x.get("house-rules"))
43 {
44 let props = metadata.as_table().context("invalid metadata format")?;
45 for (k, v) in props.iter() {
46 if k == "excluded-from-workspace" {
47 excluded_from_workspace = v
48 .as_bool()
49 .context("invalid type for excluded-from-workspace (must be bool)")?;
50 }
51 }
52 }
53
54 if !parsed.contains_key("package") {
55 return Ok(());
57 }
58
59 let mut lints_table = Table::new();
60 lints_table.insert("workspace", Item::Value(true.into()));
61 let old_lints_table = parsed.insert("lints", Item::Table(lints_table.clone()));
62
63 let package = parsed
64 .get_mut("package")
65 .unwrap()
66 .as_table_mut()
67 .with_context(|| format!("invalid package section in {}", f.display()))?;
68
69 let mut rust_version_field = Table::new();
70 rust_version_field.set_dotted(true);
71 rust_version_field.insert("workspace", Item::Value(true.into()));
72 let old_rust_version = package.insert("rust-version", Item::Table(rust_version_field.clone()));
73
74 let mut edition_field = Table::new();
75 edition_field.set_dotted(true);
76 edition_field.insert("workspace", Item::Value(true.into()));
77 let old_edition_field = package.insert("edition", Item::Table(edition_field.clone()));
78
79 let invalid = package.remove("authors").is_some()
81 | package.remove("version").is_some()
82 | (!excluded_from_workspace
83 && (old_lints_table.map(|o| o.to_string()) != Some(lints_table.to_string()))
84 | (old_rust_version.map(|o| o.to_string())
85 != Some(rust_version_field.to_string()))
86 | (old_edition_field.map(|o| o.to_string()) != Some(edition_field.to_string())));
87
88 if invalid {
89 if !fix {
90 anyhow::bail!(
91 "invalid inclusion of package authors or version, or non-workspaced lints, rust-version, or edition, in {}",
92 f.display()
93 );
94 }
95 fs_err::write(f, parsed.to_string())?;
96 log::info!("fixed package section in {}", f.display());
97 }
98
99 Ok(())
100}