77
76
This assumes that both paths are already fully specified file:// URLs.
79
if len(base) < MIN_ABS_FILEURL_LENGTH:
80
raise ValueError('Length of base must be equal or'
81
' exceed the platform minimum url length (which is %d)' %
82
MIN_ABS_FILEURL_LENGTH)
78
assert len(base) >= MIN_ABS_FILEURL_LENGTH, ('Length of base must be equal or'
79
' exceed the platform minimum url length (which is %d)' %
80
MIN_ABS_FILEURL_LENGTH)
83
82
base = local_path_from_url(base)
84
83
path = local_path_from_url(path)
85
84
return escape(osutils.relpath(base, path))
250
249
raise errors.InvalidURL(url, 'Win32 UNC path urls'
251
250
' have form file://HOST/path')
252
251
return unescape(win32_url)
254
# allow empty paths so we can serve all roots
255
if win32_url == '///':
258
252
# usual local path with drive letter
259
253
if (win32_url[3] not in ('abcdefghijklmnopqrstuvwxyz'
260
254
'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
276
270
# which actually strips trailing space characters.
277
271
# The worst part is that under linux ntpath.abspath has different
278
272
# semantics, since 'nt' is not an available module.
282
273
win32_path = osutils._win32_abspath(path)
283
274
# check for UNC path \\HOST\path
284
275
if win32_path.startswith('//'):
285
276
return 'file:' + escape(win32_path)
286
return ('file:///' + str(win32_path[0].upper()) + ':' +
287
escape(win32_path[2:]))
277
return 'file:///' + win32_path[0].upper() + ':' + escape(win32_path[2:])
290
280
local_path_to_url = _posix_local_path_to_url
380
370
other_scheme = other[:other_first_slash]
381
371
if base_scheme != other_scheme:
383
elif sys.platform == 'win32' and base_scheme == 'file://':
384
base_drive = base[base_first_slash+1:base_first_slash+3]
385
other_drive = other[other_first_slash+1:other_first_slash+3]
386
if base_drive != other_drive:
389
374
base_path = base[base_first_slash+1:]
390
375
other_path = other[other_first_slash+1:]
583
568
:return: A unicode string which can be safely encoded into the
584
569
specified encoding.
587
raise ValueError('you cannot specify None for the display encoding')
571
assert encoding is not None, 'you cannot specify None for the display encoding.'
588
572
if url.startswith('file://'):
590
574
path = local_path_from_url(url)
645
629
return from_location[sep+1:]
647
631
return from_location
650
def _is_absolute(url):
651
return (osutils.pathjoin('/foo', url) == url)
654
def rebase_url(url, old_base, new_base):
655
"""Convert a relative path from an old base URL to a new base URL.
657
The result will be a relative path.
658
Absolute paths and full URLs are returned unaltered.
660
scheme, separator = _find_scheme_and_separator(url)
661
if scheme is not None:
663
if _is_absolute(url):
665
old_parsed = urlparse.urlparse(old_base)
666
new_parsed = urlparse.urlparse(new_base)
667
if (old_parsed[:2]) != (new_parsed[:2]):
668
raise errors.InvalidRebaseURLs(old_base, new_base)
669
return determine_relative_path(new_parsed[2],
670
join(old_parsed[2], url))
673
def determine_relative_path(from_path, to_path):
674
"""Determine a relative path from from_path to to_path."""
675
from_segments = osutils.splitpath(from_path)
676
to_segments = osutils.splitpath(to_path)
678
for count, (from_element, to_element) in enumerate(zip(from_segments,
680
if from_element != to_element:
684
unique_from = from_segments[count:]
685
unique_to = to_segments[count:]
686
segments = (['..'] * len(unique_from) + unique_to)
687
if len(segments) == 0:
689
return osutils.pathjoin(*segments)