aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-04-25 12:56:38 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-04-25 12:56:38 +0200
commit0ad52283be271efaa8c8eef6844550c531f06f6f (patch)
treec9ac2ddae7a6ed39127abd5ce8241b9698244a35
parentbbb5e2cc4bf09acdc35685407e2ddd8f26c9b43f (diff)
Start specifying the version module
-rw-r--r--doc/manual.cli188
1 files changed, 188 insertions, 0 deletions
diff --git a/doc/manual.cli b/doc/manual.cli
index 0afb97f..7f27ff8 100644
--- a/doc/manual.cli
+++ b/doc/manual.cli
@@ -246,4 +246,192 @@ A directory target without an explicit target type (for example, \c{foo/}) is
treated specially. It enables all the tests at and under its directory. This
special treatment can be inhibited by specifying the target type explicitly
(for example, \c{dir{foo/\}}).
+
+
+\h1#module-version|Version Module|
+
+A project can use any version format as long as it meets the package version
+requirements. The \c{build2} toolchain also provides additional functionality
+for managing projects that conform to the \i{standard version} format. If you
+are starting a new project that uses \c{build2}, you are strongly encouraged
+to use this versioning scheme since it is based on much thought and
+experience. If you decide not to follow this advice, you are essentially on
+your own when version management is concerned.
+
+The \c{build2} standard project version conforms to \l{http://semver.org
+Semantic Versioning} and has the following form:
+
+\
+<major>.<minor>.<patch>[-<prerel>]
+\
+
+For example:
+
+\
+1.2.3
+1.2.3-a.1
+1.2.3-b.2
+\
+
+The \c{build2} package version that uses the standard project version will
+then have the following form (\i{epoch} is the versioning scheme version
+and \i{revision} is the package revision):
+
+\
+[<epoch>~]<major>.<minor>.<patch>[-<prerel>][+<revision>]
+\
+
+For example:
+
+\
+1.2.3
+1.2.3+1
+1~1.2.3-a.1+2
+\
+
+The \i{major}, \i{minor}, and \i{patch} should be numeric values between 0 and
+999 and all three cannot be zero at the same time. For initial development it
+is recommended to use 0 for \i{major}, start with version \c{0.1.0}, and change
+to \c{1.0.0} once things stabilize.
+
+In the context of C and C++ (or other compiled languages), you should
+increment \i{patch} when making binary-compatible changes, \i{minor} when
+making source-compatible changes, and \i{major} when making breaking changes.
+While the binary compatibility must be set in stone, the source compatibility
+rules can sometimes be bent. For example, you may decide to make a breaking
+change in a rarely used interface as part of a minor release. Note also that
+in the context of C++ deciding whether a change is binary-compatible is a
+non-trivial task. There are resources that list the rules but no automatic
+tooling yet. If unsure, increment \i{minor}.
+
+If present, the \i{prerel} component signifies a pre-release. Two types of
+pre-releases are supported by the standard versioning scheme: \i{final} and
+\i{snapshot} (non-pre-release versions are naturally always final). For final
+pre-releases the \i{prerel} component has the following form:
+
+\
+(a|b).<num>
+\
+
+For example:
+
+\
+1.2.3-a.1
+1.2.3-b.2
+\
+
+The letter '\c{a}' signifies an alpha release and '\c{b}' \- beta. The
+alpha/beta numbers (\i{num}) should be between 1 and 499.
+
+Note that there is no support for release candidates. Instead, it is
+recommended that you use later-stage beta releases for this purpose (and, if
+you wish, call them \"release candidates\" in announcements, etc).
+
+What version should we use during development? The common approach is to
+increment to the next version and use that until the release. This has one
+major drawback: if we publish intermediate snapshots (for example, for
+testing) they will all be indistinguishable both between each other and, even
+worse, from the final release. One way to remedy this is to increment the
+pre-release number before each publications. However, unless automated, this
+will be burdensome and error prone. Also, there is a real possibility of
+running out of version numbers if, for example, we do continuous integration
+by testing (and therefore publishing) each commit.
+
+To address this, the standard versioning scheme supports \i{snapshot
+pre-releases} with the \i{prerel} component having the following form:
+
+\
+(a|b).<num>.<snapsn>[.<snapid>]
+\
+
+For example:
+
+\
+1.2.3-a.1.1422564055.340c0a26a5efed1f
+\
+
+In essence, a snapshot pre-release is after the previous final release but
+before the next (\c{a.1} and, perhaps, \c{a.2} in the above example) and
+is uniquely identified by the snapshot sequence number (\i{snapsn}) and
+snapshot id (\i{snapid}).
+
+The \i{num} component have the same semantics as in the final pre-releases
+except that it can be 0. The \i{snapsn} component should be either the
+special value '\c{z}' or a numeric, non-zero value that increases for
+each subsequent snapshot. The \i{snapid} component, if present, should
+be an alpha-numeric value that uniquely identifies the snapshot. It is
+not required for version comparison (\i{snapsn} should be sufficient)
+and is included for reference.
+
+Where do the snapshot sn and id come from? Normally from the version control
+system. For example, for \c{git}, \i{snapsn} is the commit date (as UNIX
+timestamp) and \i{snapid} is a 16-character abbreviated commit id. As
+discussed below, the \c{build2} \c{version} module extracts all this
+data automatically.
+
+The special '\c{z}' \i{snapsn} value identifies a latest or uncommitted
+snapshot. It is chosen to be greater than any other possible \i{snapsn}
+value and its use is discussed below.
+
+As an illustration of this approach, let's examine how versions change
+during the lifetime of a project:
+
+\
+0.1.0-a.0.z # development after a.0
+0.1.0-a.1 # pre-release
+0.1.0-a.1.z # development after a.1
+0.1.0-a.2 # pre-release
+0.1.0-a.2.z # development after a.2
+0.1.0-b.1 # pre-release
+0.1.0-b.1.z # development after b.1
+0.1.0 # release
+0.1.1-b.0.z # development after b.0 (bugfix)
+0.2.0-a.0.z # development after a.0
+0.1.1 # release (bugfix)
+1.0.0 # release (jumped straight to 1.0.0)
+...
+\
+
+As shown in the above example, there is nothing wrong with \"jumping\" to a
+further version (for example, from alpha to beta, or from beta to release, or
+even from alpha to release). We cannot, however, jump backwards (for example,
+from beta back to alpha). As a result, a sensible strategy is to start with
+\c{a.0} since it can always be upgraded (but not downgrade) at a later stage.
+
+In terms of the version control system, the recommended workflow is as
+follows: The change to the final version should be the last commit in the
+(pre-)release. It is also a good idea to tag this commit with the version. A
+commit immediately after that should change the version to snapshot
+essentially \"opening\" the repository for development.
+
+The project version without the snapshot part can be represented as a 64-bit
+decimal value comparable as integers (for example, in preprocessor
+directives). The integer representation has the following form:
+
+\
+AAABBBCCCDDDE
+
+AAA - major
+BBB - minor
+CCC - patch
+DDD - alpha / beta (DDD + 500)
+E - final (0) / snapshot (1)
+\
+
+If the \i{DDD} digits are not zero, then they signify a pre-release. In this
+case one is subtracted from the \i{AAABBBCCC} value. An alpha number is stored
+as is while beta \- incremented by 500. If \i{E} is 1, then this is a snapshot
+after \i{DDD}.
+
+For example:
+
+\
+ AAABBBCCCDDDE
+0.1.0 0000010000000
+0.1.2 0000010010000
+1.2.3 0010020030000
+2.2.0-a.1 0020019990010
+3.0.0-b.2 0029999995020
+2.2.0-a.1.z 0020019990011
+\
"