29 namespace seqan3::detail
62 version_checker() =
delete;
64 version_checker(version_checker
const &) =
default;
65 version_checker & operator=(version_checker
const &) =
default;
66 version_checker(version_checker &&) =
default;
67 version_checker & operator=(version_checker &&) =
default;
68 ~version_checker() =
default;
82 message_app_update.pop_back();
83 message_app_update.append(
"[APP INFO] :: Visit " + app_url +
" for updates.\n\n");
87 timestamp_filename = cookie_path / (name +
"_usr.timestamp");
89 timestamp_filename = cookie_path / (name +
"_dev.timestamp");
94 if (!version_.
empty() &&
97 version = versionMatch.
str(1);
134 std::ifstream version_file{cookie_path / (name +
".version")};
136 if (version_file.is_open())
141 if (line != unregistered_app)
142 srv_app_version = get_numbers_from_version_string(line);
146 #endif // !defined(NDEBUG)
149 srv_seqan_version = get_numbers_from_version_string(line);
151 version_file.close();
154 #if !defined(NDEBUG) // only check seqan version in debug
155 if (srv_seqan_version != empty_version)
159 if (seqan_version < srv_seqan_version)
164 if (srv_app_version != empty_version)
166 #if defined(NDEBUG) // only check app version in release
167 if (get_numbers_from_version_string(version) < srv_app_version)
169 #endif // defined(NDEBUG)
171 #if !defined(NDEBUG) // only notify developer that app version should be updated on server
172 if (get_numbers_from_version_string(version) > srv_app_version)
173 std::cerr << message_registered_app_update;
174 #endif // !defined(NDEBUG)
195 std::string{
"http://seqan-update.informatik.uni-tuebingen.de/check/SeqAn3_"} +
200 #elif defined(_WIN32)
209 #if __x86_64__ || __ppc64__
218 "; exit [int] -not $?}\" > nul 2>&1";
230 using namespace std::filesystem;
239 tmp_path /=
".config";
257 path dummy = tmp_path /
"dummy.txt";
259 detail::safe_filesystem_entry file_guard{dummy};
261 bool is_open = file.is_open();
262 bool is_good = file.good();
264 file_guard.remove_no_throw();
266 if (!is_good || !is_open)
298 bool decide_if_check_is_performed(
bool developer_approval,
std::optional<bool> user_approval)
300 if (!developer_approval)
303 if (
std::getenv(
"SEQAN3_NO_VERSION_CHECK") !=
nullptr)
307 return user_approval.
value();
315 if (timestamp_file.is_open())
319 if (get_time_diff_to_current(cookie_line) < 86400)
326 if (cookie_line ==
"NEVER")
330 else if (cookie_line ==
"ALWAYS")
336 timestamp_file.close();
344 if (detail::is_terminal())
347 #######################################################################
348 Automatic Update Notifications
349 #######################################################################
351 This app can look for updates automatically in the background,
352 do you want to do that?
354 [a] Always perform version checks for this app (the default).
355 [n] Never perform version checks for this app.
356 [y] Yes, perform a version check now, and ask again tomorrow.
357 [s] Skip the version check now, but ask again tomorrow.
359 Please enter one of [a, n, y, s] and press [RETURN].
361 For more information, see:
362 https://github.com/seqan/seqan3/wiki/Update-Notifications
364 #######################################################################
396 #######################################################################
397 Automatic Update Notifications
398 #######################################################################
399 This app performs automatic checks for updates. For more information
400 see: https://github.com/seqan/seqan3/wiki/Update-Notifications
401 #######################################################################
412 "[SEQAN3 INFO] :: A new SeqAn version is available online.\n"
413 "[SEQAN3 INFO] :: Please visit www.github.com/seqan/seqan3.git for an update\n"
414 "[SEQAN3 INFO] :: or inform the developer of this app.\n"
415 "[SEQAN3 INFO] :: If you don't wish to receive further notifications, set --version-check OFF.\n\n";
418 "[SEQAN3 INFO] :: Thank you for using SeqAn!\n"
419 "[SEQAN3 INFO] :: Do you wish to register your app for update notifications?\n"
420 "[SEQAN3 INFO] :: Just send an email to support@seqan.de with your app name and version number.\n"
421 "[SEQAN3 INFO] :: If you don't wish to receive further notifications, set --version-check OFF.\n\n";
424 "[APP INFO] :: We noticed the app version you use is newer than the one registered with us.\n"
425 "[APP INFO] :: Please send us an email with the new version so we can correct it (support@seqan.de)\n\n";
428 "[APP INFO] :: A new version of this application is now available.\n"
429 "[APP INFO] :: If you don't wish to receive further notifications, set --version-check OFF.\n\n";
437 std::regex version_regex{
"^[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+$"};
448 return "powershell.exe -NoLogo -NonInteractive -Command \"& {Invoke-WebRequest -erroraction 'silentlycontinue' -OutFile";
449 #else // Unix based platforms.
450 if (!
system(
"/usr/bin/env -i wget --version > /dev/null 2>&1"))
451 return "/usr/bin/env -i wget --timeout=10 --tries=1 -q -O";
452 else if (!
system(
"/usr/bin/env -i curl --version > /dev/null 2>&1"))
453 return "/usr/bin/env -i curl --connect-timeout 10 -o";
456 #if defined(__OpenBSD__)
457 return "/usr/bin/env -i ftp -w10 -Vo";
458 #elif defined(__FreeBSD__)
459 return "/usr/bin/env -i fetch --timeout=10 -o";
462 #endif // __OpenBSD__
463 #endif // defined(_WIN32)
467 double get_time_diff_to_current(
std::string const & str_time)
const
469 namespace co = std::chrono;
470 double curr = co::duration_cast<co::seconds>(co::system_clock::now().time_since_epoch()).count();
475 return curr - d_time;
499 template <
typename msg_type>
500 void write_cookie(msg_type && msg)
503 namespace co = std::chrono;
504 auto curr = co::duration_cast<co::seconds>(co::system_clock::now().time_since_epoch()).count();
508 if (timestamp_file.is_open())
510 timestamp_file << curr <<
'\n' << msg;
511 timestamp_file.close();