166
166
# importing directly from posixpath allows us to test this
167
167
# on non-posix platforms
168
return 'file://' + escape(_posix_normpath(
169
bzrlib.osutils._posix_abspath(path)))
168
from posixpath import normpath
169
return 'file://' + escape(normpath(bzrlib.osutils._posix_abspath(path)))
172
172
def _win32_local_path_from_url(url):
173
"""Convert a url like file:///C:/path/to/foo into C:/path/to/foo"""
173
"""Convert a url like file:///C|/path/to/foo into C:/path/to/foo"""
174
174
if not url.startswith('file:///'):
175
175
raise errors.InvalidURL(url, 'local urls must start with file:///')
176
176
# We strip off all 3 slashes
177
177
win32_url = url[len('file:///'):]
178
if (win32_url[0] not in ('abcdefghijklmnopqrstuvwxyz'
179
'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
178
if (win32_url[0] not in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
180
179
or win32_url[1] not in '|:'
181
180
or win32_url[2] != '/'):
182
raise errors.InvalidURL(url, 'Win32 file urls start with'
183
' file:///x:/, where x is a valid drive letter')
184
# Preferentially using .lower() because os.getcwd() returns
185
# paths with lowercase drive letters, and that helps
186
# bzrlib.osutils.relpath() work correctly
181
raise errors.InvalidURL(url, 'Win32 file urls start with file:///X|/, where X is a valid drive letter')
182
# TODO: jam 20060426, we could .upper() or .lower() the drive letter
183
# for better consistency.
187
184
return win32_url[0].upper() + u':' + unescape(win32_url[2:])
190
187
def _win32_local_path_to_url(path):
191
"""Convert a local path like ./foo into a URL like file:///C:/path/to/foo
188
"""Convert a local path like ./foo into a URL like file:///C|/path/to/foo
193
190
This also handles transforming escaping unicode characters, etc.
195
192
# importing directly from ntpath allows us to test this
196
# on non-win32 platform
197
# FIXME: It turns out that on nt, ntpath.abspath uses nt._getfullpathname
198
# which actually strips trailing space characters.
199
# The worst part is that under linux ntpath.abspath has different
200
# semantics, since 'nt' is not an available module.
193
# on non-win32 platforms
201
194
win32_path = bzrlib.osutils._nt_normpath(
202
195
bzrlib.osutils._win32_abspath(path)).replace('\\', '/')
203
196
return 'file:///' + win32_path[0].upper() + ':' + escape(win32_path[2:])
206
199
local_path_to_url = _posix_local_path_to_url
207
200
local_path_from_url = _posix_local_path_from_url
208
201
MIN_ABS_FILEURL_LENGTH = len('file:///')
209
WIN32_MIN_ABS_FILEURL_LENGTH = len('file:///C:/')
202
WIN32_MIN_ABS_FILEURL_LENGTH = len('file:///C|/')
211
204
if sys.platform == 'win32':
212
205
local_path_to_url = _win32_local_path_to_url
383
376
file:///foo/ => file:///foo
384
377
# This is unique on win32 platforms, and is the only URL
385
378
# format which does it differently.
386
file:///c|/ => file:///c:/
379
file:///C|/ => file:///C|/
388
381
if not url.endswith('/'):