summaryrefslogtreecommitdiff
path: root/rtemstoolkit/path.py
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2014-02-15 06:30:06 +1100
committerChris Johns <chrisj@rtems.org>2014-02-15 06:30:06 +1100
commit50fdf12244e784bd52732be1e68d966bc9629b24 (patch)
tree93b6656d397f3ef358b50aeaef6dc4d10a653f8c /rtemstoolkit/path.py
parent8f75c4a380cb0a4330f65966784ccdfeff756e70 (diff)
rt: Add the rtems-tester.
Diffstat (limited to 'rtemstoolkit/path.py')
-rw-r--r--rtemstoolkit/path.py239
1 files changed, 239 insertions, 0 deletions
diff --git a/rtemstoolkit/path.py b/rtemstoolkit/path.py
new file mode 100644
index 0000000..238e6d9
--- /dev/null
+++ b/rtemstoolkit/path.py
@@ -0,0 +1,239 @@
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010-2014 Chris Johns (chrisj@rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# Manage paths locally. The internally the path is in Unix or shell format and
+# we convert to the native format when performing operations at the Python
+# level. This allows macro expansion to work.
+#
+
+import glob
+import log
+import os
+import shutil
+import string
+
+import error
+
+windows = os.name == 'nt'
+
+def host(path):
+ if path is not None:
+ while '//' in path:
+ path = path.replace('//', '/')
+ if windows and len(path) > 2:
+ if path[0] == '/' and path[2] == '/' and \
+ (path[1] in string.ascii_lowercase or \
+ path[1] in string.ascii_uppercase):
+ path = ('%s:%s' % (path[1], path[2:])).replace('/', '\\')
+ return path
+
+def shell(path):
+ if path is not None:
+ if windows and len(path) > 1 and path[1] == ':':
+ path = ('/%s%s' % (path[0], path[2:])).replace('\\', '/')
+ while '//' in path:
+ path = path.replace('//', '/')
+ return path
+
+def basename(path):
+ return shell(os.path.basename(path))
+
+def dirname(path):
+ return shell(os.path.dirname(path))
+
+def join(path, *args):
+ path = shell(path)
+ for arg in args:
+ if len(path):
+ path += '/' + shell(arg)
+ else:
+ path = shell(arg)
+ return shell(path)
+
+def abspath(path):
+ return shell(os.path.abspath(host(path)))
+
+def splitext(path):
+ root, ext = os.path.splitext(host(path))
+ return shell(root), ext
+
+def exists(paths):
+ if type(paths) == list:
+ results = []
+ for p in paths:
+ results += [os.path.exists(host(p))]
+ return results
+ return os.path.exists(host(paths))
+
+def isdir(path):
+ return os.path.isdir(host(path))
+
+def isfile(path):
+ return os.path.isfile(host(path))
+
+def isabspath(path):
+ return path[0] == '/'
+
+def iswritable(path):
+ return os.access(host(path), os.W_OK)
+
+def ispathwritable(path):
+ path = host(path)
+ while len(path) != 0:
+ if os.path.exists(path):
+ return iswritable(path)
+ path = os.path.dirname(path)
+ return False
+
+def mkdir(path):
+ path = host(path)
+ if exists(path):
+ if not isdir(path):
+ raise error.general('path exists and is not a directory: %s' % (path))
+ else:
+ if windows:
+ try:
+ os.makedirs(host(path))
+ except IOError, err:
+ raise error.general('cannot make directory: %s' % (path))
+ except OSError, err:
+ raise error.general('cannot make directory: %s' % (path))
+ except WindowsError, err:
+ raise error.general('cannot make directory: %s' % (path))
+ else:
+ try:
+ os.makedirs(host(path))
+ except IOError, err:
+ raise error.general('cannot make directory: %s' % (path))
+ except OSError, err:
+ raise error.general('cannot make directory: %s' % (path))
+
+def removeall(path):
+
+ def _onerror(function, path, excinfo):
+ print 'removeall error: (%s) %s' % (excinfo, path)
+
+ path = host(path)
+ shutil.rmtree(path, onerror = _onerror)
+ return
+
+def expand(name, paths):
+ l = []
+ for p in paths:
+ l += [join(p, name)]
+ return l
+
+def collect_files(path_):
+ #
+ # Convert to shell paths and return shell paths.
+ #
+ # @fixme should this use a passed in set of defaults and not
+ # not the initial set of values ?
+ #
+ path_ = shell(path_)
+ if '*' in path_ or '?' in path_:
+ dir = dirname(path_)
+ base = basename(path_)
+ if len(base) == 0:
+ base = '*'
+ files = []
+ for p in dir.split(':'):
+ hostdir = host(p)
+ for f in glob.glob(os.path.join(hostdir, base)):
+ files += [host(f)]
+ else:
+ files = [host(path_)]
+ return sorted(files)
+
+def copy_tree(src, dst):
+ hsrc = host(src)
+ hdst = host(dst)
+
+ if os.path.exists(src):
+ names = os.listdir(src)
+ else:
+ name = []
+
+ if not os.path.isdir(dst):
+ os.makedirs(dst)
+
+ for name in names:
+ srcname = os.path.join(src, name)
+ dstname = os.path.join(dst, name)
+ try:
+ if os.path.islink(srcname):
+ linkto = os.readlink(srcname)
+ if os.path.exists(dstname):
+ if os.path.islink(dstname):
+ dstlinkto = os.readlink(dstname)
+ if linkto != dstlinkto:
+ log.warning('copying tree: update of link does not match: %s -> %s' % \
+ (dstname, dstlinkto))
+ os.remove(dstname)
+ else:
+ log.warning('copying tree: destination is not a link: %s' % \
+ (dstname))
+ os.remove(dstname)
+ else:
+ os.symlink(linkto, dstname)
+ elif os.path.isdir(srcname):
+ copy_tree(srcname, dstname)
+ else:
+ shutil.copy2(srcname, dstname)
+ except shutil.Error, err:
+ raise error.general('copying tree: %s -> %s: %s' % (src, dst, str(err)))
+ except EnvironmentError, why:
+ raise error.general('copying tree: %s -> %s: %s' % (srcname, dstname, str(why)))
+ try:
+ shutil.copystat(src, dst)
+ except OSError, why:
+ ok = False
+ if windows:
+ if WindowsError is not None and isinstance(why, WindowsError):
+ ok = True
+ if not ok:
+ raise error.general('copying tree: %s -> %s: %s' % (src, dst, str(why)))
+
+if __name__ == '__main__':
+ print host('/a/b/c/d-e-f')
+ print host('//a/b//c/d-e-f')
+ print shell('/w/x/y/z')
+ print basename('/as/sd/df/fg/me.txt')
+ print dirname('/as/sd/df/fg/me.txt')
+ print join('/d', 'g', '/tyty/fgfg')
+ windows = True
+ print host('/a/b/c/d-e-f')
+ print host('//a/b//c/d-e-f')
+ print shell('/w/x/y/z')
+ print shell('w:/x/y/z')
+ print basename('x:/sd/df/fg/me.txt')
+ print dirname('x:/sd/df/fg/me.txt')
+ print join('s:/d/', '/g', '/tyty/fgfg')