我想自动生成我的版本号。在git中,我可以使用
pkgver() {
cd local_repo
printf "%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
但是,我怎么能用化石做类似的事情呢?我知道我可以使用 manifest.uuid,但它不能提供适合比较版本更新的序列号。
我想自动生成我的版本号。在git中,我可以使用
pkgver() {
cd local_repo
printf "%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
但是,我怎么能用化石做类似的事情呢?我知道我可以使用 manifest.uuid,但它不能提供适合比较版本更新的序列号。
我的建议是将虚线版本号视为营销工件。它也可以是一个代号、颜色或任何其他提供识别公开可用构建的简短方法的东西。但是,使用足够短的名称以供人们记忆是有好处的,而且这也表明了某种自然顺序,因此人们一眼就知道“kitkat”比“jellybean”更新。
让您的修订控制系统以任何一种自动化的方式提供它是一个令人头疼的秘诀。对于分布式版本控制系统,您还有一个额外的问题,即当不同的开发人员在不同的地方构建不同的版本并且可能使用不同的选项时,可能会为不同的版本分配相同的名称。您甚至不能使用构建计数,因为不同的开发人员将在不同的时间构建。
如果所有“官方”构建都来自单个系统,那么您可以在该系统上使用自动化来为每个此类构建分配唯一的名称。但是,为许多平台构建的可移植应用程序又如何呢?在这种情况下,它可能构建在许多不同的机器上?
恕我直言,唯一明智的出路是承认版本号对构建系统来说是完全任意的和人为的。
当然,作为项目管理的问题,您需要制定关于如何创建和分配版本号的策略,并仔细遵循该策略。
使用fossil
,管理此问题的一种方法是为每个公开版本创建一个分支。作为该分支上的第一个签入之一,您更改文档中显示的版本号和代码以匹配,可能包括额外的限定符,如“alpha”、“beta”或“release Candidate”。随着发布周期的推进,发现的错误可以在此分支中修复。同时,未计划发布的功能可以在他们自己的分支和/或主干上开发,而不会破坏发布过程。自然地,一旦发布,它可以并且很可能应该合并回主干,这样就不会丢失任何错误修复。
但是不要关闭该分支,它为您提供了将来维护该已发布版本的逻辑框架,使您可以轻松查看作为该版本最终发布基础的源代码。
无论是否保留了一个分支,包括足够的清单 UUID 以识别在发布本身中实际发布了哪个签入是很重要的。这可能意味着在实践中,永远不应该在具有任何待定更改的化石工作区中构建发布。
自从在我自己的项目中犯了这个错误以来,我已经在项目构建过程中添加了代码,以验证工作区是否干净,如果没有显示响亮的警告,并使构建代码显示的版本号表明构建发布也不安全。该过程还通过命令行选项(如-DUUID=[0123456789]
. 这个技巧是通过使用fossil changes
来检测脏工作区和manifest.uuid
提供 UUID 的文件来完成的。UUID 也可以从fossil info
.
我的项目的顶级 Makefile 包括以下代码:
#
# Discover fossil checkin id and public version number
#
MANIFESTUUID := $(shell sed -e "s/\(.\{10\}\).*/\1/" manifest.uuid)
VERSIONMAJ := $(shell sed -n -e "/define VERSION_MAJ/ s/^[^0-9]*\([0-9]*\)[^0-9]*$$/\1/p" src/version.h)
VERSIONMIN := $(shell sed -n -e "/define VERSION_MIN/ s/^[^0-9]*\([0-9]*\)[^0-9]*$$/\1/p" src/version.h)
VERSIONPAT := $(shell sed -n -e "/define VERSION_PAT/ s/^[^0-9]*\([0-9]*\)[^0-9]*$$/\1/p" src/version.h)
CHECKCLEAN := $(if $(shell fossil changes),-WITH-UNCOMMITTED-CHANGES)
#
# Create a filename-friendly version string like v1.123p42 where
# exacly three digits of the minor version number are displayed.
#
VERSION := v$(VERSIONMAJ).$(shell echo 000$(VERSIONMIN) | sed -n -e s/^.*\([0-9]\{3\}\).*$$/\1/p )p$(VERSIONPAT)$(CHECKCLEAN)
这取决于化石工作空间中的两个文件,以及fossil changes
构建字符串的命令输出,该字符串可用作已发布包的文件名的一部分,其中包括主要编号、次要编号、补丁级别和如果工作区不够干净,则额外的文本-WITH-UNCOMMITTED-CHANGES
。它还将 UUID 的前 10 个字符放在MANIFESTUUID
可以传递给编译的变量中。
根据政策,版本号的主要、次要和补丁部分都保存在文件src/version.h
中,并随着工作的进行不时更改。
我将忽略带有###.### 样式的版本编号,因为更普遍有用的是访问所有签入(甚至在分支之间)的唯一标识符,人们可以随心所欲地使用它。
您可以轻松获得的一个简单数字是整个项目历史中唯一签到的数量。以下命令提供此数字...
fossil info
为了演示,我克隆了fossil-scm存储库以查找签入次数...
project-name: Fossil
repository: /home/faculty/xxxx/fossil_repos/fossil-scm/../fossil-scm.fossil
local-root: /home/faculty/xxxx/fossil_repos/fossil-scm/
config-db: /home/faculty/xxxx/.fossil
project-code: CE59BB9F186226D80E49D1FA2DB29F935CCA0333
checkout: d3b2dabaa5eb64e1f73595bbe9e42d9586d5ac9e 2014-02-28 20:00:02 UTC
parent: 3d7eaeda866cc831d59abe2b1ddf15184aa14c4a 2014-02-28 19:31:38 UTC
tags: trunk
comment: re-generate other makefiles (user: jan.nijtmans)
checkins: 6713
我会以两种方式之一提取这个值。首先,如果您有带有 Perl 扩展名的 grep ("-P")...
fossil info | grep -oP 'checkins:\s*\K\d+'
不是所有的 grep 安装都支持这个(我教的大学只在大多数系统上支持这个扩展),所以你可能想用 sed 代替(下面的例子使用 GNU sed)......
fossil info | sed -n 's/checkins:[ \t]*//p'
无论哪种情况,对于上面提供的示例输出,每个命令都将提供...
6713
另外,把我的想法扔在那里,从你的 SCM 获取产品版本/内部版本号对我来说并不是一个令人愉快的想法。SCM 的角色应该是跟踪产品代码和其他工件的修订。向您的产品添加化石化或 git 化代码会将源代码与其 SCM 耦合,即使只是一点点。所以后来,当你更聪明并决定切换 SCM(它发生了,对吗?)时,你失去了另一个旧版本的编号机制......但不是因为你的代码中的编号机制不令人满意。
此外,我使用化石的一个原因是因为它允许我的团队成员使用不同的 SCM 进行远程开发,因为化石本身支持 git,并且可以毫不费力地支持其他 SCM(就像 NetBSD 使用化石/CVS 所做的那样)。在这种开发环境中,不希望代码与一个单片机结合。
无论如何...只是我的两分钱。
祝你好运。