Как я могу настроить инструмент предварительной фиксации, чтобы полагаться на одно место для всех конфигураций ловушки?
Обратите внимание, что этот вопрос касается инструмента https://pre-commit.com/, а не установки git-hooks.
Инструмент использует .pre-commit-config.yml
в корне вашего репозитория - один файл, который определяет, какие хуки следует использовать, а также закрепляет их с помощью тегов git. Закрепление полезно, так как оно позволяет избежать случайных поломок при выпуске нового крючка / линтера.
Это создает новую проблему, если у вас много репозиториев (>40) и ваши хуки активно развиваются. В репозиториях OpenStack, которые уже использовали инструмент предварительной фиксации, это создало новую нагрузку на обслуживание, существенную, особенно потому, что среднее время, затрачиваемое на CI для каждого патча, превышает 5 часов.
Настроить предварительную фиксацию для использования HEAD также нельзя, так как это слишком часто ломается. Т
В связи с этим мне интересно, есть ли другая настройка, которая позволила бы мне иметь централизованный репозиторий предварительной фиксации, который определяет его конфигурацию, и я мог бы настроить большинство проектов для ее использования.
Если это возможно, линтер ударил бы из одного места. Мы можем позаботиться о взломе некоторых репозиториев без каких-либо проблем, потому что мы можем запускать сборки в других репозиториях, если хотим, или, в качестве альтернативы, мы можем пойти на риск.
Есть еще один аспект этого: некоторым линтерам нужны собственные файлы конфигурации, например .ansible-lint
, .flake8
файлы, и было бы неплохо, если бы мы могли также хранить их в централизованном месте. Этот аспект более проблематичен, потому что будет ряд репозиториев, в которых мы будем вынуждены изменить конфигурацию по умолчанию. Это означает, что это будет работать только в том случае, если централизованная конфигурация линтера будет использоваться только при отсутствии конфигурации в репозитории.
Как я могу этого добиться?
Обратите внимание, что любое решение не должно изменять способ, которым пользователи уже выполняют линтинг (tox -e linters
который вызывает pre-commit run -a
). Требование от пользователей вручную клонировать другой репозиторий или запускать bash-скрипт, который творит какую-то магию, будет нарушением сделки, потому что это приведет к другой вещи, которую необходимо поддерживать.
Задний план
- https://github.com/pre-commit/pre-commit/issues/450 похоже, но на самом деле не предоставляет подходящего решения
1 ответ
pre-commit
намеренно разработан против централизованного управления, поскольку делает невозможным обновление централизованной конфигурации без нарушения работы большого количества репозиториев. Например, мы управляли сотнями репозиториев в режиме yelp, и когда системная команда обновит flake8, большая часть из них сломается! По сути, предварительная фиксация предназначена для повторяемости и настройки для каждого репозитория. Он предоставляет механизм, упрощающий этот путь:pre-commit autoupdate
. Вы также можете использовать инструмент распределенного рефакторинга, такой как all-repos (с прямымpre-commit
support), чтобы внести радикальные изменения в конфигурацию (и протестировать каждый отдельный репозиторий в репозитории).
Тем не менее, конструкция дает вам довольно много аварийных люков, позволяющих использовать неподдерживаемые пути, которые могут выполнить то, что вы ищете. Проблема, которую вы связали, на самом деле содержит многие из этих решений (это то место, где я пытался их накопить!), Но я повторю их здесь.
используя "предварительную фиксацию в предварительной фиксации"
в конце дня, pre-commit
это просто инструмент, который вызывает исполняемые файлы, почему этот исполняемый файл не может быть pre-commit
? (это может)
макет
$ tree -I .git -a ../testrepo/
../testrepo/
├── .pre-commit-hooks.yaml
├── orghooks.yaml
└── run-org-hooks
0 directories, 3 files
.pre-commit-hooks.yaml
- id: org-hook
name: org-wide hooks
language: script
entry: ./run-org-hooks
verbose: true
verbose: true
заставляет вывод всегда появляться независимо от того, пройдут ли что-то
./run-org-hooks
(Режим: 0755
)
#!/usr/bin/env python
import os
import sys
HERE = os.path.dirname(os.path.realpath(__file__))
def main():
cfg = os.path.join(HERE, 'orghooks.yaml')
cmd = ['pre-commit', 'run', '--config', cfg, '--files'] + sys.argv[1:]
os.execvp(cmd[0], cmd)
if __name__ == '__main__':
exit(main())
Обратите внимание, что мы используем предварительную фиксацию --config
вариант как своего рода "включить". --files
здесь важно, чтобы на высшем уровне pre-commit run --files ...
почитается.
orghooks.yaml
(практически любой старый .pre-commit-config.yaml
!)
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- repo: https://github.com/asottile/add-trailing-comma
rev: v1.5.0
hooks:
- id: add-trailing-comma
потребляющий репозиторий
.pre-commit-config.yaml
(обратите внимание, здесь я использую локальные пути и ша, потому что я хотел проверить идею, на самом деле вы бы поместили это в клонируемый репозиторий и использовали теги)
repos:
- repo: /tmp/wat/testrepo
rev: 2d76bfbfddde6129c4ec5db31ac08abfbe362114
hooks:
- id: org-hook
Бег
$ pre-commit run --all-files
org-wide hooks...........................................................Passed
hookid: org-hook
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Add trailing commas......................................................Passed
$ pre-commit run --files README.md
org-wide hooks...........................................................Passed
hookid: org-hook
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Add trailing commas..................................(no files to check)Skipped
$ SKIP=trailing-whitespace pre-commit run --files setup.py
org-wide hooks...........................................................Passed
hookid: org-hook
Trim Trailing Whitespace................................................Skipped
Fix End of Files.........................................................Passed
Add trailing commas......................................................Passed
символические ссылки
в настоящее время ничего не требует этого .pre-commit-config.yaml
это обычный файл. Вы можете сделать это символической ссылкой
Некоторые идеи о том, как символическая ссылка может этого добиться:
- условно клонированный репозиторий, примыкающий к рабочим репозиториям (
.pre-commit-config -> ../convention/pre-commit-config.yaml
) - управляемый файл управления конфигурацией (
.pre-commit-config.yaml -> /etc/pre-commit/pre-commit-config.yaml
) - подмодуль (
.pre-commit-config.yaml -> submodule/pre-commit-config.yaml
)
Не использовать pre-commit install
и используйте свой собственный сценарий оболочки для .git/hooks/pre-commit
/ так далее.
pre-commit install
это удобно, но не обязательно для работы. это ~ по сути обертка вокругpre-commit run
, вы можете легко заменить этот сценарий на сценарий оболочки, который вызывает pre-commit run --config /etc/pre-commit/pre-commit-config.yaml
.
отказ от ответственности:
- Я автор
pre-commit
- Я автор
all-repos