Question

I want to generate my version number automatically. In git, I can use

pkgver() {
    cd local_repo
    printf "%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}

But, how could I do something similar with fossil? I know I could use manifest.uuid, but that can not provide a sequence number that is suitable to compare version updates.

Was it helpful?

Solution 2

I'm going to ignore the version numbering with the ###.### style because what will be more generally useful is to access an identifier unique across all checkins (even between branches) and folks can do with it whatever they like.

A simple number you can easily acquire is the number of unique checkins throughout the project's history. The following command provides this number...

fossil info

For the sake of demonstration, I cloned the fossil-scm repository to find the number of checkins...

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

I would extract this value one of two ways. First, if you have grep with the Perl extension ("-P")...

fossil info | grep -oP 'checkins:\s*\K\d+'

Not all grep installations will support this (the university I teach at supports this extension on only most systems), so you may want to go with sed instead (the example below uses GNU sed)...

fossil info | sed -n 's/checkins:[ \t]*//p'

In either case, for the example output provided above, each command will provide...

6713

Also, to throw my thoughts out there, it's not all that pleasing an idea to me to get product version/build numbers from your SCM. The role of the SCM should be to track revisions of the product's code and other artifacts. Adding fossil-ized or git-ized code to your product couples the source to its SCM, even if only a little. So later, when you're wiser and you decide to switch SCMs (it happens, right?), you lose your old version numbering mechanism for another... but not because the numbering mechanism in your code was unsatisfactory.

Further, one reason I use fossil is because it allows members of my teams to use different SCMs for their remote development because fossil supports git natively and can be made to support other SCMs without much difficulty (like NetBSD did with fossil/CVS). In this kind of development environment, one doesn't want the code married to one SCM.

Anyway... just my two cents.

Good luck.

OTHER TIPS

Advice

My advice would be to think of the dotted version number as a marketing artifact. It could just as well be a code name, or a color, or anything else that provides a short way to identify a publicly available build. But there are advantages to using names that are short enough for people to remember and which also indicate a some sort of natural order so people know at a glance that "kitkat" is newer than "jellybean".

Getting your revisions control system to provide it in any kind of automated way is a recipe for headaches. And with a distributed version control system, you have the additional problem that different versions could be assigned the same name when built in different places by different developers and likely with different options. You can't even use a count of builds, because different developers will build at different times.

If all "official" builds come from a single system, then you could use automation on that system to assign unique names to each such build. But what about a portable application built for many platforms, and in that case likely build on many distinct machines?

IMHO, the only sensible way out is to admit that the version number is completely arbitrary and artificial to the build system.

Of course, as a matter of project management you need to have a policy for how version numbers are created and assigned, and follow that policy carefully.

Branch for Releases

With fossil, one approach to managing this is to create a branch for each public release. As one of the first checkins on that branch, you change the version number displayed in documentation and by the code to match, possibly including an additional qualifier like "alpha", "beta", or "release candidate". As the release cycle progresses, bugs found can be fixed in this branch. Meanwhile, features not scheduled for the release can be developed on their own branches and/or on the trunk without risk of disrupting the release process. Naturally, once the release is made, it can and likely should be merged back to the trunk so that none of the bug fixes get lost.

But don't close that branch, it gives you the logical framework for future maintenance of that released version, making it easy to check out the source code that was the basis for the final release of that version.

Include the UUID in the Release

Regardless of whether or not a branch was preserved, including enough of the manifest UUID to identify the which checkin was actually released in the release itself is important. That can mean that in practice one should never build a release in a fossil workspace with any pending changes.

Since making that mistake in a project of my own, I've added code to the project build process that verifies that the workspace is clean, and if not displays loud warnings, and makes the version number displayed by the built code say that the build is not safe for release as well. The process also provides the first few digits the UUID to the compiler via a command line option like -DUUID=[0123456789]. This trick was done by using fossil changes to detect a dirty workspace, and the manifest.uuid file to provide the UUID. The UUID could also be obtained from fossil info.

Example with Gnu Make

My project's top level Makefile includes the following code:

#
# 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)

This depends on two files in the fossil workpsace, and on the output of the fossil changes command to construct a string that can be used as part of the file name of a released package that includes a major number, a minor number, a patch level, and if the workspace is not clean enough the extra text -WITH-UNCOMMITTED-CHANGES. It also puts the first 10 characters of the UUID in the variable MANIFESTUUID where it can be passed in to the compilation.

By policy, the major, minor, and patch parts of the version number are maintained in the file src/version.h, and change from time to time as work progresses.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top