diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index f8d99e69..41975345 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -236,7 +236,7 @@ upstream - git@github.com:Cockatrice/Cockatrice.git $COCKATRICE_REPO - /Location/of/repository/cockatrice.git $TAG_NAME - If full release, YYYY-MM-DD-Release-MAJ.MIN.PATCH - - If dev snapshot, cockatrice-MAJ.MIN.PATCH-beta### + - If dev snapshot, YYYY-MM-DD-Development-MAJ.MIN.PATCH-betaXYZ - MAJ.MIN.PATCH will be the NEXT release version ``` diff --git a/CMakeLists.txt b/CMakeLists.txt index a4289c97..293a2301 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,10 @@ if(POLICY CMP0064) endif() set(PROJECT_NAME "Cockatrice") +# Can be overriden by git tags, see cmake/getversion.cmake +set(PROJECT_VERSION_MAJOR "2") +set(PROJECT_VERSION_MINOR "3") +set(PROJECT_VERSION_PATCH "17") # Default to "Release" build type # User-provided value for CMAKE_BUILD_TYPE must be checked before the PROJECT() call @@ -162,6 +166,7 @@ set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING") set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}") set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") +set(CPACK_PACKAGE_FILE_NAME "${PROJECT_VERSION_FILENAME}") if(UNIX) if(APPLE) @@ -170,7 +175,6 @@ if(UNIX) set(CPACK_DMG_FORMAT "UDBZ") set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}") set(CPACK_SYSTEM_NAME "OSX") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice/resources/appicon.icns") else() # linux @@ -186,11 +190,9 @@ if(UNIX) set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://github.com/Cockatrice/Cockatrice") set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5multimedia5-plugins, libqt5svg5") ENDIF() - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") endif() elseif(WIN32) set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR}) - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") # Configure file with custom definitions for NSIS. configure_file( diff --git a/cmake/NSIS.template.in b/cmake/NSIS.template.in index 10dc9b75..5fdb3aab 100644 --- a/cmake/NSIS.template.in +++ b/cmake/NSIS.template.in @@ -3,7 +3,7 @@ !include "FileFunc.nsh" Name "@CPACK_PACKAGE_NAME@" -BrandingText "@CPACK_PACKAGE_NAME@-@CPACK_PACKAGE_VERSION_MAJOR@" +BrandingText "@CPACK_PACKAGE_FILE_NAME@" OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" SetCompressor /SOLID lzma InstallDir "$PROGRAMFILES\Cockatrice" diff --git a/cmake/getversion.cmake b/cmake/getversion.cmake index ddf2fec5..2631bd2d 100644 --- a/cmake/getversion.cmake +++ b/cmake/getversion.cmake @@ -1,40 +1,215 @@ -find_package(Git) -if(GIT_FOUND) +# HELPER FUNCTIONS + +function(get_commit_id) + # get last commit hash execute_process( COMMAND ${GIT_EXECUTABLE} log -1 --abbrev=7 --date=short "--pretty=%h" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COM_ID ) - if( NOT ${res_var} EQUAL 0 ) - set( GIT_COMMIT_ID "unknown") - message( WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info." ) + if(NOT ${res_var} EQUAL 0) + message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.") + return() endif() - string( REPLACE "\n" "" GIT_COMMIT_ID "${GIT_COM_ID}" ) + string(REPLACE "\n" "" GIT_COM_ID "${GIT_COM_ID}") + set(GIT_COMMIT_ID "${GIT_COM_ID}" PARENT_SCOPE) + set(PROJECT_VERSION_LABEL "custom_${GIT_COM_ID}" PARENT_SCOPE) +endfunction() + +function(get_commit_date) + # get last commit date execute_process( COMMAND ${GIT_EXECUTABLE} log -1 --date=short "--pretty=%cd" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COM_DATE ) - if( NOT ${res_var} EQUAL 0 ) - set( GIT_COMMIT_DATE "unknown") - set( GIT_COMMIT_DATE_FRIENDLY "unknown") - message( WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info." ) + if(NOT ${res_var} EQUAL 0) + message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.") + return() endif() - string( REPLACE "\n" "" GIT_COMMIT_DATE_FRIENDLY "${GIT_COM_DATE}" ) - string( REPLACE "-" "" GIT_COMMIT_DATE "${GIT_COMMIT_DATE_FRIENDLY}" ) + + string(REPLACE "\n" "" GIT_COM_DATE "${GIT_COM_DATE}") + set(GIT_COMMIT_DATE_FRIENDLY "${GIT_COM_DATE}" PARENT_SCOPE) + + string(REPLACE "-" "" GIT_COM_DATE "${GIT_COM_DATE}") + set(GIT_COMMIT_DATE "${GIT_COM_DATE}" PARENT_SCOPE) +endfunction() + +function(clean_release_name name) + # "name": "Cockatrice: Thopter Pie Network, Revision 2" + + # Remove all double quotes + STRING(REPLACE "\"" "" name "${name}") + # Remove json prefix "name: " + STRING(REPLACE " name: " "" name "${name}") + # Remove "cockatrice" name + STRING(REPLACE "Cockatrice" "" name "${name}") + # Remove all unwanted chars + STRING(REGEX REPLACE "[^A-Za-z0-9_ ]" "" name "${name}") + # Strip (trim) whitespaces + STRING(STRIP "${name}" name) + # Replace all spaces with underscores + STRING(REPLACE " " "_" name "${name}") + + set(GIT_TAG_RELEASENAME "${name}" PARENT_SCOPE) +endfunction() + +function(get_tag_name commit) + if(${commit} STREQUAL "unknown") + return() + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --exact-match --tags ${commit} + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + RESULT_VARIABLE res_var + OUTPUT_VARIABLE GIT_TAG + ERROR_VARIABLE GIT_TAG_ERR + ) + + if((NOT ${res_var} EQUAL 0) OR (${GIT_TAG_ERR} MATCHES "fatal: no tag exactly matches.*")) + message(STATUS "Commit is not a release or prerelease (no git tag found)") + return() + endif() + + string(REPLACE "\n" "" GIT_TAG "${GIT_TAG}") + message(STATUS "Commit is a release or prerelease, git tag: ${GIT_TAG}") + + # Extract information from tag: + # YYYY-MM-DD-Release-MAJ.MIN.PATCH + # YYYY-MM-DD-Development-MAJ.MIN.PATCH-betaXYZ + string(REPLACE "-" ";" GIT_TAG_EXPLODED "${GIT_TAG}") + string(REPLACE "." ";" GIT_TAG_EXPLODED "${GIT_TAG_EXPLODED}") + + # Sanity checks: length + list(LENGTH GIT_TAG_EXPLODED GIT_TAG_LISTCOUNT) + if(${GIT_TAG_LISTCOUNT} LESS 7 OR ${GIT_TAG_LISTCOUNT} GREATER 8) + message(WARNING "Invalid tag format, got ${GIT_TAG_LISTCOUNT} tokens") + return() + endif() + + # Year + list(GET GIT_TAG_EXPLODED 0 GIT_TAG_YEAR) + if(${GIT_TAG_YEAR} LESS 2017 OR ${GIT_TAG_LISTCOUNT} GREATER 2100) + message(WARNING "Invalid tag year ${GIT_TAG_YEAR}") + return() + endif() + + # Month + list(GET GIT_TAG_EXPLODED 1 GIT_TAG_MONTH) + if(${GIT_TAG_MONTH} LESS 1 OR ${GIT_TAG_MONTH} GREATER 12) + message(WARNING "Invalid tag month ${GIT_TAG_MONTH}") + return() + endif() + + # Day + list(GET GIT_TAG_EXPLODED 2 GIT_TAG_DAY) + if(${GIT_TAG_DAY} LESS 1 OR ${GIT_TAG_DAY} GREATER 31) + message(WARNING "Invalid tag day ${GIT_TAG_DAY}") + return() + endif() + + # Type + list(GET GIT_TAG_EXPLODED 3 GIT_TAG_TYPE) + if(NOT(${GIT_TAG_TYPE} STREQUAL "Release" OR ${GIT_TAG_TYPE} STREQUAL "Development")) + message(WARNING "Invalid tag type ${GIT_TAG_TYPE}") + return() + endif() + + # Major + list(GET GIT_TAG_EXPLODED 4 GIT_TAG_MAJOR) + if(${GIT_TAG_MAJOR} LESS 0 OR ${GIT_TAG_MAJOR} GREATER 99) + message(WARNING "Invalid tag major version ${GIT_TAG_MAJOR}") + return() + endif() + + # Minor + list(GET GIT_TAG_EXPLODED 5 GIT_TAG_MINOR) + if(${GIT_TAG_MINOR} LESS 0 OR ${GIT_TAG_MINOR} GREATER 99) + message(WARNING "Invalid tag minor version ${GIT_TAG_MINOR}") + return() + endif() + + # Patch + list(GET GIT_TAG_EXPLODED 6 GIT_TAG_PATCH) + if(${GIT_TAG_PATCH} LESS 0 OR ${GIT_TAG_PATCH} GREATER 99) + message(WARNING "Invalid tag patch version ${GIT_TAG_PATCH}") + return() + endif() + + # Label + if(${GIT_TAG_LISTCOUNT} EQUAL 8) + list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL) + else() + SET(GIT_TAG_LABEL "") + endif() + + # Override hardcoded version with the informations from the tag + set(PROJECT_VERSION_MAJOR ${GIT_TAG_MAJOR} PARENT_SCOPE) + set(PROJECT_VERSION_MINOR ${GIT_TAG_MINOR} PARENT_SCOPE) + set(PROJECT_VERSION_PATCH ${GIT_TAG_PATCH} PARENT_SCOPE) + set(PROJECT_VERSION_LABEL ${GIT_TAG_LABEL} PARENT_SCOPE) + + if(${GIT_TAG_TYPE} STREQUAL "Development") + set(PROJECT_VERSION_LABEL ${GIT_TAG_LABEL} PARENT_SCOPE) + elseif(${GIT_TAG_TYPE} STREQUAL "Release") + set(PROJECT_VERSION_LABEL "" PARENT_SCOPE) + + # get version name from github + set(GIT_TAG_TEMP_FILE "${PROJECT_BINARY_DIR}/tag_informations.txt") + set(GIT_TAG_TEMP_URL "https://api.github.com/repos/Cockatrice/Cockatrice/releases/tags/${GIT_TAG}") + message(STATUS "Fetching tag informations from ${GIT_TAG_TEMP_URL}") + file(REMOVE "${GIT_TAG_TEMP_FILE}") + file(DOWNLOAD "${GIT_TAG_TEMP_URL}" "${GIT_TAG_TEMP_FILE}" STATUS status LOG log INACTIVITY_TIMEOUT 30 TIMEOUT 300 SHOW_PROGRESS) + list(GET status 0 err) + list(GET status 1 msg) + if(err) + message(WARNING "Download failed with error ${msg}: ${log}") + return() + endif() + file(STRINGS "${GIT_TAG_TEMP_FILE}" GIT_TAG_RAW_RELEASENAME REGEX "\"name\": \"" LIMIT_COUNT 1) + + clean_release_name("${GIT_TAG_RAW_RELEASENAME}") + set(PROJECT_VERSION_RELEASENAME "${GIT_TAG_RELEASENAME}" PARENT_SCOPE) + endif() + +endfunction() + +# START OF MAIN + +# fallback defaults +set(GIT_COMMIT_ID "unknown") +set(GIT_COMMIT_DATE "unknown") +set(GIT_COMMIT_DATE_FRIENDLY "unknown") +set(PROJECT_VERSION_LABEL "custom_unknown") +set(PROJECT_VERSION_RELEASENAME "") + +find_package(Git) +if(GIT_FOUND) + get_commit_id() + get_commit_date() + get_tag_name(${GIT_COMMIT_ID}) else() - set( GIT_COMMIT_ID "unknown") - set( GIT_COMMIT_DATE "unknown") - set( GIT_COMMIT_DATE_FRIENDLY "unknown") message( WARNING "Git not found. Build will not contain git revision info." ) endif() -set(PROJECT_VERSION_MAJOR "0") -set(PROJECT_VERSION_MINOR "0") -set(PROJECT_VERSION_PATCH "1~git${GIT_COMMIT_DATE}.${GIT_COMMIT_ID}") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") -set(PROJECT_VERSION_FRIENDLY "${GIT_COMMIT_ID} (${GIT_COMMIT_DATE_FRIENDLY})") +if(PROJECT_VERSION_LABEL) + set(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_LABEL}") +endif() +set(PROJECT_VERSION_FRIENDLY "${PROJECT_VERSION}
(${GIT_COMMIT_DATE_FRIENDLY})") + +# Format: [-ReleaseName]-MAJ.MIN.PATCH[-prerelease_label] +set(PROJECT_VERSION_FILENAME "${PROJECT_NAME}") +if(PROJECT_VERSION_RELEASENAME) + set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION_RELEASENAME}") +endif() +set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION}") + +message(STATUS "Project version: ${PROJECT_VERSION}") +message(STATUS "Friendly project version: ${PROJECT_VERSION_FRIENDLY}") +message(STATUS "Project version filename: ${PROJECT_VERSION_FILENAME}") diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index c7b6866e..54a58da4 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -285,7 +285,7 @@ void MainWindow::actAbout() { QMessageBox mb(QMessageBox::NoIcon, tr("About Cockatrice"), QString( "Cockatrice
" - + tr("Version %1").arg(VERSION_STRING) + + tr("Version
%1").arg(VERSION_STRING) + "

" + tr("Cockatrice Webpage") + "
" + "

" + tr("Project Manager:") + "
Gavin Bisesi

" + "" + tr("Past Project Managers:") + "
Max-Wilhelm Bruker
Marcus Schütz

"