Skip to main content

xtask/tasks/fmt/lints/
crate_name_nodash.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Checks that crate names and their containing folder names do not use
5//! dashes (hyphens). Use underscores instead.
6
7use super::Lint;
8use super::LintCtx;
9use super::Lintable;
10use toml_edit::DocumentMut;
11
12pub struct CrateNameNoDash;
13
14impl Lint for CrateNameNoDash {
15    fn new(_ctx: &LintCtx) -> Self {
16        CrateNameNoDash
17    }
18
19    fn enter_workspace(&mut self, _content: &Lintable<DocumentMut>) {}
20
21    fn enter_crate(&mut self, _content: &Lintable<DocumentMut>) {}
22
23    fn visit_file(&mut self, _content: &mut Lintable<String>) {}
24
25    fn exit_crate(&mut self, content: &mut Lintable<DocumentMut>) {
26        let package_name = match content
27            .as_table()
28            .get("package")
29            .and_then(|p| p.get("name"))
30            .and_then(|n| n.as_str())
31        {
32            Some(name) => name,
33            None => return, // Root of a different workspace, like xsync
34        };
35
36        // Check for allow-dash-in-name metadata escape hatch.
37        if let Some(metadata) = content
38            .as_table()
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().unwrap();
45            for (k, v) in props.iter() {
46                if k == "allow-dash-in-name" {
47                    if v.as_bool().unwrap_or(false) {
48                        return;
49                    }
50                }
51            }
52        }
53
54        let bad_package_name = package_name.contains('-');
55        let bad_package_path = content
56            .path()
57            .parent()
58            .and_then(|p| p.file_name())
59            .unwrap_or_default()
60            .to_string_lossy()
61            .contains('-');
62
63        let msg = match (bad_package_name, bad_package_path) {
64            (true, true) => "crate name + folder cannot contain '-' char",
65            (true, false) => "crate name cannot contain '-' char",
66            (false, true) => "crate folder cannot contain '-' char",
67            _ => return,
68        };
69
70        content.unfixable(&format!(
71            "{}: name={} folder={}",
72            msg,
73            package_name,
74            content
75                .path()
76                .parent()
77                .map(|p| p.display().to_string())
78                .unwrap_or_default()
79        ));
80    }
81
82    fn exit_workspace(&mut self, _content: &mut Lintable<DocumentMut>) {}
83}