gnucash master: Fix build failures if userdata_home exists but gnc_userdata_home doesn't

Geert Janssens gjanssens at code.gnucash.org
Tue Sep 26 06:38:21 EDT 2017


Updated	 via  https://github.com/Gnucash/gnucash/commit/d266ee34 (commit)
	from  https://github.com/Gnucash/gnucash/commit/4d59be7f (commit)



commit d266ee346c1ca770162bfae019df80963f9041a2
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Sep 26 12:37:33 2017 +0200

    Fix build failures if userdata_home exists but gnc_userdata_home  doesn't
    
    userdata_home is a different directory on each platform we support (default /home/janssege/.local/share on linux for example)
    and gnc_userdata_home is normally userdata_home/GnuCash.
    These directories may not always exist (yet) in all circumstances, so properly handle
    all of these possible situations.

diff --git a/libgnucash/core-utils/gnc-filepath-utils.cpp b/libgnucash/core-utils/gnc-filepath-utils.cpp
index 2cc52e2..0fb3de5 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 91259ac..dbc09fe 100644
--- a/libgnucash/core-utils/test/test-userdata-dir.c
+++ b/libgnucash/core-utils/test/test-userdata-dir.c
@@ -26,6 +26,7 @@
 #include <string.h>
 
 #include <glib.h>
+#include <glib/gstdio.h>
 #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();
 }



Summary of changes:
 libgnucash/core-utils/gnc-filepath-utils.cpp   | 28 +++++++--
 libgnucash/core-utils/test/test-userdata-dir.c | 80 ++++++++++++++++++++++++--
 2 files changed, 98 insertions(+), 10 deletions(-)



More information about the gnucash-changes mailing list