Remove special handling of config directory on linux (#8848)

Instead store the preferences, credentials, and lua command history files in the userdata folder, same as is done on windows and macos.

Also removes another instance of _X11 for #8806
This commit is contained in:
Pentarctagon 2024-05-06 21:57:29 -05:00 committed by GitHub
parent 03a46f1d7c
commit 78f3eb821a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 101 additions and 47 deletions

View file

@ -668,6 +668,7 @@ bfs::path windows_userdata(const std::string& newprefdir)
#ifdef PREFERENCES_DIR
if(temp.empty()) {
temp = PREFERENCES_DIR;
DBG_FS << "Using PREFERENCES_DIR '" << PREFERENCES_DIR << "'";
}
#endif
@ -678,12 +679,15 @@ bfs::path windows_userdata(const std::string& newprefdir)
if(temp.size() > 2 && temp[1] == ':') {
// allow absolute path override
dir = temp;
DBG_FS << "custom userdata folder - absolute path";
} else if(is_path_relative_to_cwd(temp)) {
// Custom directory relative to workdir (for portable installs, etc.)
dir = get_cwd() + "/" + temp;
DBG_FS << "userdata relative to current working directory";
} else {
if(temp.empty()) {
temp = "Wesnoth" + get_version_path_suffix();
DBG_FS << "using default userdata folder name";
} else {
// only warn about a relative path if it comes from the command line option, not from the PREFERENCES_DIR define
#ifdef PREFERENCES_DIR
@ -714,6 +718,7 @@ bfs::path windows_userdata(const std::string& newprefdir)
create_directory_if_missing(games_path);
dir = games_path / temp;
DBG_FS << "userdata is under My Games";
}
CoTaskMemFree(docs_path);
@ -735,8 +740,10 @@ bfs::path apple_userdata(const std::string& newprefdir)
if(temp.empty()) {
#ifdef PREFERENCES_DIR
temp = PREFERENCES_DIR;
DBG_FS << "userdata using PREFERENCES_DIR '" << PREFERENCES_DIR << "'";
if(home_str && temp[0] == '~') {
temp = home_str + temp.substr(1);
DBG_FS << "userdata is relative to HOME";
}
#elif defined(WESNOTH_BOOST_OS_IOS)
char *sdl_pref_path = SDL_GetPrefPath("wesnoth.org", "iWesnoth");
@ -744,8 +751,10 @@ bfs::path apple_userdata(const std::string& newprefdir)
temp = std::string(sdl_pref_path) + ".wesnoth" + get_version_path_suffix();
SDL_free(sdl_pref_path);
}
DBG_FS << "userdata using SDL pref path";
#else
temp = "Library/Application Support/Wesnoth_"+get_version_path_suffix();
DBG_FS << "userdata using default path relative to HOME";
#endif
} else if(temp[0] != '/') {
// TRANSLATORS: translate the part inside <...> only
@ -777,8 +786,10 @@ bfs::path linux_userdata(const std::string& newprefdir)
#ifdef PREFERENCES_DIR
if(temp.empty()) {
temp = PREFERENCES_DIR;
DBG_FS << "userdata using PREFERENCES_DIR '" << PREFERENCES_DIR << "'";
if(home_str && temp[0] == '~') {
temp = home_str + temp.substr(1);
DBG_FS << "userdata is relative to HOME";
}
}
#endif
@ -789,9 +800,11 @@ bfs::path linux_userdata(const std::string& newprefdir)
if(temp.empty() && ((xdg_data && xdg_data[0] != '\0') || home_str)) {
if(xdg_data && xdg_data[0] != '\0') {
dir = xdg_data;
DBG_FS << "userdata using XDG_DATA_HOME";
} else if(home_str) {
dir = home_str;
dir /= ".local/share";
DBG_FS << "userdata using HOME";
}
dir /= "wesnoth";
@ -802,6 +815,7 @@ bfs::path linux_userdata(const std::string& newprefdir)
// if a custom userdata dir using an absolute path was specified, just use that
if(!temp.empty() && temp[0] == '/') {
dir = temp;
DBG_FS << "userdata is an absolute path";
return dir;
}
@ -821,6 +835,7 @@ bfs::path linux_userdata(const std::string& newprefdir)
_("Use absolute paths. Relative paths are deprecated because they are interpreted relative to $HOME"));
} else {
dir = ".";
DBG_FS << "userdata unable to determine location to use, defaulting to current working directory";
}
dir /= temp;
@ -892,27 +907,7 @@ static const bfs::path& get_user_data_path()
std::string get_user_config_dir()
{
if(user_config_dir.empty()) {
#if defined(_X11) && !defined(PREFERENCES_DIR)
char const* xdg_config = getenv("XDG_CONFIG_HOME");
if(!xdg_config || xdg_config[0] == '\0') {
xdg_config = getenv("HOME");
if(!xdg_config) {
user_config_dir = get_user_data_path();
return user_config_dir.string();
}
user_config_dir = xdg_config;
user_config_dir /= ".config";
} else {
user_config_dir = xdg_config;
}
user_config_dir /= "wesnoth";
set_user_config_path(user_config_dir);
#else
user_config_dir = get_user_data_path();
#endif
}
return user_config_dir.string();

View file

@ -112,36 +112,26 @@ void migrate_version_selection::post_show(window& window)
}
}
if(migrate_prefs_file != filesystem::get_prefs_file() && filesystem::file_exists(migrate_prefs_file)) {
// if the file doesn't exist, just copy the file over
// else need to merge the preferences file
if(!filesystem::file_exists(filesystem::get_prefs_file())) {
filesystem::copy_file(migrate_prefs_file, filesystem::get_prefs_file());
} else {
config current_cfg;
filesystem::scoped_istream current_stream = filesystem::istream_file(filesystem::get_prefs_file(), false);
read(current_cfg, *current_stream);
config old_cfg;
filesystem::scoped_istream old_stream = filesystem::istream_file(migrate_prefs_file, false);
read(old_cfg, *old_stream);
#if !defined(_WIN32) && !defined(__APPLE__)
bool already_migrated = false;
std::string linux_old_config_dir = old_config_dir();
std::string old_migrate_prefs_file = linux_old_config_dir + "/preferences";
std::string old_migrate_credentials_file = linux_old_config_dir + "/credentials-aes";
// when both files have the same attribute, use the one from whichever was most recently modified
bool current_prefs_are_older = filesystem::file_modified_time(filesystem::get_prefs_file()) < filesystem::file_modified_time(migrate_prefs_file);
for(const config::attribute& val : old_cfg.attribute_range()) {
if(current_prefs_are_older || !current_cfg.has_attribute(val.first)) {
preferences::set(val.first, val.second);
}
}
// don't touch child tags
preferences::write_preferences();
}
if(filesystem::file_exists(old_migrate_prefs_file)) {
already_migrated = true;
migrate_preferences(old_migrate_prefs_file);
}
if(filesystem::file_exists(old_migrate_credentials_file)) {
already_migrated = true;
migrate_credentials(old_migrate_credentials_file);
}
// don't touch the credentials file on migrator re-run if it already exists
if(migrate_credentials_file != filesystem::get_credentials_file() && filesystem::file_exists(migrate_credentials_file) && !filesystem::file_exists(filesystem::get_credentials_file())) {
filesystem::copy_file(migrate_credentials_file, filesystem::get_credentials_file());
if(!already_migrated)
#endif
{
migrate_preferences(migrate_prefs_file);
migrate_credentials(migrate_credentials_file);
}
// reload preferences and credentials
@ -151,4 +141,69 @@ void migrate_version_selection::post_show(window& window)
preferences::load_credentials();
}
}
/**
* Prior to 1.19 linux installs would usually store the credentials and preferences file under XDG_CONFIG_HOME with no version separation.
* That special handling has been removed, but still needs to be accounted for when migrating
*/
std::string migrate_version_selection::old_config_dir()
{
char const* xdg_config = getenv("XDG_CONFIG_HOME");
std::string old_config_dir;
if(!xdg_config || xdg_config[0] == '\0') {
xdg_config = getenv("HOME");
if(!xdg_config) {
old_config_dir = filesystem::get_user_data_dir();
return old_config_dir;
}
old_config_dir = xdg_config;
old_config_dir += "/.config";
} else {
old_config_dir = xdg_config;
}
old_config_dir += "/wesnoth";
return old_config_dir;
}
void migrate_version_selection::migrate_preferences(const std::string& migrate_prefs_file)
{
if(migrate_prefs_file != filesystem::get_prefs_file() && filesystem::file_exists(migrate_prefs_file)) {
// if the file doesn't exist, just copy the file over
// else need to merge the preferences file
if(!filesystem::file_exists(filesystem::get_prefs_file())) {
filesystem::copy_file(migrate_prefs_file, filesystem::get_prefs_file());
} else {
config current_cfg;
filesystem::scoped_istream current_stream = filesystem::istream_file(filesystem::get_prefs_file(), false);
read(current_cfg, *current_stream);
config old_cfg;
filesystem::scoped_istream old_stream = filesystem::istream_file(migrate_prefs_file, false);
read(old_cfg, *old_stream);
// when both files have the same attribute, use the one from whichever was most recently modified
bool current_prefs_are_older = filesystem::file_modified_time(filesystem::get_prefs_file()) < filesystem::file_modified_time(migrate_prefs_file);
for(const config::attribute& val : old_cfg.attribute_range()) {
if(current_prefs_are_older || !current_cfg.has_attribute(val.first)) {
preferences::set(val.first, val.second);
}
}
// don't touch child tags
preferences::write_preferences();
}
}
}
void migrate_version_selection::migrate_credentials(const std::string& migrate_credentials_file)
{
// don't touch the credentials file on migrator re-run if it already exists
if(migrate_credentials_file != filesystem::get_credentials_file() && filesystem::file_exists(migrate_credentials_file) && !filesystem::file_exists(filesystem::get_credentials_file())) {
filesystem::copy_file(migrate_credentials_file, filesystem::get_credentials_file());
}
}
} // namespace gui2::dialogs

View file

@ -32,6 +32,10 @@ private:
virtual void post_show(window& window) override;
virtual const std::string& window_id() const override;
std::string old_config_dir();
void migrate_preferences(const std::string& prefs_dir);
void migrate_credentials(const std::string& credentials_dir);
std::vector<std::string> versions_;
};
} // namespace gui2::dialogs