aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flake.nix1
-rw-r--r--lib/src/lints.rs1
-rw-r--r--lib/src/lints/unquoted_uri.rs63
3 files changed, 65 insertions, 0 deletions
diff --git a/flake.nix b/flake.nix
index 3536770..3b9d011 100644
--- a/flake.nix
+++ b/flake.nix
@@ -98,6 +98,7 @@
98 mkShell rec { 98 mkShell rec {
99 nativeBuildInputs = [ 99 nativeBuildInputs = [
100 cargo-watch 100 cargo-watch
101 rust-analyzer
101 toolchain 102 toolchain
102 ]; 103 ];
103 RUST_LOG = "info"; 104 RUST_LOG = "info";
diff --git a/lib/src/lints.rs b/lib/src/lints.rs
index 09cd77c..44d5922 100644
--- a/lib/src/lints.rs
+++ b/lib/src/lints.rs
@@ -12,4 +12,5 @@ lint_map! {
12 unquoted_splice, 12 unquoted_splice,
13 empty_pattern, 13 empty_pattern,
14 redundant_pattern_bind, 14 redundant_pattern_bind,
15 unquoted_uri,
15} 16}
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}