Cookiecutter: 更好的項目模板工具:(3)高級用法


本文中的Hook就是鈎子,鈎子就是Hook

使用生成前/生成后鈎子腳本

你可以在項目生成之前和/或之后運行Python或Shell腳本。

像這樣把它們放進Hook里:

cookiecutter-something/
├── {{cookiecutter.project_slug}}/
├── hooks
│   ├── pre_gen_project.py
│   └── post_gen_project.py
└── cookiecutter.json

Shell腳本工作方式類似:

cookiecutter-something/
├── {{cookiecutter.project_slug}}/
├── hooks
│   ├── pre_gen_project.sh
│   └── post_gen_project.sh
└── cookiecutter.json

將Cookiecutter擴展到使用其他類型的腳本應該不會太難。你可以根據你系統中存在的腳本系統嘗試一下。

為了可移植性,你應該為Hook使用Python腳本(擴展名為.py),因為這些腳本可以在任何平台上運行。但是,如果您希望模板僅在單個平台上運行,則shell腳本(或Windows上的.bat文件)原則上都是可行的。

編寫鈎子

這里有一些關於如何編寫生成前/生成后鈎子腳本的細節。

以適當的狀態退出

確保鈎子腳本以一種健壯的方式工作。如果鈎子腳本運行失敗(也就是說它以非零退出狀態結束),項目生成將停止,生成的目錄將被清除。

當前工作目錄

運行鈎子腳本時,它們的工作目錄是生成的項目的根目錄。這使得后生成掛鈎可以使用相對路徑輕松查找生成的文件。

** 模板變量在腳本中呈現**

就像你的項目模板一樣,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}

可用的設置是:

  • default_context: 每當使用Cookiecutter生成項目時,您希望作為上下文注入的鍵/值對的列表。生成任何項目時,這些值將被視為cookiecutter.json中的默認值。
  • cookiecutters_dir: 當你使用Cookiecutter和git repo參數時,你的Cookiecutter模板被克隆到的目錄。
  • replay_dir: Cookiecutter轉儲上下文數據的目錄,稍后您可以在使用replay功能時獲取該目錄。
  • abbreviations: cookiecutters的縮寫列表。縮寫可以是repo名稱的簡單別名,也可以用作別名:后綴形式的前綴。任何后綴都將使用標准的Python字符串格式插入到擴展中以代替文本{0},使用上面的別名,你可以簡單地通過cookiecutter pp或cookiecutter gh:audreyr/cookiecutter-pypackage來使用cookiecutter -pypackage模板。上面顯示的gh (github)、bb (bitbucket)和gl (gitlab)縮略語實際上是內置的,不需要自己定義就可以使用它們。

在Python代碼中調用Cookiecutter

你可以在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 dictno_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,則模板化值將為:

  • my-new-project
  • mynewproject

或者,如果用戶提供Yet Another New Project,則值為:

  • yet-another-new-project
  • yetanothernewproject

復制而不渲染

可以在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/cookiedozer創建):

{
    "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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM