Robot Framework
robotpath.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import os
17 import os.path
18 import sys
19 from urllib.request import pathname2url as path_to_url
20 
21 from robot.errors import DataError
22 
23 from .encoding import system_decode
24 from .platform import WINDOWS
25 from .robottypes import is_string
26 from .unic import safe_str
27 
28 
29 if WINDOWS:
30  CASE_INSENSITIVE_FILESYSTEM = True
31 else:
32  try:
33  CASE_INSENSITIVE_FILESYSTEM = os.listdir('/tmp') == os.listdir('/TMP')
34  except OSError:
35  CASE_INSENSITIVE_FILESYSTEM = False
36 
37 
38 
46 def normpath(path, case_normalize=False):
47  if not is_string(path):
48  path = system_decode(path)
49  path = safe_str(path) # Handles NFC normalization on OSX
50  path = os.path.normpath(path)
51  if case_normalize and CASE_INSENSITIVE_FILESYSTEM:
52  path = path.lower()
53  if WINDOWS and len(path) == 2 and path[1] == ':':
54  return path + '\\'
55  return path
56 
57 
58 
65 def abspath(path, case_normalize=False):
66  path = normpath(path, case_normalize)
67  return normpath(os.path.abspath(path), case_normalize)
68 
69 
70 
78 def get_link_path(target, base):
79  path = _get_link_path(target, base)
80  url = path_to_url(path)
81  if os.path.isabs(path):
82  url = 'file:' + url
83  return url
84 
85 
86 def _get_link_path(target, base):
87  target = abspath(target)
88  base = abspath(base)
89  if os.path.isfile(base):
90  base = os.path.dirname(base)
91  if base == target:
92  return '.'
93  base_drive, base_path = os.path.splitdrive(base)
94  # Target and base on different drives
95  if os.path.splitdrive(target)[0] != base_drive:
96  return target
97  common_len = len(_common_path(base, target))
98  if base_path == os.sep:
99  return target[common_len:]
100  if common_len == len(base_drive) + len(os.sep):
101  common_len -= len(os.sep)
102  dirs_up = os.sep.join([os.pardir] * base[common_len:].count(os.sep))
103  path = os.path.join(dirs_up, target[common_len + len(os.sep):])
104  return os.path.normpath(path)
105 
106 
107 
115 def _common_path(p1, p2):
116  # os.path.dirname doesn't normalize leading double slash
117  # https://github.com/robotframework/robotframework/issues/3844
118  if p1.startswith('//'):
119  p1 = '/' + p1.lstrip('/')
120  if p2.startswith('//'):
121  p2 = '/' + p2.lstrip('/')
122  while p1 and p2:
123  if p1 == p2:
124  return p1
125  if len(p1) > len(p2):
126  p1 = os.path.dirname(p1)
127  else:
128  p2 = os.path.dirname(p2)
129  return ''
130 
131 
132 def find_file(path, basedir='.', file_type=None):
133  path = os.path.normpath(path.replace('/', os.sep))
134  if os.path.isabs(path):
135  ret = _find_absolute_path(path)
136  else:
137  ret = _find_relative_path(path, basedir)
138  if ret:
139  return ret
140  default = file_type or 'File'
141  file_type = {'Library': 'Library',
142  'Variables': 'Variable file',
143  'Resource': 'Resource file'}.get(file_type, default)
144  raise DataError("%s '%s' does not exist." % (file_type, path))
145 
146 
148  if _is_valid_file(path):
149  return path
150  return None
151 
152 
153 def _find_relative_path(path, basedir):
154  for base in [basedir] + sys.path:
155  if not (base and os.path.isdir(base)):
156  continue
157  if not is_string(base):
158  base = system_decode(base)
159  ret = os.path.abspath(os.path.join(base, path))
160  if _is_valid_file(ret):
161  return ret
162  return None
163 
164 
165 def _is_valid_file(path):
166  return os.path.isfile(path) or \
167  (os.path.isdir(path) and os.path.isfile(os.path.join(path, '__init__.py')))
def system_decode(string)
Definition: encoding.py:82
def _find_absolute_path(path)
Definition: robotpath.py:147
def abspath(path, case_normalize=False)
Replacement for os.path.abspath with some enhancements and bug fixes.
Definition: robotpath.py:65
def find_file(path, basedir='.', file_type=None)
Definition: robotpath.py:132
def get_link_path(target, base)
Returns a relative path to target from base.
Definition: robotpath.py:78
def _find_relative_path(path, basedir)
Definition: robotpath.py:153
def _get_link_path(target, base)
Definition: robotpath.py:86
def _common_path(p1, p2)
Returns the longest path common to p1 and p2.
Definition: robotpath.py:115
def _is_valid_file(path)
Definition: robotpath.py:165
def normpath(path, case_normalize=False)
Replacement for os.path.normpath with some enhancements.
Definition: robotpath.py:46
def safe_str(item)
Definition: unic.py:21