11#
2- # Copyright (c) 2015 nexB Inc. and others. All rights reserved.
2+ # Copyright (c) 2017 nexB Inc. and others. All rights reserved.
33# http://nexb.com and https://github.com/nexB/scancode-toolkit/
44# The ScanCode software is licensed under the Apache License version 2.0.
55# Data generated with ScanCode require an acknowledgment.
5959
6060def create_dir (location ):
6161 """
62- Create directory and all sub-directories recursively at location ensuring
63- these are readable and writeable.
62+ Create directory and all sub-directories recursively at location ensuring these
63+ are readable and writeable.
6464 Raise Exceptions if it fails to create the directory.
6565 """
6666 if os .path .exists (location ):
@@ -162,23 +162,65 @@ def read_text_file(location, universal_new_lines=True):
162162# PATHS AND NAMES MANIPULATIONS
163163#
164164
165+ # TODO: move these functions to paths.py
166+
167+ def is_posixpath (location ):
168+ """
169+ Return True if the `location` path is likely a POSIX-like path using POSIX path
170+ separators (slash or "/")or has no path separator.
171+
172+ Return False if the `location` path is likely a Windows-like path using backslash
173+ as path separators (e.g. "\" ).
174+ """
175+ has_slashes = '/' in location
176+ has_backslashes = '\\ ' in location
177+ # windows paths with drive
178+ if location :
179+ drive , _ = ntpath .splitdrive (location )
180+ if drive :
181+ return False
182+
183+
184+ # a path is always POSIX unless it contains ONLY backslahes
185+ # which is a rough approximation (it could still be posix)
186+ is_posix = True
187+ if has_backslashes and not has_slashes :
188+ is_posix = False
189+ return is_posix
190+
191+
165192def as_posixpath (location ):
166193 """
167- Return a posix -like path using posix path separators (slash or "/") for a
168- `location` path. This converts Windows paths to look like posix paths that
169- Python accepts gracefully on Windows for path handling .
194+ Return a POSIX -like path using POSIX path separators (slash or "/") for a
195+ `location` path. This converts Windows paths to look like POSIX paths: Python
196+ accepts gracefully POSIX paths on Windows .
170197 """
171198 return location .replace (ntpath .sep , posixpath .sep )
172199
173200
201+ def as_winpath (location ):
202+ """
203+ Return a Windows-like path using Windows path separators (backslash or "\" ) for a
204+ `location` path.
205+ """
206+ return location .replace (posixpath .sep , ntpath .sep )
207+
208+
209+ def split_parent_resource (path , force_posix = False ):
210+ """
211+ Return a (tuple of parent directory path, resource name).
212+ """
213+ splitter = is_posixpath (path ) and posixpath or ntpath
214+ path = path .rstrip ('/\\ ' )
215+ return splitter .split (path )
216+
217+
174218def resource_name (path ):
175219 """
176220 Return the resource name (file name or directory name) from `path` which
177221 is the last path segment.
178222 """
179- path = as_posixpath (path )
180- path = path .rstrip ('/' )
181- _left , right = posixpath .split (path )
223+ _left , right = split_parent_resource (path )
182224 return right or ''
183225
184226
@@ -191,12 +233,11 @@ def file_name(path):
191233
192234def parent_directory (path ):
193235 """
194- Return the parent directory of a file or directory path.
236+ Return the parent directory path of a file or directory ` path` .
195237 """
196- path = as_posixpath (path )
197- path = path .rstrip ('/' )
198- left , _ = posixpath .split (path )
199- trail = '/' if left != '/' else ''
238+ left , _right = split_parent_resource (path )
239+ sep = is_posixpath (path ) and '/' or '\\ '
240+ trail = sep if left != sep else ''
200241 return left + trail
201242
202243
@@ -267,7 +308,7 @@ def walk(location, ignored=ignore_nothing):
267308
268309 if filetype .is_file (location ) :
269310 yield parent_directory (location ), [], [file_name (location )]
270-
311+
271312 elif filetype .is_dir (location ):
272313 dirs = []
273314 files = []
@@ -326,7 +367,7 @@ def resource_iter(location, ignored=ignore_nothing, with_files=True, with_dirs=T
326367 :param with_files: If True, include the files.
327368 :return: an iterable of file and directory locations.
328369 """
329- assert with_dirs or with_files , "One or both of 'with_dirs' and 'with_files' is required"
370+ assert with_dirs or with_files , "fileutils.resource_iter: One or both of 'with_dirs' and 'with_files' is required"
330371 for top , dirs , files in walk (location , ignored ):
331372 if with_files :
332373 for f in files :
0 commit comments