Robot Framework Integrated Development Environment (RIDE)
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 
20 from robotide.lib.robot.errors import DataError
21 
22 from .encoding import system_decode
23 from .platform import IRONPYTHON, PY_VERSION, PY2, WINDOWS
24 from .robottypes import is_unicode
25 from .unic import unic
26 
27 
28 if IRONPYTHON and PY_VERSION == (2, 7, 8):
29  # https://github.com/IronLanguages/ironpython2/issues/371
30  def _abspath(path):
31  if os.path.isabs(path):
32  if not os.path.splitdrive(path)[0]:
33  drive = os.path.splitdrive(os.getcwd())[0]
34  return drive + path
35  return path
36  return os.path.abspath(path)
37 else:
38 
41  _abspath = os.path.abspath
42 
43 if PY2:
44  from urllib import pathname2url
45 
46  def path_to_url(path):
47  return pathname2url(path.encode('UTF-8'))
48 else:
49  from urllib.request import pathname2url as path_to_url
50 
51 if WINDOWS:
52  CASE_INSENSITIVE_FILESYSTEM = True
53 else:
54  try:
55  CASE_INSENSITIVE_FILESYSTEM = os.listdir('/tmp') == os.listdir('/TMP')
56  except OSError:
57  CASE_INSENSITIVE_FILESYSTEM = False
58 
59 
60 
68 def normpath(path, case_normalize=False):
69  if not is_unicode(path):
70  path = system_decode(path)
71  path = unic(path) # Handles NFC normalization on OSX
72  path = os.path.normpath(path)
73  if case_normalize and CASE_INSENSITIVE_FILESYSTEM:
74  path = path.lower()
75  if WINDOWS and len(path) == 2 and path[1] == ':':
76  return path + '\\'
77  return path
78 
79 
80 
87 def abspath(path, case_normalize=False):
88  path = normpath(path, case_normalize)
89  return normpath(_abspath(path), case_normalize)
90 
91 
92 
100 def get_link_path(target, base):
101  path = _get_link_path(target, base)
102  url = path_to_url(path)
103  if os.path.isabs(path):
104  url = 'file:' + url
105  return url
106 
107 def _get_link_path(target, base):
108  target = abspath(target)
109  base = abspath(base)
110  if os.path.isfile(base):
111  base = os.path.dirname(base)
112  if base == target:
113  return '.'
114  base_drive, base_path = os.path.splitdrive(base)
115  # Target and base on different drives
116  if os.path.splitdrive(target)[0] != base_drive:
117  return target
118  common_len = len(_common_path(base, target))
119  if base_path == os.sep:
120  return target[common_len:]
121  if common_len == len(base_drive) + len(os.sep):
122  common_len -= len(os.sep)
123  dirs_up = os.sep.join([os.pardir] * base[common_len:].count(os.sep))
124  path = os.path.join(dirs_up, target[common_len + len(os.sep):])
125  return os.path.normpath(path)
126 
127 
135 def _common_path(p1, p2):
136  while p1 and p2:
137  if p1 == p2:
138  return p1
139  if len(p1) > len(p2):
140  p1 = os.path.dirname(p1)
141  else:
142  p2 = os.path.dirname(p2)
143  return ''
144 
145 
146 def find_file(path, basedir='.', file_type=None):
147  path = os.path.normpath(path.replace('/', os.sep))
148  if os.path.isabs(path):
149  ret = _find_absolute_path(path)
150  else:
151  ret = _find_relative_path(path, basedir)
152  if ret:
153  return ret
154  default = file_type or 'File'
155  file_type = {'Library': 'Test library',
156  'Variables': 'Variable file',
157  'Resource': 'Resource file'}.get(file_type, default)
158  raise DataError("%s '%s' does not exist." % (file_type, path))
159 
160 
162  if _is_valid_file(path):
163  return path
164  return None
165 
166 
167 def _find_relative_path(path, basedir):
168  for base in [basedir] + sys.path:
169  if not (base and os.path.isdir(base)):
170  continue
171  if not is_unicode(base):
172  base = system_decode(base)
173  ret = os.path.abspath(os.path.join(base, path))
174  if _is_valid_file(ret):
175  return ret
176  return None
177 
178 
179 def _is_valid_file(path):
180  return os.path.isfile(path) or \
181  (os.path.isdir(path) and os.path.isfile(os.path.join(path, '__init__.py')))
Used when variable does not exist.
Definition: errors.py:67
def system_decode(string)
Decodes bytes from system (e.g.
Definition: encoding.py:81
def _common_path(p1, p2)
Returns the longest path common to p1 and p2.
Definition: robotpath.py:135
def _get_link_path(target, base)
Definition: robotpath.py:107
def _find_relative_path(path, basedir)
Definition: robotpath.py:167
def abspath(path, case_normalize=False)
Replacement for os.path.abspath with some enhancements and bug fixes.
Definition: robotpath.py:87
def find_file(path, basedir='.', file_type=None)
Definition: robotpath.py:146
def normpath(path, case_normalize=False)
Replacement for os.path.normpath with some enhancements.
Definition: robotpath.py:68
def get_link_path(target, base)
Returns a relative path to target from base.
Definition: robotpath.py:100