如何在setup.py和源代码中自动设置版本号?
情况:
我有一个用Python写的库,这个库是通过git来管理的,并且是用distutils/setuptools打包的。我想要根据git的标签自动生成版本号,这样在运行setup.py sdist
等命令时,以及在库本身中都能使用这个版本号。
对于第一个任务,我可以使用git describe
或者类似的解决方案(可以参考 如何在我的包中获取setup.py(setuptools)中定义的版本?)。
比如,当我在标签'0.1'下运行' setup.py sdist'时,我会得到'mylib-0.1.tar.gz';如果我在打标签后修改了代码,我会得到'mylib-0.1-3-abcd.tar.gz'。这样是可以的。
问题是:
问题出现在我想让这个版本号在库本身中可用时,这样它就可以在User-Agent的HTTP头中显示为'mylib/0.1-3-adcd'。
如果我在setup.py version
命令中添加版本号,如在如何在我的包中获取setup.py(setuptools)中定义的版本?中所示,那么这个version.py文件是在打标签之后生成的,因为它使用标签作为值。但在这种情况下,我需要在打完版本标签后再做一次提交,以保持代码的一致性。这又需要为进一步打包创建一个新的标签。
问题是:
如何打破这个依赖循环(生成-提交-标签-生成-提交-标签-...)?
7 个回答
因为这个话题还在讨论中,有时候也会出现在搜索结果里,所以我想提到一个在2012年首次出现的解决方案,现在基本上可以用了:
https://github.com/warner/python-versioneer
这个方法和之前提到的解决方案不太一样:你需要手动添加git标签,然后这个库(还有setup.py文件)会读取这些标签,动态生成版本字符串。
版本字符串包含了最新的标签、距离那个标签的距离、当前的提交哈希值、一些“脏数据”信息,以及其他一些信息。它有几种不同的版本格式。
不过,它还是没有所谓“自定义构建”的分支名称;而且当两个分支基于同一个提交时,提交距离可能会让人困惑,所以最好只给一个选定的分支(主分支)打标签和发布。
这是一个在玩弄关键词扩展时常见的问题;)
关键是要明白,你的标签是发布管理过程的一部分,而不是开发过程(以及它的版本控制)的一部分。
换句话说,你不能在开发的代码库中包含发布管理的数据,因为这会导致你在问题中提到的循环。
在生成包的时候(也就是“发布管理部分”),你需要把这些信息写入一个文件中,这样你的库就会查找并使用这个文件(如果这个文件存在的话)来设置它的用户代理HTTP头。
你也可以反过来处理这个依赖关系:把版本号放在 mylib/__init__.py
文件里,然后在 setup.py 文件中读取这个文件来获取版本号,最后在命令行中使用 git tag $(setup.py --version) 来创建你的标签。
git tag -a v$(python setup.py --version) -m 'description of version'
还有什么更复杂的事情是我没有理解的吗?