aboutsummaryrefslogtreecommitdiff
path: root/lib/src/lints/unquoted_uri.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/src/lints/unquoted_uri.rs')
-rw-r--r--lib/src/lints/unquoted_uri.rs63
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/src/lints/unquoted_uri.rs b/lib/src/lints/unquoted_uri.rs
new file mode 100644
index 0000000..b111f78
--- /dev/null
+++ b/lib/src/lints/unquoted_uri.rs
@@ -0,0 +1,63 @@
1use crate::{make, Metadata, Report, Rule, Suggestion};
2
3use if_chain::if_chain;
4use macros::lint;
5use rnix::{types::TypedNode, NodeOrToken, SyntaxElement, SyntaxKind};
6
7/// ## What it does
8/// Checks for URI expressions that are not quoted.
9///
10/// ## Why is this bad?
11/// The Nix language has a special syntax for URLs even though quoted
12/// strings can also be used to represent them. Unlike paths, URLs do
13/// not have any special properties in the Nix expression language
14/// that would make the difference useful. Moreover, using variable
15/// expansion in URLs requires some URLs to be quoted strings anyway.
16/// So the most consistent approach is to always use quoted strings to
17/// represent URLs. Additionally, a semicolon immediately after the
18/// URL can be mistaken for a part of URL by language-agnostic tools
19/// such as terminal emulators.
20///
21/// See RFC 00045 [1] for more.
22///
23/// [1]: https://github.com/NixOS/rfcs/blob/master/rfcs/0045-deprecate-url-syntax.md
24///
25/// ## Example
26///
27/// ```nix
28/// inputs = {
29/// gitignore.url = github:hercules-ci/gitignore.nix;
30/// }
31/// ```
32///
33/// Quote the URI expression:
34///
35/// ```nix
36/// inputs = {
37/// gitignore.url = "github:hercules-ci/gitignore.nix";
38/// }
39/// ```
40#[lint(
41 name = "unquoted uri",
42 note = "Found unquoted URI expression",
43 code = 12,
44 match_with = SyntaxKind::TOKEN_URI
45)]
46struct UnquotedUri;
47
48impl Rule for UnquotedUri {
49 fn validate(&self, node: &SyntaxElement) -> Option<Report> {
50 if_chain! {
51 if let NodeOrToken::Token(token) = node;
52 then {
53 let parent_node = token.parent();
54 let at = token.text_range();
55 let replacement = make::quote(&parent_node).node().clone();
56 let message = "Consider quoting this URI expression";
57 Some(self.report().suggest(at, message, Suggestion::new(at, replacement)))
58 } else {
59 None
60 }
61 }
62 }
63}