cog
cog copied to clipboard
Add support for use as pre-commit hook
Hey,
Thanks for the useful tool! Using cog
as a pre-commit
hook would increase its usefulness as you could verify that all cog
code is run before committing. The config is as simple as I have implemented here: https://github.com/nialov/cog/blob/feat-add-as-pre-commit-hook/.pre-commit-hooks.yaml.
I have configured the implemented hook locally in a project as such:
- repo: https://github.com/nialov/cog
rev: 6d73562c5cb38753bd94414a6e7612b263bc278d
hooks:
- id: cog
files: "(docs_src/index.rst)"
However, what flags to use and what to put as the default is definitely an open question. In my example I have used the checksum (-c
) and inplace conversion (-r
) flags. These probably cannot be defaults as cog
can be used in numerous different ways.
Secondly, the command line cog
should not fail when ran with no files inputted. This does not have to be the default but should be enabled by e.g., a flag (--no-fail-on-no-filenames
or something more succinct).
I would not be surprised if multiple have not already implemented this functionality in their own projects/forks. A caveat in the implementation as a pre-commit
hook is that the Python
interpreter will not have access to any other packages other than cog
and the standard library of Python
so more advanced use cases are probably out of scope of the hook implementation.
I like the idea of using cog as a pre-commit hook. I'm not sure what your first requested change is. It sounds like you have cog running just fine, so you don't need a change?
The second change (being ok with no files) makes sense. I'm not sure why I had it checking for that case explicitly.
The second change (being ok with no files) makes sense. I'm not sure why I had it checking for that case explicitly.
Sorry for the confusion, as I remember and from short testing right now the ability to not error when no files are passed is the only change I would require in the actual code.
Other than that, if you support the idea I think the .pre-commit-hooks.yaml
file could be added so that this repo could be directly used in other people's pre-commit-config.yaml
configuration. However, there is the caveat that the user will always have to explicitly setup the files
in pre-commit-config.yaml
that they want to run the cog
hook on as there is no way for pre-commit
to know which files to pass to cog
otherwise.
I can make a pull request with these minor changes if you give a thumbs up!
FYI here's a pre-commit hook I've used locally that installs cogapp
as a dependency and uses my preferred set of options (feel free to change for yourself):
click to expand
- repo: local
hooks:
- # https://github.com/nedbat/cog/issues/21#issuecomment-1919626992
id: cog
name: cog (regenerate files)
language: python
additional_dependencies:
- cogapp
entry: cog
args:
- -r # Replace the input file with the output.
- -c # Checksum the output to protect it against accidental change.
- -P # Use print() instead of cog.outl() for code output.
- -p # Prepend the generator source with PROLOGUE:
- 'import subprocess as sp, re, os, sys'
always_run: true # so that new files get picked up in generated file list below
files: |
(?x)^(
# (auto-determine which files have cog snippets)
#[[[cog
# cog_files = sp.check_output(["git", "grep", "-lF", "[[[" + "cog"], text=True).splitlines()
# print(" |\n".join(map(re.escape, cog_files)))
#]]]
\.pre\-commit\-config\.yaml
#[[[end]]] (checksum: c9a00cdff387b441693470ba709fa23d)
)$
edit 2024-04-05: After using this for a while I've found that pre-commit's "only run on changed files" filter misses times that it needs to re-run cog
. Since I always keep my cog
snippets fast I'm now using this config:
- # https://github.com/nedbat/cog/issues/21#issuecomment-1919626992
id: cog
name: cog (regenerate files)
language: python
additional_dependencies:
- cogapp
entry: bash -c 'git grep -lzF "[[[""cog" | xargs -0 cog "$@"'
args:
- -r # Replace the input file with the output.
- -c # Checksum the output to protect it against accidental change.
- -P # Use print() instead of cog.outl() for code output.
- -p # Prepend the generator source with PROLOGUE:
- 'import subprocess as sp, re, os, sys, pathlib as pl'
pass_filenames: false
always_run: true