本文中的Hook就是鉤子,鉤子就是Hookhtml
你能夠在項目生成以前和/或以後運行Python或Shell腳本。python
像這樣把它們放進Hook裏:git
cookiecutter-something/ ├── {{cookiecutter.project_slug}}/ ├── hooks │ ├── pre_gen_project.py │ └── post_gen_project.py └── cookiecutter.json
Shell腳本工做方式相似:github
cookiecutter-something/ ├── {{cookiecutter.project_slug}}/ ├── hooks │ ├── pre_gen_project.sh │ └── post_gen_project.sh └── cookiecutter.json
將Cookiecutter擴展到使用其餘類型的腳本應該不會太難。你能夠根據你係統中存在的腳本系統嘗試一下。web
爲了可移植性,你應該爲Hook使用Python腳本(擴展名爲.py),由於這些腳本能夠在任何平臺上運行。可是,若是您但願模板僅在單個平臺上運行,則shell腳本(或Windows上的.bat文件)原則上都是可行的。shell
這裏有一些關於如何編寫生成前/生成後鉤子腳本的細節。npm
以適當的狀態退出django
確保鉤子腳本以一種健壯的方式工做。若是鉤子腳本運行失敗(也就是說它以非零退出狀態結束),項目生成將中止,生成的目錄將被清除。編程
當前工做目錄json
運行鉤子腳本時,它們的工做目錄是生成的項目的根目錄。這使得後生成掛鉤可使用相對路徑輕鬆查找生成的文件。
** 模板變量在腳本中呈現**
就像你的項目模板同樣,Cookiecutter也在你的腳本中呈現Jinja模板語法。這使您能夠將Jinja模板變量合併到腳本中。例如,這行Python將module_name
設置爲cookiecutter.module_name
模板變量的值:
module_name = '{{ cookiecutter.module_name }}'
下面是一個腳本示例,它在生成項目以前驗證模板變量,將其保存到hooks/pre_gen_project.py:
中:
import re import sys MODULE_REGEX = r'^[_a-zA-Z][_a-zA-Z0-9]+$' module_name = '{{ cookiecutter.module_name }}' if not re.match(MODULE_REGEX, module_name): print('ERROR: %s 不是有效的Python模塊名稱!' % module_name) # 以狀態1退出,表示失敗 sys.exit(1)
若是你常用Cookiecutter,你會發現有一個用戶配置文件頗有用。默認狀況下,Cookiecutter嘗試從主目錄中的.cookiecutterrc文件中檢索設置。從1.3.0版本開始,您還能夠經過--config-file
在命令行上指定配置文件。
$ cookiecutter --config-file /home/tacey/my-custom-config.yaml cookiecutter-pypackage
或者你能夠設置COOKIECUTTER_CONFIG
環境變量:
export COOKIECUTTER_CONFIG=/home/tacey/my-custom-config.yaml
若是您但願堅持使用內置配置而不加載任何用戶配置文件,請使用cli選項--default-config
。阻止Cookiecutter加載用戶設置對於在隔離環境中編寫集成測試相當重要。
用戶配置示例:
default_context: full_name: "Tacey Wong" email: "xinyong.wang@qq.com" github_username: "taceywong" cookiecutters_dir: "/home/tacey/my-custom-cookiecutters-dir/" replay_dir: "/home/tacey/my-custom-replay-dir/" abbreviations: pp: https://github.com/audreyr/cookiecutter-pypackage.git gh: https://github.com/{0}.git bb: https://bitbucket.org/{0}
可用的設置是:
別名:後綴
形式的前綴。任何後綴都將使用標準的Python字符串格式插入到擴展中以代替文本{0},使用上面的別名,你能夠簡單地經過cookiecutter pp
或或cookiecutter gh:audreyr/cookiecutter-pypackage
來使用cookiecutter -pypackage模板。上面顯示的gh (github)、bb (bitbucket)和gl (gitlab)縮略語其實是內置的,不須要本身定義就可使用它們。你能夠在Python代碼中使用Cookiecutter
from cookiecutter.main import cookiecutter #根據cookiecutter-pypackage/ 模板建立項目 cookiecutter('cookiecutter-pypackage/') # 根據cookiecutter-pypackage.git repo 模板建立項目 cookiecutter('https://github.com/audreyr/cookiecutter-pypackage.git')
若是您正在編寫一個web框架,而且須要爲開發人員提供一個相似於django-admin.py startproject或npm init的工具,這將很是有用。
使用no_input
抑制要求輸入的提示。
基本示例:使用默認設置
若是與no_input
一塊兒使用,Cookiecutter將選擇一個默認值:
from cookiecutter.main import cookiecutter cookiecutter( 'cookiecutter-django', no_input=True, )
在這種狀況下,它將使用cookiecutter.json或.cookiecutterrc中定義的默認值。(來自cookiecutter.json的值將被.cookiecutterrc中的值覆蓋)
高級示例:默認+額外的上下文
若是將extra_context dict
與no_input
參數組合在一塊兒, 您可使用設置的上下文參數列表以編程方式建立項目,而無需任何命令行提示:
cookiecutter('cookiecutter-pypackage/', no_input=True, extra_context={'project_name': 'TheGreatest'})
有關這部分的更多詳細信息,請參閱API參考。
cookiecutter.json的值(但不是鍵!)也是Jinja2模板。用戶提示符中的值會當即添加到上下文中,這樣就能夠從之前的值派生出一個上下文值。經過提供更合理的默認值,這種方法能夠潛在地爲用戶節省許多鍵盤按鍵操做。
Python包顯示了其命名約定的一些模式:
這是一個帶有此模式模板值的cookiecutter.json:
{ "project_name": "My New Project", "project_slug": "{{ cookiecutter.project_name|lower|replace(' ', '-') }}", "pkg_name": "{{ cookiecutter.project_slug|replace('-', '') }}" }
若是用戶採用默認值或使用no_input
,則模板化值將爲:
或者,若是用戶提供Yet Another New Project,則值爲:
能夠在cookiecutter.json中使用_copy_without_render鍵來避免渲染cookiecutter的目錄和文件。此鍵的值接受Unix shell樣式通配符列表:
{ "project_slug": "sample", "_copy_without_render": [ "*.html", "*not_rendered_dir", "rendered_dir/not_rendered_file.ini" ] }
在調用時,Cookiecutter將json文件轉儲到〜/.cookiecutter_replay/
,這使你能夠稍後重放。
換句話說,它會保留您對模板的輸入,並在您再次運行相同模板時獲取它。
重播文件的示例(經過cookiecutter gh:hackebrot/cookiedoze
r建立):
{ "cookiecutter": { "app_class_name": "FooBarApp", "app_title": "Foo Bar", "email": "raphael@example.com", "full_name": "Raphael Pierzina", "github_username": "hackebrot", "kivy_version": "1.8.0", "project_slug": "foobar", "short_description": "A sleek slideshow app that supports swipe gestures.", "version": "0.1.0", "year": "2015" } }
要在不在命令行上提示的狀況下獲取此上下文數據,您可使用如下任一方法。
在命令行上傳遞相應選項:
cookiecutter --replay gh:hackebrot/cookiedozer
或者使用Python API:
from cookiecutter.main import cookiecutter cookiecutter('gh:hackebrot/cookiedozer', replay=True)
若是要從更新的模板建立新項目,此功能就會派上用場。
-V, --version
顯示版本並退出。
--no-input
不要提示參數,只使用cookiecutter.json文件內容
-c, --checkout
branch, tag or commit to checkout after git clone
-v, --verbose
打印調試信息
--replay
不要提示參數,只使用以前輸入的信息
-f, --overwrite-if-exists
若是輸出目錄的內容已經存在,則覆蓋它
-o, --output-dir
將生成的項目目錄輸出到哪裏,即指定建立項目的目錄。
--config-file
指定用戶配置文件
--default-config
不要加載配置文件。使用默認值
--debug-file
指定用做DEBUG日誌記錄流文件
選擇變量在建立項目時提供不一樣的選擇。 根據用戶的選擇,模板以不一樣的方式渲染內容。
選擇變量是常規鍵/值對,但值是字符串列表。
例如,若是在cookiecutter.json
中提供如下選項變量:
{ "license": ["MIT", "BSD-3", "GNU GPL v3.0", "Apache Software License 2.0"] }
運行Cookiecutter時你會獲得如下選擇:
Select license: 1 - MIT 2 - BSD-3 3 - GNU GPL v3.0 4 - Apache Software License 2.0 Choose from 1, 2, 3, 4 [1]:
根據用戶的選擇,Cookiecutter將渲染不一樣的許可證。
上面的許可選擇變量建立了cookiecutter.license
,能夠像下面這樣使用:
{%- if cookiecutter.license == "MIT" -%} # 此處可能的許可內容 {%- elif cookiecutter.license == "BSD-3" -%} # 這裏有更多可能的許可內容
Cookiecutter使用Jinja2 s if條件表達式來肯定正確的許可證。
建立的選擇變量仍然是常規的Cookiecutter變量,能夠像這樣使用:
License ------- Distributed under the terms of the `{{cookiecutter.license}}`_ license,
選擇變量可使用用戶配置文件覆蓋。
例如,可使用列表做爲值在cookiecutter.json
中建立選擇變量:
{ "license": ["MIT", "BSD-3", "GNU GPL v3.0", "Apache Software License 2.0"] }
默認狀況下,值列表中的第一個條目用做提示中的默認值。
將默認許可協議設置爲Apache Software License 2.0能夠在用戶配置文件中使用如下方法完成:
default_context: license: "Apache Software License 2.0"
提示會發生變化,以下所示:
Select license: 1 - Apache Software License 2.0 2 - MIT 3 - BSD-3 4 - GNU GPL v3.0 Choose from 1, 2, 3, 4 [1]
注意:如你所見,選項的順序從1 - MIT
更改成1 - Apache Software License 2.0
。 Cookiecutter將列表中的第一個值做爲默認值。
字典變量提供了一種在渲染模板時定義深層結構化信息的方法。
顧名思義,字典變量是鍵值對的字典。 字典值自己能夠是其餘字典和列表 - 數據結構能夠根據須要進行深刻。
例如,您能夠在cookiecutter.json
中提供如下字典變量:
{ "project_slug": "new_project", "file_types": { "png": { "name": "Portable Network Graphic", "library": "libpng", "apps": [ "GIMP" ] }, "bmp": { "name": "Bitmap", "library": "libbmp", "apps": [ "Paint", "GIMP" ] } } }
上面的file_type字典變量建立了cookiecutter.file_types,能夠像這樣使用:
{% for extension, details in cookiecutter.file_types|dictsort %} <dl> <dt>Format name:</dt> <dd>{{ details.name }}</dd> <dt>Extension:</dt> <dd>{{ extension }}</dd> <dt>Applications:</dt> <dd> <ul> {% for app in details.apps -%} <li>{{ app }}</li> {% endfor -%} </ul> </dd> </dl> {% endfor %}
Cookiecutter使用Jinja2 for表達式來迭代字典中的條目。
模板可使用自定義Jinja2擴展擴展Cookiecutter環境,能夠添加額外的過濾器,測試,全局變量甚至擴展解析器。
爲此,模板做者必須在cookiecutter.json
中指定所需的擴展名,以下所示:
{ "project_slug": "Foobar", "year": "{% now 'utc', '%Y' %}", "_extensions": ["jinja2_time.TimeExtension"] }
在調用時,Cookiecutter嘗試導入擴展並分別將它們添加到其環境中。
在上面的示例中,Cookiecutter在安裝jinja2_time.TimeExtension以後提供了附加標記now,並在cookiecutter.json
中啓用它。
請注意,Cookiecutter不會自行安裝任何依賴項! 做爲用戶,您須要確保已安裝全部擴展,而後在須要自定義Jinja2擴展的模板上運行Cookiecutter。