diff --git a/src/apps/haikudepot/server/ServerSettings.cpp b/src/apps/haikudepot/server/ServerSettings.cpp index c477868f00..8382c6f5ec 100644 --- a/src/apps/haikudepot/server/ServerSettings.cpp +++ b/src/apps/haikudepot/server/ServerSettings.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2017-2020, Andrew Lindesay . + * Copyright 2017-2021, Andrew Lindesay . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -16,6 +15,7 @@ #include #include +#include "AppUtils.h" #include "Logger.h" @@ -80,35 +80,11 @@ ServerSettings::_InitUserAgent() const BString ServerSettings::_GetUserAgentVersionString() { - app_info info; - - if (be_app->GetAppInfo(&info) != B_OK) { - HDERROR("Unable to get the application info"); - be_app->Quit(); - return BString(USERAGENT_FALLBACK_VERSION); - } - - BFile file(&info.ref, B_READ_ONLY); - - if (file.InitCheck() != B_OK) { - HDERROR("Unable to access the application info file"); - be_app->Quit(); - return BString(USERAGENT_FALLBACK_VERSION); - } - - BAppFileInfo appFileInfo(&file); - version_info versionInfo; - - if (appFileInfo.GetVersionInfo( - &versionInfo, B_APP_VERSION_KIND) != B_OK) { - HDERROR("Unable to establish the application version"); - be_app->Quit(); - return BString(USERAGENT_FALLBACK_VERSION); - } - BString result; - result.SetToFormat("%" B_PRId32 ".%" B_PRId32 ".%" B_PRId32, - versionInfo.major, versionInfo.middle, versionInfo.minor); + if (AppUtils::GetAppVersionString(result) != B_OK) { + be_app->Quit(); + return BString(USERAGENT_FALLBACK_VERSION); + } return result; } diff --git a/src/apps/haikudepot/ui/App.cpp b/src/apps/haikudepot/ui/App.cpp index ceb677f05e..ef579ee292 100644 --- a/src/apps/haikudepot/ui/App.cpp +++ b/src/apps/haikudepot/ui/App.cpp @@ -1,6 +1,6 @@ /* * Copyright 2013, Stephan Aßmus . - * Copyright 2017-2020, Andrew Lindesay . + * Copyright 2017-2021, Andrew Lindesay . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -23,6 +23,7 @@ #include "support.h" +#include "AppUtils.h" #include "FeaturedPackagesView.h" #include "Logger.h" #include "MainWindow.h" @@ -87,12 +88,13 @@ App::ReadyToRun() BMessage settings; _LoadSettings(settings); - if (!_CheckTestFile()) - { + if (!_CheckTestFile()) { Quit(); return; } + _ClearCacheOnVersionChange(); + fMainWindow = new MainWindow(settings); _ShowWindow(fMainWindow); } @@ -582,3 +584,62 @@ App::_CheckTestFile() return true; } + + +/*! This method will check to see if the version of the application has changed. + If it has changed then it will delete all of the contents of the cache + directory. This will mean that when application logic changes, it need not + bother to migrate the cached files. Also any old cached files will be + cleared out that no longer serve any purpose. + + Errors arising in this logic need not prevent the application from failing + to start as this is just a clean-up. +*/ + +void +App::_ClearCacheOnVersionChange() +{ + BString version; + + if (AppUtils::GetAppVersionString(version) != B_OK) { + HDERROR("clear cache; unable to get the application version"); + return; + } + + BPath lastVersionPath; + if (StorageUtils::LocalWorkingFilesPath( + "version.txt", lastVersionPath) != B_OK) { + HDERROR("clear cache; unable to get version file path"); + return; + } + + bool exists; + off_t size; + + if (StorageUtils::ExistsObject( + lastVersionPath, &exists, NULL, &size) != B_OK) { + HDERROR("clear cache; unable to check version file exists"); + return; + } + + BString lastVersion; + + if (exists && StorageUtils::AppendToString(lastVersionPath, lastVersion) + != B_OK) { + HDERROR("clear cache; unable to read the version from [%s]", + lastVersionPath.Path()); + return; + } + + if (lastVersion != version) { + HDINFO("last version [%s] and current version [%s] do not match" + " -> will flush cache", lastVersion.String(), version.String()); + StorageUtils::RemoveWorkingDirectoryContents(); + HDINFO("will write version [%s] to [%s]", + version.String(), lastVersionPath.Path()); + StorageUtils::AppendToFile(version, lastVersionPath); + } else { + HDINFO("last version [%s] and current version [%s] match" + " -> cache retained", lastVersion.String(), version.String()); + } +} diff --git a/src/apps/haikudepot/ui/App.h b/src/apps/haikudepot/ui/App.h index 05bba7d784..bdd890b2bc 100644 --- a/src/apps/haikudepot/ui/App.h +++ b/src/apps/haikudepot/ui/App.h @@ -1,6 +1,6 @@ /* * Copyright 2013, Stephan Aßmus . - * Copyright 2018-2020, Andrew Lindesay + * Copyright 2018-2021, Andrew Lindesay * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef APP_H @@ -40,6 +40,7 @@ private: bool _CheckTestFile(); static bool _CheckIsFirstRun(); + void _ClearCacheOnVersionChange(); private: MainWindow* fMainWindow; diff --git a/src/apps/haikudepot/util/AppUtils.cpp b/src/apps/haikudepot/util/AppUtils.cpp index b4d39351c3..5e5b6675cc 100644 --- a/src/apps/haikudepot/util/AppUtils.cpp +++ b/src/apps/haikudepot/util/AppUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020, Andrew Lindesay . + * Copyright 2018-2021, Andrew Lindesay . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -8,8 +8,10 @@ #include +#include #include #include +#include #include #include "HaikuDepotConstants.h" @@ -86,3 +88,36 @@ AppUtils::GetCodeAtIndexInMenu(BMenu* menu, int32 index, BString* result) return B_ERROR; return itemMessage->FindString("code", result); } + + +/*static*/ status_t +AppUtils::GetAppVersionString(BString& result) +{ + app_info info; + + if (be_app->GetAppInfo(&info) != B_OK) { + HDERROR("Unable to get the application info"); + return B_ERROR; + } + + BFile file(&info.ref, B_READ_ONLY); + + if (file.InitCheck() != B_OK) { + HDERROR("Unable to access the application info file"); + return B_ERROR; + } + + BAppFileInfo appFileInfo(&file); + version_info versionInfo; + + if (appFileInfo.GetVersionInfo( + &versionInfo, B_APP_VERSION_KIND) != B_OK) { + HDERROR("Unable to establish the application version"); + return B_ERROR; + } + + result.SetToFormat("%" B_PRId32 ".%" B_PRId32 ".%" B_PRId32, + versionInfo.major, versionInfo.middle, versionInfo.minor); + + return B_OK; +} diff --git a/src/apps/haikudepot/util/AppUtils.h b/src/apps/haikudepot/util/AppUtils.h index 02fdf3b34a..c05b180f1f 100644 --- a/src/apps/haikudepot/util/AppUtils.h +++ b/src/apps/haikudepot/util/AppUtils.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020, Andrew Lindesay . + * Copyright 2018-2021, Andrew Lindesay . * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef APP_UTILS_H @@ -22,6 +22,8 @@ public: static int32 IndexOfCodeInMenu(const BString& code, BMenu* menu); static status_t GetCodeAtIndexInMenu(BMenu* menu, int32 index, BString* result); + + static status_t GetAppVersionString(BString& result); }; diff --git a/src/apps/haikudepot/util/StorageUtils.cpp b/src/apps/haikudepot/util/StorageUtils.cpp index 4425ba465f..e51cb7aacc 100644 --- a/src/apps/haikudepot/util/StorageUtils.cpp +++ b/src/apps/haikudepot/util/StorageUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2017-2020, Andrew Lindesay . + * Copyright 2017-2021, Andrew Lindesay . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -41,8 +41,8 @@ StorageUtils::SetWorkingFilesUnavailable() * string provided. */ -status_t -StorageUtils::AppendToString(BPath& path, BString& result) +/*static*/ status_t +StorageUtils::AppendToString(const BPath& path, BString& result) { BFile file(path.Path(), O_RDONLY); uint8_t buffer[FILE_TO_STRING_BUFFER_LEN]; @@ -55,6 +55,46 @@ StorageUtils::AppendToString(BPath& path, BString& result) } +/*static*/ status_t +StorageUtils::AppendToFile(const BString& input, const BPath& path) +{ + BFile file(path.Path(), O_WRONLY | O_CREAT | O_APPEND); + const char* cstr = input.String(); + size_t cstrLen = strlen(cstr); + return file.WriteExactly(cstr, cstrLen); +} + + +/*static*/ status_t +StorageUtils::RemoveWorkingDirectoryContents() +{ + BPath path; + status_t result = B_OK; + + if (result == B_OK) + result = find_directory(B_USER_CACHE_DIRECTORY, &path); + if (result == B_OK) + result = path.Append(CACHE_DIRECTORY_APP); + + bool exists; + bool isDirectory; + + if (result == B_OK) + result = ExistsObject(path, &exists, &isDirectory, NULL); + + if (result == B_OK && exists && !isDirectory) { + HDERROR("the working directory at [%s] is not a directory", + path.Path()); + result = B_ERROR; + } + + if (result == B_OK && exists) + result = RemoveDirectoryContents(path); + + return result; +} + + /* This method will traverse the directory structure and will remove all of the * files that are present in the directories as well as the directories * themselves. @@ -85,9 +125,10 @@ StorageUtils::RemoveDirectoryContents(BPath& path) if (isDirectory) RemoveDirectoryContents(directoryEntryPath); - if (remove(directoryEntryPath.Path()) == 0) - HDDEBUG("did delete [%s]", directoryEntryPath.Path()); - else { + if (remove(directoryEntryPath.Path()) == 0) { + HDDEBUG("did delete contents under [%s]", + directoryEntryPath.Path()); + } else { HDERROR("unable to delete [%s]", directoryEntryPath.Path()); result = B_ERROR; } @@ -305,4 +346,4 @@ StorageUtils::SwapExtensionOnPathComponent(const char* pathComponent, result.Append("."); result.Append(extension); return result; -} \ No newline at end of file +} diff --git a/src/apps/haikudepot/util/StorageUtils.h b/src/apps/haikudepot/util/StorageUtils.h index 2860c38464..6decbc0b68 100644 --- a/src/apps/haikudepot/util/StorageUtils.h +++ b/src/apps/haikudepot/util/StorageUtils.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2020, Andrew Lindesay . + * Copyright 2017-2021, Andrew Lindesay . * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef PATH_UTILS_H @@ -22,8 +22,12 @@ public: static status_t CheckCanWriteTo(const BPath& path); + static status_t AppendToString(const BPath& path, BString& result); + static status_t AppendToFile(const BString& input, + const BPath& path); + + static status_t RemoveWorkingDirectoryContents(); static status_t RemoveDirectoryContents(BPath& path); - static status_t AppendToString(BPath& path, BString& result); static status_t ExistsObject(const BPath& path, bool* exists, bool* isDirectory,