From 7f4918f1f17b0ddde6d1a8435e63f5f94c6dd065 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Mon, 20 Apr 2026 12:50:39 -0400 Subject: Generate version string based on repository information --- CMakeLists.txt | 8 ++++++++ cmake/GitVersion.cmake | 43 ++++++++++++++++++++++++++++++++++++++++++ include/version.h.in | 6 ++++++ src/cli/stasis/stasis_main.c | 45 +++++++++++++++++++++++++++++++++++++++++++- src/lib/core/globals.c | 10 +++++----- src/lib/core/include/core.h | 2 ++ 6 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 cmake/GitVersion.cmake create mode 100644 include/version.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index fc403ca..73f5555 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,14 @@ cmake_minimum_required(VERSION 3.15) project(STASIS C) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + include(GNUInstallDirs) +include(GitVersion) +get_version_from_git() +configure_file( + ${CMAKE_SOURCE_DIR}/include/version.h.in + ${CMAKE_BINARY_DIR}/include/version.h +) set(nix_cflags -Wall -Wextra -fPIC -D_GNU_SOURCE) set(win_cflags /Wall) diff --git a/cmake/GitVersion.cmake b/cmake/GitVersion.cmake new file mode 100644 index 0000000..7280510 --- /dev/null +++ b/cmake/GitVersion.cmake @@ -0,0 +1,43 @@ +function(get_version_from_git) + find_package(Git QUIET) + if(NOT Git_FOUND) + message(WARNING "Git not found. Setting fallback version.") + set(PROJECT_VERSION "0.0.0") + set(PROJECT_VERSION ${PROJECT_VERSION} PARENT_SCOPE) + set(PROJECT_VERSION_BRANCH "unknown") + set(PROJECT_VERSION_BRANCH ${PROJECT_VERSION_BRANCH} PARENT_SCOPE) + return() + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --first-parent --long --dirty --tags --always + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_TAG + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE GIT_RESULT + ) + if(NOT GIT_RESULT EQUAL 0) + message(WARNING "Failed to get git describe info") + return() + endif() + message(${GIT_TAG}) + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_BRANCH + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE GIT_RESULT + ) + if(NOT GIT_RESULT EQUAL 0) + message(WARNING "Failed to get git branch") + return() + endif() + message(${GIT_BRANCH}) + + string(REGEX REPLACE "^v" "" CLEAN_TAG "${GIT_TAG}") + set(PROJECT_VERSION ${CLEAN_TAG}) + set(PROJECT_VERSION ${CLEAN_TAG} PARENT_SCOPE) + set(PROJECT_VERSION_BRANCH ${GIT_BRANCH}) + set(PROJECT_VERSION_BRANCH ${GIT_BRANCH} PARENT_SCOPE) +endfunction() \ No newline at end of file diff --git a/include/version.h.in b/include/version.h.in new file mode 100644 index 0000000..b33d7c7 --- /dev/null +++ b/include/version.h.in @@ -0,0 +1,6 @@ +#ifndef STASIS_VERSION_H + +#define STASIS_VERSION "@PROJECT_VERSION@" +#define STASIS_VERSION_BRANCH "@PROJECT_VERSION_BRANCH@" + +#endif // STASIS_VERSION_H \ No newline at end of file diff --git a/src/cli/stasis/stasis_main.c b/src/cli/stasis/stasis_main.c index 328d825..697791a 100644 --- a/src/cli/stasis/stasis_main.c +++ b/src/cli/stasis/stasis_main.c @@ -487,6 +487,39 @@ static void transfer_artifacts(struct Delivery *ctx) { } } +static char *center_text(const char *s, const size_t maxwidth) { + if (maxwidth < 2) { + SYSERROR("%s", "maximum width must be greater than 0"); + return NULL; + } + + if (maxwidth % 2 != 0) { + SYSERROR("maximum width (%zu) must be even", maxwidth); + return NULL; + } + + const size_t s_len = strlen(s); + if (s_len + 1 > maxwidth) { + SYSERROR("length of input string (%zu) exceeds maximum width (%zu)", s_len, maxwidth); + return NULL; + } + + char *result = calloc(maxwidth + 1, sizeof(*result)); + if (!result) { + SYSERROR("%s", "unable to allocate bytes for centered text string"); + return NULL; + } + const size_t middle = (maxwidth / 2) - s_len / 2; + size_t i = 0; + for (; i < middle; i++) { + result[i] = ' '; + } + result[i++] = 'v'; + strncpy(&result[i], s, maxwidth - middle - 1); + return result; +} + + int main(int argc, char *argv[]) { struct Delivery ctx; struct Process proc = { @@ -634,7 +667,17 @@ int main(int argc, char *argv[]) { exit(1); } - printf(BANNER, VERSION, AUTHOR); + char *version = center_text(VERSION, strlen(STASIS_BANNER_HEADER)); + if (!version) { + SYSERROR("%s", "version too long?"); + version = strdup(VERSION); + if (!version) { + SYSERROR("%s", "unable to allocate uncentered fallback version string"); + exit(1); + } + } + printf(BANNER, version, AUTHOR); + guard_free(version); setup_python_version_override(&ctx, python_override_version); configure_stasis_ini(&ctx, &config_input); diff --git a/src/lib/core/globals.c b/src/lib/core/globals.c index 63555a2..b84213e 100644 --- a/src/lib/core/globals.c +++ b/src/lib/core/globals.c @@ -3,10 +3,10 @@ #include "core.h" #include "envctl.h" -const char *VERSION = "1.0.0"; +const char *VERSION = STASIS_VERSION " (" STASIS_VERSION_BRANCH ")"; const char *AUTHOR = "Joseph Hunkeler"; const char *BANNER = - "------------------------------------------------------------------------\n" + STASIS_BANNER_HEADER "\n" #if defined(STASIS_DUMB_TERMINAL) " STASIS \n" #else @@ -18,10 +18,10 @@ const char *BANNER = " |_____/ |_/_/ \\_\\_____/|_____|_____/ \n" "\n" #endif - "------------------------------------------------------------------------\n" + STASIS_BANNER_HEADER "\n" " Delivery Generator \n" - " v%s \n" - "------------------------------------------------------------------------\n" + "%s\n" + STASIS_BANNER_HEADER "\n" "Copyright (C) 2023-2025 %s,\n" "Association of Universities for Research in Astronomy (AURA)\n"; diff --git a/src/lib/core/include/core.h b/src/lib/core/include/core.h index c895267..9a2007c 100644 --- a/src/lib/core/include/core.h +++ b/src/lib/core/include/core.h @@ -10,7 +10,9 @@ #include #include #include +#include "version.h" +#define STASIS_BANNER_HEADER "------------------------------------------------------------------------" #define STASIS_BUFSIZ 8192 #define STASIS_NAME_MAX 255 #define STASIS_DIRSTACK_MAX 1024 -- cgit From 7bd80c314dc4db2296b8a15c2f276dc9afe63fd1 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Tue, 21 Apr 2026 10:49:28 -0400 Subject: Emit stasis version --- src/cli/stasis_indexer/helpers.c | 14 +++++++++++++- src/lib/delivery/delivery_postprocess.c | 6 ++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/cli/stasis_indexer/helpers.c b/src/cli/stasis_indexer/helpers.c index 0debfe4..23e4f5a 100644 --- a/src/cli/stasis_indexer/helpers.c +++ b/src/cli/stasis_indexer/helpers.c @@ -313,13 +313,22 @@ int load_metadata(struct Delivery *ctx, const char *filename) { return -1; } + // Reserved for future use. + // i.e. adjust values based on the version of the software that produced the input + char *stasis_version = NULL; + char *stasis_version_branch = NULL; + while (fgets(line, sizeof(line) - 1, fp) != NULL) { char **parts = split(line, " ", 1); const char *name = parts[0]; char *value = parts[1]; strip(value); - if (!strcmp(name, "name")) { + if (!strcmp(name, "stasis_version")) { + stasis_version = strdup(value); + } else if (!strcmp(name, "stasis_version_branch")) { + stasis_version_branch = strdup(value); + } else if (!strcmp(name, "name")) { ctx->meta.name = strdup(value); } else if (!strcmp(name, "version")) { ctx->meta.version = strdup(value); @@ -364,6 +373,9 @@ int load_metadata(struct Delivery *ctx, const char *filename) { } guard_array_free(parts); } + + guard_free(stasis_version); + guard_free(stasis_version_branch); fclose(fp); return 0; diff --git a/src/lib/delivery/delivery_postprocess.c b/src/lib/delivery/delivery_postprocess.c index 8cb4e65..95bcc0a 100644 --- a/src/lib/delivery/delivery_postprocess.c +++ b/src/lib/delivery/delivery_postprocess.c @@ -3,6 +3,8 @@ const char *release_header = "# delivery_name: %s\n" "# delivery_fmt: %s\n" + "# stasis_version: %s\n" + "# stasis_branch: %s\n" "# creation_time: %s\n" "# conda_ident: %s\n" "# conda_build_ident: %s\n"; @@ -14,6 +16,8 @@ char *delivery_get_release_header(struct Delivery *ctx) { snprintf(output, sizeof(output), release_header, ctx->info.release_name, ctx->rules.release_fmt, + STASIS_VERSION, + STASIS_VERSION_BRANCH, stamp, ctx->conda.tool_version, ctx->conda.tool_build_version); @@ -30,6 +34,8 @@ int delivery_dump_metadata(struct Delivery *ctx) { if (globals.verbose) { msg(STASIS_MSG_L2, "%s\n", filename); } + fprintf(fp, "stasis_version %s\n", STASIS_VERSION); + fprintf(fp, "stasis_version_branch %s\n", STASIS_VERSION_BRANCH); fprintf(fp, "name %s\n", ctx->meta.name); fprintf(fp, "version %s\n", ctx->meta.version); fprintf(fp, "rc %d\n", ctx->meta.rc); -- cgit From 1098f46052e03b057d0b0d159d2ab10b635afcec Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Tue, 21 Apr 2026 12:02:23 -0400 Subject: Remove debug print statements --- cmake/GitVersion.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmake/GitVersion.cmake b/cmake/GitVersion.cmake index 7280510..94d6071 100644 --- a/cmake/GitVersion.cmake +++ b/cmake/GitVersion.cmake @@ -20,7 +20,6 @@ function(get_version_from_git) message(WARNING "Failed to get git describe info") return() endif() - message(${GIT_TAG}) execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD @@ -33,7 +32,6 @@ function(get_version_from_git) message(WARNING "Failed to get git branch") return() endif() - message(${GIT_BRANCH}) string(REGEX REPLACE "^v" "" CLEAN_TAG "${GIT_TAG}") set(PROJECT_VERSION ${CLEAN_TAG}) -- cgit From 059f3539bf3f840f8ea76b19db3713dd6696e4c1 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Tue, 21 Apr 2026 12:02:43 -0400 Subject: Show STASIS version during cmake config --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73f5555..817f88d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ configure_file( ${CMAKE_SOURCE_DIR}/include/version.h.in ${CMAKE_BINARY_DIR}/include/version.h ) +message("-- STASIS version: ${PROJECT_VERSION} (${PROJECT_VERSION_BRANCH})") set(nix_cflags -Wall -Wextra -fPIC -D_GNU_SOURCE) set(win_cflags /Wall) -- cgit From adb85b4f462c69de632372f3d8b9d8abd4dbebfb Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Tue, 21 Apr 2026 12:40:26 -0400 Subject: CI: Fetch repository tags --- .github/workflows/cmake-multi-platform.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index e2315f7..2191559 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -30,6 +30,8 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 - name: Set reusable strings id: strings -- cgit From ee4c7beb65ddef497e9349d4ffc71d5bd58777cc Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Tue, 21 Apr 2026 13:52:30 -0400 Subject: cmake: use fallback on any error --- cmake/GitVersion.cmake | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/cmake/GitVersion.cmake b/cmake/GitVersion.cmake index 94d6071..c9c6159 100644 --- a/cmake/GitVersion.cmake +++ b/cmake/GitVersion.cmake @@ -1,11 +1,16 @@ +function(set_version_fallback) + message(WARNING "Version information not available. Using fallback...") + set(PROJECT_VERSION "0.0.0") + set(PROJECT_VERSION ${PROJECT_VERSION} PARENT_SCOPE) + set(PROJECT_VERSION_BRANCH "unknown") + set(PROJECT_VERSION_BRANCH ${PROJECT_VERSION_BRANCH} PARENT_SCOPE) +endfunction() + function(get_version_from_git) find_package(Git QUIET) if(NOT Git_FOUND) - message(WARNING "Git not found. Setting fallback version.") - set(PROJECT_VERSION "0.0.0") - set(PROJECT_VERSION ${PROJECT_VERSION} PARENT_SCOPE) - set(PROJECT_VERSION_BRANCH "unknown") - set(PROJECT_VERSION_BRANCH ${PROJECT_VERSION_BRANCH} PARENT_SCOPE) + message(WARNING "Git not found.") + set_version_fallback() return() endif() @@ -18,6 +23,7 @@ function(get_version_from_git) ) if(NOT GIT_RESULT EQUAL 0) message(WARNING "Failed to get git describe info") + set_version_fallback() return() endif() @@ -30,6 +36,7 @@ function(get_version_from_git) ) if(NOT GIT_RESULT EQUAL 0) message(WARNING "Failed to get git branch") + set_version_fallback() return() endif() -- cgit