dprint / dprint

Pluggable and configurable code formatting platform written in Rust.

Home Page:https://dprint.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support assigning a file to a formatter based on its shebang

Silic0nS0ldier opened this issue · comments

It is common on POSIX systems for text files to be used as executables. Such files often lack a file extension which makes them difficult for formatters to pick up.

It would be nice if plugins could opt into formatting files matching certain shebang patterns.
e.g. #!/usr/bin/env bash, #!/bin/sh, #!/usr/bin/env node, #!/usr/bin/env python

Outside the scope of this feature request is;

  • Searching for files with a shebang (difficult to optimise as file reading is required).
  • Detecting executable files without a magic number (e.g. not #! nor .ELF).
    Context: POSIX mandates that such files be run with a POSIX compliant shell. (these may become more common as its used for https://justine.lol/ape.html and https://github.com/jart/cosmopolitan)

I think this is out of scope because it would be too slow to find the shebang patterns since it requires reading the files? The way to do this today would be to manually specify the file in a config using the "associations" feature: https://dprint.dev/config/#associations

@dsherret the issue is that more often than not hashbang'd files have no extension and are often uniquely named - so it's hard to keep them formatted as you need to remember to update each time you add / rename one of them.

I wonder if there's a way we can limit this to just extensionless files? I.e. Dprint always ignores file contents if the file has an extension, and if it has no extension then dprint will read the first 2 bytes, check if it is #!, ignore the file if it isn't, or read the first line if it is.

That would keep things as cheap as feasibly possible by limiting the scope and effort.

Seems reasonable if this is opt-in via a config property or cli flag. I'm wondering if it's worth it to have plugins say whether they can format a shebang. Maybe this is knowledge that should just live in the cli for simplicity as a shebang to extension mapping.

Yeah that sounds like the best option, I don't think dprint should do this by default as not every codebase is Unix or uses hashbang files, and I don't think dprint itself should have a baked-in mapping considering hashbangs can take any form - but a user-configurable option to opt-in sounds really reasonable.

The user could specify a mapping of hashbang to extension, maybe? First thought would be something like

{
  "hashbangs": {
    "#!/usr/bin/env bash": ".sh",
    "#!/usr/bin/env node": ".js"
  }
} 

Then dprint could probably essentially do path + mappedExt to resolve the file against the config and format it.

I like that. Takes the complexity out of handling different scenarios and leaves it up to the user to have full control.