diff options
35 files changed, 665 insertions, 49 deletions
@@ -21,6 +21,12 @@ dependencies = [ | |||
21 | ] | 21 | ] |
22 | 22 | ||
23 | [[package]] | 23 | [[package]] |
24 | name = "arrayvec" | ||
25 | version = "0.5.2" | ||
26 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
27 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" | ||
28 | |||
29 | [[package]] | ||
24 | name = "atty" | 30 | name = "atty" |
25 | version = "0.2.14" | 31 | version = "0.2.14" |
26 | source = "registry+https://github.com/rust-lang/crates.io-index" | 32 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -69,9 +75,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | |||
69 | 75 | ||
70 | [[package]] | 76 | [[package]] |
71 | name = "clap" | 77 | name = "clap" |
72 | version = "3.0.0-beta.4" | 78 | version = "3.0.0-beta.5" |
73 | source = "registry+https://github.com/rust-lang/crates.io-index" | 79 | source = "registry+https://github.com/rust-lang/crates.io-index" |
74 | checksum = "fcd70aa5597dbc42f7217a543f9ef2768b2ef823ba29036072d30e1d88e98406" | 80 | checksum = "feff3878564edb93745d58cf63e17b63f24142506e7a20c87a5521ed7bfb1d63" |
75 | dependencies = [ | 81 | dependencies = [ |
76 | "atty", | 82 | "atty", |
77 | "bitflags", | 83 | "bitflags", |
@@ -82,14 +88,14 @@ dependencies = [ | |||
82 | "strsim", | 88 | "strsim", |
83 | "termcolor", | 89 | "termcolor", |
84 | "textwrap", | 90 | "textwrap", |
85 | "vec_map", | 91 | "unicase", |
86 | ] | 92 | ] |
87 | 93 | ||
88 | [[package]] | 94 | [[package]] |
89 | name = "clap_derive" | 95 | name = "clap_derive" |
90 | version = "3.0.0-beta.4" | 96 | version = "3.0.0-beta.5" |
91 | source = "registry+https://github.com/rust-lang/crates.io-index" | 97 | source = "registry+https://github.com/rust-lang/crates.io-index" |
92 | checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac" | 98 | checksum = "8b15c6b4f786ffb6192ffe65a36855bc1fc2444bcd0945ae16748dcd6ed7d0d3" |
93 | dependencies = [ | 99 | dependencies = [ |
94 | "heck", | 100 | "heck", |
95 | "proc-macro-error", | 101 | "proc-macro-error", |
@@ -99,6 +105,19 @@ dependencies = [ | |||
99 | ] | 105 | ] |
100 | 106 | ||
101 | [[package]] | 107 | [[package]] |
108 | name = "console" | ||
109 | version = "0.14.1" | ||
110 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
111 | checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45" | ||
112 | dependencies = [ | ||
113 | "encode_unicode", | ||
114 | "lazy_static", | ||
115 | "libc", | ||
116 | "terminal_size", | ||
117 | "winapi", | ||
118 | ] | ||
119 | |||
120 | [[package]] | ||
102 | name = "countme" | 121 | name = "countme" |
103 | version = "2.0.4" | 122 | version = "2.0.4" |
104 | source = "registry+https://github.com/rust-lang/crates.io-index" | 123 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -115,6 +134,18 @@ dependencies = [ | |||
115 | ] | 134 | ] |
116 | 135 | ||
117 | [[package]] | 136 | [[package]] |
137 | name = "dtoa" | ||
138 | version = "0.4.8" | ||
139 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
140 | checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" | ||
141 | |||
142 | [[package]] | ||
143 | name = "encode_unicode" | ||
144 | version = "0.3.6" | ||
145 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
146 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" | ||
147 | |||
148 | [[package]] | ||
118 | name = "fnv" | 149 | name = "fnv" |
119 | version = "1.0.7" | 150 | version = "1.0.7" |
120 | source = "registry+https://github.com/rust-lang/crates.io-index" | 151 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -198,6 +229,21 @@ dependencies = [ | |||
198 | ] | 229 | ] |
199 | 230 | ||
200 | [[package]] | 231 | [[package]] |
232 | name = "insta" | ||
233 | version = "1.8.0" | ||
234 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
235 | checksum = "15226a375927344c78d39dc6b49e2d5562a5b0705e26a589093c6792e52eed8e" | ||
236 | dependencies = [ | ||
237 | "console", | ||
238 | "lazy_static", | ||
239 | "serde", | ||
240 | "serde_json", | ||
241 | "serde_yaml", | ||
242 | "similar 1.3.0", | ||
243 | "uuid", | ||
244 | ] | ||
245 | |||
246 | [[package]] | ||
201 | name = "itoa" | 247 | name = "itoa" |
202 | version = "0.4.8" | 248 | version = "0.4.8" |
203 | source = "registry+https://github.com/rust-lang/crates.io-index" | 249 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -224,9 +270,15 @@ dependencies = [ | |||
224 | 270 | ||
225 | [[package]] | 271 | [[package]] |
226 | name = "libc" | 272 | name = "libc" |
227 | version = "0.2.103" | 273 | version = "0.2.106" |
228 | source = "registry+https://github.com/rust-lang/crates.io-index" | 274 | source = "registry+https://github.com/rust-lang/crates.io-index" |
229 | checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" | 275 | checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673" |
276 | |||
277 | [[package]] | ||
278 | name = "linked-hash-map" | ||
279 | version = "0.5.4" | ||
280 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
281 | checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" | ||
230 | 282 | ||
231 | [[package]] | 283 | [[package]] |
232 | name = "log" | 284 | name = "log" |
@@ -278,9 +330,12 @@ checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" | |||
278 | 330 | ||
279 | [[package]] | 331 | [[package]] |
280 | name = "os_str_bytes" | 332 | name = "os_str_bytes" |
281 | version = "3.1.0" | 333 | version = "4.2.0" |
282 | source = "registry+https://github.com/rust-lang/crates.io-index" | 334 | source = "registry+https://github.com/rust-lang/crates.io-index" |
283 | checksum = "6acbef58a60fe69ab50510a55bc8cdd4d6cf2283d27ad338f54cb52747a9cf2d" | 335 | checksum = "addaa943333a514159c80c97ff4a93306530d965d27e139188283cd13e06a799" |
336 | dependencies = [ | ||
337 | "memchr", | ||
338 | ] | ||
284 | 339 | ||
285 | [[package]] | 340 | [[package]] |
286 | name = "proc-macro-error" | 341 | name = "proc-macro-error" |
@@ -308,18 +363,18 @@ dependencies = [ | |||
308 | 363 | ||
309 | [[package]] | 364 | [[package]] |
310 | name = "proc-macro2" | 365 | name = "proc-macro2" |
311 | version = "1.0.29" | 366 | version = "1.0.32" |
312 | source = "registry+https://github.com/rust-lang/crates.io-index" | 367 | source = "registry+https://github.com/rust-lang/crates.io-index" |
313 | checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" | 368 | checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" |
314 | dependencies = [ | 369 | dependencies = [ |
315 | "unicode-xid", | 370 | "unicode-xid", |
316 | ] | 371 | ] |
317 | 372 | ||
318 | [[package]] | 373 | [[package]] |
319 | name = "quote" | 374 | name = "quote" |
320 | version = "1.0.9" | 375 | version = "1.0.10" |
321 | source = "registry+https://github.com/rust-lang/crates.io-index" | 376 | source = "registry+https://github.com/rust-lang/crates.io-index" |
322 | checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" | 377 | checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" |
323 | dependencies = [ | 378 | dependencies = [ |
324 | "proc-macro2", | 379 | "proc-macro2", |
325 | ] | 380 | ] |
@@ -343,9 +398,9 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" | |||
343 | 398 | ||
344 | [[package]] | 399 | [[package]] |
345 | name = "rnix" | 400 | name = "rnix" |
346 | version = "0.9.0" | 401 | version = "0.9.1" |
347 | source = "registry+https://github.com/rust-lang/crates.io-index" | 402 | source = "registry+https://github.com/rust-lang/crates.io-index" |
348 | checksum = "1b37f8af07a0354606141df076458660af7e22238e4117a041c21c548080addd" | 403 | checksum = "294becb48f58c496d96c10a12df290266204ca75c9799be4d04222bfaebb6a37" |
349 | dependencies = [ | 404 | dependencies = [ |
350 | "cbitset", | 405 | "cbitset", |
351 | "rowan", | 406 | "rowan", |
@@ -418,6 +473,24 @@ dependencies = [ | |||
418 | ] | 473 | ] |
419 | 474 | ||
420 | [[package]] | 475 | [[package]] |
476 | name = "serde_yaml" | ||
477 | version = "0.8.21" | ||
478 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
479 | checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af" | ||
480 | dependencies = [ | ||
481 | "dtoa", | ||
482 | "indexmap", | ||
483 | "serde", | ||
484 | "yaml-rust", | ||
485 | ] | ||
486 | |||
487 | [[package]] | ||
488 | name = "similar" | ||
489 | version = "1.3.0" | ||
490 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
491 | checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec" | ||
492 | |||
493 | [[package]] | ||
421 | name = "similar" | 494 | name = "similar" |
422 | version = "2.1.0" | 495 | version = "2.1.0" |
423 | source = "registry+https://github.com/rust-lang/crates.io-index" | 496 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -425,9 +498,12 @@ checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" | |||
425 | 498 | ||
426 | [[package]] | 499 | [[package]] |
427 | name = "smol_str" | 500 | name = "smol_str" |
428 | version = "0.1.18" | 501 | version = "0.1.20" |
429 | source = "registry+https://github.com/rust-lang/crates.io-index" | 502 | source = "registry+https://github.com/rust-lang/crates.io-index" |
430 | checksum = "b203e79e90905594272c1c97c7af701533d42adaab0beb3859018e477d54a3b0" | 503 | checksum = "559b173452ec4061933b0c0e22d7d429c90ecdc1b3ae1c6e64238e7c15c3ee15" |
504 | dependencies = [ | ||
505 | "serde", | ||
506 | ] | ||
431 | 507 | ||
432 | [[package]] | 508 | [[package]] |
433 | name = "statix" | 509 | name = "statix" |
@@ -436,16 +512,27 @@ dependencies = [ | |||
436 | "ariadne", | 512 | "ariadne", |
437 | "clap", | 513 | "clap", |
438 | "ignore", | 514 | "ignore", |
515 | "insta", | ||
439 | "lib", | 516 | "lib", |
440 | "rnix", | 517 | "rnix", |
441 | "serde", | 518 | "serde", |
442 | "serde_json", | 519 | "serde_json", |
443 | "similar", | 520 | "similar 2.1.0", |
521 | "strip-ansi-escapes", | ||
444 | "thiserror", | 522 | "thiserror", |
445 | "vfs", | 523 | "vfs", |
446 | ] | 524 | ] |
447 | 525 | ||
448 | [[package]] | 526 | [[package]] |
527 | name = "strip-ansi-escapes" | ||
528 | version = "0.1.1" | ||
529 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
530 | checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8" | ||
531 | dependencies = [ | ||
532 | "vte", | ||
533 | ] | ||
534 | |||
535 | [[package]] | ||
449 | name = "strsim" | 536 | name = "strsim" |
450 | version = "0.10.0" | 537 | version = "0.10.0" |
451 | source = "registry+https://github.com/rust-lang/crates.io-index" | 538 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -453,9 +540,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" | |||
453 | 540 | ||
454 | [[package]] | 541 | [[package]] |
455 | name = "syn" | 542 | name = "syn" |
456 | version = "1.0.76" | 543 | version = "1.0.81" |
457 | source = "registry+https://github.com/rust-lang/crates.io-index" | 544 | source = "registry+https://github.com/rust-lang/crates.io-index" |
458 | checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" | 545 | checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" |
459 | dependencies = [ | 546 | dependencies = [ |
460 | "proc-macro2", | 547 | "proc-macro2", |
461 | "quote", | 548 | "quote", |
@@ -472,6 +559,16 @@ dependencies = [ | |||
472 | ] | 559 | ] |
473 | 560 | ||
474 | [[package]] | 561 | [[package]] |
562 | name = "terminal_size" | ||
563 | version = "0.1.17" | ||
564 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
565 | checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" | ||
566 | dependencies = [ | ||
567 | "libc", | ||
568 | "winapi", | ||
569 | ] | ||
570 | |||
571 | [[package]] | ||
475 | name = "text-size" | 572 | name = "text-size" |
476 | version = "1.1.0" | 573 | version = "1.1.0" |
477 | source = "registry+https://github.com/rust-lang/crates.io-index" | 574 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -516,6 +613,15 @@ dependencies = [ | |||
516 | ] | 613 | ] |
517 | 614 | ||
518 | [[package]] | 615 | [[package]] |
616 | name = "unicase" | ||
617 | version = "2.6.0" | ||
618 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
619 | checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" | ||
620 | dependencies = [ | ||
621 | "version_check", | ||
622 | ] | ||
623 | |||
624 | [[package]] | ||
519 | name = "unicode-segmentation" | 625 | name = "unicode-segmentation" |
520 | version = "1.8.0" | 626 | version = "1.8.0" |
521 | source = "registry+https://github.com/rust-lang/crates.io-index" | 627 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -534,10 +640,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
534 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" | 640 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" |
535 | 641 | ||
536 | [[package]] | 642 | [[package]] |
537 | name = "vec_map" | 643 | name = "utf8parse" |
644 | version = "0.2.0" | ||
645 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
646 | checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" | ||
647 | |||
648 | [[package]] | ||
649 | name = "uuid" | ||
538 | version = "0.8.2" | 650 | version = "0.8.2" |
539 | source = "registry+https://github.com/rust-lang/crates.io-index" | 651 | source = "registry+https://github.com/rust-lang/crates.io-index" |
540 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" | 652 | checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" |
541 | 653 | ||
542 | [[package]] | 654 | [[package]] |
543 | name = "version_check" | 655 | name = "version_check" |
@@ -553,6 +665,27 @@ dependencies = [ | |||
553 | ] | 665 | ] |
554 | 666 | ||
555 | [[package]] | 667 | [[package]] |
668 | name = "vte" | ||
669 | version = "0.10.1" | ||
670 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
671 | checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" | ||
672 | dependencies = [ | ||
673 | "arrayvec", | ||
674 | "utf8parse", | ||
675 | "vte_generate_state_changes", | ||
676 | ] | ||
677 | |||
678 | [[package]] | ||
679 | name = "vte_generate_state_changes" | ||
680 | version = "0.1.1" | ||
681 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
682 | checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" | ||
683 | dependencies = [ | ||
684 | "proc-macro2", | ||
685 | "quote", | ||
686 | ] | ||
687 | |||
688 | [[package]] | ||
556 | name = "walkdir" | 689 | name = "walkdir" |
557 | version = "2.3.2" | 690 | version = "2.3.2" |
558 | source = "registry+https://github.com/rust-lang/crates.io-index" | 691 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -595,6 +728,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
595 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | 728 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |
596 | 729 | ||
597 | [[package]] | 730 | [[package]] |
731 | name = "yaml-rust" | ||
732 | version = "0.4.5" | ||
733 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
734 | checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" | ||
735 | dependencies = [ | ||
736 | "linked-hash-map", | ||
737 | ] | ||
738 | |||
739 | [[package]] | ||
598 | name = "yansi" | 740 | name = "yansi" |
599 | version = "0.5.0" | 741 | version = "0.5.0" |
600 | source = "registry+https://github.com/rust-lang/crates.io-index" | 742 | source = "registry+https://github.com/rust-lang/crates.io-index" |
diff --git a/bin/Cargo.toml b/bin/Cargo.toml index d67e6c1..7c48083 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml | |||
@@ -6,7 +6,13 @@ license = "MIT" | |||
6 | authors = [ "Akshay <[email protected]>" ] | 6 | authors = [ "Akshay <[email protected]>" ] |
7 | description = "Lints and suggestions for the Nix programming language" | 7 | description = "Lints and suggestions for the Nix programming language" |
8 | 8 | ||
9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | 9 | [lib] |
10 | name = "statix" | ||
11 | path = "src/lib.rs" | ||
12 | |||
13 | [[bin]] | ||
14 | name = "statix" | ||
15 | path = "src/main.rs" | ||
10 | 16 | ||
11 | [dependencies] | 17 | [dependencies] |
12 | ariadne = "0.1.3" | 18 | ariadne = "0.1.3" |
@@ -27,5 +33,9 @@ version = "1.0.68" | |||
27 | features = [ "derive" ] | 33 | features = [ "derive" ] |
28 | optional = true | 34 | optional = true |
29 | 35 | ||
36 | [dev-dependencies] | ||
37 | insta = "1.8.0" | ||
38 | strip-ansi-escapes = "0.1.1" | ||
39 | |||
30 | [features] | 40 | [features] |
31 | json = [ "lib/json-out", "serde_json", "serde" ] | 41 | json = [ "lib/json-out", "serde_json", "serde" ] |
diff --git a/bin/src/config.rs b/bin/src/config.rs index 25c2a7f..d3944ac 100644 --- a/bin/src/config.rs +++ b/bin/src/config.rs | |||
@@ -2,17 +2,17 @@ use std::{default::Default, fmt, fs, path::PathBuf, str::FromStr}; | |||
2 | 2 | ||
3 | use crate::{dirs, err::ConfigErr}; | 3 | use crate::{dirs, err::ConfigErr}; |
4 | 4 | ||
5 | use clap::Clap; | 5 | use clap::Parser; |
6 | use vfs::ReadOnlyVfs; | 6 | use vfs::ReadOnlyVfs; |
7 | 7 | ||
8 | #[derive(Clap, Debug)] | 8 | #[derive(Parser, Debug)] |
9 | #[clap(version, author, about)] | 9 | #[clap(version, author, about)] |
10 | pub struct Opts { | 10 | pub struct Opts { |
11 | #[clap(subcommand)] | 11 | #[clap(subcommand)] |
12 | pub cmd: SubCommand, | 12 | pub cmd: SubCommand, |
13 | } | 13 | } |
14 | 14 | ||
15 | #[derive(Clap, Debug)] | 15 | #[derive(Parser, Debug)] |
16 | pub enum SubCommand { | 16 | pub enum SubCommand { |
17 | /// Lints and suggestions for the nix programming language | 17 | /// Lints and suggestions for the nix programming language |
18 | Check(Check), | 18 | Check(Check), |
@@ -24,7 +24,7 @@ pub enum SubCommand { | |||
24 | Explain(Explain), | 24 | Explain(Explain), |
25 | } | 25 | } |
26 | 26 | ||
27 | #[derive(Clap, Debug)] | 27 | #[derive(Parser, Debug)] |
28 | pub struct Check { | 28 | pub struct Check { |
29 | /// File or directory to run check on | 29 | /// File or directory to run check on |
30 | #[clap(default_value = ".", parse(from_os_str))] | 30 | #[clap(default_value = ".", parse(from_os_str))] |
@@ -67,7 +67,7 @@ impl Check { | |||
67 | } | 67 | } |
68 | } | 68 | } |
69 | 69 | ||
70 | #[derive(Clap, Debug)] | 70 | #[derive(Parser, Debug)] |
71 | pub struct Fix { | 71 | pub struct Fix { |
72 | /// File or directory to run fix on | 72 | /// File or directory to run fix on |
73 | #[clap(default_value = ".", parse(from_os_str))] | 73 | #[clap(default_value = ".", parse(from_os_str))] |
@@ -127,7 +127,7 @@ impl Fix { | |||
127 | } | 127 | } |
128 | } | 128 | } |
129 | 129 | ||
130 | #[derive(Clap, Debug)] | 130 | #[derive(Parser, Debug)] |
131 | pub struct Single { | 131 | pub struct Single { |
132 | /// File to run single-fix on | 132 | /// File to run single-fix on |
133 | #[clap(parse(from_os_str))] | 133 | #[clap(parse(from_os_str))] |
@@ -174,7 +174,7 @@ impl Single { | |||
174 | } | 174 | } |
175 | } | 175 | } |
176 | 176 | ||
177 | #[derive(Clap, Debug)] | 177 | #[derive(Parser, Debug)] |
178 | pub struct Explain { | 178 | pub struct Explain { |
179 | /// Warning code to explain | 179 | /// Warning code to explain |
180 | #[clap(parse(try_from_str = parse_warning_code))] | 180 | #[clap(parse(try_from_str = parse_warning_code))] |
diff --git a/bin/src/lib.rs b/bin/src/lib.rs new file mode 100644 index 0000000..49c1a41 --- /dev/null +++ b/bin/src/lib.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | pub mod config; | ||
2 | pub mod dirs; | ||
3 | pub mod err; | ||
4 | pub mod explain; | ||
5 | pub mod fix; | ||
6 | pub mod lint; | ||
7 | pub mod traits; | ||
diff --git a/bin/src/main.rs b/bin/src/main.rs index fabc509..f504796 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs | |||
@@ -1,15 +1,9 @@ | |||
1 | mod config; | 1 | use clap::Parser; |
2 | mod dirs; | 2 | use statix::{ |
3 | mod err; | 3 | config::{Opts, SubCommand}, |
4 | mod explain; | 4 | err::StatixErr, |
5 | mod fix; | 5 | explain, fix, lint, |
6 | mod lint; | 6 | }; |
7 | mod traits; | ||
8 | |||
9 | use crate::err::StatixErr; | ||
10 | |||
11 | use clap::Clap; | ||
12 | use config::{Opts, SubCommand}; | ||
13 | 7 | ||
14 | fn _main() -> Result<(), StatixErr> { | 8 | fn _main() -> Result<(), StatixErr> { |
15 | let opts = Opts::parse(); | 9 | let opts = Opts::parse(); |
diff --git a/bin/tests/data/bool_comparison.nix b/bin/tests/data/bool_comparison.nix new file mode 100644 index 0000000..dee2d08 --- /dev/null +++ b/bin/tests/data/bool_comparison.nix | |||
@@ -0,0 +1,13 @@ | |||
1 | [ | ||
2 | # trivial | ||
3 | (a == true) | ||
4 | (b == true) | ||
5 | (true == c) | ||
6 | (true == d) | ||
7 | |||
8 | # not equals | ||
9 | (e != true) | ||
10 | (f != false) | ||
11 | (true != g) | ||
12 | (false != h) | ||
13 | ] | ||
diff --git a/bin/tests/data/collapsible_let_in.nix b/bin/tests/data/collapsible_let_in.nix new file mode 100644 index 0000000..7b41014 --- /dev/null +++ b/bin/tests/data/collapsible_let_in.nix | |||
@@ -0,0 +1,9 @@ | |||
1 | let | ||
2 | a = 2; | ||
3 | b = 3; | ||
4 | in | ||
5 | let | ||
6 | c = 5; | ||
7 | d = 6; | ||
8 | in | ||
9 | a + b + c + d | ||
diff --git a/bin/tests/data/deprecated_is_null.nix b/bin/tests/data/deprecated_is_null.nix new file mode 100644 index 0000000..42596d7 --- /dev/null +++ b/bin/tests/data/deprecated_is_null.nix | |||
@@ -0,0 +1,6 @@ | |||
1 | let | ||
2 | e = null; | ||
3 | in | ||
4 | if isNull e | ||
5 | then "no" | ||
6 | else "yes" | ||
diff --git a/bin/tests/data/empty_let_in.nix b/bin/tests/data/empty_let_in.nix new file mode 100644 index 0000000..3ecb6e4 --- /dev/null +++ b/bin/tests/data/empty_let_in.nix | |||
@@ -0,0 +1,3 @@ | |||
1 | let | ||
2 | in | ||
3 | null | ||
diff --git a/bin/tests/data/empty_pattern.nix b/bin/tests/data/empty_pattern.nix new file mode 100644 index 0000000..23d99e8 --- /dev/null +++ b/bin/tests/data/empty_pattern.nix | |||
@@ -0,0 +1,9 @@ | |||
1 | [ | ||
2 | # match | ||
3 | ({ ... }: 42) | ||
4 | |||
5 | # don't match | ||
6 | ({ a, ... }: a) | ||
7 | ({ ... } @ inputs: inputs) | ||
8 | ] | ||
9 | |||
diff --git a/bin/tests/data/eta_reduction.nix b/bin/tests/data/eta_reduction.nix new file mode 100644 index 0000000..e717ee7 --- /dev/null +++ b/bin/tests/data/eta_reduction.nix | |||
@@ -0,0 +1,18 @@ | |||
1 | let | ||
2 | double = x: x * 2; | ||
3 | inherit (builtins) map; | ||
4 | xs = [ 1 2 3 ]; | ||
5 | f = { | ||
6 | inherit double; | ||
7 | val = 2; | ||
8 | }; | ||
9 | in | ||
10 | [ | ||
11 | (map (x: double x) xs) | ||
12 | |||
13 | # don't lint on non-free exprs | ||
14 | (map (f: f.double f.val) [ f ]) | ||
15 | |||
16 | # other non-free forms | ||
17 | (map (f: {inherit f;}.double f.val) [ f ]) | ||
18 | ] | ||
diff --git a/bin/tests/data/legacy_let_syntax.nix b/bin/tests/data/legacy_let_syntax.nix new file mode 100644 index 0000000..46e3191 --- /dev/null +++ b/bin/tests/data/legacy_let_syntax.nix | |||
@@ -0,0 +1,5 @@ | |||
1 | let { | ||
2 | body = x + y; | ||
3 | x = "hello,"; | ||
4 | y = " world!"; | ||
5 | } | ||
diff --git a/bin/tests/data/manual_inherit.nix b/bin/tests/data/manual_inherit.nix new file mode 100644 index 0000000..53ae4d7 --- /dev/null +++ b/bin/tests/data/manual_inherit.nix | |||
@@ -0,0 +1,12 @@ | |||
1 | let | ||
2 | a = 2; | ||
3 | y = "y"; | ||
4 | in | ||
5 | { | ||
6 | # trivial | ||
7 | a = a; | ||
8 | |||
9 | # don't lint | ||
10 | x.y = y; | ||
11 | } | ||
12 | |||
diff --git a/bin/tests/data/manual_inherit_from.nix b/bin/tests/data/manual_inherit_from.nix new file mode 100644 index 0000000..214b2a3 --- /dev/null +++ b/bin/tests/data/manual_inherit_from.nix | |||
@@ -0,0 +1,8 @@ | |||
1 | let | ||
2 | a = {b = 2; c = 3;}; | ||
3 | in | ||
4 | { | ||
5 | b = a.b; | ||
6 | c = a.c; | ||
7 | } | ||
8 | |||
diff --git a/bin/tests/data/redundant_pattern_bind.nix b/bin/tests/data/redundant_pattern_bind.nix new file mode 100644 index 0000000..d328c50 --- /dev/null +++ b/bin/tests/data/redundant_pattern_bind.nix | |||
@@ -0,0 +1 @@ | |||
{ ... } @ inputs: null | |||
diff --git a/bin/tests/data/unquoted_splices.nix b/bin/tests/data/unquoted_splices.nix new file mode 100644 index 0000000..30935b0 --- /dev/null +++ b/bin/tests/data/unquoted_splices.nix | |||
@@ -0,0 +1,15 @@ | |||
1 | let | ||
2 | x = 2; | ||
3 | y = 3; | ||
4 | a = { "2" = y; }; | ||
5 | in | ||
6 | [ | ||
7 | ${x} | ||
8 | ${toString (x + y)} | ||
9 | a.${toString x} | ||
10 | |||
11 | # multiline test | ||
12 | ${ | ||
13 | toString x | ||
14 | } | ||
15 | ] | ||
diff --git a/bin/tests/data/unquoted_uri.nix b/bin/tests/data/unquoted_uri.nix new file mode 100644 index 0000000..e56574a --- /dev/null +++ b/bin/tests/data/unquoted_uri.nix | |||
@@ -0,0 +1 @@ | |||
github:nerdypepper/statix | |||
diff --git a/bin/tests/data/useless_parens.nix b/bin/tests/data/useless_parens.nix new file mode 100644 index 0000000..cf26441 --- /dev/null +++ b/bin/tests/data/useless_parens.nix | |||
@@ -0,0 +1,16 @@ | |||
1 | let | ||
2 | # parens around primitives | ||
3 | a = { | ||
4 | b = ("hello"); | ||
5 | c = (d); | ||
6 | e = ({ f = 2; }); | ||
7 | }; | ||
8 | |||
9 | # parens around let-value | ||
10 | g = (1 + 2); | ||
11 | h = ({ inherit i; }); | ||
12 | |||
13 | # TODO: binary exprs, function args etc. | ||
14 | in | ||
15 | # parens around let body | ||
16 | (null) | ||
diff --git a/bin/tests/main.rs b/bin/tests/main.rs new file mode 100644 index 0000000..6175c90 --- /dev/null +++ b/bin/tests/main.rs | |||
@@ -0,0 +1,47 @@ | |||
1 | mod util { | ||
2 | #[macro_export] | ||
3 | macro_rules! test_lint { | ||
4 | ($($tname:ident),*,) => { | ||
5 | test_lint!($($tname),*); | ||
6 | }; | ||
7 | ($($tname:ident),*) => { | ||
8 | $( | ||
9 | #[test] | ||
10 | fn $tname() { | ||
11 | use statix::{config::OutFormat, traits::WriteDiagnostic, lint}; | ||
12 | use vfs::ReadOnlyVfs; | ||
13 | |||
14 | let file_path = concat!("data/", stringify!($tname), ".nix"); | ||
15 | let contents = include_str!(concat!("data/", stringify!($tname), ".nix")); | ||
16 | |||
17 | let vfs = ReadOnlyVfs::singleton(file_path, contents.as_bytes()); | ||
18 | |||
19 | let mut buffer = Vec::new(); | ||
20 | vfs.iter().map(lint::lint).for_each(|r| { | ||
21 | buffer.write(&r, &vfs, OutFormat::StdErr).unwrap(); | ||
22 | }); | ||
23 | |||
24 | let stripped = strip_ansi_escapes::strip(&buffer).unwrap(); | ||
25 | let out = std::str::from_utf8(&stripped).unwrap(); | ||
26 | insta::assert_snapshot!(&out); | ||
27 | } | ||
28 | )* | ||
29 | }; | ||
30 | } | ||
31 | } | ||
32 | |||
33 | test_lint! { | ||
34 | bool_comparison, | ||
35 | empty_let_in, | ||
36 | manual_inherit, | ||
37 | manual_inherit_from, | ||
38 | legacy_let_syntax, | ||
39 | collapsible_let_in, | ||
40 | eta_reduction, | ||
41 | useless_parens, | ||
42 | unquoted_splices, | ||
43 | empty_pattern, | ||
44 | redundant_pattern_bind, | ||
45 | unquoted_uri, | ||
46 | deprecated_is_null, | ||
47 | } | ||
diff --git a/bin/tests/snapshots/main__bool_comparison.snap b/bin/tests/snapshots/main__bool_comparison.snap new file mode 100644 index 0000000..0865332 --- /dev/null +++ b/bin/tests/snapshots/main__bool_comparison.snap | |||
@@ -0,0 +1,62 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W01] Warning: Unnecessary comparison with boolean | ||
7 | ╭─[data/bool_comparison.nix:3:4] | ||
8 | │ | ||
9 | 3 │ (a == true) | ||
10 | · ────┬──── | ||
11 | · ╰────── Comparing a with boolean literal true | ||
12 | ───╯ | ||
13 | [W01] Warning: Unnecessary comparison with boolean | ||
14 | ╭─[data/bool_comparison.nix:4:4] | ||
15 | │ | ||
16 | 4 │ (b == true) | ||
17 | · ────┬──── | ||
18 | · ╰────── Comparing b with boolean literal true | ||
19 | ───╯ | ||
20 | [W01] Warning: Unnecessary comparison with boolean | ||
21 | ╭─[data/bool_comparison.nix:5:4] | ||
22 | │ | ||
23 | 5 │ (true == c) | ||
24 | · ────┬──── | ||
25 | · ╰────── Comparing c with boolean literal true | ||
26 | ───╯ | ||
27 | [W01] Warning: Unnecessary comparison with boolean | ||
28 | ╭─[data/bool_comparison.nix:6:4] | ||
29 | │ | ||
30 | 6 │ (true == d) | ||
31 | · ────┬──── | ||
32 | · ╰────── Comparing d with boolean literal true | ||
33 | ───╯ | ||
34 | [W01] Warning: Unnecessary comparison with boolean | ||
35 | ╭─[data/bool_comparison.nix:9:4] | ||
36 | │ | ||
37 | 9 │ (e != true) | ||
38 | · ────┬──── | ||
39 | · ╰────── Comparing e with boolean literal true | ||
40 | ───╯ | ||
41 | [W01] Warning: Unnecessary comparison with boolean | ||
42 | ╭─[data/bool_comparison.nix:10:4] | ||
43 | │ | ||
44 | 10 │ (f != false) | ||
45 | · ─────┬──── | ||
46 | · ╰────── Comparing f with boolean literal false | ||
47 | ────╯ | ||
48 | [W01] Warning: Unnecessary comparison with boolean | ||
49 | ╭─[data/bool_comparison.nix:11:4] | ||
50 | │ | ||
51 | 11 │ (true != g) | ||
52 | · ────┬──── | ||
53 | · ╰────── Comparing g with boolean literal true | ||
54 | ────╯ | ||
55 | [W01] Warning: Unnecessary comparison with boolean | ||
56 | ╭─[data/bool_comparison.nix:12:4] | ||
57 | │ | ||
58 | 12 │ (false != h) | ||
59 | · ─────┬──── | ||
60 | · ╰────── Comparing h with boolean literal false | ||
61 | ────╯ | ||
62 | |||
diff --git a/bin/tests/snapshots/main__collapsible_let_in.snap b/bin/tests/snapshots/main__collapsible_let_in.snap new file mode 100644 index 0000000..b135abc --- /dev/null +++ b/bin/tests/snapshots/main__collapsible_let_in.snap | |||
@@ -0,0 +1,17 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W06] Warning: These let-in expressions are collapsible | ||
7 | ╭─[data/collapsible_let_in.nix:1:1] | ||
8 | │ | ||
9 | 1 │ ╭───▶ let | ||
10 | 5 │ │ ╭─▶ let | ||
11 | 9 │ │ ├─▶ a + b + c + d | ||
12 | · │ │ │ | ||
13 | · │ ╰───────────────────── This let in expression is nested | ||
14 | · │ │ | ||
15 | · ╰───────────────────┴─── This let in expression contains a nested let in expression | ||
16 | ───╯ | ||
17 | |||
diff --git a/bin/tests/snapshots/main__deprecated_is_null.snap b/bin/tests/snapshots/main__deprecated_is_null.snap new file mode 100644 index 0000000..d49b381 --- /dev/null +++ b/bin/tests/snapshots/main__deprecated_is_null.snap | |||
@@ -0,0 +1,13 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W13] Warning: Found usage of deprecated builtin isNull | ||
7 | ╭─[data/deprecated_is_null.nix:4:4] | ||
8 | │ | ||
9 | 4 │ if isNull e | ||
10 | · ────┬─── | ||
11 | · ╰───── isNull is deprecated, check equality with null instead | ||
12 | ───╯ | ||
13 | |||
diff --git a/bin/tests/snapshots/main__empty_let_in.snap b/bin/tests/snapshots/main__empty_let_in.snap new file mode 100644 index 0000000..426692f --- /dev/null +++ b/bin/tests/snapshots/main__empty_let_in.snap | |||
@@ -0,0 +1,14 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W02] Warning: Useless let-in expression | ||
7 | ╭─[data/empty_let_in.nix:1:1] | ||
8 | │ | ||
9 | 1 │ ╭─▶ let | ||
10 | 3 │ ├─▶ null | ||
11 | · │ | ||
12 | · ╰──────────── This let-in expression has no entries | ||
13 | ───╯ | ||
14 | |||
diff --git a/bin/tests/snapshots/main__empty_pattern.snap b/bin/tests/snapshots/main__empty_pattern.snap new file mode 100644 index 0000000..3ea7ae0 --- /dev/null +++ b/bin/tests/snapshots/main__empty_pattern.snap | |||
@@ -0,0 +1,20 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W10] Warning: Found empty pattern in function argument | ||
7 | ╭─[data/empty_pattern.nix:3:4] | ||
8 | │ | ||
9 | 3 │ ({ ... }: 42) | ||
10 | · ───┬─── | ||
11 | · ╰───── This pattern is empty, use _ instead | ||
12 | ───╯ | ||
13 | [W11] Warning: Found redundant pattern bind in function argument | ||
14 | ╭─[data/empty_pattern.nix:7:4] | ||
15 | │ | ||
16 | 7 │ ({ ... } @ inputs: inputs) | ||
17 | · ────────┬─────── | ||
18 | · ╰───────── This pattern bind is redundant, use inputs instead | ||
19 | ───╯ | ||
20 | |||
diff --git a/bin/tests/snapshots/main__eta_reduction.snap b/bin/tests/snapshots/main__eta_reduction.snap new file mode 100644 index 0000000..6271980 --- /dev/null +++ b/bin/tests/snapshots/main__eta_reduction.snap | |||
@@ -0,0 +1,13 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W07] Warning: This function expression is eta reducible | ||
7 | ╭─[data/eta_reduction.nix:11:9] | ||
8 | │ | ||
9 | 11 │ (map (x: double x) xs) | ||
10 | · ─────┬───── | ||
11 | · ╰─────── Found eta-reduction: double | ||
12 | ────╯ | ||
13 | |||
diff --git a/bin/tests/snapshots/main__legacy_let_syntax.snap b/bin/tests/snapshots/main__legacy_let_syntax.snap new file mode 100644 index 0000000..35aa7ee --- /dev/null +++ b/bin/tests/snapshots/main__legacy_let_syntax.snap | |||
@@ -0,0 +1,14 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W05] Warning: Using undocumented `let` syntax | ||
7 | ╭─[data/legacy_let_syntax.nix:1:1] | ||
8 | │ | ||
9 | 1 │ ╭─▶ let { | ||
10 | 5 │ ├─▶ } | ||
11 | · │ | ||
12 | · ╰─────── Prefer rec over undocumented let syntax | ||
13 | ───╯ | ||
14 | |||
diff --git a/bin/tests/snapshots/main__manual_inherit.snap b/bin/tests/snapshots/main__manual_inherit.snap new file mode 100644 index 0000000..063867c --- /dev/null +++ b/bin/tests/snapshots/main__manual_inherit.snap | |||
@@ -0,0 +1,13 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W03] Warning: Assignment instead of inherit | ||
7 | ╭─[data/manual_inherit.nix:7:3] | ||
8 | │ | ||
9 | 7 │ a = a; | ||
10 | · ───┬── | ||
11 | · ╰──── This assignment is better written with inherit | ||
12 | ───╯ | ||
13 | |||
diff --git a/bin/tests/snapshots/main__manual_inherit_from.snap b/bin/tests/snapshots/main__manual_inherit_from.snap new file mode 100644 index 0000000..9cf1f5d --- /dev/null +++ b/bin/tests/snapshots/main__manual_inherit_from.snap | |||
@@ -0,0 +1,20 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W04] Warning: Assignment instead of inherit from | ||
7 | ╭─[data/manual_inherit_from.nix:5:3] | ||
8 | │ | ||
9 | 5 │ b = a.b; | ||
10 | · ────┬─── | ||
11 | · ╰───── This assignment is better written with inherit | ||
12 | ───╯ | ||
13 | [W04] Warning: Assignment instead of inherit from | ||
14 | ╭─[data/manual_inherit_from.nix:6:3] | ||
15 | │ | ||
16 | 6 │ c = a.c; | ||
17 | · ────┬─── | ||
18 | · ╰───── This assignment is better written with inherit | ||
19 | ───╯ | ||
20 | |||
diff --git a/bin/tests/snapshots/main__redundant_pattern_bind.snap b/bin/tests/snapshots/main__redundant_pattern_bind.snap new file mode 100644 index 0000000..2f26818 --- /dev/null +++ b/bin/tests/snapshots/main__redundant_pattern_bind.snap | |||
@@ -0,0 +1,13 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W11] Warning: Found redundant pattern bind in function argument | ||
7 | ╭─[data/redundant_pattern_bind.nix:1:1] | ||
8 | │ | ||
9 | 1 │ { ... } @ inputs: null | ||
10 | · ────────┬──────── | ||
11 | · ╰────────── This pattern bind is redundant, use inputs instead | ||
12 | ───╯ | ||
13 | |||
diff --git a/bin/tests/snapshots/main__unquoted_splices.snap b/bin/tests/snapshots/main__unquoted_splices.snap new file mode 100644 index 0000000..5fd1917 --- /dev/null +++ b/bin/tests/snapshots/main__unquoted_splices.snap | |||
@@ -0,0 +1,35 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W09] Warning: Found unquoted splice expression | ||
7 | ╭─[data/unquoted_splices.nix:7:3] | ||
8 | │ | ||
9 | 7 │ ${x} | ||
10 | · ──┬─ | ||
11 | · ╰─── Consider quoting this splice expression | ||
12 | ───╯ | ||
13 | [W09] Warning: Found unquoted splice expression | ||
14 | ╭─[data/unquoted_splices.nix:8:3] | ||
15 | │ | ||
16 | 8 │ ${toString (x + y)} | ||
17 | · ─────────┬───────── | ||
18 | · ╰─────────── Consider quoting this splice expression | ||
19 | ───╯ | ||
20 | [W09] Warning: Found unquoted splice expression | ||
21 | ╭─[data/unquoted_splices.nix:9:5] | ||
22 | │ | ||
23 | 9 │ a.${toString x} | ||
24 | · ──────┬────── | ||
25 | · ╰──────── Consider quoting this splice expression | ||
26 | ───╯ | ||
27 | [W09] Warning: Found unquoted splice expression | ||
28 | ╭─[data/unquoted_splices.nix:12:3] | ||
29 | │ | ||
30 | 12 │ ╭─▶ ${ | ||
31 | 14 │ ├─▶ } | ||
32 | · │ | ||
33 | · ╰───────── Consider quoting this splice expression | ||
34 | ────╯ | ||
35 | |||
diff --git a/bin/tests/snapshots/main__unquoted_uri.snap b/bin/tests/snapshots/main__unquoted_uri.snap new file mode 100644 index 0000000..2f0e5a9 --- /dev/null +++ b/bin/tests/snapshots/main__unquoted_uri.snap | |||
@@ -0,0 +1,13 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W12] Warning: Found unquoted URI expression | ||
7 | ╭─[data/unquoted_uri.nix:1:1] | ||
8 | │ | ||
9 | 1 │ github:nerdypepper/statix | ||
10 | · ────────────┬──────────── | ||
11 | · ╰────────────── Consider quoting this URI expression | ||
12 | ───╯ | ||
13 | |||
diff --git a/bin/tests/snapshots/main__useless_parens.snap b/bin/tests/snapshots/main__useless_parens.snap new file mode 100644 index 0000000..d44176e --- /dev/null +++ b/bin/tests/snapshots/main__useless_parens.snap | |||
@@ -0,0 +1,48 @@ | |||
1 | --- | ||
2 | source: bin/tests/main.rs | ||
3 | expression: "&out" | ||
4 | |||
5 | --- | ||
6 | [W08] Warning: These parentheses can be omitted | ||
7 | ╭─[data/useless_parens.nix:16:3] | ||
8 | │ | ||
9 | 16 │ (null) | ||
10 | · ───┬── | ||
11 | · ╰──── Useless parentheses around body of let expression | ||
12 | ────╯ | ||
13 | [W08] Warning: These parentheses can be omitted | ||
14 | ╭─[data/useless_parens.nix:4:9] | ||
15 | │ | ||
16 | 4 │ b = ("hello"); | ||
17 | · ────┬──── | ||
18 | · ╰────── Useless parentheses around value in binding | ||
19 | ───╯ | ||
20 | [W08] Warning: These parentheses can be omitted | ||
21 | ╭─[data/useless_parens.nix:5:9] | ||
22 | │ | ||
23 | 5 │ c = (d); | ||
24 | · ─┬─ | ||
25 | · ╰─── Useless parentheses around value in binding | ||
26 | ───╯ | ||
27 | [W08] Warning: These parentheses can be omitted | ||
28 | ╭─[data/useless_parens.nix:6:9] | ||
29 | │ | ||
30 | 6 │ e = ({ f = 2; }); | ||
31 | · ──────┬───── | ||
32 | · ╰─────── Useless parentheses around value in binding | ||
33 | ───╯ | ||
34 | [W08] Warning: These parentheses can be omitted | ||
35 | ╭─[data/useless_parens.nix:10:7] | ||
36 | │ | ||
37 | 10 │ g = (1 + 2); | ||
38 | · ───┬─── | ||
39 | · ╰───── Useless parentheses around value in binding | ||
40 | ────╯ | ||
41 | [W08] Warning: These parentheses can be omitted | ||
42 | ╭─[data/useless_parens.nix:11:7] | ||
43 | │ | ||
44 | 11 │ h = ({ inherit i; }); | ||
45 | · ────────┬─────── | ||
46 | · ╰───────── Useless parentheses around value in binding | ||
47 | ────╯ | ||
48 | |||
@@ -93,11 +93,12 @@ | |||
93 | "clippy" | 93 | "clippy" |
94 | "rust-src" | 94 | "rust-src" |
95 | ]; | 95 | ]; |
96 | inherit (fenix.packages."${system}") rust-analyzer; | ||
96 | in | 97 | in |
97 | with pkgs; | 98 | pkgs.mkShell { |
98 | mkShell rec { | ||
99 | nativeBuildInputs = [ | 99 | nativeBuildInputs = [ |
100 | cargo-watch | 100 | pkgs.cargo-watch |
101 | pkgs.cargo-insta | ||
101 | rust-analyzer | 102 | rust-analyzer |
102 | toolchain | 103 | toolchain |
103 | ]; | 104 | ]; |
diff --git a/lib/src/lints/useless_parens.rs b/lib/src/lints/useless_parens.rs index 45d80ae..dccc717 100644 --- a/lib/src/lints/useless_parens.rs +++ b/lib/src/lints/useless_parens.rs | |||
@@ -3,7 +3,7 @@ use crate::{Diagnostic, Metadata, Report, Rule, Suggestion}; | |||
3 | use if_chain::if_chain; | 3 | use if_chain::if_chain; |
4 | use macros::lint; | 4 | use macros::lint; |
5 | use rnix::{ | 5 | use rnix::{ |
6 | types::{KeyValue, Paren, ParsedType, TypedNode, Wrapper}, | 6 | types::{KeyValue, LetIn, Paren, ParsedType, TypedNode, Wrapper}, |
7 | NodeOrToken, SyntaxElement, SyntaxKind, | 7 | NodeOrToken, SyntaxElement, SyntaxKind, |
8 | }; | 8 | }; |
9 | 9 | ||
@@ -71,7 +71,7 @@ fn do_thing(parsed_type_node: ParsedType) -> Option<Diagnostic> { | |||
71 | if let Some(inner) = value_in_parens.inner(); | 71 | if let Some(inner) = value_in_parens.inner(); |
72 | then { | 72 | then { |
73 | let at = value_range; | 73 | let at = value_range; |
74 | let message = "Useless parentheses around value in `let` binding"; | 74 | let message = "Useless parentheses around value in binding"; |
75 | let replacement = inner; | 75 | let replacement = inner; |
76 | Some(Diagnostic::suggest(at, message, Suggestion::new(at, replacement))) | 76 | Some(Diagnostic::suggest(at, message, Suggestion::new(at, replacement))) |
77 | } else { | 77 | } else { |
@@ -98,7 +98,11 @@ fn do_thing(parsed_type_node: ParsedType) -> Option<Diagnostic> { | |||
98 | 98 | ||
99 | // ensure that we don't lint inside let-in statements | 99 | // ensure that we don't lint inside let-in statements |
100 | // we already lint such cases in previous match stmt | 100 | // we already lint such cases in previous match stmt |
101 | if KeyValue::cast(father_node).is_none(); | 101 | if KeyValue::cast(father_node.clone()).is_none(); |
102 | |||
103 | // ensure that we don't lint inside let-bodies | ||
104 | // if this primitive is a let-body, we have already linted it | ||
105 | if LetIn::cast(father_node).is_none(); | ||
102 | 106 | ||
103 | if let Some(inner_node) = paren_expr.inner(); | 107 | if let Some(inner_node) = paren_expr.inner(); |
104 | if let Some(parsed_inner) = ParsedType::cast(inner_node); | 108 | if let Some(parsed_inner) = ParsedType::cast(inner_node); |
diff --git a/vfs/src/lib.rs b/vfs/src/lib.rs index 8b5df79..cd6cc03 100644 --- a/vfs/src/lib.rs +++ b/vfs/src/lib.rs | |||
@@ -7,7 +7,7 @@ use std::{ | |||
7 | use indexmap::IndexSet; | 7 | use indexmap::IndexSet; |
8 | 8 | ||
9 | #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)] | 9 | #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)] |
10 | pub struct FileId(u32); | 10 | pub struct FileId(pub u32); |
11 | 11 | ||
12 | #[derive(Debug, Default)] | 12 | #[derive(Debug, Default)] |
13 | pub struct Interner { | 13 | pub struct Interner { |