跳转到主要内容

使用版本控制标签来发现版本号

项目描述

https://travis-ci.org/habnabit/vcversioner.png

vcversioner

电梯演讲:您可以为没有指定版本信息的情况编写 setup.py,而vcversioner将找到最近的、格式正确的VCS标签,并从中提取版本号。

能够使用版本控制系统的标签机制来推导版本号,比在各个地方重复相同的信息要方便得多。我最终不得不将相同的代码复制粘贴到几个不同的 setup.py 文件中,只是为了避免重复版本信息。但是,复制粘贴是愚蠢的,而且对 setup.py 文件进行单元测试是很难的。这段代码被提取成了vcversioner。

基本用法

vcversioner将自己安装为setuptools钩子,这使得它的使用非常简单

from setuptools import setup

setup(
    # [...]
    setup_requires=['vcversioner'],
    vcversioner={},
)

存在 vcversioner 参数会自动激活vcversioner并更新项目的版本。 vcversioner 参数的参数也可以是一个关键字参数的字典,该字典会被调用 find_version

为了允许在没有要求.git(或.hg等)目录的情况下分发tar包,vcversioner还会输出一个默认名为version.txt的文件。然后,如果没有VCS程序或者程序无法找到任何版本信息,vcversioner将从version.txt文件中读取版本信息。但是,这个文件需要包含在分发的tar包中,因此应该在MANIFEST.in中添加以下行。

include version.txt

如果setup.py始终在检出目录中运行,则这不是必需的,否则这对于vcversioner知道使用哪个版本是必不可少的。

可以通过指定version_file参数来更改version.txt的名称。例如

from setuptools import setup

setup(
    # [...]
    setup_requires=['vcversioner'],
    vcversioner={
        'version_file': 'custom_version.txt',
    },
)

为了与语义化版本控制兼容,vcversioner会从版本标签中移除前缀'v'。也就是说,标签v1.0将被视为1.0

可以通过使用vcversioner的strip_prefix参数指定其他前缀以被移除。例如,为了与git-dch兼容,可以将strip_prefix指定为'debian/'

非钩子用法

并不需要依赖于vcversioner;虽然pip会自动处理依赖关系,但有时拥有一个自包含的项目会更简单。vcversioner是一个单文件,很容易添加到项目中。只需将整个vcversioner.py文件复制到现有的setup.py文件旁边,并对使用进行略微更新即可。

from setuptools import setup
import vcversioner

setup(
    # [...]
    version=vcversioner.find_version().version,
)

这是必要的,因为vcversioner的distutils钩子将不可用。

版本模块

setup.py并不是版本信息复制的唯一地方。通过生成版本模块,包的__init__.py文件可以导入版本信息。例如,对于名为spam的包

from setuptools import setup

setup(
    # [...]
    setup_requires=['vcversioner'],
    vcversioner={
        'version_module_paths': ['spam/_version.py'],
    },
)

这将在spam/_version.py文件中生成一个定义__version____revision__的文件。然后,在spam/__init__.py

from spam._version import __version__, __revision__

由于这就像(并且实际上是)一个常规的Python模块,因此不需要更改MANIFEST.in

自定义VCS命令

vcversioner默认尝试检测正在使用的VCS类型,并根据检测结果选择要运行的命令。对于git,这是git --git-dir %(root)s/.git describe --tags --long。对于hg,这是hg log -R %(root)s -r . --template '{latesttag}-{latesttagdistance}-hg{node|short}'

任何命令都应该输出一个描述当前提交的字符串,格式为1.0-0-gdeadbeef。具体来说,这是<版本号>-<当前提交和标记提交之间的提交数>-<修订号>。修订号应该有VCS特定的前缀,例如git的g和hg的hg

然而,有时这还不够。如果有人只想使用标记的标签,git命令可以这样修改

from setuptools import setup

setup(
    # [...]
    setup_requires=['vcversioner'],
    vcversioner={
        'vcs_args': ['git', 'describe', '--long'],
    },
)

vcs_args参数必须始终是一个字符串列表,这些字符串不会被shell解释。这与subprocess.Popen期望的相同。

这个参数曾经被称为git_args,直到添加了对多个VCS系统的支持。

开发版本

vcversioner 还可以自动生成与未标记的提交对应的版本。遵循 PEP 386,这是通过在早期提交中标记指定的版本后添加一个 .post 后缀来完成的。例如,如果当前提交是在 1.0 标记之后的三个修订版本,计算出的版本将是 1.0.post3

可以通过将 include_dev_version 参数设置为 False 来禁用此行为。在这种情况下,上述未标记提交的版本将只是 1.0

由于 hg 需要提交来创建标记,因此存在一个 decrement_dev_version 参数,用于从最近标记之后的提交数量中减去一个。如果检测到的 VCS 是 hg(即修订版本以 'hg' 开头)并且未指定 decrement_dev_versionFalse,则自动将 decrement_dev_version 设置为 True

项目根目录

为了避免被其他源代码库污染,1.x 版本系列的 vcversioner 将只在项目根目录中查找代码库。项目根目录默认为当前工作目录,这在运行 setup.py 时通常是这种情况。可以通过指定 root 参数来更改此设置。如果有人关心能否从除了 setup.py 所在目录之外的其他目录运行 setup.py,则应从 setup.py 中的 __file__ 确定项目根目录。

from setuptools import setup
import os

setup(
    # [...]
    setup_requires=['vcversioner'],
    vcversioner={
        'root': os.path.dirname(os.path.abspath(__file__)),
    },
)

为了在 0.x 版本系列中获得相同的行为,可以将 vcs_args 设置为包含 --git-dir 标志。

from setuptools import setup

setup(
    # [...]
    setup_requires=['vcversioner'],
    vcversioner={
        vcs_args=['git', '--git-dir', '%(root)s/.git', 'describe',
                  '--tags', '--long'],
    },
)

默认情况下,version.txt 也从项目根目录读取。

替换

如上所示,rootversion_filevcs_args 都支持一些替换。

%(root)s

root 提供的值。此值对 root 参数本身不可用。

%(pwd)s

当前工作目录。

/ 将自动转换为当前平台的正确路径分隔符,例如 :\

Sphinx 文档

Sphinx 文档是版本号重复出现的另一个地方。幸运的是,由于 sphinx 配置是 Python 代码,vcversioner 也可以在那里使用。假设 vcversioner 已安装在系统范围内,这相当简单。由于 Sphinx 通常以当前工作目录作为 <你的项目 root>/docs 运行,因此需要告诉 vcversioner 项目根目录的位置。只需将您的 conf.py 更改为包含以下内容:

import vcversioner
version = release = vcversioner.find_version(root='..').version

这假设项目根目录是当前工作目录的父目录。一个稍微长一点但更健壮的版本是

import vcversioner, os
version = release = vcversioner.find_version(
    root=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))).version

这个版本更健壮,因为它不是相对于当前工作目录,而是相对于 conf.py 文件来找到项目根目录的。

如果 vcversioner 与您的项目捆绑在一起而不是依赖它被安装,则可能需要在 import vcversioner 之前将以下内容添加到您的 conf.py 中:

import sys, os
sys.path.insert(0, os.path.abspath('..'))

有时在使用 Sphinx 的 autodoc 扩展时,该行或具有相同效果的内容已经存在。

Read the Docs

Read the Docs 上构建文档时,甚至可以使用 vcversioner。如果 vcversioner 与您的项目捆绑在一起,则无需执行任何其他操作。否则,您需要告诉 Read the Docs 在构建文档之前安装 vcversioner。这意味着使用 requirements.txt 文件。

如果您的项目已经配置为使用 requirements.txt 文件安装依赖项,请将 vcversioner 添加到其中。如果没有配置,请创建一个 requirements.txt 文件。假设您的文档位于主项目目录的 docs 子目录中,创建一个包含 vcversioner 行的 docs/requirements.txt 文件。

然后,对项目配置进行以下更改:(项目配置可以在例如 https://readthedocs.org/dashboard/vcversioner/edit/ 处编辑)

  • 使用 virtualenv 下勾选复选框。

  • 如果没有之前的 requirements.txt,将 要求文件 设置为新创建的文件,例如 docs/requirements.txt

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源代码分发

vcversioner-2.16.0.0.tar.gz (9.0 kB 查看散列值)

上传时间 源代码

构建分发

vcversioner-2.16.0.0-py2-none-any.whl (13.9 kB 查看散列值)

上传时间 Python 2

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面