source: rtems-source-builder/source-builder/sb/path.py @ edf60aa

4.104.114.95
Last change on this file since edf60aa was edf60aa, checked in by Chris Johns <chrisj@…>, on 02/04/14 at 07:35:33

sb: Do not assume the src is valid.

  • Property mode set to 100644
File size: 6.3 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-2012 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# Permission to use, copy, modify, and/or distribute this software for any
9# purpose with or without fee is hereby granted, provided that the above
10# copyright notice and this permission notice appear in all copies.
11#
12# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20#
21# Manage paths locally. The internally the path is in Unix or shell format and
22# we convert to the native format when performing operations at the Python
23# level. This allows macro expansion to work.
24#
25
26import log
27import os
28import shutil
29import string
30
31import error
32
33windows = os.name == 'nt'
34
35def host(path):
36    if path is not None:
37        while '//' in path:
38            path = path.replace('//', '/')
39        if windows and len(path) > 2:
40            if path[0] == '/' and path[2] == '/' and \
41                    (path[1] in string.ascii_lowercase or \
42                         path[1] in string.ascii_uppercase):
43                path = ('%s:%s' % (path[1], path[2:])).replace('/', '\\')
44    return path
45
46def shell(path):
47    if path is not None:
48        if windows and len(path) > 1 and path[1] == ':':
49            path = ('/%s%s' % (path[0], path[2:])).replace('\\', '/')
50        while '//' in path:
51            path = path.replace('//', '/')
52    return path
53
54def basename(path):
55    return shell(os.path.basename(path))
56
57def dirname(path):
58    return shell(os.path.dirname(path))
59
60def join(path, *args):
61    path = shell(path)
62    for arg in args:
63        if len(path):
64            path += '/' + shell(arg)
65        else:
66            path = shell(arg)
67    return shell(path)
68
69def abspath(path):
70    return shell(os.path.abspath(host(path)))
71
72def splitext(path):
73    root, ext = os.path.splitext(host(path))
74    return shell(root), ext
75
76def exists(paths):
77    if type(paths) == list:
78        results = []
79        for p in paths:
80            results += [os.path.exists(host(p))]
81        return results
82    return os.path.exists(host(paths))
83
84def isdir(path):
85    return os.path.isdir(host(path))
86
87def isfile(path):
88    return os.path.isfile(host(path))
89
90def isabspath(path):
91    return path[0] == '/'
92
93def iswritable(path):
94    return os.access(host(path), os.W_OK)
95
96def ispathwritable(path):
97    path = host(path)
98    while len(path) != 0:
99        if os.path.exists(path):
100            return iswritable(path)
101        path = os.path.dirname(path)
102    return False
103
104def mkdir(path):
105    path = host(path)
106    if exists(path):
107        if not isdir(path):
108            raise error.general('path exists and is not a directory: %s' % (path))
109    else:
110        if windows:
111            try:
112                os.makedirs(host(path))
113            except IOError, err:
114                raise error.general('cannot make directory: %s' % (path))
115            except OSError, err:
116                raise error.general('cannot make directory: %s' % (path))
117            except WindowsError, err:
118                raise error.general('cannot make directory: %s' % (path))
119        else:
120            try:
121                os.makedirs(host(path))
122            except IOError, err:
123                raise error.general('cannot make directory: %s' % (path))
124            except OSError, err:
125                raise error.general('cannot make directory: %s' % (path))
126
127def removeall(path):
128
129    def _onerror(function, path, excinfo):
130        print 'removeall error: (%s) %s' % (excinfo, path)
131
132    path = host(path)
133    shutil.rmtree(path, onerror = _onerror)
134    return
135
136def expand(name, paths):
137    l = []
138    for p in paths:
139        l += [join(p, name)]
140    return l
141
142def copy_tree(src, dst):
143    hsrc = host(src)
144    hdst = host(dst)
145
146    if os.path.exists(src):
147        names = os.listdir(src)
148    else:
149        names = []
150
151    if not os.path.isdir(dst):
152        os.makedirs(dst)
153
154    for name in names:
155        srcname = os.path.join(src, name)
156        dstname = os.path.join(dst, name)
157        try:
158            if os.path.islink(srcname):
159                linkto = os.readlink(srcname)
160                if os.path.exists(dstname):
161                    if os.path.islink(dstname):
162                        dstlinkto = os.readlink(dstname)
163                        if linkto != dstlinkto:
164                            log.warning('copying tree: update of link does not match: %s -> %s' % \
165                                            (dstname, dstlinkto))
166                            os.remove(dstname)
167                    else:
168                        log.warning('copying tree: destination is not a link: %s' % \
169                                        (dstname))
170                        os.remove(dstname)
171                else:
172                    os.symlink(linkto, dstname)
173            elif os.path.isdir(srcname):
174                copy_tree(srcname, dstname)
175            else:
176                shutil.copy2(srcname, dstname)
177        except shutil.Error, err:
178            raise error.general('copying tree: %s -> %s: %s' % (src, dst, str(err)))
179        except EnvironmentError, why:
180            raise error.general('copying tree: %s -> %s: %s' % (srcname, dstname, str(why)))
181    try:
182        shutil.copystat(src, dst)
183    except OSError, why:
184        if windows:
185            if WindowsError is not None and isinstance(why, WindowsError):
186                pass
187        else:
188            raise error.general('copying tree: %s -> %s: %s' % (src, dst, str(why)))
189
190if __name__ == '__main__':
191    print host('/a/b/c/d-e-f')
192    print host('//a/b//c/d-e-f')
193    print shell('/w/x/y/z')
194    print basename('/as/sd/df/fg/me.txt')
195    print dirname('/as/sd/df/fg/me.txt')
196    print join('/d', 'g', '/tyty/fgfg')
197    windows = True
198    print host('/a/b/c/d-e-f')
199    print host('//a/b//c/d-e-f')
200    print shell('/w/x/y/z')
201    print shell('w:/x/y/z')
202    print basename('x:/sd/df/fg/me.txt')
203    print dirname('x:/sd/df/fg/me.txt')
204    print join('s:/d/', '/g', '/tyty/fgfg')
Note: See TracBrowser for help on using the repository browser.