diff --git a/libgnucash/core-utils/gnc-filepath-utils.cpp b/libgnucash/core-utils/gnc-filepath-utils.cpp index 2cc52e2b51..0fb3de5736 100644 --- a/libgnucash/core-utils/gnc-filepath-utils.cpp +++ b/libgnucash/core-utils/gnc-filepath-utils.cpp @@ -504,6 +504,7 @@ get_userdata_home(bool create) gboolean gnc_filepath_init(gboolean create) { + userdata_is_home = userdata_is_tmp = false; auto gnc_userdata_home_exists = false; auto gnc_userdata_home_from_env = false; auto gnc_userdata_home_env = g_getenv("GNC_DATA_HOME"); @@ -559,7 +560,15 @@ gnc_filepath_init(gboolean create) * skip migrating to that location in the next step but that's * a good thing. */ - gnc_validate_directory(gnc_userdata_home, (create || userdata_is_tmp)); + try + { + gnc_validate_directory(gnc_userdata_home, (create || userdata_is_tmp)); + } + catch (const bfs::filesystem_error& ex) + { + g_warning("User data directory doesn't exist, yet the calling code requested not to create it. Proceed with caution.\n" + "(Error: %s)", ex.what()); + } } auto migrated = FALSE; @@ -567,11 +576,18 @@ gnc_filepath_init(gboolean create) migrated = copy_recursive(bfs::path (g_get_home_dir()) / ".gnucash", gnc_userdata_home); - /* Since we're in code that is only executed once.... - * Note these calls may throw and end the program! */ - gnc_validate_directory(gnc_userdata_home / "books", (create || userdata_is_tmp)); - gnc_validate_directory(gnc_userdata_home / "checks", (create || userdata_is_tmp)); - gnc_validate_directory(gnc_userdata_home / "translog", (create || userdata_is_tmp)); + /* Try to create the standard subdirectories for gnucash' user data */ + try + { + gnc_validate_directory(gnc_userdata_home / "books", (create || userdata_is_tmp)); + gnc_validate_directory(gnc_userdata_home / "checks", (create || userdata_is_tmp)); + gnc_validate_directory(gnc_userdata_home / "translog", (create || userdata_is_tmp)); + } + catch (const bfs::filesystem_error& ex) + { + g_warning("Default user data subdirectories don't exist, yet the calling code requested not to create them. Proceed with caution.\n" + "(Error: %s)", ex.what()); + } return migrated; } diff --git a/libgnucash/core-utils/test/test-userdata-dir.c b/libgnucash/core-utils/test/test-userdata-dir.c index 91259ac73b..dbc09fe793 100644 --- a/libgnucash/core-utils/test/test-userdata-dir.c +++ b/libgnucash/core-utils/test/test-userdata-dir.c @@ -26,6 +26,7 @@ #include #include +#include #include "test-stuff.h" #include "gnc-filepath-utils.h" #ifdef MAC_INTEGRATION @@ -149,9 +150,65 @@ main(int argc, char **argv) g_free(wantout); g_free(daout); } - g_free(home_dir); - g_free(tmp_dir); - /* Second run, after properly having called gnc_filepath_init */ + + /* Second run, with existing userdata_dir, but without the GnuCash subdir + This test can not be run on OS X or Windows, as our code is not using + XDG_DATA_HOME on these platforms */ +#ifndef MAC_INTEGRATION +#ifndef G_OS_WIN32 + userdata_dir = g_build_filename(home_dir, ".local", "share", (gchar *)NULL); + g_mkdir_with_parents(userdata_dir, 0750); + g_setenv("XDG_DATA_HOME", userdata_dir, TRUE); + gnc_filepath_init(FALSE); + for (i = 0; strs2[i].funcname != NULL; i++) + { + char *daout; + char *wantout; + + if (strs2[i].func_num == 0) + { + wantout = g_build_filename(userdata_dir, PACKAGE_NAME, "foo", + (gchar *)NULL); + daout = gnc_build_userdata_path("foo"); + } + else if (strs2[i].func_num == 1) + { + wantout = g_build_filename(userdata_dir, PACKAGE_NAME, strs2[i].output, "foo", + (gchar *)NULL); + daout = gnc_build_book_path("foo"); + } + else if (strs2[i].func_num == 2) + { + wantout = g_build_filename(userdata_dir, PACKAGE_NAME, strs2[i].output, "foo", + (gchar *)NULL); + daout = gnc_build_translog_path("foo"); + } + else // if (strs2[i].prefix_home == 3) + { + wantout = g_build_filename(userdata_dir, PACKAGE_NAME, strs2[i].output, "foo", + (gchar *)NULL); + daout = gnc_build_data_path("foo"); + } + + do_test_args(g_strcmp0(daout, wantout) == 0, + "gnc_build_x_path", + __FILE__, __LINE__, + "%s (%s) vs %s", daout, strs2[i].funcname, wantout); + g_free(wantout); + g_free(daout); + } + /* Remove intermediate directories again in order to test their automatic + * creation in the next test run */ + g_rmdir(userdata_dir); + g_free(userdata_dir); + userdata_dir = g_build_filename(home_dir, ".local", (gchar *)NULL); + g_rmdir(userdata_dir); + g_free(userdata_dir); +#endif +#endif + + /* Third run, with GNC_DATA_HOME not set and having run gnc_filepath_init */ + g_unsetenv("GNC_DATA_HOME"); gnc_filepath_init(TRUE); userdata_dir = test_get_userdatadir(); for (i = 0; strs2[i].funcname != NULL; i++) @@ -193,7 +250,7 @@ main(int argc, char **argv) } g_free(userdata_dir); - /* Third run, after setting GNC_DATA_HOME gnc_filepath_init */ + /* Fourth run, with GNC_DATA_HOME set and having run gnc_filepath_init */ gnc_data_home_dir = g_build_filename(home_dir, "Test", NULL); g_setenv("GNC_DATA_HOME", gnc_data_home_dir, TRUE); gnc_filepath_init(TRUE); @@ -235,6 +292,21 @@ main(int argc, char **argv) g_free(daout); } + /* Clean up the temporaries that were created for the GNC_DATA_HOME test run */ + g_free (home_dir); + g_free (tmp_dir); + tmp_dir = g_build_filename(gnc_data_home_dir, "data", (gchar *)NULL); + g_rmdir (tmp_dir); + g_free (tmp_dir); + tmp_dir = g_build_filename(gnc_data_home_dir, "translog", (gchar *)NULL); + g_rmdir (tmp_dir); + g_free (tmp_dir); + tmp_dir = g_build_filename(gnc_data_home_dir, "books", (gchar *)NULL); + g_rmdir (tmp_dir); + g_free (tmp_dir); + g_rmdir (gnc_data_home_dir); + g_free(gnc_data_home_dir); + print_test_results(); return get_rv(); }