oxalica / nil

NIx Language server, an incremental analysis assistant for writing in Nix.
Apache License 2.0
1.28k stars 39 forks source link

Discover all `.nix` files in `nil diagnostics` #127

Open 9999years opened 6 months ago

9999years commented 6 months ago

Follow-up to #125.

nil diagnostics now accepts directories in addition to files as arguments. If no arguments are given, the current directory (.) is used.

The ignore crate is used to traverse the directories and discover files. This is slightly slower than find . -path '*.nix' -exec nil diagnostics {} + because it inspects .gitignore files and performs glob matching: in my tests, this branch ran nil diagnostics in nixpkgs in 6.75 seconds, compared to 6.35 seconds for the find-based solution.

oxalica commented 3 weeks ago

I don't like to do this kind of trivial traversal ourselves, given many tools like fd already satisfies this goal. We could extend diagnostics subcommand to accept multiple paths so it would be faster with fd --exec-batch (as in #126).

If it's possible, I would prefer discover all nix files using path reference traversal which is already in the code but not enabled yet. Though it may take more time to be fully implemented.

9999years commented 1 week ago

We could extend diagnostics subcommand to accept multiple paths so it would be faster with fd --exec-batch

It would still be limited by command-line argument size limits, and it would still be a lot clumsier to use than just traversing the directories natively. There's a reason (e.g.) cargo clippy doesn't make you list every Rust file in your project.

If it's possible, I would prefer discover all nix files using path reference traversal which is already in the code but not enabled yet. Though it may take more time to be fully implemented.

I'm not confident this is feasible or desirable. Paths can be constructed programmatically, so it's not easy to get a list of imported paths with static analysis. Functions like builtins.readDir (and nixpkgs' lib.packagesFromDirectoryRecursive) further complicate matters.

It's also fairly normal for users to import paths from a directory or flake manually, even if the default expressions don't invoke them. (Nixpkgs makes use of this in several places, for example.) For that reason, I'll want to lint all of the Nix code in my repo, even if it's not explicitly imported by another file.