Browse Source

ensure valid file urls are created from windows paths

valtron 1 week ago
parent
commit
fcc5a5beff
1 changed files with 15 additions and 2 deletions
  1. 15 2
      src/borg/repository.py

+ 15 - 2
src/borg/repository.py

@@ -1,4 +1,5 @@
 import os
+import sys
 import time
 
 from borgstore.store import Store
@@ -105,11 +106,11 @@ class Repository:
         if isinstance(path_or_location, Location):
             location = path_or_location
             if location.proto == "file":
-                url = f"file://{location.path}"  # frequently users give without file:// prefix
+                url = _local_abspath_to_file_url(location.path)  # frequently users give without file:// prefix
             else:
                 url = location.processed  # location as given by user, processed placeholders
         else:
-            url = "file://%s" % os.path.abspath(path_or_location)
+            url = _local_abspath_to_file_url(os.path.abspath(path_or_location))
             location = Location(url)
         self._location = location
         self.url = url
@@ -565,3 +566,15 @@ class Repository:
     def store_move(self, name, new_name=None, *, delete=False, undelete=False, deleted=False):
         self._lock_refresh()
         return self.store.move(name, new_name, delete=delete, undelete=undelete, deleted=deleted)
+
+def _local_abspath_to_file_url(path: str) -> str:
+    """Create a file URL from a local, absolute path.
+    
+    Expects `path` to be an absolute path on the local filesystem, e.g.:
+    - POSIX: `/foo/bar`
+    - Windows: `c:/foo/bar` (or `c:\foo\bar`)
+    The easiest way to ensure this is for the caller to pass `path` through `os.path.abspath` first.
+    """
+    if sys.platform in ("win32", "msys", "cygwin"):
+        path = "/" + path.replace("\\", "/")
+    return "file://%s" % path