# version.cmake - Script pour gérer la version SemVer de manière centralisée # Usage: cmake -P version.cmake [GET|SET|PATCH|MINOR|MAJOR] [new_version] set(PACKAGE_JSON_FILES "${CMAKE_CURRENT_LIST_DIR}/package.json" "${CMAKE_CURRENT_LIST_DIR}/backend/package.json" "${CMAKE_CURRENT_LIST_DIR}/frontend/package.json" ) # Fonction pour lire la version depuis le package.json racine function(get_current_version OUT_VAR) file(READ "${CMAKE_CURRENT_LIST_DIR}/package.json" ROOT_JSON) string(JSON CURRENT_VERSION GET "${ROOT_JSON}" "version") set(${OUT_VAR} ${CURRENT_VERSION} PARENT_SCOPE) endfunction() # Fonction pour incrémenter la version SemVer function(increment_version CURRENT_VERSION TYPE OUT_VAR) if(CURRENT_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") set(MAJOR ${CMAKE_MATCH_1}) set(MINOR ${CMAKE_MATCH_2}) set(PATCH ${CMAKE_MATCH_3}) else() message(FATAL_ERROR "Format de version invalide: ${CURRENT_VERSION}. Attendu: X.Y.Z") endif() if("${TYPE}" STREQUAL "MAJOR") math(EXPR MAJOR "${MAJOR} + 1") set(MINOR 0) set(PATCH 0) elseif("${TYPE}" STREQUAL "MINOR") math(EXPR MINOR "${MINOR} + 1") set(PATCH 0) elseif("${TYPE}" STREQUAL "PATCH") math(EXPR PATCH "${PATCH} + 1") endif() set(${OUT_VAR} "${MAJOR}.${MINOR}.${PATCH}" PARENT_SCOPE) endfunction() # Fonction pour créer un commit git pour les changements de version function(commit_version_changes VERSION) find_package(Git QUIET) if(GIT_FOUND) # On n'ajoute que les fichiers package.json modifiés set(ADDED_ANY FALSE) foreach(JSON_FILE ${PACKAGE_JSON_FILES}) if(EXISTS "${JSON_FILE}") execute_process( COMMAND ${GIT_EXECUTABLE} add "${JSON_FILE}" WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" ) set(ADDED_ANY TRUE) endif() endforeach() if(ADDED_ANY) # On commit uniquement les fichiers qui ont été ajoutés (staged) # L'utilisation de --only ou spécifier les fichiers à nouveau assure qu'on ne prend pas d'autres changements execute_process( COMMAND ${GIT_EXECUTABLE} commit -m "chore: bump version to ${VERSION}" -- ${PACKAGE_JSON_FILES} WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" RESULT_VARIABLE COMMIT_RESULT ) if(COMMIT_RESULT EQUAL 0) message(STATUS "Changements commités avec succès pour la version ${VERSION}") else() message(WARNING "Échec du commit des changements. Il n'y a peut-être rien à commiter ou aucun changement sur les fichiers JSON.") endif() endif() else() message(WARNING "Git non trouvé, impossible de commiter les changements.") endif() endfunction() # Fonction pour créer un tag git function(create_git_tag VERSION) find_package(Git QUIET) if(GIT_FOUND) execute_process( COMMAND ${GIT_EXECUTABLE} tag -a "v${VERSION}" -m "Release v${VERSION}" WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" RESULT_VARIABLE TAG_RESULT ) if(TAG_RESULT EQUAL 0) message(STATUS "Tag v${VERSION} créé avec succès") else() message(WARNING "Échec de la création du tag v${VERSION}. Il existe peut-être déjà.") endif() else() message(WARNING "Git non trouvé, impossible de créer le tag.") endif() endfunction() # Fonction pour mettre à jour la version dans tous les fichiers package.json function(set_new_version NEW_VERSION) foreach(JSON_FILE ${PACKAGE_JSON_FILES}) if(EXISTS "${JSON_FILE}") message(STATUS "Mise à jour de ${JSON_FILE} vers la version ${NEW_VERSION}") file(READ "${JSON_FILE}" CONTENT) # Utilisation de string(JSON ...) pour modifier la version si disponible (CMake >= 3.19) # Sinon on peut utiliser une regex simple pour package.json string(REGEX REPLACE "\"version\": \"[^\"]+\"" "\"version\": \"${NEW_VERSION}\"" NEW_CONTENT "${CONTENT}") file(WRITE "${JSON_FILE}" "${NEW_CONTENT}") else() message(WARNING "Fichier non trouvé: ${JSON_FILE}") endif() endforeach() # Commiter les changements commit_version_changes(${NEW_VERSION}) # Créer le tag git create_git_tag(${NEW_VERSION}) endfunction() # Logique principale if(CMAKE_SCRIPT_MODE_FILE STREQUAL CMAKE_CURRENT_LIST_FILE) set(ARG_OFFSET 0) while(ARG_OFFSET LESS CMAKE_ARGC) if("${CMAKE_ARGV${ARG_OFFSET}}" STREQUAL "-P") math(EXPR COMMAND_INDEX "${ARG_OFFSET} + 2") math(EXPR VERSION_INDEX "${ARG_OFFSET} + 3") break() endif() math(EXPR ARG_OFFSET "${ARG_OFFSET} + 1") endwhile() if(NOT DEFINED COMMAND_INDEX OR COMMAND_INDEX GREATER_EQUAL CMAKE_ARGC) message(FATAL_ERROR "Usage: cmake -P version.cmake [GET|SET|PATCH|MINOR|MAJOR] [new_version]") endif() set(COMMAND "${CMAKE_ARGV${COMMAND_INDEX}}") if("${COMMAND}" STREQUAL "GET") get_current_version(VERSION) message("${VERSION}") elseif("${COMMAND}" STREQUAL "SET") if(VERSION_INDEX GREATER_EQUAL CMAKE_ARGC) message(FATAL_ERROR "Veuillez spécifier la nouvelle version: cmake -P version.cmake SET 0.0.0") endif() set(NEW_VERSION "${CMAKE_ARGV${VERSION_INDEX}}") set_new_version("${NEW_VERSION}") elseif("${COMMAND}" MATCHES "^(PATCH|MINOR|MAJOR)$") get_current_version(CURRENT_VERSION) increment_version("${CURRENT_VERSION}" "${COMMAND}" NEW_VERSION) set_new_version("${NEW_VERSION}") else() message(FATAL_ERROR "Commande inconnue: ${COMMAND}. Utilisez GET, SET, PATCH, MINOR ou MAJOR.") endif() endif()