From 5b05f229a10a14ea74f0e77934a619a86cc853df Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sun, 13 Apr 2014 17:22:12 +0000 Subject: [PATCH] Try to form a consistent program title and revision specification from all types of build. CMake builds use 'svn info' (the git-svn equivalent is also supported) to get the real latest revision of the workspace that is used to source a build. If the sources are not in VCS workspace (build from source snapshot archive for example) then the $Rev$ svn keyword expansion in mainwindow.cpp is used despite its issues with accuracy. Non-CMake builds use the $Rev$ keyword expansion where possible. If a CMake build is from a VCS workspace with local modifications; a '-dirty' suffix is added to the revision number to denote that. If no revision number information can be found the word 'local' is used as a revision number. The revision specification is used in the WSJT-X "about" box and is sent to PSKReporter.info as part of the local station information (this can be viewed at the statistics page http://pskreporter.info/cgi-bin/pskstats.pl). git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@4017 ab8295b8-cf94-4d9e-aec4-7959e3be5d79 --- CMake/getsvn.cmake | 2 +- CMakeLists.txt | 1 + ConfigTest.cpp | 5 ++- TestConfiguration.cpp | 5 ++- about.cpp | 4 +-- about.h | 2 +- logqso.cpp | 2 +- main.cpp | 4 +-- mainwindow.cpp | 24 ++++--------- mainwindow.h | 3 -- revision_utils.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++ revision_utils.hpp | 9 +++++ 12 files changed, 107 insertions(+), 34 deletions(-) create mode 100644 revision_utils.cpp create mode 100644 revision_utils.hpp diff --git a/CMake/getsvn.cmake b/CMake/getsvn.cmake index 315d0e30c..354aeef82 100644 --- a/CMake/getsvn.cmake +++ b/CMake/getsvn.cmake @@ -20,7 +20,7 @@ if (Subversion_FOUND AND EXISTS "${SOURCE_DIR}/.svn") endif (__svn_changes) message (STATUS "${SOURCE_DIR} contains a .svn and is revision ${MY_WC_REVISION}") # write a file with the SVNVERSION define - file (WRITE "${OUTPUT_DIR}/svnversion.h.txt" "#define SVNVERSION r${MY_WC_REVISION}\n") + file (WRITE "${OUTPUT_DIR}/svnversion.h.txt" "#define SVNVERSION ${MY_WC_REVISION}\n") else (Subversion_FOUND AND EXISTS "${SOURCE_DIR}/.svn") # try git-svn if (Subversion_FOUND AND EXISTS "${SOURCE_DIR}/.git") diff --git a/CMakeLists.txt b/CMakeLists.txt index 01d0d7b5c..5be358e2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ set (PROJECT_MANUAL "http://www.physics.princeton.edu/pulsar/K1JT/wsjtx-doc/wsjt # set (wsjt_qt_CXXSRCS NetworkServerLookup.cpp + revision_utils.cpp WFPalette.cpp Radio.cpp Bands.cpp diff --git a/ConfigTest.cpp b/ConfigTest.cpp index ea3fbedb5..ca24f6ce6 100644 --- a/ConfigTest.cpp +++ b/ConfigTest.cpp @@ -8,8 +8,7 @@ #include #include -#include "svnversion.h" - +#include "revision_utils.hpp" #include "GetUserId.hpp" #include "TraceFile.hpp" #include "TestConfiguration.hpp" @@ -34,7 +33,7 @@ int main (int argc, char *argv[]) TraceFile trace_file {QDir {QApplication::applicationDirPath () + "/logs"}.absoluteFilePath (id + "_config_test.log")}; // announce to log file - qDebug () << "Configuration Test v" WSJTX_STRINGIZE (CONFIG_TEST_VERSION_MAJOR) "." WSJTX_STRINGIZE (CONFIG_TEST_VERSION_MINOR) "." WSJTX_STRINGIZE (CONFIG_TEST_VERSION_PATCH) ", " WSJTX_STRINGIZE (SVNVERSION) " - Program startup"; + qDebug () << program_title (revision ()) + " - Program startup"; // open user specific settings QSettings settings {QDir {QApplication::applicationDirPath () + "/settings"}.absoluteFilePath (id + "_config_test.ini"), QSettings::IniFormat}; diff --git a/TestConfiguration.cpp b/TestConfiguration.cpp index 150f289bd..78b6d3533 100644 --- a/TestConfiguration.cpp +++ b/TestConfiguration.cpp @@ -12,8 +12,7 @@ #include #include -#include "svnversion.h" - +#include "revision_utils.hpp" #include "Bands.hpp" #include "FrequencyList.hpp" #include "Configuration.hpp" @@ -129,7 +128,7 @@ TestConfiguration::impl::impl (QString const& instance_key, QSettings * settings { ui_->setupUi (this); - setWindowTitle (QApplication::applicationName () + " - " + title); + setWindowTitle (program_title (revision ())); // mode "Unknown" is display only ui_->mode_combo_box->setItemData (ui_->mode_combo_box->findText ("Unknown"), combo_box_item_disabled, Qt::UserRole - 1); diff --git a/about.cpp b/about.cpp index 17fa0f276..789290d91 100644 --- a/about.cpp +++ b/about.cpp @@ -6,13 +6,13 @@ #include "moc_about.cpp" -CAboutDlg::CAboutDlg(QWidget *parent) : +CAboutDlg::CAboutDlg(QString const& program_title, QWidget *parent) : QDialog(parent), ui(new Ui::CAboutDlg) { ui->setupUi(this); - ui->labelTxt->setText ("

WSJT-X v" WSJTX_STRINGIZE (WSJTX_VERSION_MAJOR) "." WSJTX_STRINGIZE (WSJTX_VERSION_MINOR) "." WSJTX_STRINGIZE (WSJTX_VERSION_PATCH) ", " WSJTX_STRINGIZE (SVNVERSION) "

\n\n" + ui->labelTxt->setText ("

" + program_title + "

\n\n" "WSJT-X implements digital modes JT9 and JT65 for
" "Amateur Radio communication.

" "© 2001-2014 by Joe Taylor, K1JT, with grateful
" diff --git a/about.h b/about.h index c2ac75d1b..f0938ccfe 100644 --- a/about.h +++ b/about.h @@ -14,7 +14,7 @@ class CAboutDlg : public QDialog Q_OBJECT; public: - explicit CAboutDlg(QWidget *parent = nullptr); + explicit CAboutDlg(QString const& program_title, QWidget *parent = nullptr); ~CAboutDlg (); private: diff --git a/logqso.cpp b/logqso.cpp index e5aa531ac..1fc3ecf69 100644 --- a/logqso.cpp +++ b/logqso.cpp @@ -19,7 +19,7 @@ LogQSO::LogQSO(QString const& programTitle, QSettings * settings, Configuration m_configuration (configuration) { ui->setupUi(this); - setWindowTitle(programTitle + " Log QSO"); + setWindowTitle(programTitle + " - Log QSO"); loadSettings (); } diff --git a/main.cpp b/main.cpp index 4f5857e39..937c887ed 100644 --- a/main.cpp +++ b/main.cpp @@ -19,7 +19,7 @@ #include #include -#include "svnversion.h" +#include "revision_utils.hpp" #include "SettingsGroup.hpp" #include "TraceFile.hpp" @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) // TraceFile trace_file {QDir {QApplication::applicationDirPath ()}.absoluteFilePath ("wsjtx_trace.log")}; // // announce to log file - // qDebug () << "WSJT-X v" WSJTX_STRINGIZE (WSJTX_VERSION_MAJOR) "." WSJTX_STRINGIZE (WSJTX_VERSION_MINOR) "." WSJTX_STRINGIZE (WSJTX_VERSION_PATCH) ", " WSJTX_STRINGIZE (SVNVERSION) " - Program startup"; + // qDebug () << program_title (revision ()) + " - Program startup"; // Create and initialize shared memory segment // Multiple instances: use rig_name as shared memory key diff --git a/mainwindow.cpp b/mainwindow.cpp index 93fbb872a..e71569ff9 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -7,13 +7,11 @@ #include #include +#include #include -#ifdef QT5 #include -#endif - -#include "svnversion.h" +#include "revision_utils.hpp" #include "soundout.h" #include "plotter.h" #include "about.h" @@ -76,18 +74,9 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme m_multiple {multiple}, m_settings (settings), ui(new Ui::MainWindow), - -#if defined (CMAKE_BUILD) - m_rev {" " WSJTX_STRINGIZE (SVNVERSION)}, - m_windowTitle {QApplication::applicationName () + " v" WSJTX_STRINGIZE (WSJTX_VERSION_MAJOR) "." WSJTX_STRINGIZE (WSJTX_VERSION_MINOR) "." WSJTX_STRINGIZE (WSJTX_VERSION_PATCH) " by K1JT"}, -#else - m_rev {"$Rev$"}, - m_windowTitle {"WSJT-X v1.4, r" + m_rev.mid(6,4) + " by K1JT"}, -#endif - m_config (thekey, settings, this), m_wideGraph (new WideGraph (settings)), - m_logDlg (new LogQSO (m_windowTitle, settings, &m_config, this)), + m_logDlg (new LogQSO (program_title (), settings, &m_config, this)), m_dialFreq {0}, m_detector (RX_SAMPLE_RATE, NTMAX / 2, 6912 / 2, downSampleFactor), m_modulator (TX_SAMPLE_RATE, NTMAX / 2), @@ -212,7 +201,7 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme setDecodedTextFont (font); }); - setWindowTitle(m_windowTitle); + setWindowTitle (program_title ()); createStatusBar(); connect(&proc_jt9, SIGNAL(readyReadStandardOutput()), @@ -706,8 +695,7 @@ void MainWindow::monitor (bool state) void MainWindow::on_actionAbout_triggered() //Display "About" { - CAboutDlg dlg(this); - dlg.exec(); + CAboutDlg {program_title (revision ("$Rev$")), this}.exec (); } void MainWindow::on_autoButton_clicked (bool checked) @@ -2947,5 +2935,5 @@ void MainWindow::pskSetLocal () psk_Reporter->setLocalStation( m_config.my_callsign () , m_config.my_grid () - , antenna_description, "WSJT-X r" + m_rev.mid(6,4)); + , antenna_description, "WSJT-X " + revision ("$Rev$")); } diff --git a/mainwindow.h b/mainwindow.h index ce9d12fa6..ddb8e46a6 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -200,9 +200,6 @@ private: QScopedPointer ui; - QString m_rev; - QString m_windowTitle; - // other windows Configuration m_config; QMessageBox m_rigErrorMessageBox; diff --git a/revision_utils.cpp b/revision_utils.cpp new file mode 100644 index 000000000..dd6c3c543 --- /dev/null +++ b/revision_utils.cpp @@ -0,0 +1,80 @@ +#include "revision_utils.hpp" + +#include +#include + +#include "svnversion.h" + +namespace +{ + QString revision_extract_number (QString const& s) + { + QString revision; + + // try and match a number + QRegularExpression re {R"(^[$:]\w+: (\d+[^$]*)\$$)"}; + auto match = re.match (s); + if (match.hasMatch ()) + { + revision = 'r' + match.captured (1); + } + return revision; + } +} + +QString revision (QString const& svn_rev_string) +{ + QString result; + auto revision_from_svn = revision_extract_number (svn_rev_string); + +#if defined (CMAKE_BUILD) + QString svn_info {":Rev: " WSJTX_STRINGIZE (SVNVERSION) " $"}; + + auto revision_from_svn_info = revision_extract_number (svn_info); + if (!revision_from_svn_info.isEmpty ()) + { + // we managed to get the revision number from svn info etc. + result = revision_from_svn_info; + } + else if (!revision_from_svn.isEmpty ()) + { + // fall back to revision in ths file, this is potentially + // wrong because svn only updates the id when this file is + // touched + // + // this case gets us a revision when someone builds from a + // source snapshot or copy + result = revision_from_svn; + } + else + { + // match anything + QRegularExpression re {R"(^[$:]\w+: ([^$]*)\$$)"}; + auto match = re.match (svn_info); + if (match.hasMatch ()) + { + result = match.captured (1); + } + } +#else + if (!revision_from_svn.isEmpty ()) + { + // not CMake build so all we have is svn revision in this file + result = revision_from_svn; + } +#endif + if (result.isEmpty ()) + { + result = "local"; // last resort fall back + } + return result.trimmed (); +} + +QString program_title (QString const& revision) +{ +#if defined (CMAKE_BUILD) + return QCoreApplication::applicationName () + " v" WSJTX_STRINGIZE (WSJTX_VERSION_MAJOR) "." WSJTX_STRINGIZE (WSJTX_VERSION_MINOR) "." WSJTX_STRINGIZE (WSJTX_VERSION_PATCH) " " + revision + " by K1JT"; +#else + return "WSJT-X v1.4 " + revision + " by K1JT"; +#endif +} diff --git a/revision_utils.hpp b/revision_utils.hpp new file mode 100644 index 000000000..8da0c9586 --- /dev/null +++ b/revision_utils.hpp @@ -0,0 +1,9 @@ +#ifndef REVISION_UTILS_HPP__ +#define REVISION_UTILS_HPP__ + +#include + +QString revision (QString const& svn_rev_string = QString {}); +QString program_title (QString const& revision = QString {}); + +#endif