1# This file is part of the Spring engine (GPL v2 or later), see LICENSE.html
2
3#
4# Spring version related CMake utilities
5# --------------------------------------
6#
7# Functions and macros defined in this file:
8# * ParseSpringVersion        - Parses a Spring version string into one var for each part of the version
9# * CreateSpringVersionString - Concatenates Spring version string parts to form a full version specifier
10# * CheckSpringReleaseVersion - Checks whether a given string is a release version
11# * GetVersionFromFile        - Retrieves the version from the VERSION file
12# * FetchSpringVersion        - Retrieves the version either from git, or from the VERSION file, in case we are not in a git repo (tarball)
13#
14
15Include(Util)
16Include(UtilGit)
17
18
19Set(D10 "[0-9]") # matches a decimal digit
20Set(D16 "[0-9a-f]") # matches a (lower-case) hexadecimal digit
21
22# Matches the engine major version part
23# Releases that do NOT preserve sync show a change here (see release branch)
24Set(VERSION_REGEX_MAJOR "${D10}+")
25Set(VERSION_REGEX_MAJOR_MATCH_EXAMPLES "\"83\", \"90\", \"999\"")
26
27
28# Matches the engine patchSet version part
29# Releases that preserve sync show a change here (see hotfix branch)
30Set(VERSION_REGEX_PATCH "${D10}+")
31Set(VERSION_REGEX_PATCH_MATCH_EXAMPLES "\"0\", \"5\", \"999\"")
32
33# Matches the engine dev version postfix (".1-<#commits>-g<SHA1> <branch>")
34Set(VERSION_REGEX_DEV_POSTFIX "[.]1-(${D10}+)-g(${D16}${D16}${D16}${D16}${D16}${D16}${D16}) ([^ ]+)")
35Set(VERSION_REGEX_DEV_POSTFIX_MATCH_EXAMPLES "\".1-13-g1234aaf develop\", \".1-1354-g1234567 release\"")
36
37
38# Matches engine release version strings
39# Match-groups (Caution: not consecutive! example input: "0.82.7.1"):
40# \\1 : Major version, for example "83"
41# \\2 : Minor version, for example "0"
42# \\3 : Commits since last release, for example "2302"
43# \\4 : First 7 digits of the current commit's SHA1, for example "6d3a71e"
44# \\5 : Git branch, for example "develop"
45Set(VERSION_REGEX_RELEASE "(${VERSION_REGEX_MAJOR})[.](${VERSION_REGEX_PATCH})")
46Set(VERSION_REGEX_RELEASE_MATCH_EXAMPLES "\"83.0\", \"84.1\"")
47Set(VERSION_REGEX_DEV "${VERSION_REGEX_RELEASE}${VERSION_REGEX_DEV_POSTFIX}")
48Set(VERSION_REGEX_DEV_MATCH_EXAMPLES "\"83.0.1-13-g1234aaf develop\", \"84.1.1-1354-g1234567 release\"")
49Set(VERSION_REGEX_ANY "${VERSION_REGEX_RELEASE}(${VERSION_REGEX_DEV_POSTFIX})?")
50Set(VERSION_REGEX_ANY_MATCH_EXAMPLES "\"83.0\", \"84.1\", \"83.0.1-13-g1234aaf develop\", \"84.1.1-1354-g1234567 release\"")
51
52
53# Parses a Spring version string into one var for each part of the version.
54# @see CreateSpringVersionString
55# sample version: "83.2.1-2302-g6d3a71e develop"
56# sample output:
57#   - ${varPrefix}_MAJOR     "83"
58#   - ${varPrefix}_PATCH_SET "2"
59#   - ${varPrefix}_COMMITS   "2302"
60#   - ${varPrefix}_HASH      "6d3a71e"
61#   - ${varPrefix}_BRANCH    "develop"
62Macro    (ParseSpringVersion varPrefix version)
63	CatchRegexGroup("${VERSION_REGEX_ANY}" 1 "${varPrefix}_MAJOR"     "${version}")
64	CatchRegexGroup("${VERSION_REGEX_ANY}" 2 "${varPrefix}_PATCH_SET" "${version}")
65	CatchRegexGroup("${VERSION_REGEX_DEV}" 3 "${varPrefix}_COMMITS"   "${version}")
66	CatchRegexGroup("${VERSION_REGEX_DEV}" 4 "${varPrefix}_HASH"      "${version}")
67	CatchRegexGroup("${VERSION_REGEX_DEV}" 5 "${varPrefix}_BRANCH"    "${version}")
68EndMacro (ParseSpringVersion)
69
70Macro    (PrintParsedSpringVersion varPrefix)
71	Message("  major:     ${${varPrefix}_MAJOR}")
72	Message("  patch-set: ${${varPrefix}_PATCH_SET}")
73	Message("  commits:   ${${varPrefix}_COMMITS}")
74	Message("  hash:      ${${varPrefix}_HASH}")
75	Message("  branch:    ${${varPrefix}_BRANCH}")
76EndMacro (PrintParsedSpringVersion)
77
78
79# Concatenates Spring version string parts to form a full version specifier.
80# @see ParseSpringVersion
81# sample input:
82#   - major    "0.82"
83#   - minor    "7"
84#   - patchSet "1"
85#   - commits  "2302"
86#   - hash     "6d3a71e"
87# sample output: "0.82.7.1-2302-g6d3a71e"
88Macro    (CreateSpringVersionString res_var major patchSet commits hash branch)
89	Set(${res_var} "${major}.${patchSet}")
90	If     (NOT "${commits}" STREQUAL "")
91		Set(${res_var} "${${res_var}}-${commits}-g${hash} ${branch}")
92	EndIf  ()
93EndMacro (CreateSpringVersionString)
94
95
96
97
98
99# Sets res_var to TRUE if version is a Spring release version specifier,
100# as oposed to a non-release/development version.
101Macro    (CheckSpringReleaseVersion res_var version)
102	Set(${res_var} FALSE)
103	If     ("${version}" MATCHES "^${VERSION_REGEX_RELEASE}$")
104		Set(${res_var} TRUE)
105	EndIf  ()
106EndMacro (CheckSpringReleaseVersion)
107
108
109
110
111# Gets the version from a text file.
112# (actually just reads the text file content into a variable)
113Macro    (GetVersionFromFile vers_var vers_file)
114	# unset the vars
115	Set(${vers_var})
116	Set(${vers_var}-NOTFOUND)
117
118	If    (EXISTS "${vers_file}")
119		File(STRINGS "${vers_file}" ${vers_var}_tmp LIMIT_COUNT 1 REGEX "^${VERSION_REGEX_ANY}$")
120		If    (NOT "${${vers_var}_tmp}" STREQUAL "")
121			Set(${vers_var} "${${vers_var}_tmp}")
122		Else  ()
123			Set(${vers_var}-NOTFOUND "1")
124		EndIf ()
125	Else  (EXISTS "${vers_file}")
126		Set(${vers_var}-NOTFOUND "1")
127	EndIf (EXISTS "${vers_file}")
128EndMacro (GetVersionFromFile)
129
130
131
132
133
134# Gets the version for a source directory, either from GIT,
135# or if that fails (for example if it is not a git repository,
136# as is the case when using a tarball), from the VERSION file.
137# Creates a FATAL_ERROR on failure.
138# Sets the following vars:
139# - ${prefix}_VERSION
140Macro    (FetchSpringVersion dir prefix)
141	# unset the vars
142	Set(${prefix}_VERSION)
143	Set(${prefix}_VERSION-NOTFOUND)
144
145	If     (EXISTS "${dir}/.git")
146		# Try to fetch version through git
147		If     (NOT GIT_FOUND)
148			Message(FATAL_ERROR "Git repository detected, but git executable not found; failed to fetch ${prefix} version.")
149		EndIf  (NOT GIT_FOUND)
150
151		# Fetch git version info
152		Git_Util_Describe(${prefix}_Describe ${dir} "*")
153		If     (NOT ${prefix}_Describe)
154			Message(FATAL_ERROR "Failed to fetch git-describe for ${prefix}.")
155		EndIf  (NOT ${prefix}_Describe)
156		If     ("${${prefix}_Describe}" MATCHES "^${VERSION_REGEX_RELEASE}$")
157			Set(${prefix}_IsRelease TRUE)
158		Else   ("${${prefix}_Describe}" MATCHES "^${VERSION_REGEX_RELEASE}$")
159			Set(${prefix}_IsRelease FALSE)
160		EndIf  ("${${prefix}_Describe}" MATCHES "^${VERSION_REGEX_RELEASE}$")
161		If     (NOT ${prefix}_IsRelease)
162			# We always want the long git-describe output on non-releases
163			# for example: 83.0.1-0-g1234567
164			Git_Util_Describe(${prefix}_Describe ${dir} "*" --long)
165		EndIf  (NOT ${prefix}_IsRelease)
166
167		Git_Util_Branch(${prefix}_Branch ${dir})
168		If     (${prefix}_IsRelease)
169			Set(${prefix}_VERSION "${${prefix}_Describe}")
170		Else   (${prefix}_IsRelease)
171			If     (NOT ${prefix}_Branch)
172				Message(FATAL_ERROR "Failed to fetch the git branch for ${prefix}.")
173			EndIf  (NOT ${prefix}_Branch)
174			Set(${prefix}_VERSION "${${prefix}_Describe} ${${prefix}_Branch}")
175		EndIf  (${prefix}_IsRelease)
176		ParseSpringVersion(${prefix} "${${prefix}_VERSION}")
177		If     ("${${prefix}_Branch}" STREQUAL "master")
178			If     (NOT "${${prefix}_COMMITS}" STREQUAL "" OR NOT "${${prefix}_HASH}" STREQUAL "")
179				Message(AUTHOR_WARNING "Commit without a version tag found on branch master for ${prefix}; this indicates a tagging/branching/push error.")
180			EndIf  (NOT "${${prefix}_COMMITS}" STREQUAL "" OR NOT "${${prefix}_HASH}" STREQUAL "")
181		EndIf  ("${${prefix}_Branch}" STREQUAL "master")
182	Else   (EXISTS "${dir}/.git")
183		# Try to fetch version through VERSION file
184		GetVersionFromFile(${prefix}_VERSION "${dir}/VERSION")
185		If    (${${prefix}_VERSION-NOTFOUND})
186			Message(FATAL_ERROR "Failed to fetch ${prefix} version.")
187		Else  (${${prefix}_VERSION-NOTFOUND})
188			Message(STATUS "${prefix} version fetched from VERSION file: ${${prefix}_VERSION}")
189		EndIf (${${prefix}_VERSION-NOTFOUND})
190	EndIf  (EXISTS "${dir}/.git")
191
192	if(DEFINED ENV{CI})
193		Message(STATUS "Build on travis-ci detected, not checking version (git clone --depth=...)")
194	else()
195		if(NOT "${${prefix}_VERSION}" MATCHES "^${VERSION_REGEX_ANY}$")
196			Message(FATAL_ERROR "Invalid version format: ${${prefix}_VERSION}")
197		endif()
198	endif()
199EndMacro (FetchSpringVersion)
200
201