Add ability for salt.utils.path_join to force the use of posixpath

Also remove unused and unnecessary behavior from this function when the
first path component is of single length. An empty first parameter to
this function will normalze to "." and result in an incorrectly-joined
result.
This commit is contained in:
Erik Johnson 2017-03-28 14:18:29 -05:00
parent 1381f97292
commit cafa08d8e0
2 changed files with 17 additions and 12 deletions

View file

@ -18,6 +18,7 @@ import json
import logging
import numbers
import os
import posixpath
import pprint
import random
import re
@ -870,16 +871,26 @@ def backup_minion(path, bkroot):
os.chmod(bkpath, fstat.st_mode)
def path_join(*parts):
def path_join(*parts, **kwargs):
'''
This functions tries to solve some issues when joining multiple absolute
paths on both *nix and windows platforms.
See tests/unit/utils/path_join_test.py for some examples on what's being
talked about here.
The "use_posixpath" kwarg can be be used to force joining using poxixpath,
which is useful for Salt fileserver paths on Windows masters.
'''
kwargs = salt.utils.clean_kwargs(**kwargs)
use_posixpath = kwargs.pop('use_posixpath', False)
if kwargs:
invalid_kwargs(kwargs)
pathlib = posixpath if use_posixpath else os.path
# Normalize path converting any os.sep as needed
parts = [os.path.normpath(p) for p in parts]
parts = [pathlib.normpath(p) for p in parts]
try:
root = parts.pop(0)
@ -890,14 +901,9 @@ def path_join(*parts):
if not parts:
ret = root
else:
if is_windows():
if len(root) == 1:
root += ':'
root = root.rstrip(os.sep) + os.sep
stripped = [p.lstrip(os.sep) for p in parts]
try:
ret = os.path.join(root, *stripped)
ret = pathlib.join(root, *stripped)
except UnicodeDecodeError:
# This is probably Python 2 and one of the parts contains unicode
# characters in a bytestring. First try to decode to the system
@ -907,13 +913,13 @@ def path_join(*parts):
except NameError:
enc = sys.stdin.encoding or sys.getdefaultencoding()
try:
ret = os.path.join(root.decode(enc),
ret = pathlib.join(root.decode(enc),
*[x.decode(enc) for x in stripped])
except UnicodeDecodeError:
# Last resort, try UTF-8
ret = os.path.join(root.decode('UTF-8'),
ret = pathlib.join(root.decode('UTF-8'),
*[x.decode('UTF-8') for x in stripped])
return os.path.normpath(ret)
return pathlib.normpath(ret)
def pem_finger(path=None, key=None, sum_type='sha256'):

View file

@ -48,7 +48,6 @@ class PathJoinTestCase(TestCase):
((r'c:\\', r'\temp', r'\foo'), 'c:\\temp\\foo'),
(('c:', r'\temp', r'\foo', 'bar'), 'c:\\temp\\foo\\bar'),
(('c:', r'\temp', r'\foo\bar'), 'c:\\temp\\foo\\bar'),
(('c', r'\temp', r'\foo\bar'), 'c:\\temp\\foo\\bar')
)
@skipIf(True, 'Skipped until properly mocked')