mirror of
https://github.com/nerdypepper/statix.git
synced 2024-09-11 13:45:32 +03:00
add snapshot test suite
This commit is contained in:
parent
78decf580d
commit
4e063b2abc
186
Cargo.lock
generated
186
Cargo.lock
generated
@ -20,6 +20,12 @@ dependencies = [
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
@ -69,9 +75,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.0.0-beta.4"
|
||||
version = "3.0.0-beta.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcd70aa5597dbc42f7217a543f9ef2768b2ef823ba29036072d30e1d88e98406"
|
||||
checksum = "feff3878564edb93745d58cf63e17b63f24142506e7a20c87a5521ed7bfb1d63"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
@ -82,14 +88,14 @@ dependencies = [
|
||||
"strsim",
|
||||
"termcolor",
|
||||
"textwrap",
|
||||
"vec_map",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.0.0-beta.4"
|
||||
version = "3.0.0-beta.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac"
|
||||
checksum = "8b15c6b4f786ffb6192ffe65a36855bc1fc2444bcd0945ae16748dcd6ed7d0d3"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
@ -98,6 +104,19 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45"
|
||||
dependencies = [
|
||||
"encode_unicode",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"terminal_size",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "countme"
|
||||
version = "2.0.4"
|
||||
@ -114,6 +133,18 @@ dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@ -197,6 +228,21 @@ dependencies = [
|
||||
"hashbrown 0.11.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "insta"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15226a375927344c78d39dc6b49e2d5562a5b0705e26a589093c6792e52eed8e"
|
||||
dependencies = [
|
||||
"console",
|
||||
"lazy_static",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"similar 1.3.0",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
@ -224,9 +270,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.103"
|
||||
version = "0.2.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
|
||||
checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
@ -278,9 +330,12 @@ checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "3.1.0"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6acbef58a60fe69ab50510a55bc8cdd4d6cf2283d27ad338f54cb52747a9cf2d"
|
||||
checksum = "addaa943333a514159c80c97ff4a93306530d965d27e139188283cd13e06a799"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
@ -308,18 +363,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.29"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -343,9 +398,9 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rnix"
|
||||
version = "0.9.0"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b37f8af07a0354606141df076458660af7e22238e4117a041c21c548080addd"
|
||||
checksum = "294becb48f58c496d96c10a12df290266204ca75c9799be4d04222bfaebb6a37"
|
||||
dependencies = [
|
||||
"cbitset",
|
||||
"rowan",
|
||||
@ -417,6 +472,24 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af"
|
||||
dependencies = [
|
||||
"dtoa",
|
||||
"indexmap",
|
||||
"serde",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec"
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.1.0"
|
||||
@ -425,9 +498,12 @@ checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3"
|
||||
|
||||
[[package]]
|
||||
name = "smol_str"
|
||||
version = "0.1.18"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b203e79e90905594272c1c97c7af701533d42adaab0beb3859018e477d54a3b0"
|
||||
checksum = "559b173452ec4061933b0c0e22d7d429c90ecdc1b3ae1c6e64238e7c15c3ee15"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "statix"
|
||||
@ -436,15 +512,26 @@ dependencies = [
|
||||
"ariadne",
|
||||
"clap",
|
||||
"ignore",
|
||||
"insta",
|
||||
"lib",
|
||||
"rnix",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"similar",
|
||||
"similar 2.1.0",
|
||||
"strip-ansi-escapes",
|
||||
"thiserror",
|
||||
"vfs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strip-ansi-escapes"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8"
|
||||
dependencies = [
|
||||
"vte",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
@ -453,9 +540,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.76"
|
||||
version = "1.0.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84"
|
||||
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -471,6 +558,16 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "terminal_size"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "text-size"
|
||||
version = "1.1.0"
|
||||
@ -515,6 +612,15 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.8.0"
|
||||
@ -534,10 +640,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
name = "utf8parse"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
@ -552,6 +664,27 @@ dependencies = [
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vte"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"utf8parse",
|
||||
"vte_generate_state_changes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vte_generate_state_changes"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
@ -594,6 +727,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "0.5.0"
|
||||
|
@ -6,7 +6,13 @@ license = "MIT"
|
||||
authors = [ "Akshay <nerdy@peppe.rs>" ]
|
||||
description = "Lints and suggestions for the Nix programming language"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
name = "statix"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "statix"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
ariadne = "0.1.3"
|
||||
@ -27,5 +33,9 @@ version = "1.0.68"
|
||||
features = [ "derive" ]
|
||||
optional = true
|
||||
|
||||
[dev-dependencies]
|
||||
insta = "1.8.0"
|
||||
strip-ansi-escapes = "0.1.1"
|
||||
|
||||
[features]
|
||||
json = [ "lib/json-out", "serde_json", "serde" ]
|
||||
|
@ -2,17 +2,17 @@ use std::{default::Default, fmt, fs, path::PathBuf, str::FromStr};
|
||||
|
||||
use crate::{dirs, err::ConfigErr};
|
||||
|
||||
use clap::Clap;
|
||||
use clap::Parser;
|
||||
use vfs::ReadOnlyVfs;
|
||||
|
||||
#[derive(Clap, Debug)]
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(version, author, about)]
|
||||
pub struct Opts {
|
||||
#[clap(subcommand)]
|
||||
pub cmd: SubCommand,
|
||||
}
|
||||
|
||||
#[derive(Clap, Debug)]
|
||||
#[derive(Parser, Debug)]
|
||||
pub enum SubCommand {
|
||||
/// Lints and suggestions for the nix programming language
|
||||
Check(Check),
|
||||
@ -24,7 +24,7 @@ pub enum SubCommand {
|
||||
Explain(Explain),
|
||||
}
|
||||
|
||||
#[derive(Clap, Debug)]
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct Check {
|
||||
/// File or directory to run check on
|
||||
#[clap(default_value = ".", parse(from_os_str))]
|
||||
@ -67,7 +67,7 @@ impl Check {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clap, Debug)]
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct Fix {
|
||||
/// File or directory to run fix on
|
||||
#[clap(default_value = ".", parse(from_os_str))]
|
||||
@ -127,7 +127,7 @@ impl Fix {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clap, Debug)]
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct Single {
|
||||
/// File to run single-fix on
|
||||
#[clap(parse(from_os_str))]
|
||||
@ -174,7 +174,7 @@ impl Single {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clap, Debug)]
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct Explain {
|
||||
/// Warning code to explain
|
||||
#[clap(parse(try_from_str = parse_warning_code))]
|
||||
|
7
bin/src/lib.rs
Normal file
7
bin/src/lib.rs
Normal file
@ -0,0 +1,7 @@
|
||||
pub mod config;
|
||||
pub mod dirs;
|
||||
pub mod err;
|
||||
pub mod explain;
|
||||
pub mod fix;
|
||||
pub mod lint;
|
||||
pub mod traits;
|
@ -1,15 +1,9 @@
|
||||
mod config;
|
||||
mod dirs;
|
||||
mod err;
|
||||
mod explain;
|
||||
mod fix;
|
||||
mod lint;
|
||||
mod traits;
|
||||
|
||||
use crate::err::StatixErr;
|
||||
|
||||
use clap::Clap;
|
||||
use config::{Opts, SubCommand};
|
||||
use clap::Parser;
|
||||
use statix::{
|
||||
config::{Opts, SubCommand},
|
||||
err::StatixErr,
|
||||
explain, fix, lint,
|
||||
};
|
||||
|
||||
fn _main() -> Result<(), StatixErr> {
|
||||
let opts = Opts::parse();
|
||||
|
13
bin/tests/data/bool_comparison.nix
Normal file
13
bin/tests/data/bool_comparison.nix
Normal file
@ -0,0 +1,13 @@
|
||||
[
|
||||
# trivial
|
||||
(a == true)
|
||||
(b == true)
|
||||
(true == c)
|
||||
(true == d)
|
||||
|
||||
# not equals
|
||||
(e != true)
|
||||
(f != false)
|
||||
(true != g)
|
||||
(false != h)
|
||||
]
|
9
bin/tests/data/collapsible_let_in.nix
Normal file
9
bin/tests/data/collapsible_let_in.nix
Normal file
@ -0,0 +1,9 @@
|
||||
let
|
||||
a = 2;
|
||||
b = 3;
|
||||
in
|
||||
let
|
||||
c = 5;
|
||||
d = 6;
|
||||
in
|
||||
a + b + c + d
|
6
bin/tests/data/deprecated_is_null.nix
Normal file
6
bin/tests/data/deprecated_is_null.nix
Normal file
@ -0,0 +1,6 @@
|
||||
let
|
||||
e = null;
|
||||
in
|
||||
if isNull e
|
||||
then "no"
|
||||
else "yes"
|
3
bin/tests/data/empty_let_in.nix
Normal file
3
bin/tests/data/empty_let_in.nix
Normal file
@ -0,0 +1,3 @@
|
||||
let
|
||||
in
|
||||
null
|
9
bin/tests/data/empty_pattern.nix
Normal file
9
bin/tests/data/empty_pattern.nix
Normal file
@ -0,0 +1,9 @@
|
||||
[
|
||||
# match
|
||||
({ ... }: 42)
|
||||
|
||||
# don't match
|
||||
({ a, ... }: a)
|
||||
({ ... } @ inputs: inputs)
|
||||
]
|
||||
|
18
bin/tests/data/eta_reduction.nix
Normal file
18
bin/tests/data/eta_reduction.nix
Normal file
@ -0,0 +1,18 @@
|
||||
let
|
||||
double = x: x * 2;
|
||||
inherit (builtins) map;
|
||||
xs = [ 1 2 3 ];
|
||||
f = {
|
||||
inherit double;
|
||||
val = 2;
|
||||
};
|
||||
in
|
||||
[
|
||||
(map (x: double x) xs)
|
||||
|
||||
# don't lint on non-free exprs
|
||||
(map (f: f.double f.val) [ f ])
|
||||
|
||||
# other non-free forms
|
||||
(map (f: {inherit f;}.double f.val) [ f ])
|
||||
]
|
5
bin/tests/data/legacy_let_syntax.nix
Normal file
5
bin/tests/data/legacy_let_syntax.nix
Normal file
@ -0,0 +1,5 @@
|
||||
let {
|
||||
body = x + y;
|
||||
x = "hello,";
|
||||
y = " world!";
|
||||
}
|
12
bin/tests/data/manual_inherit.nix
Normal file
12
bin/tests/data/manual_inherit.nix
Normal file
@ -0,0 +1,12 @@
|
||||
let
|
||||
a = 2;
|
||||
y = "y";
|
||||
in
|
||||
{
|
||||
# trivial
|
||||
a = a;
|
||||
|
||||
# don't lint
|
||||
x.y = y;
|
||||
}
|
||||
|
8
bin/tests/data/manual_inherit_from.nix
Normal file
8
bin/tests/data/manual_inherit_from.nix
Normal file
@ -0,0 +1,8 @@
|
||||
let
|
||||
a = {b = 2; c = 3;};
|
||||
in
|
||||
{
|
||||
b = a.b;
|
||||
c = a.c;
|
||||
}
|
||||
|
1
bin/tests/data/redundant_pattern_bind.nix
Normal file
1
bin/tests/data/redundant_pattern_bind.nix
Normal file
@ -0,0 +1 @@
|
||||
{ ... } @ inputs: null
|
15
bin/tests/data/unquoted_splices.nix
Normal file
15
bin/tests/data/unquoted_splices.nix
Normal file
@ -0,0 +1,15 @@
|
||||
let
|
||||
x = 2;
|
||||
y = 3;
|
||||
a = { "2" = y; };
|
||||
in
|
||||
[
|
||||
${x}
|
||||
${toString (x + y)}
|
||||
a.${toString x}
|
||||
|
||||
# multiline test
|
||||
${
|
||||
toString x
|
||||
}
|
||||
]
|
1
bin/tests/data/unquoted_uri.nix
Normal file
1
bin/tests/data/unquoted_uri.nix
Normal file
@ -0,0 +1 @@
|
||||
github:nerdypepper/statix
|
16
bin/tests/data/useless_parens.nix
Normal file
16
bin/tests/data/useless_parens.nix
Normal file
@ -0,0 +1,16 @@
|
||||
let
|
||||
# parens around primitives
|
||||
a = {
|
||||
b = ("hello");
|
||||
c = (d);
|
||||
e = ({ f = 2; });
|
||||
};
|
||||
|
||||
# parens around let-value
|
||||
g = (1 + 2);
|
||||
h = ({ inherit i; });
|
||||
|
||||
# TODO: binary exprs, function args etc.
|
||||
in
|
||||
# parens around let body
|
||||
(null)
|
47
bin/tests/main.rs
Normal file
47
bin/tests/main.rs
Normal file
@ -0,0 +1,47 @@
|
||||
mod util {
|
||||
#[macro_export]
|
||||
macro_rules! test_lint {
|
||||
($($tname:ident),*,) => {
|
||||
test_lint!($($tname),*);
|
||||
};
|
||||
($($tname:ident),*) => {
|
||||
$(
|
||||
#[test]
|
||||
fn $tname() {
|
||||
use statix::{config::OutFormat, traits::WriteDiagnostic, lint};
|
||||
use vfs::ReadOnlyVfs;
|
||||
|
||||
let file_path = concat!("data/", stringify!($tname), ".nix");
|
||||
let contents = include_str!(concat!("data/", stringify!($tname), ".nix"));
|
||||
|
||||
let vfs = ReadOnlyVfs::singleton(file_path, contents.as_bytes());
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
vfs.iter().map(lint::lint).for_each(|r| {
|
||||
buffer.write(&r, &vfs, OutFormat::StdErr).unwrap();
|
||||
});
|
||||
|
||||
let stripped = strip_ansi_escapes::strip(&buffer).unwrap();
|
||||
let out = std::str::from_utf8(&stripped).unwrap();
|
||||
insta::assert_snapshot!(&out);
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
test_lint! {
|
||||
bool_comparison,
|
||||
empty_let_in,
|
||||
manual_inherit,
|
||||
manual_inherit_from,
|
||||
legacy_let_syntax,
|
||||
collapsible_let_in,
|
||||
eta_reduction,
|
||||
useless_parens,
|
||||
unquoted_splices,
|
||||
empty_pattern,
|
||||
redundant_pattern_bind,
|
||||
unquoted_uri,
|
||||
deprecated_is_null,
|
||||
}
|
62
bin/tests/snapshots/main__bool_comparison.snap
Normal file
62
bin/tests/snapshots/main__bool_comparison.snap
Normal file
@ -0,0 +1,62 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W01] Warning: Unnecessary comparison with boolean
|
||||
╭─[data/bool_comparison.nix:3:4]
|
||||
│
|
||||
3 │ (a == true)
|
||||
· ────┬────
|
||||
· ╰────── Comparing a with boolean literal true
|
||||
───╯
|
||||
[W01] Warning: Unnecessary comparison with boolean
|
||||
╭─[data/bool_comparison.nix:4:4]
|
||||
│
|
||||
4 │ (b == true)
|
||||
· ────┬────
|
||||
· ╰────── Comparing b with boolean literal true
|
||||
───╯
|
||||
[W01] Warning: Unnecessary comparison with boolean
|
||||
╭─[data/bool_comparison.nix:5:4]
|
||||
│
|
||||
5 │ (true == c)
|
||||
· ────┬────
|
||||
· ╰────── Comparing c with boolean literal true
|
||||
───╯
|
||||
[W01] Warning: Unnecessary comparison with boolean
|
||||
╭─[data/bool_comparison.nix:6:4]
|
||||
│
|
||||
6 │ (true == d)
|
||||
· ────┬────
|
||||
· ╰────── Comparing d with boolean literal true
|
||||
───╯
|
||||
[W01] Warning: Unnecessary comparison with boolean
|
||||
╭─[data/bool_comparison.nix:9:4]
|
||||
│
|
||||
9 │ (e != true)
|
||||
· ────┬────
|
||||
· ╰────── Comparing e with boolean literal true
|
||||
───╯
|
||||
[W01] Warning: Unnecessary comparison with boolean
|
||||
╭─[data/bool_comparison.nix:10:4]
|
||||
│
|
||||
10 │ (f != false)
|
||||
· ─────┬────
|
||||
· ╰────── Comparing f with boolean literal false
|
||||
────╯
|
||||
[W01] Warning: Unnecessary comparison with boolean
|
||||
╭─[data/bool_comparison.nix:11:4]
|
||||
│
|
||||
11 │ (true != g)
|
||||
· ────┬────
|
||||
· ╰────── Comparing g with boolean literal true
|
||||
────╯
|
||||
[W01] Warning: Unnecessary comparison with boolean
|
||||
╭─[data/bool_comparison.nix:12:4]
|
||||
│
|
||||
12 │ (false != h)
|
||||
· ─────┬────
|
||||
· ╰────── Comparing h with boolean literal false
|
||||
────╯
|
||||
|
17
bin/tests/snapshots/main__collapsible_let_in.snap
Normal file
17
bin/tests/snapshots/main__collapsible_let_in.snap
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W06] Warning: These let-in expressions are collapsible
|
||||
╭─[data/collapsible_let_in.nix:1:1]
|
||||
│
|
||||
1 │ ╭───▶ let
|
||||
5 │ │ ╭─▶ let
|
||||
9 │ │ ├─▶ a + b + c + d
|
||||
· │ │ │
|
||||
· │ ╰───────────────────── This let in expression is nested
|
||||
· │ │
|
||||
· ╰───────────────────┴─── This let in expression contains a nested let in expression
|
||||
───╯
|
||||
|
13
bin/tests/snapshots/main__deprecated_is_null.snap
Normal file
13
bin/tests/snapshots/main__deprecated_is_null.snap
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W13] Warning: Found usage of deprecated builtin isNull
|
||||
╭─[data/deprecated_is_null.nix:4:4]
|
||||
│
|
||||
4 │ if isNull e
|
||||
· ────┬───
|
||||
· ╰───── isNull is deprecated, check equality with null instead
|
||||
───╯
|
||||
|
14
bin/tests/snapshots/main__empty_let_in.snap
Normal file
14
bin/tests/snapshots/main__empty_let_in.snap
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W02] Warning: Useless let-in expression
|
||||
╭─[data/empty_let_in.nix:1:1]
|
||||
│
|
||||
1 │ ╭─▶ let
|
||||
3 │ ├─▶ null
|
||||
· │
|
||||
· ╰──────────── This let-in expression has no entries
|
||||
───╯
|
||||
|
20
bin/tests/snapshots/main__empty_pattern.snap
Normal file
20
bin/tests/snapshots/main__empty_pattern.snap
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W10] Warning: Found empty pattern in function argument
|
||||
╭─[data/empty_pattern.nix:3:4]
|
||||
│
|
||||
3 │ ({ ... }: 42)
|
||||
· ───┬───
|
||||
· ╰───── This pattern is empty, use _ instead
|
||||
───╯
|
||||
[W11] Warning: Found redundant pattern bind in function argument
|
||||
╭─[data/empty_pattern.nix:7:4]
|
||||
│
|
||||
7 │ ({ ... } @ inputs: inputs)
|
||||
· ────────┬───────
|
||||
· ╰───────── This pattern bind is redundant, use inputs instead
|
||||
───╯
|
||||
|
13
bin/tests/snapshots/main__eta_reduction.snap
Normal file
13
bin/tests/snapshots/main__eta_reduction.snap
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W07] Warning: This function expression is eta reducible
|
||||
╭─[data/eta_reduction.nix:11:9]
|
||||
│
|
||||
11 │ (map (x: double x) xs)
|
||||
· ─────┬─────
|
||||
· ╰─────── Found eta-reduction: double
|
||||
────╯
|
||||
|
14
bin/tests/snapshots/main__legacy_let_syntax.snap
Normal file
14
bin/tests/snapshots/main__legacy_let_syntax.snap
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W05] Warning: Using undocumented `let` syntax
|
||||
╭─[data/legacy_let_syntax.nix:1:1]
|
||||
│
|
||||
1 │ ╭─▶ let {
|
||||
5 │ ├─▶ }
|
||||
· │
|
||||
· ╰─────── Prefer rec over undocumented let syntax
|
||||
───╯
|
||||
|
13
bin/tests/snapshots/main__manual_inherit.snap
Normal file
13
bin/tests/snapshots/main__manual_inherit.snap
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W03] Warning: Assignment instead of inherit
|
||||
╭─[data/manual_inherit.nix:7:3]
|
||||
│
|
||||
7 │ a = a;
|
||||
· ───┬──
|
||||
· ╰──── This assignment is better written with inherit
|
||||
───╯
|
||||
|
20
bin/tests/snapshots/main__manual_inherit_from.snap
Normal file
20
bin/tests/snapshots/main__manual_inherit_from.snap
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W04] Warning: Assignment instead of inherit from
|
||||
╭─[data/manual_inherit_from.nix:5:3]
|
||||
│
|
||||
5 │ b = a.b;
|
||||
· ────┬───
|
||||
· ╰───── This assignment is better written with inherit
|
||||
───╯
|
||||
[W04] Warning: Assignment instead of inherit from
|
||||
╭─[data/manual_inherit_from.nix:6:3]
|
||||
│
|
||||
6 │ c = a.c;
|
||||
· ────┬───
|
||||
· ╰───── This assignment is better written with inherit
|
||||
───╯
|
||||
|
13
bin/tests/snapshots/main__redundant_pattern_bind.snap
Normal file
13
bin/tests/snapshots/main__redundant_pattern_bind.snap
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W11] Warning: Found redundant pattern bind in function argument
|
||||
╭─[data/redundant_pattern_bind.nix:1:1]
|
||||
│
|
||||
1 │ { ... } @ inputs: null
|
||||
· ────────┬────────
|
||||
· ╰────────── This pattern bind is redundant, use inputs instead
|
||||
───╯
|
||||
|
35
bin/tests/snapshots/main__unquoted_splices.snap
Normal file
35
bin/tests/snapshots/main__unquoted_splices.snap
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W09] Warning: Found unquoted splice expression
|
||||
╭─[data/unquoted_splices.nix:7:3]
|
||||
│
|
||||
7 │ ${x}
|
||||
· ──┬─
|
||||
· ╰─── Consider quoting this splice expression
|
||||
───╯
|
||||
[W09] Warning: Found unquoted splice expression
|
||||
╭─[data/unquoted_splices.nix:8:3]
|
||||
│
|
||||
8 │ ${toString (x + y)}
|
||||
· ─────────┬─────────
|
||||
· ╰─────────── Consider quoting this splice expression
|
||||
───╯
|
||||
[W09] Warning: Found unquoted splice expression
|
||||
╭─[data/unquoted_splices.nix:9:5]
|
||||
│
|
||||
9 │ a.${toString x}
|
||||
· ──────┬──────
|
||||
· ╰──────── Consider quoting this splice expression
|
||||
───╯
|
||||
[W09] Warning: Found unquoted splice expression
|
||||
╭─[data/unquoted_splices.nix:12:3]
|
||||
│
|
||||
12 │ ╭─▶ ${
|
||||
14 │ ├─▶ }
|
||||
· │
|
||||
· ╰───────── Consider quoting this splice expression
|
||||
────╯
|
||||
|
13
bin/tests/snapshots/main__unquoted_uri.snap
Normal file
13
bin/tests/snapshots/main__unquoted_uri.snap
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W12] Warning: Found unquoted URI expression
|
||||
╭─[data/unquoted_uri.nix:1:1]
|
||||
│
|
||||
1 │ github:nerdypepper/statix
|
||||
· ────────────┬────────────
|
||||
· ╰────────────── Consider quoting this URI expression
|
||||
───╯
|
||||
|
48
bin/tests/snapshots/main__useless_parens.snap
Normal file
48
bin/tests/snapshots/main__useless_parens.snap
Normal file
@ -0,0 +1,48 @@
|
||||
---
|
||||
source: bin/tests/main.rs
|
||||
expression: "&out"
|
||||
|
||||
---
|
||||
[W08] Warning: These parentheses can be omitted
|
||||
╭─[data/useless_parens.nix:16:3]
|
||||
│
|
||||
16 │ (null)
|
||||
· ───┬──
|
||||
· ╰──── Useless parentheses around body of let expression
|
||||
────╯
|
||||
[W08] Warning: These parentheses can be omitted
|
||||
╭─[data/useless_parens.nix:4:9]
|
||||
│
|
||||
4 │ b = ("hello");
|
||||
· ────┬────
|
||||
· ╰────── Useless parentheses around value in binding
|
||||
───╯
|
||||
[W08] Warning: These parentheses can be omitted
|
||||
╭─[data/useless_parens.nix:5:9]
|
||||
│
|
||||
5 │ c = (d);
|
||||
· ─┬─
|
||||
· ╰─── Useless parentheses around value in binding
|
||||
───╯
|
||||
[W08] Warning: These parentheses can be omitted
|
||||
╭─[data/useless_parens.nix:6:9]
|
||||
│
|
||||
6 │ e = ({ f = 2; });
|
||||
· ──────┬─────
|
||||
· ╰─────── Useless parentheses around value in binding
|
||||
───╯
|
||||
[W08] Warning: These parentheses can be omitted
|
||||
╭─[data/useless_parens.nix:10:7]
|
||||
│
|
||||
10 │ g = (1 + 2);
|
||||
· ───┬───
|
||||
· ╰───── Useless parentheses around value in binding
|
||||
────╯
|
||||
[W08] Warning: These parentheses can be omitted
|
||||
╭─[data/useless_parens.nix:11:7]
|
||||
│
|
||||
11 │ h = ({ inherit i; });
|
||||
· ────────┬───────
|
||||
· ╰───────── Useless parentheses around value in binding
|
||||
────╯
|
||||
|
@ -93,11 +93,12 @@
|
||||
"clippy"
|
||||
"rust-src"
|
||||
];
|
||||
inherit (fenix.packages."${system}") rust-analyzer;
|
||||
in
|
||||
with pkgs;
|
||||
mkShell rec {
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = [
|
||||
cargo-watch
|
||||
pkgs.cargo-watch
|
||||
pkgs.cargo-insta
|
||||
rust-analyzer
|
||||
toolchain
|
||||
];
|
||||
|
@ -3,7 +3,7 @@ use crate::{Diagnostic, Metadata, Report, Rule, Suggestion};
|
||||
use if_chain::if_chain;
|
||||
use macros::lint;
|
||||
use rnix::{
|
||||
types::{KeyValue, Paren, ParsedType, TypedNode, Wrapper},
|
||||
types::{KeyValue, LetIn, Paren, ParsedType, TypedNode, Wrapper},
|
||||
NodeOrToken, SyntaxElement, SyntaxKind,
|
||||
};
|
||||
|
||||
@ -71,7 +71,7 @@ fn do_thing(parsed_type_node: ParsedType) -> Option<Diagnostic> {
|
||||
if let Some(inner) = value_in_parens.inner();
|
||||
then {
|
||||
let at = value_range;
|
||||
let message = "Useless parentheses around value in `let` binding";
|
||||
let message = "Useless parentheses around value in binding";
|
||||
let replacement = inner;
|
||||
Some(Diagnostic::suggest(at, message, Suggestion::new(at, replacement)))
|
||||
} else {
|
||||
@ -98,7 +98,11 @@ fn do_thing(parsed_type_node: ParsedType) -> Option<Diagnostic> {
|
||||
|
||||
// ensure that we don't lint inside let-in statements
|
||||
// we already lint such cases in previous match stmt
|
||||
if KeyValue::cast(father_node).is_none();
|
||||
if KeyValue::cast(father_node.clone()).is_none();
|
||||
|
||||
// ensure that we don't lint inside let-bodies
|
||||
// if this primitive is a let-body, we have already linted it
|
||||
if LetIn::cast(father_node).is_none();
|
||||
|
||||
if let Some(inner_node) = paren_expr.inner();
|
||||
if let Some(parsed_inner) = ParsedType::cast(inner_node);
|
||||
|
@ -7,7 +7,7 @@ use std::{
|
||||
use indexmap::IndexSet;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
pub struct FileId(u32);
|
||||
pub struct FileId(pub u32);
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Interner {
|
||||
|
Loading…
Reference in New Issue
Block a user