source: rtems-tools/rtemstoolkit/path.py @ 606c08c

4.10
Last change on this file since 606c08c was 606c08c, checked in by Sebastian Huber <sebastian.huber@…>, on Jan 8, 2016 at 6:44:52 AM

rtemstoolkit: msys2 compatibility

  • Property mode set to 100644
File size: 7.5 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-2014 Chris Johns (chrisj@rtems.org)
4# All rights reserved.
5#
6# This file is part of the RTEMS Tools package in 'rtems-tools'.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions are met:
10#
11# 1. Redistributions of source code must retain the above copyright notice,
12# this list of conditions and the following disclaimer.
13#
14# 2. Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29#
30
31#
32# Manage paths locally. The internally the path is in Unix or shell format and
33# we convert to the native format when performing operations at the Python
34# level. This allows macro expansion to work.
35#
36
37import glob
38import os
39import shutil
40import string
41
42from . import error
43from . import log
44
45windows = os.name == 'nt'
46
47def host(path):
48    if path is not None:
49        while '//' in path:
50            path = path.replace('//', '/')
51        if windows and len(path) > 2:
52            if path[0] == '/' and path[2] == '/' and \
53                    (path[1] in string.ascii_lowercase or \
54                         path[1] in string.ascii_uppercase):
55                path = ('%s:%s' % (path[1], path[2:])).replace('/', '\\')
56    return path
57
58def shell(path):
59    if path is not None:
60        if windows and len(path) > 1 and path[1] == ':':
61            path = ('/%s%s' % (path[0], path[2:])).replace('\\', '/')
62        while '//' in path:
63            path = path.replace('//', '/')
64    return path
65
66def basename(path):
67    return shell(os.path.basename(path))
68
69def dirname(path):
70    return shell(os.path.dirname(path))
71
72def join(path, *args):
73    path = shell(path)
74    for arg in args:
75        if len(path):
76            path += '/' + shell(arg)
77        else:
78            path = shell(arg)
79    return shell(path)
80
81def abspath(path):
82    return shell(os.path.abspath(host(path)))
83
84def splitext(path):
85    root, ext = os.path.splitext(host(path))
86    return shell(root), ext
87
88def exists(paths):
89    if type(paths) == list:
90        results = []
91        for p in paths:
92            results += [os.path.exists(host(p))]
93        return results
94    return os.path.exists(host(paths))
95
96def isdir(path):
97    return os.path.isdir(host(path))
98
99def isfile(path):
100    return os.path.isfile(host(path))
101
102def isabspath(path):
103    return path[0] == '/'
104
105def iswritable(path):
106    return os.access(host(path), os.W_OK)
107
108def ispathwritable(path):
109    path = host(path)
110    while len(path) != 0:
111        if os.path.exists(path):
112            return iswritable(path)
113        path = os.path.dirname(path)
114    return False
115
116def mkdir(path):
117    path = host(path)
118    if exists(path):
119        if not isdir(path):
120            raise error.general('path exists and is not a directory: %s' % (path))
121    else:
122        if windows:
123            try:
124                os.makedirs(host(path))
125            except IOError:
126                raise error.general('cannot make directory: %s' % (path))
127            except OSError:
128                raise error.general('cannot make directory: %s' % (path))
129            except WindowsError:
130                raise error.general('cannot make directory: %s' % (path))
131        else:
132            try:
133                os.makedirs(host(path))
134            except IOError:
135                raise error.general('cannot make directory: %s' % (path))
136            except OSError:
137                raise error.general('cannot make directory: %s' % (path))
138
139def removeall(path):
140
141    def _onerror(function, path, excinfo):
142        print('removeall error: (%s) %s' % (excinfo, path))
143
144    path = host(path)
145    shutil.rmtree(path, onerror = _onerror)
146    return
147
148def expand(name, paths):
149    l = []
150    for p in paths:
151        l += [join(p, name)]
152    return l
153
154def collect_files(path_):
155    #
156    # Convert to shell paths and return shell paths.
157    #
158    # @fixme should this use a passed in set of defaults and not
159    #        not the initial set of values ?
160    #
161    path_ = shell(path_)
162    if '*' in path_ or '?' in path_:
163        dir = dirname(path_)
164        base = basename(path_)
165        if len(base) == 0:
166            base = '*'
167        files = []
168        for p in dir.split(':'):
169            hostdir = host(p)
170            for f in glob.glob(os.path.join(hostdir, base)):
171                files += [host(f)]
172    else:
173        files = [host(path_)]
174    return sorted(files)
175
176def copy_tree(src, dst):
177    hsrc = host(src)
178    hdst = host(dst)
179
180    if os.path.exists(src):
181        names = os.listdir(src)
182    else:
183        name = []
184
185    if not os.path.isdir(dst):
186        os.makedirs(dst)
187
188    for name in names:
189        srcname = os.path.join(src, name)
190        dstname = os.path.join(dst, name)
191        try:
192            if os.path.islink(srcname):
193                linkto = os.readlink(srcname)
194                if os.path.exists(dstname):
195                    if os.path.islink(dstname):
196                        dstlinkto = os.readlink(dstname)
197                        if linkto != dstlinkto:
198                            log.warning('copying tree: update of link does not match: %s -> %s' % \
199                                            (dstname, dstlinkto))
200                            os.remove(dstname)
201                    else:
202                        log.warning('copying tree: destination is not a link: %s' % \
203                                        (dstname))
204                        os.remove(dstname)
205                else:
206                    os.symlink(linkto, dstname)
207            elif os.path.isdir(srcname):
208                copy_tree(srcname, dstname)
209            else:
210                shutil.copy2(srcname, dstname)
211        except shutil.Error as err:
212            raise error.general('copying tree: %s -> %s: %s' % (src, dst, str(err)))
213        except EnvironmentError as why:
214            raise error.general('copying tree: %s -> %s: %s' % (srcname, dstname, str(why)))
215    try:
216        shutil.copystat(src, dst)
217    except OSError as why:
218        ok = False
219        if windows:
220            if WindowsError is not None and isinstance(why, WindowsError):
221                ok = True
222        if not ok:
223            raise error.general('copying tree: %s -> %s: %s' % (src, dst, str(why)))
224
225if __name__ == '__main__':
226    print(host('/a/b/c/d-e-f'))
227    print(host('//a/b//c/d-e-f'))
228    print(shell('/w/x/y/z'))
229    print(basename('/as/sd/df/fg/me.txt'))
230    print(dirname('/as/sd/df/fg/me.txt'))
231    print(join('/d', 'g', '/tyty/fgfg'))
232    windows = True
233    print(host('/a/b/c/d-e-f'))
234    print(host('//a/b//c/d-e-f'))
235    print(shell('/w/x/y/z'))
236    print(shell('w:/x/y/z'))
237    print(basename('x:/sd/df/fg/me.txt'))
238    print(dirname('x:/sd/df/fg/me.txt'))
239    print(join('s:/d/', '/g', '/tyty/fgfg'))
Note: See TracBrowser for help on using the repository browser.