ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Cookiecutter 1.6.0 版本技术解读:`_template` 上下文注入、GitLab 缩写与 Zip 模板支持

Cookiecutter 1.6.0 版本技术解读:`_template` 上下文注入、GitLab 缩写与 Zip 模板支持 Cookiecutter 1.6.0 版本技术解读_template上下文注入、GitLab 缩写与 Zip 模板支持【免费下载链接】cookiecutterA cross-platform command-line utility that creates projects from cookiecutters (project templates), e.g. Python package projects, C projects.项目地址: https://gitcode.com/gh_mirrors/co/cookiecutter导读本文基于 CHANGELOG/1.6.0.md 发布说明逐项解读 Cookiecutter 1.6.0 引入的三项新特性——在渲染上下文中注入模板路径/URL_template、新增 GitLab 模板项目 URL 缩写gl:、以及支持从 Zip 文件或 Zip URL 直接使用模板——并结合 cookiecutter/main.py、cookiecutter/repository.py、cookiecutter/zipfile.py 等源码与配套测试说明其底层实现原理、使用方法和边界条件。读完本文你将掌握如何在模板中引用_template等内置上下文变量、如何用gl:缩写快速拉取 GitLab 模板以及如何通过 Zip 模板免去 VCS 克隆流程。一、发布背景与版本定位Cookiecutter 1.6.0 是一个以“模板获取方式扩展”为核心的版本。与 1.5.1仅更新安装文档、修复 dict 变量默认值、扩充模板清单相比1.6.0 在模板来源和上下文信息两条线上同时发力模板来源从“本地目录 / Git(Hg) 仓库”扩展为“本地目录 / Git(Hg) 仓库 / Zip 文件 / Zip URL”四种形态上下文信息把模板的原始引用路径或 URL注入渲染上下文让模板本身也能感知“我是从哪里被使用的”。版本内还包含对默认缩写失效、生成失败时输出目录清理、Python 3 下git操作异常处理等问题的修复。下文按“新特性 → Bug 修复 → 其他变更”的顺序展开并在每节给出源码级依据。二、新特性一将模板路径或 URL 注入上下文_template2.1 功能描述自 1.6.0 起Cookiecutter 会把用户最初传给 Cookiecutter 的模板引用本地路径或远程 URL写入渲染上下文的cookiecutter._template键中PR #774作者 aroig。这意味着模板作者可以在 Jinja2 模板的任何位置读取到“本项目来自哪个模板”用于生成文档中的溯源信息、构建脚本中的模板依赖声明等场景。2.2 源码实现注入发生在主流程的上下文组装阶段。在 cookiecutter/main.py 中cookiecutter()函数在完成上下文生成与交互式提问之后、调用generate_files()之前统一写入四个内置上下文键# include template dir or url in the context dict context[cookiecutter][_template] template # include outputdir in the context dict context[cookiecutter][_output_dir] os.path.abspath(output_dir) # include repo dir or url in the context dict context[cookiecutter][_repo_dir] f{repo_dir} # include checkout details in the context dict context[cookiecutter][_checkout] checkout四个键的取值含义如下上下文键值说明_templatetemplate参数原值用户传入的模板引用可能为缩写、本地路径或 URL未经缩写展开_output_diros.path.abspath(output_dir)输出目录的绝对路径默认.当前目录_repo_dirrepo_dir实际解析到的模板仓库目录可能位于cookiecutters_dir缓存中_checkoutcheckout参数指定的分支/标签/提交未指定时为None从实现细节看_template保存的是用户传入的原始字符串而_repo_dir保存的是经过缩写展开、克隆/解压后实际定位到的仓库目录两者可以不同。此外 cookiecutter/main.py 还会把不以下划线开头的上下文键快照到context[_cookiecutter]供失败调试时还原“用户实际填写的值”。2.3 测试佐证该行为在 tests/test_cli.py 中有直接断言CLI 输出verbose 模式中必须包含形如下面的上下文结构context { _cookiecutter: { github_username: hackebrot, project_slug: testproject, }, cookiecutter: { github_username: hackebrot, project_slug: testproject, _template: template_path, _repo_dir: template_path, _output_dir: output_dir, _checkout: None, }, }2.4 使用示例在模板内例如{{cookiecutter.project_slug}}/README.rst可以这样引用本项目由 Cookiecutter 模板生成。 模板来源{{ cookiecutter._template }} 输出目录{{ cookiecutter._output_dir }}注意_template反映的是用户输入时的写法。如果用户用gh:user/repo缩写调用_template里保存的就是gh:user/repo本身而_repo_dir才是克隆后的完整路径。需要原始 URL 时可在模板中对_template再做处理或直接使用_repo_dir。三、新特性二GitLab 模板项目的 URL 缩写gl:3.1 功能描述1.6.0 在既有gh:GitHub与bb:Bitbucket缩写的基础上新增了gl:缩写用于快速引用 GitLab 上的模板项目PR #963。调用形式为cookiecutter gl:用户/仓库名例如cookiecutter gl:pydanny/cookiecutter-django会被展开为https://gitlab.com/pydanny/cookiecutter-django.git3.2 源码实现内置缩写定义在 cookiecutter/config.pyBUILTIN_ABBREVIATIONS { gh: https://github.com/{0}.git, gl: https://gitlab.com/{0}.git, bb: https://bitbucket.org/{0}, }展开逻辑在 cookiecutter/repository.py 的expand_abbreviations()中先尝试整串匹配缩写若不匹配则按:切分前缀若前缀命中缩写则以{0}占位符填充剩余部分def expand_abbreviations(template, abbreviations): if template in abbreviations: return abbreviations[template] prefix, _sep, rest template.partition(:) if prefix in abbreviations: return abbreviations[prefix].format(rest) return template展开后 determine_repo_dir() 会继续用is_repo_url()判定其为仓库 URL 并进入克隆流程见 cookiecutter/vcs.py 的clone()。3.3 测试佐证tests/repository/test_abbreviation_expansion.py 明确覆盖了gl:的展开( gl:pydanny/cookiecutter-django, BUILTIN_ABBREVIATIONS, https://gitlab.com/pydanny/cookiecutter-django.git, ),用户自定义缩写同样支持{0}占位符语法若占位符下标非法如{1}会抛出IndexError对应测试见同文件的test_abbreviation_expansion_prefix_not_0_in_braces()。3.4 使用注意事项缩写是前缀匹配的gl:foo展开为https://gitlab.com/foo.gitgh:foo展开为https://github.com/foo.git缩写展开后的字符串会参与is_repo_url()判定因此必须命中 REPO_REGEX支持git://、ssh://、file://、https?://、userhost等形式你可以在~/.cookiecutterrc中自定义abbreviations覆盖内置定义详见 cookiecutter/config.py 的merge_configs()自定义项与内置项做递归合并、保留已有键。四、新特性三支持从 Zip 文件或 Zip URL 使用模板4.1 功能描述1.6.0 起Cookiecutter 可以直接把.zip归档文件本地路径或 URL作为模板源使用PR #961作者 freakboy3742。这对于无法或不想安装 Git/Hg、或模板以归档形式分发的场景非常有用——无需 VCS只要有 HTTP(S) 可达的 Zip 即可# 本地 Zip 文件 cookiecutter /path/to/mytemplate.zip # 远程 Zip URL cookiecutter https://example.com/templates/mytemplate.zip4.2 源码实现判定与分派逻辑位于 cookiecutter/repository.py 与 determine_repo_dir()def is_zip_file(value: str) - bool: Return True if value is a zip file. return value.lower().endswith(.zip)在determine_repo_dir()中判定顺序为先判断 Zip再判断仓库 URL最后按本地目录处理if is_zip_file(template): unzipped_dir unzip( zip_uritemplate, is_urlis_repo_url(template), clone_to_dirclone_to_dir, no_inputno_input, passwordpassword, ) repository_candidates [unzipped_dir] cleanup True elif is_repo_url(template): ... else: ...注意这里cleanup TrueZip 模板会被解压到临时目录项目生成完成后由主流程清理cookiecutter/main.py 中的rmtree(repo_dir)。核心的下载与解压逻辑在 cookiecutter/zipfile.py 的unzip()中确保缓存目录存在make_sure_path_exists(clone_to_dir)URL 则下载缓存以 URL 最后一段路径作为缓存文件名存放在cookiecutters_dir下若文件已存在会调用prompt_and_delete()询问是否重新下载no_inputTrue时直接删除重下见 cookiecutter/prompt.py 的prompt_and_delete本地文件直接使用os.path.abspath(zip_uri)校验并解压归档不能为空、第一条记录必须是顶层目录以/结尾否则抛出InvalidZipRepository随后解压到tempfile.mkdtemp()创建的临时目录密码保护支持解压抛RuntimeError时依次尝试“显式传入的password→no_input时直接失败 → 交互式询问密码最多重试 3 次”归档损坏处理BadZipFile会被转换为带明确信息的InvalidZipRepository异常。4.3 测试佐证仓库在 tests/files/ 下准备了多种 Zip 测试样本并由 tests/zipfile/test_unzip.py 覆盖包括fake-repo-tmpl.zip正常模板归档empty.zip空归档应报InvalidZipRepositorybad-zip-file.zip损坏的 Zip应报InvalidZipRepositorynot-a-repo.zip缺少顶层目录的归档protected-fake-repo-tmpl.zip密码保护的模板归档验证密码提示与重试逻辑。Zip 模板同样支持directory参数子目录定位与checkout无关因为它不走 VCS 流程。4.4 使用注意事项Zip 判定仅凭.zip后缀大小写不敏感URL 查询串如?foobar不影响判定但请确保 URL 本身以.zip结尾归档必须包含一个顶层目录且该目录名会成为模板名用于 replay 记录与项目目录命名远程 Zip 的下载使用requests.get(..., streamTrue, timeout100)流式写入cookiecutter/zipfile.py适用于较大归档临时解压目录在生成结束后会被自动清理无需手动处理。五、Bug 修复解析5.1 用户自定义缩写导致内置缩写丢失当用户自定义abbreviations时原本会整体覆盖内置缩写导致gh:/bb:失效。1.6.0 通过merge_configs()的递归合并逻辑修复字典类型的配置项包括abbreviations会与默认值做“保留已有键”的合并cookiecutter/config.py因此自定义缩写与内置缩写可以共存issue #966、PR #967。相关回归测试见 tests/test_get_config.py自定义gl指向https://gitlab.com/hackebrot/{0}.git等场景。5.2 生成失败时保留已有输出目录此前项目生成失败会误删用户已存在的输出目录。1.6.0 引入keep_project_on_failure语义只有“本次生成新建的输出目录”才允许在失败时清理。见 cookiecutter/generate.py# if we created the output directory, then its ok to remove it # if rendering fails delete_project_on_failure output_directory_created and not keep_project_on_failureoutput_directory_created来自render_and_create_dir()的返回值标记目录是否为本次新建后续所有UndefinedError未定义变量导致目录/文件渲染失败清理动作均受该标志约束cookiecutter/generate.pyCLI 层通过--keep-project-on-failure开关暴露该行为对应 issue #629、PR #964。5.3 Python 3 下git操作失败的异常处理vcs.py 的clone()中subprocess.CalledProcessError的stderr输出被解码后分类处理输出包含not found→ 抛出RepositoryNotFound提示用户可能拼写错误输出命中BRANCH_ERRORSerror: pathspec、unknown revision→ 抛出RepositoryCloneFailed提示 checkout 的分支/标签不存在其余失败记录git clone failed with error: ...日志后原样抛出。该修复解决了 Python 3 下字节串解码与异常分类问题issue #905相关测试位于 tests/vcs/test_clone.py。六、其他变更与工程化改进1.6.0 还包含一批文档与工程质量改进详见 CHANGELOG/1.6.0.md文档修复修复Copy without Render文档的失效链接#912、pytest 文档链接#939/#940、优化copy without render与extra context文档措辞#938、#863/#864——明确提示 extra context 的键必须预先存在于模板cookiecutter.json中docstring 规范化pep257涉及 cookiecutter/cli.py、cookiecutter/config.py、cookiecutter/extensions.py、cookiecutter/utils.pyis_copy_only_path()及expand_abbreviations()等模块构建与测试重新实现 Makefile 并更新若干 make 规则#930、新增test_requirements.txt便于脱离 tox 直接测试#945、修复文档构建问题#889模板生态扩充新增 20 社区模板覆盖 C 测试kata-cpputest/kata-gtest、Android、Djangowemake-django-template、Flask、Molecule/Ansible、conda-python、RAML、Telegram Bot、dotfile 等方向可在 README.md 的模板列表中查看。七、升级与验证建议升级方式通过pip install --upgrade cookiecutter安装 1.6.0 或更高版本当前仓库还包含 2.x 系列更新见 CHANGELOG/ 目录快速验证_template对任意本地模板运行cookiecutter --verbose 模板目录观察输出上下文中的_template/_repo_dir/_output_dir/_checkout四个键对照 tests/test_cli.py 的期望结构快速验证gl:缩写执行cookiecutter gl:user/repo或直接运行python -c from cookiecutter.repository import expand_abbreviations; from cookiecutter.config import BUILTIN_ABBREVIATIONS; print(expand_abbreviations(gl:user/repo, BUILTIN_ABBREVIATIONS))观察展开结果快速验证 Zip 模板用 tests/files/fake-repo-tmpl.zip 作为模板输入确认本地 Zip 流程可用再尝试将同一文件托管到 HTTP 地址验证 URL 下载路径回归自测tests/repository/、tests/zipfile/、tests/vcs/下的测试覆盖了本节全部特性可在修改模板或扩展缩写时作为回归基线。小结Cookiecutter 1.6.0 通过_template上下文注入、gl:GitLab 缩写与 Zip 模板支持把“模板来源”和“上下文可见性”两条能力线同时向前推进了一大步模板作者可以感知自身来源用户可以绕过 Git/Hg 直接使用归档模板自定义缩写也不再破坏内置缩写。这些能力在 cookiecutter/repository.py、cookiecutter/zipfile.py、cookiecutter/main.py 与配套测试中均有完整实现与验证是理解 Cookiecutter 模板解析管线缩写展开 → 来源判定 → 获取/解压 → 上下文组装 → 渲染生成的最佳入口。【免费下载链接】cookiecutterA cross-platform command-line utility that creates projects from cookiecutters (project templates), e.g. Python package projects, C projects.项目地址: https://gitcode.com/gh_mirrors/co/cookiecutter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表