mirror of https://github.com/borgbackup/borg.git
implement /./relpath hack, fixes #1655
This commit is contained in:
parent
12a127ace1
commit
e829e8372d
|
@ -835,26 +835,32 @@ class Location:
|
|||
return True
|
||||
|
||||
def _parse(self, text):
|
||||
def normpath_special(p):
|
||||
# avoid that normpath strips away our relative path hack and even makes p absolute
|
||||
relative = p.startswith('/./')
|
||||
p = os.path.normpath(p)
|
||||
return ('/.' + p) if relative else p
|
||||
|
||||
m = self.ssh_re.match(text)
|
||||
if m:
|
||||
self.proto = m.group('proto')
|
||||
self.user = m.group('user')
|
||||
self.host = m.group('host')
|
||||
self.port = m.group('port') and int(m.group('port')) or None
|
||||
self.path = os.path.normpath(m.group('path'))
|
||||
self.path = normpath_special(m.group('path'))
|
||||
self.archive = m.group('archive')
|
||||
return True
|
||||
m = self.file_re.match(text)
|
||||
if m:
|
||||
self.proto = m.group('proto')
|
||||
self.path = os.path.normpath(m.group('path'))
|
||||
self.path = normpath_special(m.group('path'))
|
||||
self.archive = m.group('archive')
|
||||
return True
|
||||
m = self.scp_re.match(text)
|
||||
if m:
|
||||
self.user = m.group('user')
|
||||
self.host = m.group('host')
|
||||
self.path = os.path.normpath(m.group('path'))
|
||||
self.path = normpath_special(m.group('path'))
|
||||
self.archive = m.group('archive')
|
||||
self.proto = self.host and 'ssh' or 'file'
|
||||
return True
|
||||
|
@ -885,9 +891,9 @@ class Location:
|
|||
return self.path
|
||||
else:
|
||||
if self.path and self.path.startswith('~'):
|
||||
path = '/' + self.path
|
||||
path = '/' + self.path # /~/x = path x relative to home dir
|
||||
elif self.path and not self.path.startswith('/'):
|
||||
path = '/~/' + self.path
|
||||
path = '/./' + self.path # /./x = path x relative to cwd
|
||||
else:
|
||||
path = self.path
|
||||
return 'ssh://{}{}{}{}'.format('{}@'.format(self.user) if self.user else '',
|
||||
|
|
|
@ -129,8 +129,10 @@ class RepositoryServer: # pragma: no cover
|
|||
|
||||
def open(self, path, create=False, lock_wait=None, lock=True, exclusive=None, append_only=False):
|
||||
path = os.fsdecode(path)
|
||||
if path.startswith('/~'):
|
||||
if path.startswith('/~'): # /~/x = path x relative to home dir, /~username/x = relative to "user" home dir
|
||||
path = path[1:]
|
||||
elif path.startswith('/./'): # /./x = path x relative to cwd
|
||||
path = path[3:]
|
||||
path = os.path.realpath(os.path.expanduser(path))
|
||||
if self.restrict_to_paths:
|
||||
# if --restrict-to-path P is given, we make sure that we only operate in/below path P.
|
||||
|
|
|
@ -69,6 +69,8 @@ class TestLocationWithoutEnv:
|
|||
"Location(proto='file', user=None, host=None, port=None, path='/some/absolute/path', archive='archive')"
|
||||
assert repr(Location('/some/absolute/path')) == \
|
||||
"Location(proto='file', user=None, host=None, port=None, path='/some/absolute/path', archive=None)"
|
||||
assert repr(Location('ssh://user@host/some/path')) == \
|
||||
"Location(proto='ssh', user='user', host='host', port=None, path='/some/path', archive=None)"
|
||||
|
||||
def test_relpath(self, monkeypatch):
|
||||
monkeypatch.delenv('BORG_REPO', raising=False)
|
||||
|
@ -76,6 +78,12 @@ class TestLocationWithoutEnv:
|
|||
"Location(proto='file', user=None, host=None, port=None, path='some/relative/path', archive='archive')"
|
||||
assert repr(Location('some/relative/path')) == \
|
||||
"Location(proto='file', user=None, host=None, port=None, path='some/relative/path', archive=None)"
|
||||
assert repr(Location('ssh://user@host/./some/path')) == \
|
||||
"Location(proto='ssh', user='user', host='host', port=None, path='/./some/path', archive=None)"
|
||||
assert repr(Location('ssh://user@host/~/some/path')) == \
|
||||
"Location(proto='ssh', user='user', host='host', port=None, path='/~/some/path', archive=None)"
|
||||
assert repr(Location('ssh://user@host/~user/some/path')) == \
|
||||
"Location(proto='ssh', user='user', host='host', port=None, path='/~user/some/path', archive=None)"
|
||||
|
||||
def test_with_colons(self, monkeypatch):
|
||||
monkeypatch.delenv('BORG_REPO', raising=False)
|
||||
|
@ -107,7 +115,7 @@ class TestLocationWithoutEnv:
|
|||
'ssh://user@host:1234/some/path::archive']
|
||||
for location in locations:
|
||||
assert Location(location).canonical_path() == \
|
||||
Location(Location(location).canonical_path()).canonical_path()
|
||||
Location(Location(location).canonical_path()).canonical_path(), "failed: %s" % location
|
||||
|
||||
def test_format_path(self, monkeypatch):
|
||||
monkeypatch.delenv('BORG_REPO', raising=False)
|
||||
|
|
Loading…
Reference in New Issue