From 5b87c6feb3e4a2fcc30ad94125be3dcd4e554754 Mon Sep 17 00:00:00 2001 From: Akshay Date: Tue, 2 Nov 2021 13:18:36 +0530 Subject: new lint: unquoted_uri --- flake.nix | 1 + lib/src/lints.rs | 1 + lib/src/lints/unquoted_uri.rs | 63 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 lib/src/lints/unquoted_uri.rs diff --git a/flake.nix b/flake.nix index 3536770..3b9d011 100644 --- a/flake.nix +++ b/flake.nix @@ -98,6 +98,7 @@ mkShell rec { nativeBuildInputs = [ cargo-watch + rust-analyzer toolchain ]; 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! { unquoted_splice, empty_pattern, redundant_pattern_bind, + unquoted_uri, } 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 @@ +use crate::{make, Metadata, Report, Rule, Suggestion}; + +use if_chain::if_chain; +use macros::lint; +use rnix::{types::TypedNode, NodeOrToken, SyntaxElement, SyntaxKind}; + +/// ## What it does +/// Checks for URI expressions that are not quoted. +/// +/// ## Why is this bad? +/// The Nix language has a special syntax for URLs even though quoted +/// strings can also be used to represent them. Unlike paths, URLs do +/// not have any special properties in the Nix expression language +/// that would make the difference useful. Moreover, using variable +/// expansion in URLs requires some URLs to be quoted strings anyway. +/// So the most consistent approach is to always use quoted strings to +/// represent URLs. Additionally, a semicolon immediately after the +/// URL can be mistaken for a part of URL by language-agnostic tools +/// such as terminal emulators. +/// +/// See RFC 00045 [1] for more. +/// +/// [1]: https://github.com/NixOS/rfcs/blob/master/rfcs/0045-deprecate-url-syntax.md +/// +/// ## Example +/// +/// ```nix +/// inputs = { +/// gitignore.url = github:hercules-ci/gitignore.nix; +/// } +/// ``` +/// +/// Quote the URI expression: +/// +/// ```nix +/// inputs = { +/// gitignore.url = "github:hercules-ci/gitignore.nix"; +/// } +/// ``` +#[lint( + name = "unquoted uri", + note = "Found unquoted URI expression", + code = 12, + match_with = SyntaxKind::TOKEN_URI +)] +struct UnquotedUri; + +impl Rule for UnquotedUri { + fn validate(&self, node: &SyntaxElement) -> Option { + if_chain! { + if let NodeOrToken::Token(token) = node; + then { + let parent_node = token.parent(); + let at = token.text_range(); + let replacement = make::quote(&parent_node).node().clone(); + let message = "Consider quoting this URI expression"; + Some(self.report().suggest(at, message, Suggestion::new(at, replacement))) + } else { + None + } + } + } +} -- cgit v1.2.3