pre-commit / pre-commit

A framework for managing and maintaining multi-language pre-commit hooks.
https://pre-commit.com
MIT License
12.68k stars 799 forks source link

How to add support for a language? #926

Closed katrinleinweber closed 5 years ago

katrinleinweber commented 5 years ago

Hi! Please apologise the definitely honest, but probably noob-y question.

I skimmed through pre-commit.com/#contributing, CONTRIBUTING.md and https://github.com/pre-commit/pre-commit/issues/564 looking for info on adding support for a new language.

Having found languages/all.py, as well as the PRs 812 & 120, I'm left wondering what level of Python knowledge would be needed? Merely Python modules (like for data analysis), or system-level integration & experience with git-interfacing modules?

Thanks for any hints :-)

PS: Specifically, R would be of interest (see https://github.com/r-lib/styler/issues/467) because of its use in academia.

asottile commented 5 years ago

Yep! you've found the right files to get started. I'd be happy to help you through the python parts of this if you're interested in getting started! You shouldn't need to deal with git at all as the framework bits handle that. The parts for adding a "language" are just installing $your-language packages and running the executables that get installed.

There's ~roughly a couple flavors of "languages" right now -- either those which pre-commit will bootstrap an entire environment for you (node / ruby), or where pre-commit will assume some amount of system installation (python, because well, you need python to run pre-commit) or where pre-commit assumes you've installed some sort of system tooling (go / rust / docker / etc.).

Depending on how the R ecosystem works (I'm not at all familiar with it) you'd pick to either set up a full R runtime or to depend on R already being installed at the system.

For the apis you have to implement for a language here's what they would do (for instance for R):

ENVIRONMENT_DIR

a short string which will be used for the prefix of where packages will be installed. Probably r_env or something like that. (For python for instance, we use py_env and then packages are referenced from py_env/bin/...)

get_default_version

probably don't need to implement this for a first pass -- right now this is only implemented by the python language which guesses what interpreter version to try and use for hooks.

healthy

probably don't need to implement this for a first pass -- right now this is only implemented by the python language which makes sure that a virtual environment is still dll-linked properly

install_environment

this is the tricky part and where the smart bits come in. probably need to do the following things:

run_hook

This is usually the easiest to implement, most of them look the same as the python hook implementation:

https://github.com/pre-commit/pre-commit/blob/160238220f022035c8ef869c9a8642f622c02118/pre_commit/languages/node.py#L72-L74

recent PRs

Probably the best most-recent PR which added a language is this one: https://github.com/pre-commit/pre-commit/pull/751

Then the last bit is adding a few tests for that -- I can help you out with that :)

lorenzwalthert commented 5 years ago

Depending on how the R ecosystem works (I'm not at all familiar with it) you'd pick to either set up a full R runtime or to depend on R already being installed at the system.

I think we can for simplicity depend on the global installation of R.

asottile commented 5 years ago

Sounds good, is there a mechanism for local package installation in R?

lorenzwalthert commented 5 years ago

Within the R console (again), you can install.packages("styler") to satisfy all requirements needed. So in the console, when assuming R is installed, you can run

$ Rscript -e "install.packages('styler', repos='http://cran.rstudio.com')"
asottile commented 5 years ago

I've decided to clean this up and add it to the docs #1056 -- thanks for the issue it definitely helped me collect my thoughts on this :)

katrinleinweber commented 5 years ago

Awesome, thank you :-)

scottgigante-immunai commented 3 years ago

@katrinleinweber did you ever work out how to write a pre-commit hook for styler? I'm interested in doing the same but don't want to reinvent the wheel

lorenzwalthert commented 3 years ago

@scottgigante-immunai you can use the {styler} hook from https://github.com/lorenzwalthert/precommit, hopefully soon with pre-commit.ci support :D

scottgigante-immunai commented 3 years ago

Amazing! Thank you!