From 7ddacd319930e643633d7abae842300963a27e2e Mon Sep 17 00:00:00 2001 From: nerdCopter Date: Sat, 17 Jan 2026 13:33:31 -0600 Subject: [PATCH 1/5] feat: add --version flag and -V alias; add tests Print 'fstl ' and exit for --version/-V; use raw argv checks for robustness; add CTest entries to validate outputs. --- CMakeLists.txt | 9 +++++++++ src/main.cpp | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2fbea669..d8c38bdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,6 +118,15 @@ target_link_libraries(fstl Qt5::Widgets Qt5::Core Qt5::Gui Qt5::OpenGL ${OPENGL_ # Add version definitions to use within the code. target_compile_definitions(fstl PRIVATE -DFSTL_VERSION="${PROJECT_VERSION}") +# Enable a simple test that validates the CLI `--version` output is exact. +enable_testing() +add_test(NAME version_check COMMAND $ --version) +set_tests_properties(version_check PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION}") + +# Also validate the short alias `-V` produces the same output. +add_test(NAME version_check_short COMMAND $ -V) +set_tests_properties(version_check_short PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION}") + #installer information that is platform independent set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Fast .stl file viewer.") set(CPACK_PACKAGE_VERSION_MAJOR ${FSTL_VERSION_MAJOR}) diff --git a/src/main.cpp b/src/main.cpp index 3999846d..e867f2fa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,9 @@ #include "app.h" +#include +#include + int main(int argc, char* argv[]) { // Force C locale to force decimal point @@ -11,6 +14,17 @@ int main(int argc, char* argv[]) QCoreApplication::setOrganizationDomain("https://github.com/fstl-app/fstl"); QCoreApplication::setApplicationName("fstl"); QCoreApplication::setApplicationVersion(FSTL_VERSION); + + // If user asked for the version, print and exit immediately. + // Use raw argv comparison to avoid any QString conversion edge-cases. + for (int i = 1; i < argc; ++i) { + if (std::strcmp(argv[i], "--version") == 0 || std::strcmp(argv[i], "-V") == 0) { + std::cout << QCoreApplication::applicationName().toStdString() << " " + << QCoreApplication::applicationVersion().toStdString() << std::endl; + return 0; + } + } + App a(argc, argv); return a.exec(); From fbf89ee6bd9dfb8e11bf041f0958d432dd22cb62 Mon Sep 17 00:00:00 2001 From: nerdCopter Date: Sat, 17 Jan 2026 13:37:27 -0600 Subject: [PATCH 2/5] feat: accept -v as version alias and add test Recognize --version, -V, and -v; add CTest to validate -v output; use literal '.' matching in version regex and skip tests on WIN32. --- CMakeLists.txt | 23 +++++++++++++++++------ src/main.cpp | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d8c38bdb..348af5f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,13 +119,24 @@ target_link_libraries(fstl Qt5::Widgets Qt5::Core Qt5::Gui Qt5::OpenGL ${OPENGL_ target_compile_definitions(fstl PRIVATE -DFSTL_VERSION="${PROJECT_VERSION}") # Enable a simple test that validates the CLI `--version` output is exact. -enable_testing() -add_test(NAME version_check COMMAND $ --version) -set_tests_properties(version_check PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION}") +# Escape dots in PROJECT_VERSION so version is matched literally in the regex. Use character class to avoid backslash escaping issues. +string(REPLACE "." "[.]" PROJECT_VERSION_ESCAPED "${PROJECT_VERSION}") -# Also validate the short alias `-V` produces the same output. -add_test(NAME version_check_short COMMAND $ -V) -set_tests_properties(version_check_short PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION}") +if(NOT WIN32) + enable_testing() + add_test(NAME version_check COMMAND $ --version) + set_tests_properties(version_check PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION_ESCAPED}") + + # Also validate the short alias `-V` produces the same output. + add_test(NAME version_check_short COMMAND $ -V) + set_tests_properties(version_check_short PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION_ESCAPED}") + + # Validate lowercase `-v` also produces the same output. + add_test(NAME version_check_v COMMAND $ -v) + set_tests_properties(version_check_v PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION_ESCAPED}") +else() + message(STATUS "Skipping version_check tests on WIN32 (GUI targets may not provide stdout)") +endif() #installer information that is platform independent set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Fast .stl file viewer.") diff --git a/src/main.cpp b/src/main.cpp index e867f2fa..d01234ef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,7 +18,7 @@ int main(int argc, char* argv[]) // If user asked for the version, print and exit immediately. // Use raw argv comparison to avoid any QString conversion edge-cases. for (int i = 1; i < argc; ++i) { - if (std::strcmp(argv[i], "--version") == 0 || std::strcmp(argv[i], "-V") == 0) { + if (std::strcmp(argv[i], "--version") == 0 || std::strcmp(argv[i], "-V") == 0 || std::strcmp(argv[i], "-v") == 0) { std::cout << QCoreApplication::applicationName().toStdString() << " " << QCoreApplication::applicationVersion().toStdString() << std::endl; return 0; From 539c0d33da334587726a022cdbaa0051df4795d7 Mon Sep 17 00:00:00 2001 From: nerdCopter Date: Sun, 18 Jan 2026 16:12:49 -0600 Subject: [PATCH 3/5] feat: add cross-platform version tests and Qt CLI best practices Implement POSIX-compliant version handling using QCommandLineParser: Changes: - Enable version tests on all platforms (remove WIN32 restriction) - Use QCommandLineParser for proper --help, -h, and --version handling - Support -V (uppercase, POSIX-compliant) and --version for version output - Remove -v (lowercase) to follow POSIX conventions (typically reserved for verbose) - Tests: version_check (--version) and version_check_V (-V) on all platforms Benefits: - Cross-platform compatibility (Windows, Linux, macOS) - Qt best practices with QCommandLineParser - No hardcoded program name or version (uses CMake PROJECT_VERSION) - Proper --help output with option documentation - All values sourced from QCoreApplication and CMake configuration --- CMakeLists.txt | 22 +++++++--------------- src/main.cpp | 34 +++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 348af5f4..83a635c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,21 +122,13 @@ target_compile_definitions(fstl PRIVATE -DFSTL_VERSION="${PROJECT_VERSION}") # Escape dots in PROJECT_VERSION so version is matched literally in the regex. Use character class to avoid backslash escaping issues. string(REPLACE "." "[.]" PROJECT_VERSION_ESCAPED "${PROJECT_VERSION}") -if(NOT WIN32) - enable_testing() - add_test(NAME version_check COMMAND $ --version) - set_tests_properties(version_check PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION_ESCAPED}") - - # Also validate the short alias `-V` produces the same output. - add_test(NAME version_check_short COMMAND $ -V) - set_tests_properties(version_check_short PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION_ESCAPED}") - - # Validate lowercase `-v` also produces the same output. - add_test(NAME version_check_v COMMAND $ -v) - set_tests_properties(version_check_v PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION_ESCAPED}") -else() - message(STATUS "Skipping version_check tests on WIN32 (GUI targets may not provide stdout)") -endif() +enable_testing() +add_test(NAME version_check COMMAND $ --version) +set_tests_properties(version_check PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION_ESCAPED}") + +# Also validate the POSIX-compliant short alias `-V` produces the same output. +add_test(NAME version_check_V COMMAND $ -V) +set_tests_properties(version_check_V PROPERTIES PASS_REGULAR_EXPRESSION "fstl ${PROJECT_VERSION_ESCAPED}") #installer information that is platform independent set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Fast .stl file viewer.") diff --git a/src/main.cpp b/src/main.cpp index d01234ef..6ad93cc4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,8 @@ #include +#include #include "app.h" -#include -#include - int main(int argc, char* argv[]) { // Force C locale to force decimal point @@ -15,17 +13,27 @@ int main(int argc, char* argv[]) QCoreApplication::setApplicationName("fstl"); QCoreApplication::setApplicationVersion(FSTL_VERSION); - // If user asked for the version, print and exit immediately. - // Use raw argv comparison to avoid any QString conversion edge-cases. - for (int i = 1; i < argc; ++i) { - if (std::strcmp(argv[i], "--version") == 0 || std::strcmp(argv[i], "-V") == 0 || std::strcmp(argv[i], "-v") == 0) { - std::cout << QCoreApplication::applicationName().toStdString() << " " - << QCoreApplication::applicationVersion().toStdString() << std::endl; - return 0; - } - } - App a(argc, argv); + // Set up QCommandLineParser to handle --help, --version, and file argument + QCommandLineParser parser; + parser.setApplicationDescription("Fast .stl file viewer"); + parser.addHelpOption(); + + // Add custom version option with both -V (uppercase, POSIX) and --version + QCommandLineOption versionOption(QStringList() << "V" << "version", "Displays version information."); + parser.addOption(versionOption); + + parser.addPositionalArgument("file", "STL file to open (optional)", "[file]"); + parser.process(a); + + // Handle version option manually since we use custom -V + if (parser.isSet(versionOption)) { + printf("%s %s\n", + QCoreApplication::applicationName().toStdString().c_str(), + QCoreApplication::applicationVersion().toStdString().c_str()); + return 0; + } + return a.exec(); } From 638eaf02717c6a62f44d9b384b8362a311449c48 Mon Sep 17 00:00:00 2001 From: nerdCopter <56646290+nerdCopter@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:21:40 -0600 Subject: [PATCH 4/5] Update src/main.cpp Co-authored-by: Paul T <6591180+ptsouchlos@users.noreply.github.com> --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 6ad93cc4..acbeb338 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,7 @@ int main(int argc, char* argv[]) parser.addHelpOption(); // Add custom version option with both -V (uppercase, POSIX) and --version - QCommandLineOption versionOption(QStringList() << "V" << "version", "Displays version information."); + QCommandLineOption versionOption(QStringList{"V", "version"}, "Displays version information."); parser.addOption(versionOption); parser.addPositionalArgument("file", "STL file to open (optional)", "[file]"); From 2c2df465805142b3187c67084a1cfbe80b73d7b9 Mon Sep 17 00:00:00 2001 From: nerdCopter Date: Mon, 19 Jan 2026 15:25:14 -0600 Subject: [PATCH 5/5] refactor: replace printf with std::cout for C++14 compatibility Use standard iostream streams instead of C-style printf for version output, improving consistency with modern C++ practices. --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index acbeb338..fd857ae9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -29,9 +30,8 @@ int main(int argc, char* argv[]) // Handle version option manually since we use custom -V if (parser.isSet(versionOption)) { - printf("%s %s\n", - QCoreApplication::applicationName().toStdString().c_str(), - QCoreApplication::applicationVersion().toStdString().c_str()); + std::cout << QCoreApplication::applicationName().toStdString() << " " + << QCoreApplication::applicationVersion().toStdString() << "\n"; return 0; }