2025, Dec 14 00:01
Как подставлять имя и email из git в cookiecutter без обёртки
Как получить динамические значения по умолчанию в cookiecutter.json без Python-обёртки: подставляем author_name и email из git config выражениями Jinja
Cookiecutter упрощает создание каркасов проектов из терминала, включая работу с удалёнными шаблонами, но возникает очевидное неудобство, когда значения по умолчанию в cookiecutter.json жёстко привязаны к конкретному автору. Хочется простого: продолжать пользоваться штатной командой cookiecutter, по‑прежнему поддерживать удалённые репозитории и подставлять разумные значения по умолчанию из локальной конфигурации git — без отдельного Python-раннера.
Постановка задачи
Представьте шаблон, где имя автора и email заданы статически. Очевидный способ сделать их динамическими — программно подставлять контекст. Но это быстро приводит к появлению входной точки на Python, что нивелирует удобство запуска cookiecutter напрямую из оболочки.
Очерк минимального варианта выглядит так:
import os as sys_os
from cookiecutter.main import cookiecutter as bake_template
bake_template(
'cookiecutter-pypackage',
extra_context={
'author_name': sys_os.popen('git config --get user.name').read().strip(),
'author_email': sys_os.popen('git config --get user.email').read().strip(),
}
)
А значения по умолчанию в шаблоне будут ссылаться на те же ключи, чтобы подставленные данные заранее заполняли подсказки:
{
"author_name": "{{ cookiecutter.author_name }}",
"author_email": "{{ cookiecutter.author_email }}"
}
Это работает, но ценой отказа от штатной команды и возможности запускать инструмент прямо по URL репозитория. Хуки в этой ситуации тоже не выручают.
Что здесь по сути
Суть проблемы в том, что cookiecutter.json вычисляется, чтобы определить значения по умолчанию для подсказок. Если там жёсткие строки, все увидят одинаковые данные об авторе. Если нужны динамические значения, остаются два пути: подмешивать их из обёртки через extra_context или научиться вычислять их в момент оценки прямо внутри шаблона — не меняя способ вызова cookiecutter.
Решение: вычислять значения по умолчанию внутри cookiecutter.json
Подход ниже переносит динамику прямо в cookiecutter.json, используя выражения Jinja, которые вычисляются во время рендеринга шаблона. Это намеренно «кустарный» proof of concept, про который сообщалось, что он работает с Python 3.13.3.
{
"full_name" : "{{ ''.__class__.__mro__[1].__subclasses__()[116].__init__.__globals__['__builtins__']['__import__']('subprocess').getoutput('git config --get user.name' ) }}",
"email" : "{{ ''.__class__.__mro__[1].__subclasses__()[116].__init__.__globals__['__builtins__']['__import__']('subprocess').getoutput('git config --get user.email') }}"
}
Эти выражения выполняются при оценке шаблона, обращаются к git config и возвращают локальные user.name и user.email. В итоге вы продолжаете использовать cookiecutter <template> или даже cookiecutter https://github.com/audreyr/cookiecutter-pypackage, а значения по умолчанию больше не привязаны к конкретному автору.
Почему это важно
Так шаблон остаётся универсальным и нейтральным — без вшитых персональных данных — и при этом сразу предлагает удобные значения по умолчанию для большинства пользователей. Сохраняется привычная работа из командной строки и поддержка URL удалённых репозиториев — зачастую именно ради этого команды и выбирают Cookiecutter.
Выводы
Если вам нужны динамические значения по умолчанию, но не хочется городить собственную точку входа на Python, вычисление их внутри cookiecutter.json — рабочий proof of concept. Он избавляет публичные шаблоны от жёстко зашитых данных автора и всё же даёт удобные дефолты, подтягивая информацию из локальной git‑конфигурации пользователя. Относитесь к этому как к прагматичному обходному решению, проверьте его в своей среде и постарайтесь сохранить опыт использования максимально близким к привычному потоку cookiecutter.