Repository: lra/mackup

Issue:
Box Sync ignores files that start with a dot
Mackup creates the backup folder in the Box Sync local folder properly and all dot files (.bash_profile, .bashrc, .gitconfig, etc.) are copied there but they are never synced to Box, which means that after the local Box Sync folder is deleted, the dot files will not be restored from Box.

This is due to Box Sync ignoring files that start with a dot "." as hidden files.

Documented here: [https://community.box.com/t5/Box-Sync/Which-File-Types-Are-Ignored-Or-Blocked-In-Box-Sync/ta-p/117](https://community.box.com/t5/Box-Sync/Which-File-Types-Are-Ignored-Or-Blocked-In-Box-Sync/ta-p/117)

The way around this could involve copying the files to names that do not start with a dot and creating symlinks back to the original dot file names, e.g., .bashrc -> Box Sync/Mackup/bashrc.txt



Discussion:
Wow, that's really stupid...

OK, I guess the box engine needs to rename those files to something line `.bashrc -> box_dot_bashrc_`.
That could work for individual files, but if a linked folder contains dotfiles, mackup cannot help here.

Not sure if there are a lot of dotfiles in folders, but it's a possible source of bugs and confusion.

Also what about dot folders? Same behavior? Sounds like there is no easy fix on mackup side. Is there a way to ask box if they could make this an option? (ignoring dot files)

It looks messy to implement. Given that Dropbox is ok with dotfiles, am happy to close this as a dontfix and take it up with Box.

The problem is that it's a valid issue... Should we just drop Box's support?

Dropping Box support would suffice, but leave a note as to why, it's going to become a frequently asked question. 👍 

Just realized this is why my preferences were always out of sync between my Macs. This issue really needs to be added to the readme. Box is listed as "Supported Storage", but in real-world usage it won't work properly.
Are there any updates that might make this work? Box is still listed as Supported Storage.

Resolving patch:
diff --git a/mackup/config.py b/mackup/config.py
--- a/mackup/config.py
+++ b/mackup/config.py
@@ -11,7 +11,6 @@
     ENGINE_GDRIVE,
     ENGINE_COPY,
     ENGINE_ICLOUD,
-    ENGINE_BOX,
     ENGINE_FS,
 )
 
@@ -21,7 +20,6 @@
     get_copy_folder_location,
     get_google_drive_folder_location,
     get_icloud_folder_location,
-    get_box_folder_location,
 )
 
 try:
@@ -70,8 +68,7 @@ def engine(self):
         """
         The engine used by the storage.
 
-        ENGINE_DROPBOX, ENGINE_GDRIVE, ENGINE_COPY, ENGINE_ICLOUD, ENGINE_BOX
-        or ENGINE_FS.
+        ENGINE_DROPBOX, ENGINE_GDRIVE, ENGINE_COPY, ENGINE_ICLOUD or ENGINE_FS.
 
         Returns:
             str
@@ -194,7 +191,6 @@ def _parse_engine(self):
             ENGINE_GDRIVE,
             ENGINE_COPY,
             ENGINE_ICLOUD,
-            ENGINE_BOX,
             ENGINE_FS,
         ]:
             raise ConfigError("Unknown storage engine: {}".format(engine))
@@ -216,8 +212,6 @@ def _parse_path(self):
             path = get_copy_folder_location()
         elif self.engine == ENGINE_ICLOUD:
             path = get_icloud_folder_location()
-        elif self.engine == ENGINE_BOX:
-            path = get_box_folder_location()
         elif self.engine == ENGINE_FS:
             if self._parser.has_option("storage", "path"):
                 cfg_path = self._parser.get("storage", "path")
diff --git a/mackup/constants.py b/mackup/constants.py
--- a/mackup/constants.py
+++ b/mackup/constants.py
@@ -22,7 +22,6 @@
 CUSTOM_APPS_DIR = ".mackup"
 
 # Supported engines
-ENGINE_BOX = "box"
 ENGINE_COPY = "copy"
 ENGINE_DROPBOX = "dropbox"
 ENGINE_FS = "file_system"
diff --git a/mackup/utils.py b/mackup/utils.py
--- a/mackup/utils.py
+++ b/mackup/utils.py
@@ -246,27 +246,6 @@ def get_google_drive_folder_location():
     return googledrive_home
 
 
-def get_box_folder_location():
-    """
-    Try to locate the Box folder.
-
-    Returns:
-        (str) Full path to the current Box folder
-    """
-    box_prefs_path = "Library/Application Support/Box/Box Sync/" "sync_root_folder.txt"
-    box_home = None
-
-    box_prefs = os.path.join(os.environ["HOME"], box_prefs_path)
-    try:
-        with open(box_prefs, "r") as sync_path:
-            data = sync_path.read()
-            box_home = data
-    except IOError:
-        error("Unable to find your Box prefs =(")
-
-    return box_home
-
-
 def get_copy_folder_location():
     """
     Try to locate the Copy folder.


Test patch:
diff --git a/tests/config_tests.py b/tests/config_tests.py
--- a/tests/config_tests.py
+++ b/tests/config_tests.py
@@ -6,7 +6,6 @@
     ENGINE_GDRIVE,
     ENGINE_COPY,
     ENGINE_ICLOUD,
-    ENGINE_BOX,
     ENGINE_FS,
 )
 from mackup.config import Config, ConfigError
@@ -169,24 +168,6 @@ def test_config_engine_icloud(self):
         assert cfg.apps_to_ignore == set(["subversion", "sequel-pro", "sabnzbd"])
         assert cfg.apps_to_sync == set(["sublime-text-3", "x11", "sabnzbd"])
 
-    def test_config_engine_box(self):
-        cfg = Config("mackup-engine-box.cfg")
-
-        assert isinstance(cfg.engine, str)
-        assert cfg.engine == ENGINE_BOX
-
-        assert isinstance(cfg.path, str)
-        assert cfg.path == u"/Users/whatever/Box Sync"
-
-        assert isinstance(cfg.directory, str)
-        assert cfg.directory == u"some_weirder_name"
-
-        assert isinstance(cfg.fullpath, str)
-        assert cfg.fullpath == u"/Users/whatever/Box Sync/some_weirder_name"
-
-        assert cfg.apps_to_ignore == set()
-        assert cfg.apps_to_sync == set()
-
     def test_config_engine_filesystem_no_path(self):
         with self.assertRaises(ConfigError):
             Config("mackup-engine-file_system-no_path.cfg")
diff --git a/tests/fixtures/mackup-engine-box.cfg b/tests/fixtures/mackup-engine-box.cfg
deleted file mode 100644
--- a/tests/fixtures/mackup-engine-box.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-[storage]
-engine = box
-directory = some_weirder_name
diff --git a/tests/utils_test.py b/tests/utils_test.py
--- a/tests/utils_test.py
+++ b/tests/utils_test.py
@@ -279,7 +279,7 @@ def test_error(self):
     def test_failed_backup_location(self):
         """
         Tests for the error that should occur if the backup folder cannot be
-        found for Dropbox, Google, Box and Copy
+        found for Dropbox, Google, and Copy
         """
         # Hack to make our home folder some temporary folder
         temp_home = tempfile.mkdtemp()
@@ -297,15 +297,6 @@ def test_failed_backup_location(self):
         )
         self.assertRaises(SystemExit, utils.get_google_drive_folder_location)
 
-        # Check for the missing Box folder
-        assert not os.path.exists(
-            os.path.join(
-                temp_home,
-                "Library/Application Support/Box/Box Sync/sync_root_folder.txt",
-            )
-        )
-        self.assertRaises(SystemExit, utils.get_box_folder_location)
-
         # Check for the missing Copy Folder
         assert not os.path.exists(
             os.path.join(temp_home, "Library/Application Support/Copy Agent/config.db")