Skip to content

Commit

Permalink
Make versioning a macro.
Browse files Browse the repository at this point in the history
  • Loading branch information
nealkruis committed Oct 23, 2024
1 parent c5ffbc4 commit 4775c0b
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 58 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ include(build-options-interface)

# Automatic generation of version info
include(git-versioning)
process_git_version()
make_version_header()
message(STATUS "Building ${PROJECT_NAME} ${${PROJECT_NAME}_version}")

# Set up testing/coverage
if (${PROJECT_NAME}_BUILD_TESTING)
Expand Down
118 changes: 60 additions & 58 deletions cmake/git-versioning.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,85 +14,87 @@ macro(git_command args output_variable)
set(${output_variable} "${temp_variable}")
endmacro()

find_package(Git)
macro(process_git_version)

if (GIT_FOUND)
find_package(Git)

# Branch
git_command("rev-parse;--abbrev-ref;HEAD" ${PROJECT_NAME}_git_branch)
if (GIT_FOUND)

# SHA
git_command("rev-parse;--verify;--short;HEAD" ${PROJECT_NAME}_git_sha)
# Branch
git_command("rev-parse;--abbrev-ref;HEAD" ${PROJECT_NAME}_git_branch)

# Tag
git_command("tag" tag_list)
# SHA
git_command("rev-parse;--verify;--short;HEAD" ${PROJECT_NAME}_git_sha)

if (tag_list MATCHES "^$")
# Use v0.0.0 if there aren't tags yet
set(${PROJECT_NAME}_git_tag "v0.0.0")
git_command("rev-list;--count;HEAD" ${PROJECT_NAME}_git_build_number)
else ()
git_command("describe;--tags;--abbrev=0" ${PROJECT_NAME}_git_tag)
# Tag
git_command("tag" tag_list)

# Build number
git_command("rev-list;--count;HEAD;^${${PROJECT_NAME}_git_tag}" ${PROJECT_NAME}_git_build_number)
if (tag_list MATCHES "^$")
# Use v0.0.0 if there aren't tags yet
set(${PROJECT_NAME}_git_tag "v0.0.0")
git_command("rev-list;--count;HEAD" ${PROJECT_NAME}_git_build_number)
else ()
git_command("describe;--tags;--abbrev=0" ${PROJECT_NAME}_git_tag)

endif ()
# Build number
git_command("rev-list;--count;HEAD;^${${PROJECT_NAME}_git_tag}" ${PROJECT_NAME}_git_build_number)

# Status (dirty?)
git_command("diff;--shortstat" ${PROJECT_NAME}_git_status)
endif ()

if (${PROJECT_NAME}_git_status MATCHES "changed")
set(${PROJECT_NAME}_git_status "dirty")
else ()
unset(${PROJECT_NAME}_git_status)
endif ()
# Status (dirty?)
git_command("diff;--shortstat" ${PROJECT_NAME}_git_status)

# Get version components
set(semver_normal_regex "v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)")
set(semver_prerelease_regex "(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))")
set(semver_regex "^${semver_normal_regex}${semver_prerelease_regex}?$")
if (NOT ${PROJECT_NAME}_git_tag MATCHES ${semver_regex})
message(FATAL_ERROR "Tag, \"${${PROJECT_NAME}_git_tag}\", does not conform to SemVer \"${${PROJECT_NAME}_semver_regex}\".")
endif ()
if (${PROJECT_NAME}_git_status MATCHES "changed")
set(${PROJECT_NAME}_git_status "dirty")
else ()
unset(${PROJECT_NAME}_git_status)
endif ()

string(REGEX REPLACE ${semver_regex} "\\1" ${PROJECT_NAME}_version_major "${${PROJECT_NAME}_git_tag}")
string(REGEX REPLACE ${semver_regex} "\\2" ${PROJECT_NAME}_version_minor "${${PROJECT_NAME}_git_tag}")
string(REGEX REPLACE ${semver_regex} "\\3" ${PROJECT_NAME}_version_patch "${${PROJECT_NAME}_git_tag}")
if (${PROJECT_NAME}_git_tag MATCHES "^${semver_normal_regex}${semver_prerelease_regex}$")
string(REGEX REPLACE ${semver_regex} "\\4" ${PROJECT_NAME}_version_prerelease "${${PROJECT_NAME}_git_tag}")
else ()
set(${PROJECT_NAME}_version_prerelease "")
endif ()
# Get version components
set(semver_normal_regex "v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)")
set(semver_prerelease_regex "(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))")
set(semver_regex "^${semver_normal_regex}${semver_prerelease_regex}?$")
if (NOT ${PROJECT_NAME}_git_tag MATCHES ${semver_regex})
message(FATAL_ERROR "Tag, \"${${PROJECT_NAME}_git_tag}\", does not conform to SemVer \"${${PROJECT_NAME}_semver_regex}\".")
endif ()

# Build meta info
if (NOT ${PROJECT_NAME}_git_build_number MATCHES "^0$")
set(${PROJECT_NAME}_version_meta "+${${PROJECT_NAME}_git_branch}.${${PROJECT_NAME}_git_sha}.${${PROJECT_NAME}_git_build_number}")
if (DEFINED ${PROJECT_NAME}_git_status)
set(${PROJECT_NAME}_version_meta "${${PROJECT_NAME}_version_meta}.${${PROJECT_NAME}_git_status}")
string(REGEX REPLACE ${semver_regex} "\\1" ${PROJECT_NAME}_version_major "${${PROJECT_NAME}_git_tag}")
string(REGEX REPLACE ${semver_regex} "\\2" ${PROJECT_NAME}_version_minor "${${PROJECT_NAME}_git_tag}")
string(REGEX REPLACE ${semver_regex} "\\3" ${PROJECT_NAME}_version_patch "${${PROJECT_NAME}_git_tag}")
if (${PROJECT_NAME}_git_tag MATCHES "^${semver_normal_regex}${semver_prerelease_regex}$")
string(REGEX REPLACE ${semver_regex} "\\4" ${PROJECT_NAME}_version_prerelease "${${PROJECT_NAME}_git_tag}")
else ()
set(${PROJECT_NAME}_version_prerelease "")
endif ()
else ()
if (DEFINED ${PROJECT_NAME}_git_status)
set(${PROJECT_NAME}_version_meta "+${${PROJECT_NAME}_git_status}")

# Build meta info
if (NOT ${PROJECT_NAME}_git_build_number MATCHES "^0$")
set(${PROJECT_NAME}_version_meta "+${${PROJECT_NAME}_git_branch}.${${PROJECT_NAME}_git_sha}.${${PROJECT_NAME}_git_build_number}")
if (DEFINED ${PROJECT_NAME}_git_status)
set(${PROJECT_NAME}_version_meta "${${PROJECT_NAME}_version_meta}.${${PROJECT_NAME}_git_status}")
endif ()
else ()
set(${PROJECT_NAME}_version_meta "")
if (DEFINED ${PROJECT_NAME}_git_status)
set(${PROJECT_NAME}_version_meta "+${${PROJECT_NAME}_git_status}")
else ()
set(${PROJECT_NAME}_version_meta "")
endif ()
endif ()
endif ()


else ()
else ()

message(WARNING "Failed to find git executable. Unable to establish version information for ${PROJECT_NAME}.")
set(${PROJECT_NAME}_version_major "0")
set(${PROJECT_NAME}_version_minor "0")
set(${PROJECT_NAME}_version_patch "0")
set(${PROJECT_NAME}_version_meta "+git.not.found")
message(WARNING "Failed to find git executable. Unable to establish version information for ${PROJECT_NAME}.")
set(${PROJECT_NAME}_version_major "0")
set(${PROJECT_NAME}_version_minor "0")
set(${PROJECT_NAME}_version_patch "0")
set(${PROJECT_NAME}_version_meta "+git.not.found")

endif ()
endif ()

set(${PROJECT_NAME}_version "v${${PROJECT_NAME}_version_major}.${${PROJECT_NAME}_version_minor}.${${PROJECT_NAME}_version_patch}${${PROJECT_NAME}_version_prerelease}${${PROJECT_NAME}_version_meta}")
set(${PROJECT_NAME}_version "v${${PROJECT_NAME}_version_major}.${${PROJECT_NAME}_version_minor}.${${PROJECT_NAME}_version_patch}${${PROJECT_NAME}_version_prerelease}${${PROJECT_NAME}_version_meta}")

message(STATUS "Making ${PROJECT_NAME}: ${${PROJECT_NAME}_version}")
endmacro()

macro(add_version_variable version_variable)
string(TOUPPER ${version_variable} temp_upper)
Expand Down

0 comments on commit 4775c0b

Please sign in to comment.