基于VCS的项目版本字符串管理
项目描述
Versioneer
- 像火箭飞行员一样,但用于版本管理!
- https://github.com/python-versioneer/python-versioneer
- Brian Warner
- 许可证:公共领域 (Unlicense)
- 兼容性:Python 3.7、3.8、3.9、3.10、3.11和pypy3
这是一个用于管理基于setuptools的Python项目中记录的版本号的工具。目标是消除发布流程中繁琐且容易出错的“更新嵌入式版本字符串”步骤。发布新版本应该和记录版本控制系统中的新标签一样简单,也许还需要制作新的tarball。
快速安装
Versioneer提供了两种安装模式。经典的 vendored 模式将versioneer的一个副本安装到你的仓库中。实验性的构建时依赖模式旨在允许你跳过此步骤并简化升级过程。
Vendored 模式
pip install versioneer
安装到你的$PATH中的某个位置- 有可用的conda-forge配方,因此你也可以使用
conda install -c conda-forge versioneer
- 有可用的conda-forge配方,因此你也可以使用
- 将
[tool.versioneer]
部分添加到你的pyproject.toml
中,或将[versioneer]
部分添加到你的setup.cfg
中(参见安装)- 注意,如果你使用
pyproject.toml
,你需要将tomli; python_version < "3.11"
添加到你的构建时依赖中
- 注意,如果你使用
- 在你的源树中运行
versioneer install --vendor
,提交结果 - 使用
python setup.py version
验证版本信息
构建时依赖模式
pip install versioneer
安装到你的$PATH中的某个位置- 有可用的conda-forge配方,因此你也可以使用
conda install -c conda-forge versioneer
- 有可用的conda-forge配方,因此你也可以使用
- 将
[tool.versioneer]
部分添加到你的pyproject.toml
中,或将[versioneer]
部分添加到你的setup.cfg
中(参见安装) - 将
versioneer
(如果配置在pyproject.toml
中,则带有[toml]
额外部分)添加到pyproject.toml
中build-system
表的requires
键中[build-system] requires = ["setuptools", "versioneer[toml]"] build-backend = "setuptools.build_meta"
- 在你的源树中运行
versioneer install --no-vendor
,提交结果 - 使用
python setup.py version
验证版本信息
版本标识符
源树来自各种地方
- 版本控制系统的检出(主要用于开发者)
- 由构建自动化产生的夜间tarball
- 由基于Web的VCS浏览器(如github的“标签tarball”功能)产生的快照tarball
- 由“setup.py sdist”产生的发布tarball,通过PyPI分发
在每个源树内部,版本标识符(可以是字符串或数字,此工具不关心格式)可以来自各种地方
- 询问VCS工具本身,例如“git describe”(用于检出),该工具了解最近的“标签”和绝对修订号
- 解包tarball的目录名称
- 展开的VCS关键字($Id$等)
- 由某些早期构建步骤创建的
_version.py
对于已发布的软件,版本标识符与VCS标签密切相关。有些项目使用包含不仅仅是版本字符串的标签名称(例如,“myproject-1.2”而不是只是“1.2”),在这种情况下,工具需要删除标签前缀以提取版本标识符。对于未发布的软件(在标签之间),版本标识符应提供足够的信息以帮助开发者重建相同的树,同时让他们了解树的大致年龄(在版本1.2之后,在版本1.3之前)。许多VCS系统可以报告描述这一点的信息,例如,git describe --tags --dirty --always
报告类似于“0.7-1-g574ab98-dirty”的信息,表示检出是0.7标签之后的一个修订,有一个唯一的修订号“574ab98”,并且是“dirty”(它有未提交的更改)。
版本标识符用于多个目的
- 允许模块自我标识其版本:
myproject.__version__
- 为“setup.py sdist” tarball选择名称和前缀
工作原理
Versioneer通过在源树中添加一个特殊的_version.py
文件来工作,其中你的__init__.py
可以导入它。这个_version.py
知道如何在导入时动态地从VCS工具获取版本信息。
_version.py
还包含$Revision$
标记,安装过程将_version.py
标记为在git archive
命令期间用标签名称重写此标记。因此,生成的tarballs将包含足够的信息来获取正确的版本。
为了允许setup.py
也计算版本,我们在源树的最顶层添加了versioneer.py
,它紧挨着setup.py
和配置它的setup.cfg
。这覆盖了几个distutils/setuptools命令,在调用时计算版本,并将setup.py build
和setup.py sdist
改为用包含生成版本数据的小静态文件替换_version.py
。
安装
有关详细安装说明,请参阅INSTALL.md。
版本字符串类型
使用Versioneer的代码可以通过从主__init__.py
文件导入_version
并在其中运行get_versions()
函数来在运行时了解其版本字符串。从“外部”(例如在setup.py
中),您可以导入顶级versioneer.py
并运行get_versions()
。
这两个函数都返回一个包含不同版本信息类型的字典
-
['version']
:使用所选样式渲染的简短版本字符串。这是项目版本字符串最常用的值。默认的“pep440”样式产生如0.11
、0.11+2.g1076c97
或0.11+2.g1076c97.dirty
之类的字符串。有关替代样式的信息,请参阅下方的“样式”部分。 -
['full-revisionid']
:详细的修订标识符。对于Git,这是完整的SHA1提交ID,例如“1076c978a8d3cfc70f408fe5974aa6c092c949ac”。 -
['date']
:最新HEAD
提交的日期和时间。对于Git,它是ISO 8601格式的提交日期。如果没有日期,这将是None。 -
['dirty']
:布尔值,如果树中有未提交的更改,则为True。请注意,只有在这些更改是在VCS签出中运行的时,这个值才是准确的,否则它可能是False或None。 -
['error']
:如果无法计算版本字符串,这将设置为描述问题的字符串,否则将为None。如果在setup.py中设置此值,可能会抛出异常,以避免例如创建版本字符串为“未知”的tarball。
某些变体比其他变体更有用。在错误报告中包括full-revisionid
应允许开发者重建正在测试的确切代码(或指示应该与开发者共享的本地更改)。version
适用于在“关于”框或CLI --version
输出中显示:它可以轻松地与发布说明和各个版本中修复的错误列表进行比较。
安装程序会将以下文本添加到您的__init__.py
中,以便在YOURPROJECT.__version__
中放置一个基本版本
from ._version import get_versions
__version__ = get_versions()['version']
del get_versions
样式
setup.cfg中的style=
配置控制如何将VCS信息渲染到版本字符串中。
默认样式“pep440”产生一个PEP440兼容的字符串,等于实际发布的不带前缀的标签名称,并包含一个附加的“本地版本”部分,其中包含更多中间构建的详细信息。对于Git,这是TAG[+DISTANCE.gHEX[.dirty]],使用git describe --tags --dirty --always
的信息。例如,“0.11+2.g1076c97.dirty”表示树类似于“1076c97”提交,但具有未提交的更改(“.dirty”),并且此提交比“0.11”标签两个修订版。对于已发布的软件(与已知标签完全相等),标识符将仅包含清除的标签,例如“0.11”。
其他样式可用。有关描述,请参阅Versioneer源树中的details.md。
调试
Versioneer试图避免致命错误:如果出现问题,它往往会返回版本为“0+unknown”。要调查问题,请运行setup.py version
,这将以详细模式运行版本查找代码,并显示get_versions()
的完整内容(包括可能有助于识别错误的error
字符串)。
已知限制
一些已知情况会导致Versioneer版本控制出现问题。以下列出了其中最重要的几个。更多详情可以在Github 问题页面找到。
子项目
Versioneer对那些setup.py
不在根目录的源树(例如,setup.py
和.git/
不是兄弟)支持有限。以下有两种常见原因导致setup.py
不在根目录:
- 包含多个子项目的源树,例如Buildbot,其中包含“master”和“slave”子项目,每个子项目都有自己的
setup.py
、setup.cfg
和tox.ini
。这类项目会生成多个PyPI发行版(并上传多个独立安装的tar包)。 - 以包含C库为主要目的,但也在子目录中提供Python(以及其他语言)绑定的源树。
Versioneer会在父目录中查找.git
,并且大多数操作应该得到正确的版本字符串。然而,pip
和setuptools
存在bug和实现细节,这通常会导致从子项目目录执行pip install .
时无法找到正确的版本字符串(所以它通常默认为0+unknown
)。
pip install --editable .
应该能正常工作。有时setup.py install
也可能工作。
已知Pip-8.1.1存在此问题,但希望它会在后续版本中得到修复。
问题#38正在跟踪此问题。在PR#61的讨论中,从Versioneer的角度更详细地描述了该问题。pip PR#3176和pip PR#3615包含了改进pip以使Versioneer正确工作的代码。
Versioneer-0.16及更早版本只会在setup.cfg
旁边查找.git
目录,所以这些版本中完全不支持子项目。
setuptools <= 18.5的编辑安装
setup.py develop
和pip install --editable .
允许您将项目安装到一个虚拟环境中一次,然后继续编辑源代码(和测试),而无需在每次更改后重新安装。
“入口脚本”(setup(entry_points={"console_scripts": ..})
)是指定应与Python包一起安装的可执行脚本的一种方便方式。
这两种方式在使用现代setuptools时按预期工作。然而,在使用setuptools-18.5或更早版本时,某些操作在运行入口脚本时会导致pkg_resources.DistributionNotFound
错误,这需要通过重新安装包来解决问题。这发生在安装使用一个版本进行,然后在检出不同版本时重新生成egg_info数据。许多setup.py命令会导致egg_info重建(包括sdist
、wheel
和安装到不同的虚拟环境中),所以这可能会令人惊讶。
问题#83描述了这个问题,但升级到较新的setuptools版本可能解决它。
更新Versioneer
要将您的项目升级到Versioneer的新版本,请执行以下操作:
- 安装新的Versioneer(
pip install -U versioneer
或等效命令) - 如有必要,编辑
setup.cfg
和pyproject.toml
,以包括发布说明中指示的任何新配置设置。有关详细信息,请参阅UPGRADING。 - 在您的源树中重新运行
versioneer install --[no-]vendor
,以替换SRC/_version.py
- 提交所有更改的文件
未来方向
该工具旨在使其易于扩展到其他版本控制系统:所有特定于版本控制系统的组件都位于单独的目录中,如src/git/。顶层的versioneer.py
脚本通过运行make-versioneer.py来组装这些组件。在未来,make-versioneer.py将接受VCS名称作为参数,并构建一个针对特定VCS的versioneer.py
版本。它也可能接受在安装期间通过编辑setup.py手动提供的配置参数。或者,它也可能朝相反的方向发展,包括所有受支持的VCS系统的代码,减少中间脚本的数目。
类似的项目
- setuptools_scm - 一个非捆绑的构建时依赖项
- minver - versioneer的轻量级实现
- versioningit - 一个基于PEP 518的setuptools插件
许可证
为了使Versioneer更容易嵌入,其所有代码都归入公共领域。它创建的_version.py
也位于公共领域。具体来说,两者都根据https://unlicense.org/中描述的“Unlicense”发布。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源代码分发
构建分发
versioneer-0.29.tar.gz的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 5ab283b9857211d61b53318b7c792cf68e798e765ee17c27ade9f6c924235731 |
|
MD5 | 1703d6ced3656553066fa71e42c5eee6 |
|
BLAKE2b-256 | 32d7854e45d2b03e1a8ee2aa6429dd396d002ce71e5d88b77551b2fb249cb382 |
versioneer-0.29-py3-none-any.whl的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 0f1a137bb5d6811e96a79bb0486798aeae9b9c6efc24b389659cebb0ee396cb9 |
|
MD5 | e729747a44741abd03952a5df81035e0 |
|
BLAKE2b-256 | b079f0f1ca286b78f6f33c521a36b5cbd5bd697c0d66217d8856f443aeb9dd77 |